Browse Source

SQL datasource: implement LeClass.get() and LeType.get()

ArnAud 9 years ago
parent
commit
a5efcdbfd8
2 changed files with 51 additions and 26 deletions
  1. 17
    0
      DataSource/MySQL/MySQL.py
  2. 34
    26
      leapi/datasources/ledatasourcesql.py

+ 17
- 0
DataSource/MySQL/MySQL.py View File

@@ -92,3 +92,20 @@ class MySQL(object):
92 92
             raise ValueError("Unsupported fieldtype ftype : %s" % ftype)
93 93
 
94 94
         return res
95
+
96
+    ## Brief add table prefix to a column name
97
+    # @param name string: column name to prefix
98
+    # @param prefixes dict(prefix:list(name,))
99
+    # @return prefixed_name string: the name prefixed
100
+    # find the same name in some list of names, prepend the key of the dict to the name
101
+    @staticmethod
102
+    def find_prefix(name, prefixes):
103
+        for prefix, names in prefixes:
104
+            if name in names:
105
+                return MySQL.column_prefix(prefix, name)
106
+        return name
107
+
108
+    ## prefix a column name with the table name
109
+    @staticmethod
110
+    def column_prefix(table, column):
111
+        return '%s.%s' % (table, column)

+ 34
- 26
leapi/datasources/ledatasourcesql.py View File

@@ -36,48 +36,56 @@ class LeDataSourceSQL(DummyDatasource):
36 36
     ## @brief select lodel editorial components using given filters
37 37
     # @param target_cls LeCrud(class): The component class concerned by the select (a LeCrud child class (not instance !) )
38 38
     # @param field_list list: List of field to fetch
39
-    # @param filters list: List of filters (see @ref leobject_filters)
40
-    # @param rel_filters list: List of relational filters (see @ref leobject_filters)
39
+    # @param filters list: List of filters (see @ref lecrud_filters)
40
+    # @param rel_filters list: List of relational filters (see @ref lecrud_filters)
41 41
     # @return a list of LeCrud child classes
42
-    # @todo this only works with LeObject.get()
42
+    # @todo this only works with LeObject.get(), LeClass.get() and LeType.get()
43 43
     # @todo for speed get rid of all_to_dicts
44
+    # @todo filters: all use cases are not implemented
44 45
     def select(self, target_cls, field_list, filters, rel_filters=None):
45 46
 
46 47
         joins = []
47 48
         # it is a LeObject, query only on main table
48 49
         if target_cls.__name__ == 'LeObject':
49 50
             main_table = self.datasource_utils.objects_table_name
50
-        # it is a LeType, query on main and class table
51
-        elif (hasattr(target_cls, '_leclass')):
51
+            fields = [(main_table, common_fields)]
52
+
53
+        # it is a LeType or a LeClass, query on main table left join class table on lodel_id
54
+        elif hasattr(target_cls, '_leclass') or hasattr(target_cls, '_class_id'):
52 55
             # find main table and main table datas
53 56
             main_table = self.datasource_utils.objects_table_name
54
-            class_table = self.datasource_utils.get_table_name_from_class(target_cls._leclass.__name__)
55
-            joins = [left_join(class_table, self.datasource_utils.field_lodel_id)]
56
-
57
-        if rel_filters is not None and len(rel_filters) > 0:
58
-            rel_filters = self._prepare_rel_filters(rel_filters)
59
-            for rel_filter in rel_filters:
60
-                # join condition
61
-                relation_table_join_field = "%s.%s" % (self.datasource_utils.relations_table_name, self.RELATIONS_POSITIONS_FIELDS[rel_filter['position']])
62
-                query_table_join_field = "%s.%s" % (query_table_name, self.datasource_utils.relations_field_nature)
63
-                join_fields[query_table_join_field] = relation_table_join_field
64
-                # adding "where" filters
65
-                where_filters['%s.%s' % (self.datasource_utils.relations_table_name, self.datasource_utils.relations_field_nature)] = rel_filter['nature']
66
-                where_filters[rel_filter['condition_key']] = rel_filter['condition_value']
67
-
68
-            # building the query
69
-            #query = select(query_table_name, where=where_filters, joins=join(self.datasource_utils.relations_table_name, join_fields))
70
-        #else:
71
-            #query = select(query_table_name, where=where_filters)
72
-
73
-        wheres = {(name, op):value for name,op,value in filters}
74
-        query = select(main_table, select=field_list, where=wheres, joins=joins)
57
+            main_class = target_cls._leclass if hasattr(target_cls, '_leclass') else target_cls
58
+            class_table = self.datasource_utils.get_table_name_from_class(main_class.__name__)
59
+            main_lodel_id = self.datasource_utils.column_prefix(main_table, self.datasource_utils.field_lodel_id)
60
+            class_lodel_id = self.datasource_utils.column_prefix(class_table, self.datasource_utils.field_lodel_id)
61
+            joins = [left_join(class_table, {main_lodel_id:class_lodel_id})]
62
+            fields = [(main_table, common_fields), (class_table, main_class.fieldlist())]
63
+
64
+        # prefix column name in field list
65
+        prefixed_field_list = [self.datasource_utils.find_prefix(name, fields) for name in field_list]
66
+
67
+        # @todo implement that
68
+        #if rel_filters is not None and len(rel_filters) > 0:
69
+            #rel_filters = self._prepare_rel_filters(rel_filters)
70
+            #for rel_filter in rel_filters:
71
+                ## join condition
72
+                #relation_table_join_field = "%s.%s" % (self.datasource_utils.relations_table_name, self.RELATIONS_POSITIONS_FIELDS[rel_filter['position']])
73
+                #query_table_join_field = "%s.%s" % (query_table_name, self.datasource_utils.relations_field_nature)
74
+                #join_fields[query_table_join_field] = relation_table_join_field
75
+                ## adding "where" filters
76
+                #where_filters['%s.%s' % (self.datasource_utils.relations_table_name, self.datasource_utils.relations_field_nature)] = rel_filter['nature']
77
+                #where_filters[rel_filter['condition_key']] = rel_filter['condition_value']
78
+
79
+        # prefix filters'' column names, and prepare dict for mosql where {(fieldname, op): value}
80
+        wheres = {(self.datasource_utils.find_prefix(name, fields), op):value for name,op,value in filters}
81
+        query = select(main_table, select=prefixed_field_list, where=wheres, joins=joins)
75 82
         #print ('SQL', query)
76 83
 
77 84
         # Executing the query
78 85
         cur = self.datasource_utils.query(self.connection, query)
79 86
         results = all_to_dicts(cur)
80 87
 
88
+        # instanciate each row to editorial components
81 89
         results = [target_cls.uid2leobj(datas['type_id'])(**datas) for datas in results]
82 90
         #print('results', results)
83 91
 

Loading…
Cancel
Save