|
@@ -101,8 +101,11 @@ class MongoDbDatasource(object):
|
101
|
101
|
#@param offset int: used with limit to choose the start record
|
102
|
102
|
#@return list
|
103
|
103
|
#@todo Implement group for abstract LeObject childs
|
104
|
|
- def select(self, target, field_list, filters = None,
|
105
|
|
- relational_filters=None, order=None, group=None, limit=None, offset=0):
|
|
104
|
+ def select(self, target, field_list, filters = None,
|
|
105
|
+ relational_filters=None, order=None, group=None, limit=None,
|
|
106
|
+ offset=0):
|
|
107
|
+ logger.debug("Select %s on %s filtered by %s and %s " % (
|
|
108
|
+ field_list, target, filters, relational_filters))
|
106
|
109
|
if target.is_abstract():
|
107
|
110
|
#Reccursiv calls for abstract LeObject child
|
108
|
111
|
results = self.__act_on_abstract(target, filters,
|
|
@@ -208,13 +211,24 @@ class MongoDbDatasource(object):
|
208
|
211
|
res = self.__collection(target).delete_many(mongo_filters)
|
209
|
212
|
return res.deleted_count
|
210
|
213
|
|
211
|
|
- ## @brief updates records according to given filters
|
|
214
|
+ ##@brief updates records according to given filters
|
212
|
215
|
#@param target Emclass : class of the object to insert
|
213
|
216
|
#@param filters list : List of filters
|
214
|
217
|
#@param relational_filters list : List of relational filters
|
215
|
218
|
#@param upd_datas dict : datas to update (new values)
|
216
|
219
|
#@return int : Number of updated records
|
217
|
220
|
def update(self, target, filters, relational_filters, upd_datas):
|
|
221
|
+ res = self.__upodate_no_backref(target, filters, relational_filters,
|
|
222
|
+ upd_datas)
|
|
223
|
+ self.__update_backref_filtered(target, filters, relational_filters,
|
|
224
|
+ upd_datas)
|
|
225
|
+ return res
|
|
226
|
+
|
|
227
|
+ ##@brief Designed to be called by backref update in order to avoid
|
|
228
|
+ #infinite updates between back references
|
|
229
|
+ #@see update()
|
|
230
|
+ def __update_no_backref(self, target, filters, relational_filters,
|
|
231
|
+ upd_datas):
|
218
|
232
|
if target.is_abstract():
|
219
|
233
|
#Update using abstract LeObject as target (reccursiv calls)
|
220
|
234
|
return self.__act_on_abstract(target, filters,
|
|
@@ -223,10 +237,10 @@ class MongoDbDatasource(object):
|
223
|
237
|
mongo_filters = self.__process_filters(
|
224
|
238
|
target, filters, relational_filters)
|
225
|
239
|
res = self.__collection(target).update(mongo_filters, upd_datas)
|
226
|
|
- self.__update_backref_filtered(target, filters, relational_filters,
|
227
|
|
- upd_datas)
|
228
|
240
|
return res['n']
|
229
|
241
|
|
|
242
|
+
|
|
243
|
+
|
230
|
244
|
## @brief Inserts a record in a given collection
|
231
|
245
|
# @param target Emclass : class of the object to insert
|
232
|
246
|
# @param new_datas dict : datas to insert
|
|
@@ -256,7 +270,7 @@ class MongoDbDatasource(object):
|
256
|
270
|
def __update_backref_filtered(self, target, act,
|
257
|
271
|
filters, relational_filters, datas = None):
|
258
|
272
|
#gathering datas
|
259
|
|
- old_datas_l = target.select(target, None, filters, relational_filters)
|
|
273
|
+ old_datas_l = target.get(target, None, filters, relational_filters)
|
260
|
274
|
for old_datas in old_datas_l:
|
261
|
275
|
self.__update_backref(target, old_datas, datas)
|
262
|
276
|
|
|
@@ -334,7 +348,7 @@ class MongoDbDatasource(object):
|
334
|
348
|
to_add = []
|
335
|
349
|
elif not oldd and newd:
|
336
|
350
|
to_del = []
|
337
|
|
- to_add = [new_datas[fname]]
|
|
351
|
+ to_add = new_datas[fname]
|
338
|
352
|
#Calling __back_ref_upd_one_value() with good arguments
|
339
|
353
|
for vtype, vlist in [('old',to_del), ('new', to_add)]:
|
340
|
354
|
for value in vlist:
|
|
@@ -343,16 +357,16 @@ class MongoDbDatasource(object):
|
343
|
357
|
bref_cls, value, bref_fname)
|
344
|
358
|
#preparing the upd_dict
|
345
|
359
|
upd_dict = self.__update_backref_upd_dict_prepare(
|
346
|
|
- upd_dict, bref_infos)
|
|
360
|
+ upd_dict, bref_infos, bref_fname, value)
|
347
|
361
|
#preparing updated bref_infos
|
348
|
362
|
bref_cls, bref_leo, bref_dh, bref_value = bref_infos
|
349
|
|
- bref_infos = tuple(bref_cls, bref_leo, bref_dh,
|
350
|
|
- upd_dict[bref_cls][uid_val][1][bref_fname])
|
|
363
|
+ bref_infos = (bref_cls, bref_leo, bref_dh,
|
|
364
|
+ upd_dict[bref_cls][value][1][bref_fname])
|
351
|
365
|
vdict = {vtype: value}
|
352
|
366
|
#fetch and store updated value
|
353
|
367
|
new_bref_val = self.__back_ref_upd_one_value(
|
354
|
368
|
fname, fdh, bref_infos, **vdict)
|
355
|
|
- upd_dict[bref_cls][uid_val][1][bref_fname] = new_bref_val
|
|
369
|
+ upd_dict[bref_cls][value][1][bref_fname] = new_bref_val
|
356
|
370
|
else:
|
357
|
371
|
#fdh is a single ref so the process is simpler, we do not have
|
358
|
372
|
#to loop and we may do an update in only one
|
|
@@ -371,7 +385,7 @@ class MongoDbDatasource(object):
|
371
|
385
|
bref_cls, uid_val, bref_fname)
|
372
|
386
|
#prepare the upd_dict
|
373
|
387
|
upd_dict = self.__update_backref_upd_dict_prepare(
|
374
|
|
- upd_dict, bref_infos)
|
|
388
|
+ upd_dict, bref_infos, bref_fname, uid_val)
|
375
|
389
|
#forging update bref_infos
|
376
|
390
|
bref_cls, bref_leo, bref_dh, bref_value = bref_infos
|
377
|
391
|
bref_infos = tuple(bref_cls, bref_leo, bref_dh,
|
|
@@ -384,21 +398,29 @@ class MongoDbDatasource(object):
|
384
|
398
|
#running the updates
|
385
|
399
|
for bref_cls, uid_dict in upd_dict.items():
|
386
|
400
|
for uidval, (leo, datas) in uid_dict.items():
|
387
|
|
- leo.update(datas)
|
|
401
|
+ #MULTIPLE UID BROKEN 2 LINES BELOW
|
|
402
|
+ self.__update_no_backref(
|
|
403
|
+ leo.__class__, [(leo.uid_fieldname()[0], '=', uidval)],
|
|
404
|
+ [], datas)
|
388
|
405
|
|
389
|
406
|
##@brief Utility function designed to handle the upd_dict of
|
390
|
407
|
#__update_backref()
|
391
|
408
|
#
|
|
409
|
+ #Basically checks if a key exists at some level, if not create it with
|
|
410
|
+ #the good default value (in most case dict())
|
392
|
411
|
#@param upd_dict dict : in & out args modified by reference
|
393
|
412
|
#@param bref_infos tuple : as returned by __bref_get_check()
|
|
413
|
+ #@param bref_fname str : name of the field in referenced class
|
|
414
|
+ #@param uid_val mixed : the UID of the referenced object
|
394
|
415
|
#@return the updated version of upd_dict
|
395
|
416
|
@staticmethod
|
396
|
|
- def __update_backref_upd_dict_prepare(upd_dict,bref_infos):
|
|
417
|
+ def __update_backref_upd_dict_prepare(upd_dict,bref_infos, bref_fname,
|
|
418
|
+ uid_val):
|
397
|
419
|
bref_cls, bref_leo, bref_dh, bref_value = bref_infos
|
398
|
420
|
if bref_cls not in upd_dict:
|
399
|
421
|
upd_dict[bref_cls] = {}
|
400
|
422
|
if uid_val not in upd_dict[bref_cls]:
|
401
|
|
- upd_dict[bref_cls][uid_val] = tuple(bref_leo, {})
|
|
423
|
+ upd_dict[bref_cls][uid_val] = (bref_leo, {})
|
402
|
424
|
if bref_fname not in upd_dict[bref_cls][uid_val]:
|
403
|
425
|
upd_dict[bref_cls][uid_val][1][bref_fname] = bref_value
|
404
|
426
|
return upd_dict
|
|
@@ -419,7 +441,7 @@ class MongoDbDatasource(object):
|
419
|
441
|
#
|
420
|
442
|
# We got an old value. It can be an update or a delete
|
421
|
443
|
#
|
422
|
|
- old_value = old_datas[fname]
|
|
444
|
+ old_value = values['old']
|
423
|
445
|
bref_cls, bref_leo, bref_dh, bref_val = self.__bref_get_check(
|
424
|
446
|
bref_cls, old_value, bref_fname)
|
425
|
447
|
if issubclass(bref_dh.__class__, MultipleRef):
|
|
@@ -442,7 +464,7 @@ object : %s field %s" % (bref_leo, ref_fname))
|
442
|
464
|
if val == old_value:
|
443
|
465
|
if newd:
|
444
|
466
|
#Update
|
445
|
|
- bref_val[ki] = new_datas[fname]
|
|
467
|
+ bref_val[ki] = values['new']
|
446
|
468
|
else:
|
447
|
469
|
#Deletion
|
448
|
470
|
del(bref_val[ki])
|
|
@@ -452,7 +474,7 @@ object : %s field %s" % (bref_leo, ref_fname))
|
452
|
474
|
raised ! We just checked that oldv is in bref_val...")
|
453
|
475
|
else:
|
454
|
476
|
#Single ref handling
|
455
|
|
- if bref_val != old_value:
|
|
477
|
+ if bref_val != values['old']:
|
456
|
478
|
raise MongoDbConsistencyError("The value we wanted to \
|
457
|
479
|
update do not match excpected value during aback reference singleReference \
|
458
|
480
|
update : expected value was '%s' but found '%s' in field '%s' of leo %s" % (
|
|
@@ -460,7 +482,7 @@ update : expected value was '%s' but found '%s' in field '%s' of leo %s" % (
|
460
|
482
|
|
461
|
483
|
if newd:
|
462
|
484
|
#update
|
463
|
|
- bref_val = new_datas[fname]
|
|
485
|
+ bref_val = values['new']
|
464
|
486
|
else:
|
465
|
487
|
#delete
|
466
|
488
|
if not hasattr(bref_dh, "default"):
|
|
@@ -470,8 +492,10 @@ value : in %s field %s" % (bref_leo, ref_fname))
|
470
|
492
|
bref_val = getattr(bref_dh, "default")
|
471
|
493
|
elif newd:
|
472
|
494
|
#It's an "insert"
|
473
|
|
- new_value = new_datas[fname]
|
|
495
|
+ new_value = values['new']
|
474
|
496
|
if issubclass(bref_dh.__class__, MultipleRef):
|
|
497
|
+ if bref_val is None:
|
|
498
|
+ bref_val = bref_dh.empty()
|
475
|
499
|
if isinstance(bref_val, set):
|
476
|
500
|
bref_val |= set([new_value])
|
477
|
501
|
else:
|
|
@@ -498,8 +522,12 @@ value : in %s field %s" % (bref_leo, ref_fname))
|
498
|
522
|
if len(bref_leo) == 0:
|
499
|
523
|
raise MongoDbConsistencyError("Unable to get the object we make \
|
500
|
524
|
reference to : %s with uid = %s" % (bref_cls, repr(uidv)))
|
|
525
|
+ if len(bref_leo) > 1:
|
|
526
|
+ raise MongoDbConsistencyFatalError("Will retrieving data with UID \
|
|
527
|
+as filter we got more than one result !!! Bailout !!!")
|
|
528
|
+ bref_leo = bref_leo[0]
|
501
|
529
|
bref_dh = bref_leo.data_handler(bref_fname)
|
502
|
|
- if not isinstance(bref_leo, Reference):
|
|
530
|
+ if not isinstance(bref_dh, Reference):
|
503
|
531
|
raise LodelFatalError("Found a back reference field that \
|
504
|
532
|
is not a reference : '%s' field '%s'" % (bref_leo, bref_fname))
|
505
|
533
|
bref_val = bref_leo.data(bref_fname)
|