|
@@ -295,183 +295,6 @@ class LeDataSourceSQL(DummyDatasource):
|
295
|
295
|
res.append(self.insert(target_cls, data))
|
296
|
296
|
return len(res)
|
297
|
297
|
|
298
|
|
- ## @brief prepares the relational filters
|
299
|
|
- # @params rel_filters : (("superior"|"subordinate"), operator, value)
|
300
|
|
- # @return list
|
301
|
|
- def _prepare_rel_filters(self, rel_filters):
|
302
|
|
- prepared_rel_filters = []
|
303
|
|
-
|
304
|
|
- if rel_filters is not None and len(rel_filters) > 0:
|
305
|
|
- for rel_filter in rel_filters:
|
306
|
|
- rel_filter_dict = {
|
307
|
|
- 'position': REL_SUB if rel_filter[0][0] == REL_SUP else REL_SUB,
|
308
|
|
- 'nature': rel_filter[0][1],
|
309
|
|
- 'condition_key': (self.RELATIONS_POSITIONS_FIELDS[rel_filter[0][0]], rel_filter[1]),
|
310
|
|
- 'condition_value': rel_filter[2]
|
311
|
|
- }
|
312
|
|
- prepared_rel_filters.append(rel_filter_dict)
|
313
|
|
-
|
314
|
|
- return prepared_rel_filters
|
315
|
|
-
|
316
|
|
- ## @brief prepares the filters to be used by the mosql library's functions
|
317
|
|
- # @params filters : (FIELD, OPERATOR, VALUE) tuples
|
318
|
|
- # @return dict : Dictionnary with (FIELD, OPERATOR):VALUE style elements
|
319
|
|
- def _prepare_filters(self, filters, tablename=None):
|
320
|
|
- prepared_filters = {}
|
321
|
|
- if filters is not None and len(filters) > 0:
|
322
|
|
- for filter_item in filters:
|
323
|
|
- if '.' in filter_item[0]:
|
324
|
|
- prepared_filter_key = (filter_item[0], filter_item[1])
|
325
|
|
- else:
|
326
|
|
- prepared_filter_key = ("%s.%s" % (tablename, filter_item[0]), filter_item[1])
|
327
|
|
- prepared_filter_value = filter_item[2]
|
328
|
|
- prepared_filters[prepared_filter_key] = prepared_filter_value
|
329
|
|
-
|
330
|
|
- return prepared_filters
|
331
|
|
-
|
332
|
|
- # ================================================================================================================ #
|
333
|
|
- # FONCTIONS A DEPLACER #
|
334
|
|
- # ================================================================================================================ #
|
335
|
|
-
|
336
|
|
- ## @brief Make a relation between 2 LeType
|
337
|
|
- # @note rel2type relations. Superior is the LeType from the EmClass and subordinate the LeType for the EmType
|
338
|
|
- # @param lesup LeType : LeType child class instance that is from the EmClass containing the rel2type field
|
339
|
|
- # @param lesub LeType : LeType child class instance that is from the EmType linked by the rel2type field ( @ref EditorialModel.fieldtypes.rel2type.EmFieldType.rel_to_type_id )
|
340
|
|
- # @return The relation_id if success else return False
|
341
|
|
- def add_related(self, lesup, lesub, rank, **rel_attr):
|
342
|
|
- with self.connection as cur:
|
343
|
|
- #First step : relation table insert
|
344
|
|
- sql = insert(MySQL.relations_table_name, {
|
345
|
|
- 'id_sup': lesup.lodel_id,
|
346
|
|
- 'id_sub': lesub.lodel_id,
|
347
|
|
- 'rank': 0, # default value that will be set latter
|
348
|
|
- })
|
349
|
|
- cur.execute(sql)
|
350
|
|
- relation_id = cur.lastrowid
|
351
|
|
-
|
352
|
|
- if len(rel_attr) > 0:
|
353
|
|
- #There is some relation attribute to add in another table
|
354
|
|
- attr_table = get_r2t2table_name(lesup._leclass.__name__, lesub.__class__.__name__)
|
355
|
|
- rel_attr['id_relation'] = relation_id
|
356
|
|
- sql = insert(attr_table, rel_attr)
|
357
|
|
- cur.execute(sql)
|
358
|
|
- self._set_relation_rank(id_relation, rank)
|
359
|
|
- return relation_id
|
360
|
|
-
|
361
|
|
- ## @brief Deletes the relation between 2 LeType
|
362
|
|
- # @param lesup LeType
|
363
|
|
- # @param lesub LeType
|
364
|
|
- # @param fields dict
|
365
|
|
- # @return True if success else False
|
366
|
|
- # @todo Add fields parameter to identify relation
|
367
|
|
- # @todo Delete relationnal fields if some exists
|
368
|
|
- def del_related(self, lesup, lesub, fields=None):
|
369
|
|
- with self.connection as cur:
|
370
|
|
- del_params = {
|
371
|
|
- 'id_sup': lesup.lodel_id,
|
372
|
|
- 'id_sub': lesub.lodel_id
|
373
|
|
- }
|
374
|
|
- delete_params = {}
|
375
|
|
-
|
376
|
|
- if fields is not None:
|
377
|
|
- delete_params = del_params.copy()
|
378
|
|
- delete_params.update(fields)
|
379
|
|
- else:
|
380
|
|
- delete_params = del_params
|
381
|
|
-
|
382
|
|
- sql = delete(
|
383
|
|
- self.datasource_utils.relations_table_name,
|
384
|
|
- delete_params
|
385
|
|
- )
|
386
|
|
-
|
387
|
|
- if cur.execute(sql) != 1:
|
388
|
|
- return False
|
389
|
|
-
|
390
|
|
- return True
|
391
|
|
-
|
392
|
|
- ## @brief Fetch related (rel2type) by LeType
|
393
|
|
- # @param leo LeType : We want related LeObject of this LeType child class instance
|
394
|
|
- # @param letype LeType(class) : We want related LeObject of this LeType child class (not instance)
|
395
|
|
- # @param get_sub bool : If True leo is the superior and we want subordinates, else its the opposite
|
396
|
|
- # @return a list of dict { 'id_relation':.., 'rank':.., 'lesup':.., 'lesub'.., 'rel_attrs': dict() }
|
397
|
|
- # TODO A conserver , utilisé par la nouvelle méthode update_rank
|
398
|
|
- def get_related(self, leo, letype, get_sub=True):
|
399
|
|
- if LeCrud.name2class('LeType') not in letype.__bases__:
|
400
|
|
- raise ValueError("letype argument should be a LeType child class, but got %s" % type(letype))
|
401
|
|
-
|
402
|
|
- if not isinstance(leo, LeType):
|
403
|
|
- raise ValueError("leo argument should be a LeType child class instance but got %s" % type(leo))
|
404
|
|
- with self.connection as cur:
|
405
|
|
- id_leo, id_type = 'id_sup', 'id_sub' if get_sub else 'id_sub', 'id_sup'
|
406
|
|
-
|
407
|
|
- joins = [
|
408
|
|
- join(
|
409
|
|
- (MySQL.objects_table_name, 'o'),
|
410
|
|
- on={'r.' + id_type: 'o.' + MySQL.field_lodel_id}
|
411
|
|
- ),
|
412
|
|
- join(
|
413
|
|
- (MySQL.objects_table_name, 'p'),
|
414
|
|
- on={'r.' + id_leo: 'p.' + MySQL.field_lodel_id}
|
415
|
|
- ),
|
416
|
|
- ]
|
417
|
|
-
|
418
|
|
- lesup, lesub = leo.__class__, letype if get_sub else letype, leo.__class__
|
419
|
|
- common_infos = ('r.id_relation', 'r.id_sup', 'r.id_sub', 'r.rank', 'r.depth')
|
420
|
|
- if len(lesup._linked_types[lesub]) > 0:
|
421
|
|
- #relationnal attributes, need to join with r2t table
|
422
|
|
- cls_name = leo.__class__.__name__ if get_sub else letype.__name__
|
423
|
|
- type_name = letype.__name__ if get_sub else leo.__class__.__name__
|
424
|
|
- joins.append(
|
425
|
|
- join(
|
426
|
|
- (MySQL.get_r2t2table_name(cls_name, type_name), 'r2t'),
|
427
|
|
- on={'r.' + MySQL.relations_pkname: 'r2t' + MySQL.relations_pkname}
|
428
|
|
- )
|
429
|
|
- )
|
430
|
|
- select = ('r.id_relation', 'r.id_sup', 'r.id_sub', 'r.rank', 'r.depth', 'r2t.*')
|
431
|
|
- else:
|
432
|
|
- select = common_infos
|
433
|
|
-
|
434
|
|
- sql = select(
|
435
|
|
- (MySQL.relations_table_name, 'r'),
|
436
|
|
- select=select,
|
437
|
|
- where={
|
438
|
|
- id_leo: leo.lodel_id,
|
439
|
|
- 'type_id': letype._type_id,
|
440
|
|
- },
|
441
|
|
- joins=joins
|
442
|
|
- )
|
443
|
|
-
|
444
|
|
- cur.execute(sql)
|
445
|
|
- res = all_to_dicts(cur)
|
446
|
|
-
|
447
|
|
- #Building result
|
448
|
|
- ret = list()
|
449
|
|
- for datas in res:
|
450
|
|
- r_letype = letype(res['r.' + id_type])
|
451
|
|
- ret_item = {
|
452
|
|
- 'id_relation': +datas[MySQL.relations_pkname],
|
453
|
|
- 'lesup': r_leo if get_sub else r_letype,
|
454
|
|
- 'lesub': r_letype if get_sub else r_leo,
|
455
|
|
- 'rank': res['rank']
|
456
|
|
- }
|
457
|
|
-
|
458
|
|
- rel_attr = copy.copy(datas)
|
459
|
|
- for todel in common_infos:
|
460
|
|
- del rel_attr[todel]
|
461
|
|
- ret_item['rel_attrs'] = rel_attr
|
462
|
|
- ret.append(ret_item)
|
463
|
|
-
|
464
|
|
- return ret
|
465
|
|
-
|
466
|
|
- ## @brief Set the rank of a relation identified by its ID
|
467
|
|
- # @param id_relation int : relation ID
|
468
|
|
- # @param rank int|str : 'first', 'last', or an integer value
|
469
|
|
- # @throw ValueError if rank is not valid
|
470
|
|
- # @throw leapi.leapi.LeObjectQueryError if id_relation don't exists
|
471
|
|
- def set_relation_rank(self, id_relation, rank):
|
472
|
|
- self._check_rank(rank)
|
473
|
|
- self._set_relation_rank(id_relation, rank)
|
474
|
|
-
|
475
|
298
|
## @brief Sets a new rank on a relation
|
476
|
299
|
# @param le_relation LeRelation
|
477
|
300
|
# @param new_rank int: integer representing the absolute new rank
|
|
@@ -499,371 +322,3 @@ class LeDataSourceSQL(DummyDatasource):
|
499
|
322
|
return False
|
500
|
323
|
else:
|
501
|
324
|
return True
|
502
|
|
-
|
503
|
|
-
|
504
|
|
- ## @brief Set the rank of a relation identified by its ID
|
505
|
|
- #
|
506
|
|
- # @note this solution is not the more efficient solution but it
|
507
|
|
- # garantee that ranks are continuous and starts at 1
|
508
|
|
- # @warning there is no way to fail on rank parameters even giving very bad parameters, if you want a method that may fail on rank use set_relation_rank() instead
|
509
|
|
- # @param id_relation int : relation ID
|
510
|
|
- # @param rank int|str : 'first', 'last', or an integer value
|
511
|
|
- # @throw leapi.leapi.LeObjectQueryError if id_relation don't exists
|
512
|
|
- def _set_relation_rank(self, id_relation, rank):
|
513
|
|
- ret = self.get_relation(id_relation, no_attr=True)
|
514
|
|
- if not ret:
|
515
|
|
- raise leapi.leapi.LeObjectQueryError("No relation with id_relation = %d" % id_relation)
|
516
|
|
- lesup = ret['lesup']
|
517
|
|
- lesub = ret['lesup']
|
518
|
|
- cur_rank = ret['rank']
|
519
|
|
- rank = 1 if rank == 'first' or rank < 1 else rank
|
520
|
|
- if cur_rank == rank:
|
521
|
|
- return True
|
522
|
|
-
|
523
|
|
- relations = self.get_related(lesup, lesub.__class__, get_sub=True)
|
524
|
|
-
|
525
|
|
- if not isinstance(rank, int) or rank > len(relations):
|
526
|
|
- rank = len(relations)
|
527
|
|
- if cur_rank == rank:
|
528
|
|
- return True
|
529
|
|
-
|
530
|
|
- #insert the relation at the good position
|
531
|
|
- our_relation = relations.pop(cur_rank)
|
532
|
|
- relations.insert(our_relation, rank)
|
533
|
|
-
|
534
|
|
- #gathering (relation_id, new_rank)
|
535
|
|
- rdatas = [(attrs['relation_id'], new_rank + 1) for new_rank, (sup, sub, attrs) in enumerate(relations)]
|
536
|
|
- sql = insert(MySQL.relations_table_name, columns=(MySQL.relations_pkname, 'rank'), values=rdatas, on_duplicate_key_update={'rank', mosql.util.raw('VALUES(`rank`)')})
|
537
|
|
-
|
538
|
|
- ## @brief Check a rank value
|
539
|
|
- # @param rank int | str : Can be an integer >= 1 , 'first' or 'last'
|
540
|
|
- # @throw ValueError if the rank is not valid
|
541
|
|
- def _check_rank(self, rank):
|
542
|
|
- if isinstance(rank, str) and rank != 'first' and rank != 'last':
|
543
|
|
- raise ValueError("Invalid rank value : %s" % rank)
|
544
|
|
- elif isinstance(rank, int) and rank < 1:
|
545
|
|
- raise ValueError("Invalid rank value : %d" % rank)
|
546
|
|
- else:
|
547
|
|
- raise ValueError("Invalid rank type : %s" % type(rank))
|
548
|
|
-
|
549
|
|
- ## @brief Link two object given a relation nature, depth and rank
|
550
|
|
- # @param lesup LeObject : a LeObject
|
551
|
|
- # @param lesub LeObject : a LeObject
|
552
|
|
- # @param nature str|None : The relation nature or None if rel2type
|
553
|
|
- # @param rank int : a rank
|
554
|
|
- def add_relation(self, lesup, lesub, nature=None, depth=None, rank=None, **rel_attr):
|
555
|
|
- if len(rel_attr) > 0 and nature is not None:
|
556
|
|
- #not a rel2type but have some relation attribute
|
557
|
|
- raise AttributeError("No relation attributes allowed for non rel2type relations")
|
558
|
|
-
|
559
|
|
- with self.connection as cur:
|
560
|
|
- sql = insert(self.datasource_utils.relations_table_name, {'id_sup': lesup.lodel_id, 'id_sub': lesub.lodel_id, 'nature': nature, 'rank': rank, 'depth': depth})
|
561
|
|
- if cur.execute(sql) != 1:
|
562
|
|
- raise RuntimeError("Unknow SQL error")
|
563
|
|
-
|
564
|
|
- if len(rel_attr) > 0:
|
565
|
|
- #a relation table exists
|
566
|
|
- cur.execute('SELECT last_insert_id()')
|
567
|
|
- relation_id, = cur.fetchone()
|
568
|
|
- raise NotImplementedError()
|
569
|
|
-
|
570
|
|
- return True
|
571
|
|
-
|
572
|
|
- ## @brief Delete a relation
|
573
|
|
- # @warning this method may not be efficient
|
574
|
|
- # @param id_relation int : The relation identifier
|
575
|
|
- # @return bool
|
576
|
|
- def del_relation(self, id_relation):
|
577
|
|
- with self.connection as cur:
|
578
|
|
- pk_where = {MySQL.relations_pkname: id_relation}
|
579
|
|
- if not MySQL.fk_on_delete_cascade and len(lesup._linked_types[lesub.__class__]) > 0:
|
580
|
|
- #Delete the row in the relation attribute table
|
581
|
|
- ret = self.get_relation(id_relation, no_attr=False)
|
582
|
|
- lesup = ret['lesup']
|
583
|
|
- lesub = ret['lesub']
|
584
|
|
- sql = delete(MySQL.relations_table_name, pk_where)
|
585
|
|
- if cur.execute(sql) != 1:
|
586
|
|
- raise RuntimeError("Unknown SQL Error")
|
587
|
|
- sql = delete(MySQL.relations_table_name, pk_where)
|
588
|
|
- if cur.execute(sql) != 1:
|
589
|
|
- raise RuntimeError("Unknown SQL Error")
|
590
|
|
-
|
591
|
|
- return True
|
592
|
|
-
|
593
|
|
- ## @brief Fetch a relation
|
594
|
|
- # @param id_relation int : The relation identifier
|
595
|
|
- # @param no_attr bool : If true dont fetch rel_attr
|
596
|
|
- # @return a dict{'id_relation':.., 'lesup':.., 'lesub':..,'rank':.., 'depth':.., #if not none#'nature':.., #if exists#'dict_attr':..>}
|
597
|
|
- #
|
598
|
|
- # @todo TESTS
|
599
|
|
- # TODO conserver, appelé par la méthode update_rank
|
600
|
|
- def get_relation(self, id_relation, no_attr=False):
|
601
|
|
- relation = dict()
|
602
|
|
- with self.connection as cur:
|
603
|
|
- sql = select(MySQL.relation_table_name, {MySQL.relations_pkname: id_relation})
|
604
|
|
- if cur.execute(sql) != 1:
|
605
|
|
- raise RuntimeError("Unknow SQL error")
|
606
|
|
- res = all_to_dicts(cur)
|
607
|
|
- if len(res) == 0:
|
608
|
|
- return False
|
609
|
|
- if len(res) > 1:
|
610
|
|
- raise RuntimeError("When selecting on primary key, get more than one result. Bailout")
|
611
|
|
-
|
612
|
|
- if res['nature'] is not None:
|
613
|
|
- raise ValueError("The relation with id %d is not a rel2type relation" % id_relation)
|
614
|
|
-
|
615
|
|
- leobj = leapi.lefactory.LeFactory.leobj_from_name('LeObject')
|
616
|
|
- lesup = leobj.uid2leobj(res['id_sup'])
|
617
|
|
- lesub = leobj.uid2leobj(res['id_sub'])
|
618
|
|
-
|
619
|
|
- relation['id_relation'] = res['id_relation']
|
620
|
|
- relation['lesup'] = lesup
|
621
|
|
- relation['lesub'] = lesub
|
622
|
|
- relation['rank'] = rank
|
623
|
|
- relation['depth'] = depth
|
624
|
|
- if res['nature'] is not None:
|
625
|
|
- relation['nature'] = res['nature']
|
626
|
|
-
|
627
|
|
- if not no_attr and res['nature'] is None and len(lesup._linked_types[lesub.__class__]) != 0:
|
628
|
|
- #Fetch relation attributes
|
629
|
|
- rel_attr_table = MySQL.get_r2t2table_name(lesup.__class__.__name__, lesub.__class__.__name__)
|
630
|
|
- sql = select(MySQL.rel_attr_table, {MySQL.relations_pkname: id_relation})
|
631
|
|
- if cur.execute(sql) != 1:
|
632
|
|
- raise RuntimeError("Unknow SQL error")
|
633
|
|
-
|
634
|
|
- res = all_to_dicts(cur)
|
635
|
|
- if len(res) == 0:
|
636
|
|
- #Here raising a warning and adding empty (or default) attributes will be better
|
637
|
|
- raise RuntimeError("This relation should have attributes but none found !!!")
|
638
|
|
- if len(res) > 1:
|
639
|
|
- raise RuntimeError("When selecting on primary key, get more than one result. Bailout")
|
640
|
|
- attrs = res[0]
|
641
|
|
- relation['rel_attr'] = attrs
|
642
|
|
-
|
643
|
|
- return relation
|
644
|
|
-
|
645
|
|
- ## @brief Fetch all relations concerning an object (rel2type relations)
|
646
|
|
- # @param leo LeType : LeType child instance
|
647
|
|
- # @return a list of tuple (lesup, lesub, dict_attr)
|
648
|
|
- def get_relations(self, leo):
|
649
|
|
-
|
650
|
|
- sql = select(self.datasource_utils.relations_table_name, where=or_(({'id_sub': leo.lodel_id}, {'id_sup': leo.lodel_id})))
|
651
|
|
-
|
652
|
|
- with self.connection as cur:
|
653
|
|
- results = all_to_dicts(cur.execute(sql))
|
654
|
|
-
|
655
|
|
- relations = []
|
656
|
|
- for result in results:
|
657
|
|
- id_sup = result['id_sup']
|
658
|
|
- id_sub = result['id_sub']
|
659
|
|
-
|
660
|
|
- del result['id_sup']
|
661
|
|
- del result['id_sub']
|
662
|
|
- rel_attr = result
|
663
|
|
-
|
664
|
|
- relations.append((id_sup, id_sub, rel_attr))
|
665
|
|
-
|
666
|
|
- return relations
|
667
|
|
-
|
668
|
|
- ## @brief Add a superior to a LeObject
|
669
|
|
- # @note in the MySQL version the method will have a depth=None argument to allow reccursive calls to add all the path to the root with corresponding depth
|
670
|
|
- # @param lesup LeType : superior LeType child class instance
|
671
|
|
- # @param lesub LeType : subordinate LeType child class instance
|
672
|
|
- # @param nature str : A relation nature @ref EditorialModel.classtypesa
|
673
|
|
- # @param rank int : The rank of this relation
|
674
|
|
- # @param depth None|int : The depth of the relation (used to make reccursive calls in order to link with all superiors)
|
675
|
|
- # @return The relation ID or False if fails
|
676
|
|
- def add_superior(self, lesup, lesub, nature, rank, depth=None):
|
677
|
|
-
|
678
|
|
- params = {'id_sup': lesup.lodel_id, 'id_sub': lesub.lodel_id, 'nature': nature, 'rank': rank}
|
679
|
|
- if depth is not None:
|
680
|
|
- params['depth'] = depth
|
681
|
|
-
|
682
|
|
- sql_insert = insert(self.datasource_utils.relations_table_name, params)
|
683
|
|
- with self.connection as cur:
|
684
|
|
- if cur.execute(sql_insert) != 1:
|
685
|
|
- return False
|
686
|
|
-
|
687
|
|
- cur.execute('SELECT last_insert_id()')
|
688
|
|
- relation_id, = cur.fetchone()
|
689
|
|
-
|
690
|
|
- if nature in EmNature.getall():
|
691
|
|
- parent_superiors = lesup.superiors()
|
692
|
|
- for superior in parent_superiors:
|
693
|
|
- depth = depth - 1 if depth is not None else 1
|
694
|
|
- self.add_relation(lesup=superior.lodel_id, lesub=lesub.lodel_id, nature=nature, depth=depth, rank=rank)
|
695
|
|
-
|
696
|
|
- return relation_id
|
697
|
|
-
|
698
|
|
- ## @brief Fetch a superiors list ordered by depth for a LeType
|
699
|
|
- # @param lesub LeType : subordinate LeType child class instance
|
700
|
|
- # @param nature str : A relation nature @ref EditorialModel.classtypes
|
701
|
|
- # @return A list of LeType ordered by depth (the first is the direct superior)
|
702
|
|
- def get_superiors(self, lesub, nature):
|
703
|
|
-
|
704
|
|
- sql = select(
|
705
|
|
- self.datasource_utils.relations_table_name,
|
706
|
|
- columns=('id_sup',),
|
707
|
|
- where={'id_sub': lesub.lodel_id, 'nature': nature},
|
708
|
|
- order_by=('depth desc',)
|
709
|
|
- )
|
710
|
|
-
|
711
|
|
- result = []
|
712
|
|
- with self.connection as cur:
|
713
|
|
- results = all_to_dicts(cur.execute(sql))
|
714
|
|
-
|
715
|
|
- superiors = [LeType(result['id_sup']) for result in results]
|
716
|
|
-
|
717
|
|
- return superiors
|
718
|
|
-
|
719
|
|
- ## @brief Fetch the list of the subordinates given a nature
|
720
|
|
- # @param lesup LeType : superior LeType child class instance
|
721
|
|
- # @param nature str : A relation nature @ref EditorialModel.classtypes
|
722
|
|
- # @return A list of LeType ordered by rank that are subordinates of lesup in a "nature" relation
|
723
|
|
- def get_subordinates(self, lesup, nature):
|
724
|
|
- with self.connection as cur:
|
725
|
|
- id_sup = lesup.lodel_id if isinstance(lesup, leapi.letype.LeType) else MySQL.leroot_lodel_id
|
726
|
|
- sql = select(
|
727
|
|
- MySQL.relations_table_name,
|
728
|
|
- columns=('id_sup',),
|
729
|
|
- where={'id_sup': id_sup, 'nature': nature},
|
730
|
|
- order_by=('rank',)
|
731
|
|
- )
|
732
|
|
- cur.execut(sql)
|
733
|
|
- res = all_to_dicts(cur)
|
734
|
|
-
|
735
|
|
- return [LeType(r['id_sup']) for r in res]
|
736
|
|
-
|
737
|
|
- # ================================================================================================================ #
|
738
|
|
- # FONCTIONS A SUPPRIMER #
|
739
|
|
- # ================================================================================================================ #
|
740
|
|
-
|
741
|
|
- ## @brief inserts a new object
|
742
|
|
- # @param letype LeType
|
743
|
|
- # @param leclass LeClass
|
744
|
|
- # @param datas dict : dictionnary of field:value pairs to save
|
745
|
|
- # @return int : lodel_id of the created object
|
746
|
|
- # @todo add the returning clause and the insertion in "object"
|
747
|
|
- # def insert(self, letype, leclass, datas):
|
748
|
|
- # if isinstance(datas, list):
|
749
|
|
- # res = list()
|
750
|
|
- # for data in datas:
|
751
|
|
- # res.append(self.insert(letype, leclass, data))
|
752
|
|
- # return res if len(res)>1 else res[0]
|
753
|
|
- # elif isinstance(datas, dict):
|
754
|
|
- #
|
755
|
|
- # object_datas = {'class_id': leclass._class_id, 'type_id': letype._type_id}
|
756
|
|
- #
|
757
|
|
- # cur = self.datasource_utils.query(self.connection, insert(self.datasource_utils.objects_table_name, object_datas))
|
758
|
|
- # lodel_id = cur.lastrowid
|
759
|
|
- #
|
760
|
|
- # datas[self.datasource_utils.field_lodel_id] = lodel_id
|
761
|
|
- # query_table_name = self.datasource_utils.get_table_name_from_class(leclass.__name__)
|
762
|
|
- # self.datasource_utils.query(self.connection, insert(query_table_name, datas))
|
763
|
|
- #
|
764
|
|
- # return lodel_id
|
765
|
|
-
|
766
|
|
- ## @brief search for a collection of objects
|
767
|
|
- # @param leclass LeClass
|
768
|
|
- # @param letype LeType
|
769
|
|
- # @field_list list
|
770
|
|
- # @param filters list : list of tuples formatted as (FIELD, OPERATOR, VALUE)
|
771
|
|
- # @param relation_filters list : list of tuples formatted as (('superior'|'subordinate', FIELD), OPERATOR, VALUE)
|
772
|
|
- # @return list
|
773
|
|
- # def get(self, leclass, letype, field_list, filters, relational_filters=None):
|
774
|
|
- #
|
775
|
|
- # if leclass is None:
|
776
|
|
- # query_table_name = self.datasource_utils.objects_table_name
|
777
|
|
- # else:
|
778
|
|
- # query_table_name = self.datasource_utils.get_table_name_from_class(leclass.__name__)
|
779
|
|
- # where_filters = self._prepare_filters(filters, query_table_name)
|
780
|
|
- # join_fields = {}
|
781
|
|
- #
|
782
|
|
- # if relational_filters is not None and len(relational_filters) > 0:
|
783
|
|
- # rel_filters = self._prepare_rel_filters(relational_filters)
|
784
|
|
- # for rel_filter in rel_filters:
|
785
|
|
- # # join condition
|
786
|
|
- # relation_table_join_field = "%s.%s" % (self.datasource_utils.relations_table_name, self.RELATIONS_POSITIONS_FIELDS[rel_filter['position']])
|
787
|
|
- # query_table_join_field = "%s.%s" % (query_table_name, self.datasource_utils.field_lodel_id)
|
788
|
|
- # join_fields[query_table_join_field] = relation_table_join_field
|
789
|
|
- # # Adding "where" filters
|
790
|
|
- # where_filters['%s.%s' % (self.datasource_utils.relations_table_name, self.datasource_utils.relations_field_nature)] = rel_filter['nature']
|
791
|
|
- # where_filters[rel_filter['condition_key']] = rel_filter['condition_value']
|
792
|
|
- #
|
793
|
|
- # # building the query
|
794
|
|
- # query = select(query_table_name, where=where_filters, select=field_list, joins=join(self.datasource_utils.relations_table_name, join_fields))
|
795
|
|
- # else:
|
796
|
|
- # query = select(query_table_name, where=where_filters, select=field_list)
|
797
|
|
- #
|
798
|
|
- # Executing the query
|
799
|
|
- # cur = self.datasource_utils.query(self.connection, query)
|
800
|
|
- # results = all_to_dicts(cur)
|
801
|
|
- #
|
802
|
|
- # return results
|
803
|
|
-
|
804
|
|
- ## @brief delete an existing object
|
805
|
|
- # @param letype LeType
|
806
|
|
- # @param leclass LeClass
|
807
|
|
- # @param filters list : list of tuples formatted as (FIELD, OPERATOR, VALUE)
|
808
|
|
- # @param relational_filters list : list of tuples formatted as (('superior'|'subordinate', FIELD), OPERATOR, VALUE)
|
809
|
|
- # @return bool : True on success
|
810
|
|
- # def delete(self, letype, leclass, filters, relational_filters):
|
811
|
|
- # query_table_name = self.datasource_utils.get_table_name_from_class(leclass.__name__)
|
812
|
|
- # prep_filters = self._prepare_filters(filters, query_table_name)
|
813
|
|
- # prep_rel_filters = self._prepare_rel_filters(relational_filters)
|
814
|
|
- #
|
815
|
|
- # if len(prep_rel_filters) > 0:
|
816
|
|
- # query = "DELETE %s FROM " % query_table_name
|
817
|
|
- #
|
818
|
|
- # for prep_rel_filter in prep_rel_filters:
|
819
|
|
- # query += "%s INNER JOIN %s ON (%s.%s = %s.%s)" % (
|
820
|
|
- # self.datasource_utils.relations_table_name,
|
821
|
|
- # query_table_name,
|
822
|
|
- # self.datasource_utils.relations_table_name,
|
823
|
|
- # prep_rel_filter['position'],
|
824
|
|
- # query_table_name,
|
825
|
|
- # self.datasource_utils.field_lodel_id
|
826
|
|
- # )
|
827
|
|
- #
|
828
|
|
- # if prep_rel_filter['condition_key'][0] is not None:
|
829
|
|
- # prep_filters[("%s.%s" % (self.datasource_utils.relations_table_name, prep_rel_filter['condition_key'][0]), prep_rel_filter['condition_key'][1])] = prep_rel_filter['condition_value']
|
830
|
|
- #
|
831
|
|
- # if prep_filters is not None and len(prep_filters) > 0:
|
832
|
|
- # query += " WHERE "
|
833
|
|
- # filter_counter = 0
|
834
|
|
- # for filter_item in prep_filters:
|
835
|
|
- # if filter_counter > 1:
|
836
|
|
- # query += " AND "
|
837
|
|
- # query += "%s %s %s" % (filter_item[0][0], filter_item[0][1], filter_item[1])
|
838
|
|
- # else:
|
839
|
|
- # query = delete(query_table_name, filters)
|
840
|
|
- #
|
841
|
|
- # query_delete_from_object = delete(self.datasource_utils.objects_table_name, {'lodel_id': filters['lodel_id']})
|
842
|
|
- # with self.connection as cur:
|
843
|
|
- # cur.execute(query)
|
844
|
|
- # cur.execute(query_delete_from_object)
|
845
|
|
- #
|
846
|
|
- # return True
|
847
|
|
-
|
848
|
|
- ## @brief update an existing object's data
|
849
|
|
- # @param letype LeType
|
850
|
|
- # @param leclass LeClass
|
851
|
|
- # @param filters list : list of tuples formatted as (FIELD, OPERATOR, VALUE)
|
852
|
|
- # @param rel_filters list : list of tuples formatted as (('superior'|'subordinate', FIELD), OPERATOR, VALUE)
|
853
|
|
- # @param data dict
|
854
|
|
- # @return bool
|
855
|
|
- # @todo prendre en compte les rel_filters
|
856
|
|
- # def update(self, letype, leclass, filters, rel_filters, data):
|
857
|
|
- #
|
858
|
|
- # query_table_name = self.datasource_utils.get_table_name_from_class(leclass.__name__)
|
859
|
|
- # where_filters = filters
|
860
|
|
- # set_data = data
|
861
|
|
- #
|
862
|
|
- # prepared_rel_filters = self._prepare_rel_filters(rel_filters)
|
863
|
|
- #
|
864
|
|
- # Building the query
|
865
|
|
- # query = update(table=query_table_name, where=where_filters, set=set_data)
|
866
|
|
- # Executing the query
|
867
|
|
- # with self.connection as cur:
|
868
|
|
- # cur.execute(query)
|
869
|
|
- # return True
|