Browse Source

Merge branch 'master' of git.labocleo.org:lodel2

Yann Weber 9 years ago
parent
commit
10c3924ec0

+ 19
- 547
DataSource/MySQL/leapidatasource.py View File

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

+ 1
- 0
Lodel/settings_format.py View File

@@ -19,4 +19,5 @@ MANDATORY = [
19 19
 ALLOWED = [
20 20
     'em_graph_output',
21 21
     'em_graph_format',
22
+    'templates_base_dir'
22 23
 ]

+ 5
- 1
Template/Loader.py View File

@@ -21,9 +21,13 @@ class TemplateLoader(object):
21 21
     # @param template_file str : path to the template file (starting from the base path used to instanciate the
22 22
     #                            TemplateLoader)
23 23
     # @param template_vars dict : parameters to be used in the template
24
+    # @param template_extra list : list of custom modules to import in the template (default value : None)
24 25
     # @return str. String containing the HTML output of the processed templated
25
-    def render_to_html(self, template_file, template_vars):
26
+    def render_to_html(self, template_file, template_vars={}, template_extra=None):
26 27
         loader = jinja2.FileSystemLoader(searchpath=self.search_path, followlinks=self.follow_links)
27 28
         environment = jinja2.Environment(loader=loader)
28 29
         template = environment.get_template(template_file)
30
+        if template_extra is not None:
31
+            for extra in template_extra:
32
+                template.globals[extra[0]] = extra[1]
29 33
         return template.render(template_vars)

+ 3
- 0
install/instance_settings.py View File

@@ -1,10 +1,13 @@
1 1
 #-*- coding:utf8 -*-
2 2
 
3 3
 import pymysql
4
+import os
4 5
 
5 6
 sitename = 'LODEL2_INSTANCE_NAME'
6 7
 lodel2_lib_path = 'LODEL2_LIB_ABS_PATH'
7 8
 
9
+templates_base_dir = 'LODEL2_INSTANCE_TEMPLATES_BASE_DIR'
10
+
8 11
 debug = False
9 12
 
10 13
 em_file = 'em.json'

+ 0
- 24
makemigrations_interactive_rename.patch View File

@@ -1,24 +0,0 @@
1
---- orig/django/core/management/commands/makemigrations.py	2015-09-16 11:52:59.456895569 +0200
2
-+++ new/django/core/management/commands/makemigrations.py	2015-09-16 11:51:34.344896348 +0200
3
-@@ -84,11 +84,20 @@ class Command(BaseCommand):
4
-         if self.merge and conflicts:
5
-             return self.handle_merge(loader, conflicts)
6
- 
7
-+        questionner_kwargs = {
8
-+            'specified_apps': app_labels,
9
-+            'dry_run': self.dry_run
10
-+        }
11
-+        if self.interactive:
12
-+            questionner = InteractiveMigrationQuestioner(**questionner_kwargs)
13
-+        else:
14
-+            questionner = MigrationQuestioner(**questionner_kwargs)
15
-+
16
-         # Set up autodetector
17
-         autodetector = MigrationAutodetector(
18
-             loader.project_state(),
19
-             ProjectState.from_apps(apps),
20
--            InteractiveMigrationQuestioner(specified_apps=app_labels, dry_run=self.dry_run),
21
-+            questionner
22
-         )
23
- 
24
-         # If they want to make an empty migration, make one for each app

Loading…
Cancel
Save