Merge branch 'master' into senslab2
[sfa.git] / sfa / senslab / slabpostgres.py
1 import sys
2
3 from sqlalchemy import create_engine, and_
4 from sqlalchemy.orm import sessionmaker
5
6 from sfa.util.config import Config
7 from sfa.util.sfalogging import logger
8
9 from sqlalchemy import Column, Integer, String, DateTime
10 from sqlalchemy import Table, Column, MetaData, join, ForeignKey
11 import sfa.storage.model as model
12 from sfa.storage.model import RegSlice
13 from sqlalchemy.ext.declarative import declarative_base
14 from sqlalchemy.orm import relationship, backref
15
16
17 from sqlalchemy.dialects import postgresql
18
19 from sqlalchemy import MetaData, Table
20 from sqlalchemy.exc import NoSuchTableError
21
22 from sqlalchemy import String
23 from sfa.storage.alchemy import dbsession
24
25 #Dict holding the columns names of the table as keys
26 #and their type, used for creation of the table
27 slice_table = {'record_id_user':'integer PRIMARY KEY references X ON DELETE CASCADE ON UPDATE CASCADE','oar_job_id':'integer DEFAULT -1',  'record_id_slice':'integer', 'slice_hrn':'text NOT NULL'}
28
29 #Dict with all the specific senslab tables
30 tablenames_dict = {'slice_senslab': slice_table}
31
32 ##############################
33
34
35
36 SlabBase = declarative_base()
37
38
39
40
41 class SliceSenslab (SlabBase):
42     __tablename__ = 'slice_senslab' 
43     #record_id_user = Column(Integer, primary_key=True)
44
45     slice_hrn = Column(String,primary_key=True)
46     peer_authority = Column( String,nullable = True)
47     record_id_slice = Column(Integer)    
48     record_id_user = Column(Integer) 
49
50     #oar_job_id = Column( Integer,default = -1)
51     #node_list = Column(postgresql.ARRAY(String), nullable =True)
52     
53     def __init__ (self, slice_hrn =None, record_id_slice=None, record_id_user= None,peer_authority=None):
54         if record_id_slice: 
55             self.record_id_slice = record_id_slice
56         if slice_hrn:
57             self.slice_hrn = slice_hrn
58         if record_id_user: 
59             self.record_id_user= record_id_user
60         if peer_authority:
61             self.peer_authority = peer_authority
62             
63             
64     def __repr__(self):
65         result="<Record id user =%s, slice hrn=%s, Record id slice =%s ,peer_authority =%s"% \
66                 (self.record_id_user, self.slice_hrn, self.record_id_slice, self.peer_authority)
67         result += ">"
68         return result
69           
70     def dump_sqlalchemyobj_to_dict(self):
71         dict = {'slice_hrn':self.slice_hrn,
72         'peer_authority':self.peer_authority,
73         'record_id':self.record_id_slice, 
74         'record_id_user':self.record_id_user,
75         'record_id_slice':self.record_id_slice, }
76         return dict 
77           
78              
79
80 #class PeerSenslab(SlabBase):
81     #__tablename__ = 'peer_senslab' 
82     #peername = Column(String, nullable = False)
83     #peerid = Column( Integer,primary_key=True)
84     
85     #def __init__ (self,peername = None ):
86         #if peername:
87             #self.peername = peername
88             
89             
90       #def __repr__(self):
91         #result="<Peer id  =%s, Peer name =%s" % (self.peerid, self.peername)
92         #result += ">"
93         #return result
94           
95 class SlabDB:
96     def __init__(self,config, debug = False):
97         self.sl_base = SlabBase
98         dbname="slab_sfa"
99         if debug == True :
100             l_echo_pool = True
101             l_echo=True 
102         else :
103             l_echo_pool = False
104             l_echo = False 
105         # will be created lazily on-demand
106         self.slab_session = None
107         # the former PostgreSQL.py used the psycopg2 directly and was doing
108         #self.connection.set_client_encoding("UNICODE")
109         # it's unclear how to achieve this in sqlalchemy, nor if it's needed at all
110         # http://www.sqlalchemy.org/docs/dialects/postgresql.html#unicode
111         # we indeed have /var/lib/pgsql/data/postgresql.conf where
112         # this setting is unset, it might be an angle to tweak that if need be
113         # try a unix socket first - omitting the hostname does the trick
114         unix_url = "postgresql+psycopg2://%s:%s@:%s/%s"%\
115             (config.SFA_DB_USER,config.SFA_DB_PASSWORD,config.SFA_DB_PORT,dbname)
116         print >>sys.stderr, " \r\n \r\n SLAPOSTGRES INIT unix_url %s" %(unix_url)
117         # the TCP fallback method
118         tcp_url = "postgresql+psycopg2://%s:%s@%s:%s/%s"%\
119             (config.SFA_DB_USER,config.SFA_DB_PASSWORD,config.SFA_DB_HOST,config.SFA_DB_PORT,dbname)
120         for url in [ unix_url, tcp_url ] :
121             try:
122                 self.slab_engine = create_engine (url,echo_pool = l_echo_pool, echo = l_echo)
123                 self.check()
124                 self.url=url
125                 return
126             except:
127                 pass
128         self.slab_engine=None
129         raise Exception,"Could not connect to database"
130     
131     
132     
133     def check (self):
134         self.slab_engine.execute ("select 1").scalar()
135         
136         
137         
138     def session (self):
139         if self.slab_session is None:
140             Session=sessionmaker ()
141             self.slab_session=Session(bind=self.slab_engine)
142         return self.slab_session
143         
144         
145    
146         
147     #Close connection to database
148     def close(self):
149         if self.connection is not None:
150             self.connection.close()
151             self.connection = None
152             
153    
154         
155         
156     def exists(self, tablename):
157         """
158         Checks if the table specified as tablename exists.
159     
160         """
161        
162         try:
163             metadata = MetaData (bind=self.slab_engine)
164             table=Table (tablename, metadata, autoload=True)
165            
166             return True
167         except NoSuchTableError:
168             print>>sys.stderr, " \r\n \r\n \t SLABPOSTGRES EXISTS NOPE! tablename %s " %(tablename)
169             return False
170        
171     
172     def createtable(self, tablename ):
173         """
174         Creates the specifed table. Uses the global dictionnary holding the tablenames and
175         the table schema.
176     
177         """
178
179         print>>sys.stderr, " \r\n \r\n \t SLABPOSTGRES createtable SlabBase.metadata.sorted_tables %s \r\n engine %s" %(SlabBase.metadata.sorted_tables , slab_engine)
180         SlabBase.metadata.create_all(slab_engine)
181         return
182     
183     
184
185        
186
187
188 from sfa.util.config import Config
189
190 slab_alchemy= SlabDB(Config())
191 slab_engine=slab_alchemy.slab_engine
192 slab_dbsession=slab_alchemy.session()