blob: 0ccd753327195057563b3c77aa6433a490123a01 [file] [log] [blame]
mblighaf25f062007-12-03 17:48:35 +00001import re, os, sys, types
mblighd5c33db2006-10-08 21:34:16 +00002
mblighaf25f062007-12-03 17:48:35 +00003class db_sql:
mbligh432bad42007-10-09 19:56:07 +00004 def __init__(self, debug = False, autocommit=True):
mbligh8e1ab172007-09-13 17:29:56 +00005 self.debug = debug
mbligh432bad42007-10-09 19:56:07 +00006 self.autocommit = autocommit
mbligha218d112007-10-03 20:15:09 +00007
8 path = os.path.dirname(os.path.abspath(sys.argv[0]))
mblighb32cd432007-09-25 18:20:04 +00009 try:
mbligha218d112007-10-03 20:15:09 +000010 file = os.path.join(path, '.database')
mbligh432bad42007-10-09 19:56:07 +000011 db_prefs = open(file, 'r')
mbligh728ff0a2007-09-27 17:05:12 +000012 host = db_prefs.readline().rstrip()
13 database = db_prefs.readline().rstrip()
14 except:
15 host = 'localhost'
16 database = 'tko'
17
18 try:
mbligha218d112007-10-03 20:15:09 +000019 file = os.path.join(path, '.priv_login')
20 login = open(file, 'r')
mblighb32cd432007-09-25 18:20:04 +000021 user = login.readline().rstrip()
22 password = login.readline().rstrip()
mbligh95fca572007-09-27 17:11:00 +000023 except:
24 try:
mbligha218d112007-10-03 20:15:09 +000025 file = os.path.join(path, '.unpriv_login')
mbligh432bad42007-10-09 19:56:07 +000026 login = open(file, 'r')
mbligh95fca572007-09-27 17:11:00 +000027 user = login.readline().rstrip()
28 password = login.readline().rstrip()
29 except:
30 user = 'nobody'
31 password = ''
mblighb32cd432007-09-25 18:20:04 +000032
mblighaf25f062007-12-03 17:48:35 +000033 self.con = self.connect(host, database, user, password)
mblighd5c33db2006-10-08 21:34:16 +000034 self.cur = self.con.cursor()
35
mbligh8e1ab172007-09-13 17:29:56 +000036 # if not present, insert statuses
37 self.status_idx = {}
38 self.status_word = {}
mblighc82f2462007-10-02 19:19:17 +000039 status_rows = self.select('status_idx, word', 'status', None)
40 for s in status_rows:
mbligh97894452007-10-05 15:10:33 +000041 self.status_idx[s[1]] = s[0]
mblighc82f2462007-10-02 19:19:17 +000042 self.status_word[s[0]] = s[1]
mbligh048e1c92007-10-07 00:10:33 +000043
44 dir = os.path.abspath(os.path.dirname(sys.argv[0]))
45 machine_map = os.path.join(dir, 'machines')
46 if os.path.exists(machine_map):
47 self.machine_map = machine_map
mblighba9c54c2007-10-26 16:41:26 +000048 else:
49 self.machine_map = None
mbligh048e1c92007-10-07 00:10:33 +000050 self.machine_group = {}
51
mbligh8e1ab172007-09-13 17:29:56 +000052
mbligh8e1ab172007-09-13 17:29:56 +000053 def dprint(self, value):
54 if self.debug:
mbligh83f63a02007-12-12 19:13:04 +000055 sys.stdout.write('SQL: ' + str(value) + '\n')
mbligh8e1ab172007-09-13 17:29:56 +000056
mblighd5c33db2006-10-08 21:34:16 +000057
mbligh432bad42007-10-09 19:56:07 +000058 def commit(self):
59 self.con.commit()
60
61
mbligh83f63a02007-12-12 19:13:04 +000062 def select(self, fields, table, where, wherein={}, distinct = False,
63 group_by = None):
mbligh608c3252007-08-31 13:53:00 +000064 """\
65 select fields from table where {dictionary}
66 """
mbligh31d29c42007-09-27 00:51:33 +000067 cmd = ['select']
68 if distinct:
69 cmd.append('distinct')
70 cmd += [fields, 'from', table]
mbligh608c3252007-08-31 13:53:00 +000071
mbligh31d29c42007-09-27 00:51:33 +000072 values = []
mbligh414c69e2007-10-05 15:13:06 +000073 if where and isinstance(where, types.DictionaryType):
mbligh53d14252007-09-12 16:33:14 +000074 keys = [field + '=%s' for field in where.keys()]
75 values = [where[field] for field in where.keys()]
76
mbligh31d29c42007-09-27 00:51:33 +000077 cmd.append(' where ' + ' and '.join(keys))
mbligh414c69e2007-10-05 15:13:06 +000078 elif where and isinstance(where, types.StringTypes):
79 cmd.append(' where ' + where)
mbligh53d14252007-09-12 16:33:14 +000080
mbligh85952b42007-12-07 16:28:33 +000081 if wherein and isinstance(wherein, types.DictionaryType):
82 keys_in = []
83 for field_in in wherein.keys():
84 keys_in += [field_in + ' in (' + ','.join(wherein[field_in])+') ']
85
86 cmd.append(' and '+' and '.join(keys_in))
mbligh83f63a02007-12-12 19:13:04 +000087 if group_by:
88 cmd.append(' GROUP BY ' + group_by)
89
90 self.dprint('%s %s' % (' '.join(cmd), values))
mbligh31d29c42007-09-27 00:51:33 +000091 self.cur.execute(' '.join(cmd), values)
mblighd5c33db2006-10-08 21:34:16 +000092 return self.cur.fetchall()
93
mbligh056d0d32006-10-08 22:31:10 +000094
mbligh414c69e2007-10-05 15:13:06 +000095 def select_sql(self, fields, table, sql, values):
96 """\
97 select fields from table "sql"
98 """
99 cmd = 'select %s from %s %s' % (fields, table, sql)
100 self.dprint(cmd)
101 self.cur.execute(cmd, values)
102 return self.cur.fetchall()
103
104
mbligh432bad42007-10-09 19:56:07 +0000105 def insert(self, table, data, commit = None):
mbligh608c3252007-08-31 13:53:00 +0000106 """\
107 'insert into table (keys) values (%s ... %s)', values
108
109 data:
110 dictionary of fields and data
111 """
mbligh432bad42007-10-09 19:56:07 +0000112 if commit == None:
113 commit = self.autocommit
mbligh608c3252007-08-31 13:53:00 +0000114 fields = data.keys()
115 refs = ['%s' for field in fields]
116 values = [data[field] for field in fields]
117 cmd = 'insert into %s (%s) values (%s)' % \
118 (table, ','.join(fields), ','.join(refs))
mbligh53d14252007-09-12 16:33:14 +0000119
mbligh8e1ab172007-09-13 17:29:56 +0000120 self.dprint('%s %s' % (cmd,values))
mbligh608c3252007-08-31 13:53:00 +0000121 self.cur.execute(cmd, values)
mbligh432bad42007-10-09 19:56:07 +0000122 if commit:
123 self.con.commit()
mbligh608c3252007-08-31 13:53:00 +0000124
125
mbligh96b9a5a2007-11-24 19:32:20 +0000126 def delete(self, table, where, commit = None):
127 cmd = ['delete from', table]
128 if commit == None:
129 commit = self.autocommit
130 if where and isinstance(where, types.DictionaryType):
131 keys = [field + '=%s' for field in where.keys()]
132 values = [where[field] for field in where.keys()]
133 cmd += ['where', ' and '.join(keys)]
134 self.dprint('%s %s' % (' '.join(cmd),values))
135 self.cur.execute(' '.join(cmd), values)
136 if commit:
137 self.con.commit()
138
139
mbligh432bad42007-10-09 19:56:07 +0000140 def update(self, table, data, where, commit = None):
mbligh414c69e2007-10-05 15:13:06 +0000141 """\
142 'update table set data values (%s ... %s) where ...'
143
144 data:
145 dictionary of fields and data
146 """
mbligh432bad42007-10-09 19:56:07 +0000147 if commit == None:
148 commit = self.autocommit
mbligh414c69e2007-10-05 15:13:06 +0000149 cmd = 'update %s ' % table
150 fields = data.keys()
151 data_refs = [field + '=%s' for field in fields]
152 data_values = [data[field] for field in fields]
153 cmd += ' set ' + ' and '.join(data_refs)
154
155 where_keys = [field + '=%s' for field in where.keys()]
156 where_values = [where[field] for field in where.keys()]
157 cmd += ' where ' + ' and '.join(where_keys)
158
159 print '%s %s' % (cmd, data_values + where_values)
160 self.cur.execute(cmd, data_values + where_values)
mbligh432bad42007-10-09 19:56:07 +0000161 if commit:
162 self.con.commit()
mbligh414c69e2007-10-05 15:13:06 +0000163
164
mbligh96b9a5a2007-11-24 19:32:20 +0000165 def delete_job(self, tag, commit = None):
166 job_idx = self.find_job(tag)
167 for test_idx in self.find_tests(job_idx):
168 where = {'test_idx' : test_idx}
169 self.delete('iteration_result', where)
170 self.delete('test_attributes', where)
171 where = {'job_idx' : job_idx}
172 self.delete('tests', where)
173 self.delete('jobs', where)
174
175
mbligh432bad42007-10-09 19:56:07 +0000176 def insert_job(self, tag, job, commit = None):
mbligh2aaeb672007-10-01 14:54:18 +0000177 job.machine_idx = self.lookup_machine(job.machine)
178 if not job.machine_idx:
mbligh7a41a862007-11-30 17:44:24 +0000179 job.machine_idx = self.insert_machine(job,
mbligh432bad42007-10-09 19:56:07 +0000180 commit=commit)
mblighb10a60f2007-10-17 00:03:32 +0000181 self.insert('jobs', {'tag':tag,
182 'label': job.label,
mbligh05067a32007-12-03 17:48:04 +0000183 'username': job.user,
mblighb10a60f2007-10-17 00:03:32 +0000184 'machine_idx':job.machine_idx},
185 commit=commit)
mbligh608c3252007-08-31 13:53:00 +0000186 job.index = self.find_job(tag)
187 for test in job.tests:
mbligh432bad42007-10-09 19:56:07 +0000188 self.insert_test(job, test, commit=commit)
mbligh608c3252007-08-31 13:53:00 +0000189
mbligh96b9a5a2007-11-24 19:32:20 +0000190
mbligh432bad42007-10-09 19:56:07 +0000191 def insert_test(self, job, test, commit = None):
192 kver = self.insert_kernel(test.kernel, commit=commit)
mbligh608c3252007-08-31 13:53:00 +0000193 data = {'job_idx':job.index, 'test':test.testname,
mbligh2bd48872007-09-20 18:32:25 +0000194 'subdir':test.subdir, 'kernel_idx':kver,
mbligh8e1ab172007-09-13 17:29:56 +0000195 'status':self.status_idx[test.status],
mbligh2aaeb672007-10-01 14:54:18 +0000196 'reason':test.reason, 'machine_idx':job.machine_idx }
mbligh432bad42007-10-09 19:56:07 +0000197 self.insert('tests', data, commit=commit)
mbligh2bd48872007-09-20 18:32:25 +0000198 test_idx = self.find_test(job.index, test.subdir)
199 data = { 'test_idx':test_idx }
200
201 for i in test.iterations:
202 data['iteration'] = i.index
203 for key in i.keyval:
204 data['attribute'] = key
205 data['value'] = i.keyval[key]
mbligh432bad42007-10-09 19:56:07 +0000206 self.insert('iteration_result',
207 data,
208 commit=commit)
mbligh994a23d2007-10-25 15:28:58 +0000209 data = {'test_idx':test_idx, 'attribute':'version', 'value':test.version}
210 self.insert('test_attributes', data, commit=commit)
mblighe9cf9d42007-08-31 08:56:00 +0000211
212
mbligh048e1c92007-10-07 00:10:33 +0000213 def read_machine_map(self):
214 self.machine_group = {}
215 for line in open(self.machine_map, 'r').readlines():
216 (machine, group) = line.split()
217 self.machine_group[machine] = group
218
219
mbligh7a41a862007-11-30 17:44:24 +0000220 def insert_machine(self, job, group = None, commit = None):
221 hostname = job.machine
mbligh048e1c92007-10-07 00:10:33 +0000222 if self.machine_map and not self.machine_group:
223 self.read_machine_map()
224
225 if not group:
226 group = self.machine_group.get(hostname, hostname)
mbligh7a41a862007-11-30 17:44:24 +0000227 if group == hostname and job.machine_owner:
228 group = job.machine_owner + '/' + hostname
229
mbligh432bad42007-10-09 19:56:07 +0000230 self.insert('machines',
231 { 'hostname' : hostname ,
mbligh7a41a862007-11-30 17:44:24 +0000232 'machine_group' : group ,
233 'owner' : job.machine_owner },
mbligh432bad42007-10-09 19:56:07 +0000234 commit=commit)
mbligh2aaeb672007-10-01 14:54:18 +0000235 return self.lookup_machine(hostname)
236
237
238 def lookup_machine(self, hostname):
239 where = { 'hostname' : hostname }
240 rows = self.select('machine_idx', 'machines', where)
241 if rows:
242 return rows[0][0]
243 else:
244 return None
245
246
mbligh9bb92fe2007-09-12 15:54:23 +0000247 def lookup_kernel(self, kernel):
248 rows = self.select('kernel_idx', 'kernels',
mbligh048e1c92007-10-07 00:10:33 +0000249 {'kernel_hash':kernel.kernel_hash})
mbligh237bed32007-09-05 13:05:57 +0000250 if rows:
251 return rows[0][0]
252 else:
253 return None
mblighe9cf9d42007-08-31 08:56:00 +0000254
255
mbligh432bad42007-10-09 19:56:07 +0000256 def insert_kernel(self, kernel, commit = None):
mbligh9bb92fe2007-09-12 15:54:23 +0000257 kver = self.lookup_kernel(kernel)
mbligh237bed32007-09-05 13:05:57 +0000258 if kver:
259 return kver
mbligh432bad42007-10-09 19:56:07 +0000260 self.insert('kernels',
261 {'base':kernel.base,
262 'kernel_hash':kernel.kernel_hash,
263 'printable':kernel.base},
264 commit=commit)
mbligh9bb92fe2007-09-12 15:54:23 +0000265 # WARNING - incorrectly shoving base into printable here.
266 kver = self.lookup_kernel(kernel)
mbligh237bed32007-09-05 13:05:57 +0000267 for patch in kernel.patches:
mbligh432bad42007-10-09 19:56:07 +0000268 self.insert_patch(kver, patch, commit=commit)
mbligh237bed32007-09-05 13:05:57 +0000269 return kver
270
271
mbligh432bad42007-10-09 19:56:07 +0000272 def insert_patch(self, kver, patch, commit = None):
mbligh237bed32007-09-05 13:05:57 +0000273 print patch.reference
274 name = os.path.basename(patch.reference)[:80]
mbligh432bad42007-10-09 19:56:07 +0000275 self.insert('patches',
276 {'kernel_idx': kver,
277 'name':name,
278 'url':patch.reference,
279 'hash':patch.hash},
280 commit=commit)
mbligh056d0d32006-10-08 22:31:10 +0000281
mbligh048e1c92007-10-07 00:10:33 +0000282
mbligh2bd48872007-09-20 18:32:25 +0000283 def find_test(self, job_idx, subdir):
284 where = { 'job_idx':job_idx , 'subdir':subdir }
285 rows = self.select('test_idx', 'tests', where)
286 if rows:
287 return rows[0][0]
288 else:
289 return None
290
mbligh056d0d32006-10-08 22:31:10 +0000291
mbligh96b9a5a2007-11-24 19:32:20 +0000292 def find_tests(self, job_idx):
293 where = { 'job_idx':job_idx }
294 rows = self.select('test_idx', 'tests', where)
295 if rows:
296 return [row[0] for row in rows]
297 else:
mbligh2e57e7b2007-11-29 16:10:50 +0000298 return []
mbligh96b9a5a2007-11-24 19:32:20 +0000299
300
mbligh056d0d32006-10-08 22:31:10 +0000301 def find_job(self, tag):
mbligh608c3252007-08-31 13:53:00 +0000302 rows = self.select('job_idx', 'jobs', {'tag': tag})
303 if rows:
304 return rows[0][0]
305 else:
306 return None
mblighaf25f062007-12-03 17:48:35 +0000307
308
309# Use a class method as a class factory, generating a relevant database object.
310def db(*args, **dargs):
311 path = os.path.dirname(os.path.abspath(sys.argv[0]))
mbligha044e562007-12-07 16:26:13 +0000312 db_type = None
mblighaf25f062007-12-03 17:48:35 +0000313 try:
mbligha044e562007-12-07 16:26:13 +0000314 db_file = os.path.join(path, '.database')
315 db_prefs = open(db_file, 'r')
mblighaf25f062007-12-03 17:48:35 +0000316 host = db_prefs.readline().rstrip()
317 database = db_prefs.readline().rstrip()
mbligha044e562007-12-07 16:26:13 +0000318 db_type = db_prefs.readline().rstrip()
319 except:
320 pass
mblighaf25f062007-12-03 17:48:35 +0000321
mbligha044e562007-12-07 16:26:13 +0000322 if not db_type:
323 db_type = 'mysql'
324
325 db_type = 'db_' + db_type
326 exec 'import %s; db = %s.%s(*args, **dargs)' % (db_type, db_type, db_type)
mblighaf25f062007-12-03 17:48:35 +0000327
328 return db