1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import time
20 import string
21
22 from UserDict import UserDict
23 from spacewalk.common.usix import ListType, StringType, DictType, IntType, UnicodeType
24
25
26
27
30
31
34
35
38
39
40
41
44
45
48
49
54
55
58
59
62
63
66
67
68
69
71
72 keywords = {
73 'fields': DictType,
74 'pk': ListType,
75 'attribute': StringType,
76 'map': DictType,
77 'nullable': ListType,
78 'severityHash': DictType,
79 'defaultSeverity': IntType,
80 'sequenceColumn': StringType,
81 }
82
84 self.name = name
85 for k in kwargs.keys():
86 if k not in self.keywords:
87 raise TypeError("Unknown keyword attribute '%s'" % k)
88
89
90 self.fields = {}
91
92 self.pk = []
93
94 self.map = {}
95
96 self.attribute = None
97
98 self.nullable = []
99
100 self.severityHash = {}
101 self.defaultSeverity = 4
102
103 self.sequenceColumn = None
104
105 for k, v in kwargs.items():
106 datatype = self.keywords[k]
107 if not isinstance(v, datatype):
108 raise TypeError("%s expected to be %s; got %s" % (
109 k, datatype, type(v)))
110 setattr(self, k, v)
111
112
113 nullable = self.nullable
114 self.nullable = {}
115 if nullable:
116 for field in nullable:
117 if field not in self.fields:
118 raise TypeError("Unknown nullable field %s in table %s" % (
119 field, name))
120 self.nullable[field] = None
121
122
123 for field in self.pk:
124 if field not in self.fields:
125 raise TypeError("Unknown primary key field %s" % field)
126
128 return "Instance of class %s.%s: PK: %s, Fields: %s" % (self.__class__.__module__,
129 self.__class__.__name__, self.pk, self.fields)
130 __repr__ = __str__
131
133 if field not in self.fields:
134 raise TypeError("Unknown field %s" % field)
135 return field in self.nullable
136
139
142
144 return self.attribute
145
147 if attribute in self.map:
148 return self.map[attribute]
149 return attribute
150
152 for field in self.fields.keys():
153 if field not in self.severityHash:
154 self.severityHash[field] = self.defaultSeverity
155 return self.severityHash
156
157
158
159
172
173
174
175
176
177
179
189
191
192 keys = [[]]
193
194 queries = [[]]
195 for col in self.pks:
196 k = []
197 q = []
198 for i in range(len(keys)):
199 key = keys[i]
200 query = queries[i]
201 k.append(key + [0])
202 q.append(query + ["%s = :%s" % (col, col)])
203 if self.table.isNullable(col):
204 k.append(key + [1])
205 q.append(query + ["%s is null" % col])
206 keys = k
207 queries = q
208
209 for i in range(len(keys)):
210 key = tuple(keys[i])
211 query = string.join(queries[i], ' and ')
212 self.whereclauses[key] = query
213
215
216
217 hash = {}
218 key = []
219 for col in self.pks:
220 if self.table.isNullable(col) and value[col] in [None, '']:
221 key.append(1)
222 else:
223 key.append(0)
224 hash[col] = value[col]
225 key = tuple(key)
226 return key, hash
227
231
233 if key in self.queries:
234
235 return self.queries[key]
236
237 statement = self.dbmodule.prepare(self._buildQuery(key), blob_map=blob_map)
238
239 self.queries[key] = statement
240 return statement
241
242 - def query(self, values):
247
248
250
254
256 return self.queryTemplate % (self.table.name, self.whereclauses[key])
257
258
260
262 BaseTableLookup.__init__(self, table, dbmodule)
263 self.queryTemplate = "update %s set %s where %s"
264 self.fields = list(self.table.getFields().keys())
265 self.count = 1000
266
267 self.otherfields = []
268
269 self.blob_fields = []
270 for field in self.fields:
271 if field in self.pks:
272 continue
273 datatype = self.table.fields[field]
274 if isinstance(datatype, DBblob):
275 self.blob_fields.append(field)
276 else:
277 self.otherfields.append(field)
278 self.updateclause = string.join(
279 ["%s = :%s" % (x, x) for x in self.otherfields], ', ')
280
281 self.firstkey = None
282 for pk in self.pks:
283 if not self.table.isNullable(pk):
284
285 self.firstkey = pk
286 break
287
289 return self.queryTemplate % (self.table.name, self.updateclause,
290 self.whereclauses[key])
291
293
294
295 valuesHash = {}
296
297
298
299 blobValuesHash = {}
300 for key in self.whereclauses.keys():
301 hash = {}
302 for i in range(len(key)):
303 pk = self.pks[i]
304
305 if not key[i]:
306 hash[pk] = []
307
308 for k in self.otherfields:
309 hash[k] = []
310 valuesHash[key] = hash
311 blobValuesHash[key] = []
312
313
314 for i in range(len(values[self.firstkey])):
315
316 pk_val = {}
317 val = {}
318 for k in self.pks:
319 pk_val[k] = val[k] = values[k][i]
320 key, val = self._selectQueryKey(val)
321
322 if not blob_only:
323
324 for k in self.otherfields:
325 val[k] = values[k][i]
326 addHash(valuesHash[key], val)
327
328 if not self.blob_fields:
329
330 continue
331 val = {}
332 for k in self.blob_fields:
333 val[k] = values[k][i]
334 blobValuesHash[key].append((pk_val, val))
335
336 return valuesHash, blobValuesHash
337
338 - def query(self, values):
339 valuesHash, blobValuesHash = self._split_blob_values(values, blob_only=0)
340
341 if self.otherfields:
342 for key, val in valuesHash.items():
343 if not val[self.firstkey]:
344
345 continue
346 statement = self._getCachedQuery(key)
347 executeStatement(statement, val, self.count)
348
349 if not self.blob_fields:
350 return
351
352 self._update_blobs(blobValuesHash)
353
355
356 template = "select %s from %s where %s for update"
357 blob_fields_string = string.join(self.blob_fields, ", ")
358 for key, val in blobValuesHash.items():
359 statement = template % (blob_fields_string, self.table.name,
360 self.whereclauses[key])
361 h = self.dbmodule.prepare(statement)
362 for lookup_hash, blob_hash in val:
363 h.execute(**lookup_hash)
364
365 row = h.fetchone_dict()
366 if not row:
367
368 raise ValueError("BLOB query did not retrieve a value")
369 for k, v in blob_hash.items():
370 blob = row[k]
371 len_v = len(v)
372
373
374 if blob.size() > len_v:
375 blob.trim(len_v)
376
377 if len_v:
378 blob.write(v)
379
380 row = h.fetchone_dict()
381 if row is not None:
382
383
384 raise ValueError("Primary key not unique",
385 self.table.name, lookup_hash)
386
387
389
391 TableLookup.__init__(self, table, dbmodule)
392 self.queryTemplate = "delete from %s where %s"
393 self.count = 1000
394
395 - def query(self, values):
396
397 valuesHash = {}
398 for key in self.whereclauses.keys():
399 hash = {}
400 for i in range(len(key)):
401 pk = self.pks[i]
402
403 if not key[i]:
404 hash[pk] = []
405 valuesHash[key] = hash
406
407
408 firstkey = self.pks[0]
409 for i in range(len(values[firstkey])):
410
411 val = {}
412 for k in self.pks:
413 val[k] = values[k][i]
414 key, val = self._selectQueryKey(val)
415 addHash(valuesHash[key], val)
416
417
418 for key, val in valuesHash.items():
419 firstkey = val.keys()[0]
420 if not val[firstkey]:
421
422 continue
423 statement = self._getCachedQuery(key)
424 executeStatement(statement, val, self.count)
425
426
428
430 TableUpdate.__init__(self, table, dbmodule)
431 self.queryTemplate = "insert into %s (%s) values (%s)"
432 self.count = 1000
433
434 self.insert_fields = self.pks + self.otherfields + self.blob_fields
435 self.insert_values = [':%s' % x for x in self.pks + self.otherfields + self.blob_fields]
436
438 q = self.queryTemplate % (self.table.name,
439 string.join(self.insert_fields, ', '),
440 string.join(self.insert_values, ', '))
441 return q
442
443 - def query(self, values):
444 if self.blob_fields:
445 chunksize = 1
446 blob_map = {}
447 for f in self.blob_fields:
448 blob_map[f] = f
449 else:
450 chunksize = self.count
451 blob_map = None
452
453
454 statement = self._getCachedQuery(None, blob_map=blob_map)
455 executeStatement(statement, values, chunksize)
456
457
459
460 if not valuesHash:
461
462 return
463 count = 0
464 while 1:
465 tempdict = {}
466 for k, vals in valuesHash.items():
467 if not vals:
468
469 break
470 if chunksize > 1:
471 tempdict[k] = vals[:chunksize]
472 else:
473 tempdict[k] = vals[0]
474 del vals[:chunksize]
475 if not tempdict:
476
477 break
478
479 if chunksize > 1:
480 count += statement.executemany(**tempdict)
481 else:
482 count += statement.execute(**tempdict)
483 return count
484
485
487 if isinstance(datatype, DBstring):
488 if value is None or value == '':
489 return None
490
491
492
493 elif isinstance(value, UnicodeType):
494 value = UnicodeType.encode(value, 'utf-8')
495 if len(value) > datatype.limit:
496 value = value[:datatype.limit]
497
498 value = value.decode('utf-8', 'ignore')
499 value = value.encode('utf-8')
500 return value
501 if isinstance(datatype, DBblob):
502 if value is None:
503 value = ''
504 if isinstance(value, UnicodeType):
505 value = UnicodeType.encode(value, 'utf-8')
506 return str(value)
507 if value in [None, '']:
508 return None
509 if isinstance(datatype, DBdateTime):
510 s = str(value)
511 if len(s) == 10:
512
513 s = s + " 00:00:00"
514 return s
515 if isinstance(datatype, DBdate):
516 return str(value)[:10]
517 if isinstance(datatype, DBint):
518 return int(value)
519 return value
520
521
523
524
525 for k, v in hash.items():
526 if k in hasharray:
527 hasharray[k].append(v)
528