can update and delete using sqlalchemy
[sfa.git] / sfa / storage / persistentobjs.py
1 from types import StringTypes
2
3 from sqlalchemy import create_engine
4 from sqlalchemy import Column, Integer, String, DateTime
5 from sqlalchemy import Table, Column, MetaData, join, ForeignKey
6 from sqlalchemy.orm import relationship, backref
7 from sqlalchemy.orm import column_property
8 from sqlalchemy.ext.declarative import declarative_base
9
10 from sfa.util.sfalogging import logger
11
12 from sfa.trust.gid import GID
13
14 from sfa.storage.alchemy import Base, alchemy, dbsession, engine, AlchemyObj
15
16 ##############################
17 class Type (Base):
18     __table__ = Table ('types', Base.metadata,
19                        Column ('type',String, primary_key=True)
20                        )
21     def __init__ (self, type): self.type=type
22     def __repr__ (self): return "<Type %s>"%self.type
23     
24 #BUILTIN_TYPES = [ 'authority', 'slice', 'node', 'user' ]
25 # xxx for compat but sounds useless
26 BUILTIN_TYPES = [ 'authority', 'slice', 'node', 'user',
27                   'authority+sa', 'authority+am', 'authority+sm' ]
28
29 def insert_builtin_types(engine,dbsession):
30     Base.metadata.create_all(engine)
31     for type in BUILTIN_TYPES :
32         count = dbsession.query (Type).filter_by (type=type).count()
33         if count==0:
34             dbsession.add (Type (type))
35     dbsession.commit()
36
37 ##############################
38 class RegRecord (Base,AlchemyObj):
39     # xxx tmp would be 'records'
40     __table__ = Table ('records', Base.metadata,
41                        Column ('record_id', Integer, primary_key=True),
42                        Column ('type', String, ForeignKey ("types.type")),
43                        Column ('hrn',String),
44                        Column ('gid',String),
45                        Column ('authority',String),
46                        Column ('peer_authority',String),
47                        Column ('pointer',Integer,default=-1),
48                        Column ('date_created',DateTime),
49                        Column ('last_updated',DateTime),
50                        )
51     def __init__ (self, type, hrn=None, gid=None, authority=None, peer_authority=None, pointer=-1):
52         self.type=type
53         if hrn: self.hrn=hrn
54         if gid: 
55             if isinstance(gid, StringTypes): self.gid=gid
56             else: self.gid=gid.save_to_string(save_parents=True)
57         if authority: self.authority=authority
58         if peer_authority: self.peer_authority=peer_authority
59         self.pointer=pointer
60
61     def __repr__(self):
62         result="[Record(record_id=%s, hrn=%s, type=%s, authority=%s, pointer=%s" % \
63                 (self.record_id, self.hrn, self.type, self.authority, self.pointer)
64         if self.gid: result+=" %s..."%self.gid[:10]
65         else: result+=" no-gid"
66         result += "]"
67         return result
68
69     def get_gid_object (self):
70         if not self.gid: return None
71         else: return GID(string=self.gid)
72
73 ##############################
74 class User (Base):
75     __table__ = Table ('users', Base.metadata,
76                        Column ('user_id', Integer, primary_key=True),
77                        Column ('record_id',Integer, ForeignKey('records.record_id')),
78                        Column ('email', String),
79                        )
80     def __init__ (self, email):
81         self.email=email
82     def __repr__ (self): return "<User(%d) %s, record_id=%d>"%(self.user_id,self.email,self.record_id,)
83                            
84 record_table = RegRecord.__table__
85 user_table = User.__table__
86 record_user_join = join (record_table, user_table)
87
88 class UserRecord (Base):
89     __table__ = record_user_join
90     record_id = column_property (record_table.c.record_id, user_table.c.record_id)
91     user_id = user_table.c.user_id
92     def __init__ (self, gid, email):
93         self.type='user'
94         self.gid=gid
95         self.email=email
96     def __repr__ (self): return "<UserRecord %s %s>"%(self.email,self.gid)
97
98 ##############################    
99 def init_tables():
100     logger.info("Initializing db schema and builtin types")
101     Base.metadata.create_all(engine)
102     insert_builtin_types(engine,dbsession)
103
104 def drop_tables():
105     logger.info("Dropping tables")
106     Base.metadata.drop_all(engine)