2 import psycopg2.extensions
3 psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
4 # UNICODEARRAY not exported yet
5 psycopg2.extensions.register_type(psycopg2._psycopg.UNICODEARRAY)
6 from sfa.util.config import Config
7 from sfa.util.table import SfaTable
8 from sfa.util.sfalogging import logger
9 # allow to run sfa2wsdl if this is missing (for mac)
12 except: print >> sys.stderr, "WARNING, could not import pgdb"
14 #Dict holding the columns names of the table as keys
15 #and their type, used for creation of the table
16 slice_table = {'record_id_user':'integer PRIMARY KEY references sfa ON DELETE CASCADE ON UPDATE CASCADE','oar_job_id':'integer DEFAULT -1', 'record_id_slice':'integer', 'slice_hrn':'text NOT NULL'}
18 #Dict with all the specific senslab tables
19 tablenames_dict = {'slice': slice_table}
23 self.config = Config()
24 self.connection = None
27 if self.connection is None:
28 # (Re)initialize database connection
31 # Try UNIX socket first
32 self.connection = psycopg2.connect(user = 'sfa',
35 #self.connection = psycopg2.connect(user = self.config.SFA_PLC_DB_USER,
36 #password = self.config.SFA_PLC_DB_PASSWORD,
37 #database = self.config.SFA_PLC_DB_NAME)
38 except psycopg2.OperationalError:
40 self.connection = psycopg2.connect(user = self.config.SFA_PLC_DB_USER,
41 password = self.config.SFA_PLC_DB_PASSWORD,
42 database = self.config.SFA_PLC_DB_NAME,
43 host = self.config.SFA_PLC_DB_HOST,
44 port = self.config.SFA_PLC_DB_PORT)
45 self.connection.set_client_encoding("UNICODE")
47 self.connection = pgdb.connect(user = self.config.SFA_PLC_DB_USER,
48 password = self.config.SFA_PLC_DB_PASSWORD,
49 host = "%s:%d" % (self.config.SFA_PLC_DB_HOST, self.config.SFA_PLC_DB_PORT),
50 database = self.config.SFA_PLC_DB_NAME)
52 return self.connection.cursor()
54 #Close connection to database
56 if self.connection is not None:
57 self.connection.close()
58 self.connection = None
60 def selectall(self, query, hashref = True, key_field = None):
62 Return each row as a dictionary keyed on field name (like DBI
63 selectrow_hashref()). If key_field is specified, return rows
64 as a dictionary keyed on the specified field (like DBI
68 cursor = self.cursor()
70 rows = cursor.fetchall()
72 self.connection.commit()
74 if hashref or key_field is not None:
75 # Return each row as a dictionary keyed on field name
76 # (like DBI selectrow_hashref()).
77 labels = [column[0] for column in cursor.description]
78 rows = [dict(zip(labels, row)) for row in rows]
80 if key_field is not None and key_field in labels:
81 # Return rows as a dictionary keyed on the specified field
82 # (like DBI selectall_hashref()).
83 return dict([(row[key_field], row) for row in rows])
88 def exists(self, tablename):
90 Checks if the table specified as tablename exists.
94 sql = "SELECT * from pg_tables"
96 #rows = mark.fetchall()
98 #labels = [column[0] for column in mark.description]
99 #rows = [dict(zip(labels, row)) for row in rows]
100 rows = self.selectall(sql)
101 rows = filter(lambda row: row['tablename'].startswith(tablename), rows)
106 def createtable(self, tablename ):
108 Creates the specifed table. Uses the global dictionnary holding the tablenames and
114 if tablename not in tablenames_dict:
115 logger.error("Tablename unknown - creation failed")
118 T = tablenames_dict[tablename]
121 tmp = str(k) +' ' + T[k]
122 tablelist.append(tmp)
124 end_of_statement = ",".join(tablelist)
126 statement = "CREATE TABLE " + tablename + " ("+ end_of_statement +");"
128 #template = "CREATE INDEX %s_%s_idx ON %s (%s);"
129 #indexes = [template % ( self.tablename, field, self.tablename, field) \
130 #for field in ['hrn', 'type', 'authority', 'peer_authority', 'pointer']]
131 # IF EXISTS doenst exist in postgres < 8.2
133 mark.execute('DROP TABLE IF EXISTS ' + tablename +';')
136 mark.execute('DROP TABLE' + tablename +';')
140 mark.execute(statement)
141 #for index in indexes:
143 self.connection.commit()
151 def insert(self, table, columns,values):
153 Inserts data (values) into the columns of the specified table.
157 statement = "INSERT INTO " + table + \
158 "(" + ",".join(columns) + ") " + \
159 "VALUES(" + ", ".join(values) + ");"
161 mark.execute(statement)
162 self.connection.commit()
167 def insert_slab_slice(self, person_rec):
169 Inserts information about a user and his slice into the slice table.
172 sfatable = SfaTable()
173 keys = slice_table.keys()
175 #returns a list of records from the sfa table (dicts)
176 #the filters specified will return only one matching record, into a list of dicts
177 #Finds the slice associated with the user (Senslabs slices hrns contains the user hrn)
179 userrecord = sfatable.find({'hrn': person_rec['hrn'], 'type':'user'})
180 slicerec = sfatable.find({'hrn': person_rec['hrn']+'_slice', 'type':'slice'})
182 if (isinstance (userrecord, list)):
183 userrecord = userrecord[0]
184 if (isinstance (slicerec, list)):
185 slicerec = slicerec[0]
188 values = [ str(oar_dflt_jobid), ' \''+ str(slicerec['hrn']) + '\'', str(userrecord['record_id']), str( slicerec['record_id'])]
190 self.insert('slice', keys, values)
192 logger.error("Trying to import a not senslab slice")
196 def update(self, table, column_names, values, whereclause, valueclause):
198 Updates a record in a given table.
201 #Creates the values string for the update SQL command
202 if len(column_names) is not len(values):
206 valuesdict = dict(zip(column_names,values))
207 for k in valuesdict.keys():
208 valuesdict[k] = str(valuesdict[k])
209 v = ' \''+ str(k) + '\''+ '='+' \''+ valuesdict[k]+'\''
212 statement = "UPDATE %s SET %s WHERE %s = %s" % \
213 (table, ", ".join(valueslist), whereclause, valueclause)
216 mark.execute(statement)
217 self.connection.commit()
223 def update_senslab_slice(self, slice_rec):
224 sfatable = SfaTable()
225 userhrn = slice_rec['hrn'].strip('_slice')
226 userrecord = sfatable.find({'hrn': userhrn, 'type':'user'})
227 if (isinstance (userrecord, list)):
228 userrecord = userrecord[0]
229 columns = [ 'record_user_id', 'oar_job_id']
230 values = [slice_rec['record_user_id'],slice_rec['oar_job_id']]
231 self.update('slice',columns, values,'record_slice_id', slice_rec['record_slice_id'])
235 def find(self, tablename,record_filter = None, columns=None):
239 columns = ",".join(columns)
240 sql = "SELECT %s FROM %s WHERE True " % (columns, tablename)
242 #if isinstance(record_filter, (list, tuple, set)):
243 #ints = filter(lambda x: isinstance(x, (int, long)), record_filter)
244 #strs = filter(lambda x: isinstance(x, StringTypes), record_filter)
245 #record_filter = Filter(SfaRecord.all_fields, {'record_id': ints, 'hrn': strs})
246 #sql += "AND (%s) %s " % record_filter.sql("OR")
247 #elif isinstance(record_filter, dict):
248 #record_filter = Filter(SfaRecord.all_fields, record_filter)
249 #sql += " AND (%s) %s" % record_filter.sql("AND")
250 #elif isinstance(record_filter, StringTypes):
251 #record_filter = Filter(SfaRecord.all_fields, {'hrn':[record_filter]})
252 #sql += " AND (%s) %s" % record_filter.sql("AND")
253 #elif isinstance(record_filter, int):
254 #record_filter = Filter(SfaRecord.all_fields, {'record_id':[record_filter]})
255 #sql += " AND (%s) %s" % record_filter.sql("AND")
257 if isinstance(record_filter, dict):
258 for k in record_filter.keys():
259 sql += "AND "+' \''+ str(k) + '\''+ '='+' \''+ str(record_filter[k])+'\''
261 elif isinstance(record_filter, str):
262 sql += "AND slice_hrn ="+ ' \''+record_filter+'\''
264 #elif isinstance(record_filter, int):
265 #record_filter = Filter(SfaRecord.all_fields, {'record_id':[record_filter]})
266 #sql += " AND (%s) %s" % record_filter.sql("AND")
268 print>>sys.stderr, " \r\n \r\n \t SLABPOSTGRES.PY find : sql %s record_filter %s %s" %(sql, record_filter , type(record_filter))
269 results = self.selectall(sql)
270 if isinstance(results, dict):