Browse Source

Update the _LeObject.get() method to handle relationnal filters

Yann Weber 9 years ago
parent
commit
6123d23be4
3 changed files with 69 additions and 49 deletions
  1. 15
    0
      leobject/lefactory.py
  2. 31
    16
      leobject/leobject.py
  3. 23
    33
      leobject/letype.py

+ 15
- 0
leobject/lefactory.py View File

@@ -1,5 +1,7 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 
3
+import importlib
4
+
3 5
 import EditorialModel
4 6
 from EditorialModel.model import Model
5 7
 from EditorialModel.fieldtypes.generic import GenericFieldType
@@ -9,8 +11,21 @@ from EditorialModel.fieldtypes.generic import GenericFieldType
9 11
 # The name is not good but i've no other ideas for the moment
10 12
 class LeFactory(object):
11 13
     
14
+    output_file = 'dyn.py'
15
+
12 16
     def __init__(LeFactory):raise NotImplementedError("Not designed (yet?) to be implemented")
13 17
 
18
+    ## @brief Return a LeObject child class given its name
19
+    # @return a python class or False
20
+    @staticmethod
21
+    def leobj_from_name(name):
22
+        mod = importlib.import_module('leobject.'+LeFactory.output_file.split('.')[-1])
23
+        try:
24
+            res = getattr(mod, name)
25
+        except AttributeError:
26
+            return False
27
+        return res
28
+
14 29
     ## @brief Convert an EmType or EmClass name in a python class name
15 30
     # @param name str : The name
16 31
     # @return name.title()

+ 31
- 16
leobject/leobject.py View File

@@ -70,8 +70,9 @@ class _LeObject(object):
70 70
         return okay
71 71
 
72 72
     ## @brief make a search to retrieve a collection of LeObject
73
-    # @param 
74 73
     # @param query_filters list : list of string of query filters (or tuple (FIELD, OPERATOR, VALUE) )
74
+    # @param typename str : The name of the LeType we want
75
+    # @param classname str : The name of the LeClass we want
75 76
     # @return responses ({string:*}): a list of dict with field:value
76 77
     def get(self, query_filters, typename = None, classname = None):
77 78
         filters = list()
@@ -85,42 +86,56 @@ class _LeObject(object):
85 86
         
86 87
         #Fetching EmType
87 88
         if typename is None:
88
-            emtype = None
89
+            letype = None
89 90
         else:
90
-            emtype = self._model.component_from_name(typename, 'EmType')
91
-            if not emtype:
92
-                raise LeObjectQueryError("No such EmType : '%s'"%typename)
91
+            letype = leobject.lefactory.LeFactory.leobj_from_name(typename)
92
+
93 93
         #Fetching EmClass
94 94
         if classname is None:
95
-            emclass = None
95
+            leclass = None
96 96
         else:
97
-            emclass = self._model.component_from_name(classname, 'EmClass')
97
+            leclass = leobject.lefactory.LeFactory.leobj_from_name(classname)
98 98
             if not emclass:
99 99
                 raise LeObjectQueryError("No such EmClass : '%s'"%classname)
100
+        
101
+        #Checking relational filters (for the moment fields like superior.NATURE)
102
+        relational_filters = list()
103
+        
104
+        for i in range(len(filters),0,-1): #reverse iteration to be able to delete relational filters from the list
105
+            field,_,_ = filters[i]
106
+            if field.startwith('superior.'):
107
+                #relationnal field
108
+                spl = field.split('.')
109
+                if len(spl) != 2:
110
+                    raise LeObjectQueryError("Not a valid relationnal field : '%s'"%(field))
111
+                nature = spl[1]
112
+                if nature not in EditorialModel.classtypes.EmNature.getall():
113
+                    raise LeObjectQueryError("'%s' is not a valid nature in the field %s"%(nature, field))
114
+                relational_filters.append(nature)
100 115
 
101 116
         #Checking that fields in the query_filters are correct
102
-        if emtype is None and emclass is None:
117
+        if letype is None and leclass is None:
103 118
             #Only fields from the object table are allowed
104 119
             for field,_,_ in filters:
105 120
                 if field not in EditorialModel.classtype.common_fields:
106 121
                     raise LeObjectQueryError("Not typename and no classname given, but the field %s is not in the common_fields list"%field)
107 122
         else:
108
-            if emtype is None:
109
-                field_l = emclass.fields()
123
+            if letype is None:
124
+                field_l = leclass._fieldtypes.keys()
110 125
             else:
111
-                if not (emclass is None):
112
-                    if emtype.em_class != emclass:
126
+                if not (leclass is None):
127
+                    if letype._leclass != leclass:
113 128
                         raise LeObjectQueryError("The EmType %s is not a specialisation of the EmClass %s"%(typename, classname))
114 129
                 else:
115 130
                     #Set emclass (to query the db ?
