Browse Source

Implements get_related in MySQL datasource

Yann Weber 9 years ago
parent
commit
d45b84c5d9
2 changed files with 72 additions and 3 deletions
  1. 1
    1
      leobject/datasources/dummy.py
  2. 71
    2
      leobject/datasources/ledatasourcesql.py

+ 1
- 1
leobject/datasources/dummy.py View File

@@ -99,7 +99,7 @@ class DummyDatasource(object):
99 99
     # @param leo LeType : The from LeType child class instance
100 100
     # @param letype LeType : The wanted LeType child class (not instance !)
101 101
     # @param get_sub bool : If True, leo will be the superior and we wants all subordinates of Type letype, else its the oposite, leo is the subordinates and we want superiors with Type letype
102
-    # @return A list of tuple( LeType instance, dict('id_relation':id,'rank':rank,  attr_name:attr_val, ...) ) ordered by rank
102
+    # @return a list of dict { 'id_relation':.., 'rank':.., 'lesup':.., 'lesub'.., 'rel_attrs': dict() }
103 103
     def get_related(self, leo, letype, get_sub=True):
104 104
         pass
105 105
 

+ 71
- 2
leobject/datasources/ledatasourcesql.py View File

@@ -1,6 +1,7 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 
3 3
 import pymysql
4
+import copy
4 5
 
5 6
 import leobject
6 7
 from leobject.datasources.dummy import DummyDatasource
@@ -244,6 +245,76 @@ class LeDataSourceSQL(DummyDatasource):
244 245
 
245 246
         return True
246 247
 
248
+    ## @brief Fetch related (rel2type) by LeType
249
+    # @param leo LeType : We want related LeObject of this LeType child class instance
250
+    # @param letype LeType(class) : We want related LeObject of this LeType child class (not instance)
251
+    # @param get_sub bool : If True leo is the superior and we want subordinates, else its the opposite
252
+    # @return a list of dict { 'id_relation':.., 'rank':.., 'lesup':.., 'lesub'.., 'rel_attrs': dict() }
253
+    def get_related(self, leo, letype, get_sub=True):
254
+        if leobject.letype.LeType not in letype.__bases__:
255
+            raise ValueError("letype argument should be a LeType child class, but got %s"%type(letype))
256
+        if not isinstance(leo, LeType):
257
+            raise ValueError("leo argument should be a LeType child class instance but got %s"%type(leo))
258
+        with self.connection as cur:
259
+            id_leo, id_type = 'id_sup', 'id_sub' if get_sub else 'id_sub', 'id_sup'
260
+            
261
+            joins = [
262
+                join(
263
+                    (MySQL.objects_table_name, 'o'),
264
+                    on={'r.'+id_type: 'o.'+MySQL.field_lodel_id}
265
+                ),
266
+                join(
267
+                    (MySQL.objects_table_name, 'p'),
268
+                    on={'r.'+id_leo: 'p.'+MySQL.field_lodel_id}
269
+                ),
270
+            ]
271
+
272
+            lesup, lesub = leo.__class__, letype if get_sub else letype, leo.__class__
273
+            common_infos = ('r.id_relation', 'r.id_sup', 'r.id_sub', 'r.rank', 'r.depth')
274
+            if len(lesup._linked_types[lesub]) > 0:
275
+                #relationnal attributes, need to join with r2t table
276
+                joins.append(
277
+                    join(
278
+                        (MySQL.get_r2t2table_name, 'r2t'),
279
+                        on={'r.'+MySQL.relations_pkname: 'r2t'+MySQL.relations_pkname}
280
+                    )
281
+                )
282
+                select=('r.id_relation', 'r.id_sup', 'r.id_sub', 'r.rank', 'r.depth', 'r2t.*')
283
+            else:
284
+                select = common_infos
285
+
286
+            sql = select(
287
+                (MySQL.relations_table_name, 'r'),
288
+                select=select,
289
+                where={
290
+                    id_leo: leo.lodel_id,
291
+                    'type_id': letype._type_id,
292
+                },
293
+                joins=joins
294
+            )
295
+
296
+            cur.execute(sql)
297
+            res = all_to_dicts(cur)
298
+            
299
+            #Building result
300
+            ret = list()
301
+            for datas in res:
302
+                r_letype = letype(res['r.'+id_type])
303
+                ret_item = {
304
+                    'id_relation':+datas[MySQL.relations_pkname],
305
+                    'lesup': r_leo if get_sub else r_letype,
306
+                    'lesub': r_letype if get_sub else r_leo,
307
+                    'rank': res['rank']
308
+                }
309
+
310
+                rel_attr = copy.copy(datas)
311
+                for todel in common_infos:
312
+                    del(rel_attr[todel])
313
+                ret_item['rel_attrs'] = rel_attr
314
+                ret.append(ret_item)
315
+
316
+            return ret
317
+    
247 318
     ## @brief Set the rank of a relation identified by its ID
248 319
     # @param id_relation int : relation ID
249 320
     # @param rank int|str : 'first', 'last', or an integer value
@@ -253,8 +324,6 @@ class LeDataSourceSQL(DummyDatasource):
253 324
         self._check_rank(rank)
254 325
         self._set_relation_rank(id_relation, rank)
255 326
 
256
-        
257
-
258 327
     ## @brief Set the rank of a relation identified by its ID
259 328
     #
260 329
     # @note this solution is not the more efficient solution but it

Loading…
Cancel
Save