116
-                    emclass = emtype.em_class
117
-                field_l = emtype.fields()
131
+                    leclass = emtype._leclass
132
+                field_l = letype._fields
118 133
             #Checks that fields are in this type
119 134
             for field,_,_ in filters:
120
-                if field not in [ f.name for f in fields_l ]:
135
+                if field not in fields_l:
121 136
                     raise LeObjectQueryError("No field named '%s' in '%s'"%(field, typename))
122 137
 
123
-        return self._datasource.get(emclass, emtype, filters)
138
+        return self._datasource.get(emclass, emtype, filters, relational_filters)
124 139
 
125 140
     ## @brief check if data dict fits with the model
126 141
     # @param data dict: dictionnary of field:value to check

+ 23
- 33
leobject/letype.py View File

@@ -28,13 +28,32 @@ class LeType(object):
28 28
             if name not in self._fields:
29 29
                 raise AttributeError("No such field '%s' for %s"%(name, self.__class__.__name__)
30 30
             setattr(self, name, value)
31
-    
31
+
32
+    ## @brief Delete the LeType from Db
33
+    # @note equivalent to LeType::delete(this.lodel_id)
32 34
     @classinstancemethod
33 35
     def delete(self):
34 36
         pass
35 37
     
38
+    ## @brief Delete a LeType from the datasource
39
+    # @param lodel_id int : The lodel_id identifying the LeType
40
+    # @param return True if deleted False if not existing
41
+    # @throw InvalidArgumentError if invalid parameters
42
+    # @throw Leo exception if the lodel_id identify an object from another type
36 43
     @delete.classmethod
37
-    def delete(cls, uid):
44
+    def delete(cls, uid_l):
45
+        pass
46
+
47
+    @classinstancemethod
48
+    ## @brief Update a LeType in db
49
+    def update(self):
50
+        pass
51
+
52
+    @update.classmethod
53
+    ## @brief Update some LeType in db
54
+    # @param datas : keys are lodel_id and value are dict of fieldname => value
55
+    # @throw Some exception for some errors in datas
56
+    def update(cls, datas):
38 57
         pass
39 58
 
40 59
     ## @brief Insert a new LeType in the datasource
@@ -43,29 +62,10 @@ class LeType(object):
43 62
     # @thorw A leo exception if invalid stuff
44 63
     # @throw InvalidArgumentError if invalid argument
45 64
     @classmethod
46
-    def insert(cls, **datas):
65
+    def insert(self, **datas):
47 66
         super(LeType, self).insert(typename=self.__class__.__name__, classname=self._leclass.__name__, **datas)
48 67
         pass
49 68
     
50
-    ## @brief Delete a LeType from the datasource
51
-    # @param lodel_id int : The lodel_id identifying the LeType
52
-    # @param return True if deleted False if not existing
53
-    # @throw InvalidArgumentError if invalid parameters
54
-    # @throw Leo exception if the lodel_id identify an object from another type
55
-    @classmethod
56
-    def c_delete(cls, lodel_id):
57
-        pass
58
-    
59
-    ## @brief Update some objects in db
60
-    # @param lodel_id_l list : A list of lodel_id to update
61
-    # @param data dict : Represent the datas to update
62
-    # @return True if updated else False
63
-    # @throw InvalidArgumentError if invalid parameters
64
-    # @throw other Leo exceptions
65
-    @classmethod
66
-    def c_update(cls, lodel_id_l, datas):
67
-        pass
68
-    
69 69
     ## @brief Check that datas are valid for this type
70 70
     # @param datas dict : key == field name value are field values
71 71
     # @param complete bool : if True expect that datas provide values for all non internal fields
@@ -106,16 +106,6 @@ class LeType(object):
106 106
             self._fields[name].check_or_raise(value)
107 107
         return super(LeType, self).__setattr__(name, value)
108 108
     
109
-    ## @brief Delete the LeType
110
-    # @return True if deleted False if not
111
-    def delete(self):
112
-        return self.__class__.delete(self.lodel_id)
113
-    
114
-    ## @brief Update a LeType
115
-    # @return True if ok else False
116
-    def update(self):
117
-        return self.__class__.update(self.lodel_id, self._datas)
118
-        
119 109
     ## @brief Fetch superiors
120 110
     # @param nature str : The relation nature
121 111
     # @return if no nature given return a dict with nature as key and arrays of LeObject as value. Else return an array of LeObject
@@ -134,6 +124,6 @@ class LeType(object):
134 124
     # @param return True if done False if already done
135 125
     # @throw A Leo exception if trying to link with an invalid leo
136 126
     # @throw InvalidArgumentError if invalid argument
137
-    def add_superior(self, nature, leo):
127
+    def set_superior(self, nature, leo):
138 128
         pass
139 129
     

Loading…
Cancel
Save