Browse Source

The automatic UID creation by datasource implementation implies somes changes :

	The UniqID datahandler has to call the datasource
	LeObject has to be able to determine wich parent class define its UID datahandler
	[NOT IMPLEMENTED] the datasource should be able to select with an abstract LeObject as target ( see #92 )
Yann Weber 8 years ago
parent
commit
6e89fca151

+ 7
- 0
em_test.py View File

19
 ####################
19
 ####################
20
 #   Lodel Object   #
20
 #   Lodel Object   #
21
 ####################
21
 ####################
22
+em_abstract = em.new_class( 'abstract_object',
23
+    display_name = 'Abstract lodel object',
24
+    help_text = 'For testing purpose',
25
+    group = base_group,
26
+    abstract = True)
27
+
22
 em_object = em.new_class(   'object',
28
 em_object = em.new_class(   'object',
23
                             display_name = 'Object',
29
                             display_name = 'Object',
24
                             help_text = 'Main class for all Em objects',
30
                             help_text = 'Main class for all Em objects',
25
                             group = base_group,
31
                             group = base_group,
26
                             abstract = True,
32
                             abstract = True,
33
+                            parents = em_abstract,
27
 )
34
 )
28
 em_object.new_field(    'lodel_id',
35
 em_object.new_field(    'lodel_id',
29
                         display_name = 'Lodel identifier',
36
                         display_name = 'Lodel identifier',

BIN
examples/em_test.pickle View File


+ 6
- 0
lodel/leapi/datahandlers/datas.py View File

75
     def _check_data_value(self, value):
75
     def _check_data_value(self, value):
76
         return value, None
76
         return value, None
77
 
77
 
78
+    def construct_data(self, emcomponent, fname, datas, cur_value):
79
+        if cur_value is None:
80
+            #Ask datasource to provide a new uniqID
81
+            return emcomponent._ro_datasource.new_numeric_id(emcomponent)
82
+        return cur_value
83
+
78
 class LeobjectSubclassIdentifier(Varchar):
84
 class LeobjectSubclassIdentifier(Varchar):
79
     
85
     
80
     help = 'Datahandler designed to handle LeObject subclass identifier in DB'
86
     help = 'Datahandler designed to handle LeObject subclass identifier in DB'

+ 1
- 0
lodel/leapi/datahandlers/datas_base.py View File

93
     def construct_data(self, emcomponent, fname, datas, cur_value):
93
     def construct_data(self, emcomponent, fname, datas, cur_value):
94
         if (self.now_on_create and cur_value is None) or self.now_on_update:
94
         if (self.now_on_create and cur_value is None) or self.now_on_update:
95
             return datetime.datetime.now()
95
             return datetime.datetime.now()
96
+        return cur_value
96
 
97
 
97
 ##@brief Data field designed to handle long string
98
 ##@brief Data field designed to handle long string
98
 class Text(DataField):
99
 class Text(DataField):

+ 39
- 0
lodel/leapi/leobject.py View File

181
     def fields(cls):
181
     def fields(cls):
182
         return copy.copy(cls._fields)
182
         return copy.copy(cls._fields)
183
     
183
     
184
+    ##@brief Return the list of parents classes
185
+    #
186
+    #@note the first item of the list is the current class, the second is it's
187
+    #parent etc...
188
+    #@param cls
189
+    #@warning multiple inheritance broken by this method
190
+    #@return a list of LeObject child classes
191
+    #@todo multiple parent capabilities implementation
192
+    @classmethod
193
+    def hierarch(cls):
194
+        res = [cls]
195
+        cur = cls
196
+        while True:
197
+            cur = cur.__bases__[0] # Multiple inheritance broken HERE
198
+            if cur in (LeObject, object):
199
+                break
200
+            else:
201
+                res.append(cur)
202
+        return res
203
+    
204
+    ##@brief Return the parent class that is the "source" of uid
205
+    #
206
+    #The method goal is to return the parent class that defines UID.
207
+    #@return a LeObject child class or false if no UID defined
208
+    @classmethod
209
+    def uid_source(cls):
210
+        if cls._uid is None or len(cls._uid) == 0:
211
+            return False
212
+        hierarch = cls.hierarch()
213
+        prev = hierarch[0]
214
+        uid_handlers = set( cls._fields[name] for name in cls._uid )
215
+        for pcls in cls.hierarch()[1:]:
216
+            puid_handlers = set(cls._fields[name] for name in pcls._uid)
217
+            if set(pcls._uid) != set(pcls._uid) \
218
+                or puid_handlers != uid_handlers:
219
+                break
220
+            prev = pcls
221
+        return prev
222
+    
184
     ##@brief Initialise both datasources (ro and rw)
223
     ##@brief Initialise both datasources (ro and rw)
185
     #
224
     #
186
     #This method is used once at dyncode load to replace the datasource string
225
     #This method is used once at dyncode load to replace the datasource string

+ 18
- 11
plugins/dummy_datasource/datasource.py View File

5
     def __init__(self, *conn_args, **conn_kwargs):
5
     def __init__(self, *conn_args, **conn_kwargs):
6
         self.conn_args = conn_args
6
         self.conn_args = conn_args
7
         self.conn_kwargs = conn_kwargs
7
         self.conn_kwargs = conn_kwargs
8
+    
9
+    ##@brief Provide a new uniq numeric ID
10
+    #@param emcomp LeObject subclass (not instance) : To know on wich things we
11
+    #have to be uniq
12
+    #@return an integer
13
+    def new_numeric_id(self, emcomp):
14
+        pass
8
 
15
 
9
-    ## @brief returns a selection of documents from the datasource
10
-    # @param target_cls Emclass
11
-    # @param field_list list
12
-    # @param filters list : List of filters
13
-    # @param rel_filters list : List of relational filters
14
-    # @param order list : List of column to order. ex: order = [('title', 'ASC'),]
15
-    # @param group list : List of tupple representing the column to group together. ex: group = [('title', 'ASC'),]
16
-    # @param limit int : Number of records to be returned
17
-    # @param offset int: used with limit to choose the start record
18
-    # @param instanciate bool : If true, the records are returned as instances, else they are returned as dict
19
-    # @return list
16
+    ##@brief returns a selection of documents from the datasource
17
+    #@param target_cls Emclass
18
+    #@param field_list list
19
+    #@param filters list : List of filters
20
+    #@param rel_filters list : List of relational filters
21
+    #@param order list : List of column to order. ex: order = [('title', 'ASC'),]
22
+    #@param group list : List of tupple representing the column to group together. ex: group = [('title', 'ASC'),]
23
+    #@param limit int : Number of records to be returned
24
+    #@param offset int: used with limit to choose the start record
25
+    #@param instanciate bool : If true, the records are returned as instances, else they are returned as dict
26
+    #@return list
20
     def select(self, target_cls, field_list, filters, rel_filters=None, order=None, group=None, limit=None, offset=0,
27
     def select(self, target_cls, field_list, filters, rel_filters=None, order=None, group=None, limit=None, offset=0,
21
                instanciate=True):
28
                instanciate=True):
22
         pass
29
         pass

+ 17
- 1
plugins/mongodb_datasource/datasource.py View File

66
             del(self._connections[self.__conn_hash])
66
             del(self._connections[self.__conn_hash])
67
             logger.info("Closing connection to database")
67
             logger.info("Closing connection to database")
68
 
68
 
69
+    ##@brief Provide a new uniq numeric ID
70
+    #@param emcomp LeObject subclass (not instance) : To know on wich things we
71
+    #have to be uniq
72
+    #@warning multiple UID broken by this method
73
+    #@return an integer
74
+    def new_numeric_id(self, emcomp):
75
+        target = emcomp.uid_source()
76
+        tuid = target._uid[0] # Multiple UID broken here
77
+        results = self.select(
78
+            target, [tuid], [], order=[(tuid, 'DESC')], limit = 1)
79
+        return results[0][tuid]+1
80
+
69
     ##@brief returns a selection of documents from the datasource
81
     ##@brief returns a selection of documents from the datasource
70
     #@param target Emclass
82
     #@param target Emclass
71
     #@param field_list list
83
     #@param field_list list
78
     #@param instanciate bool : If true, the records are returned as instances, else they are returned as dict
90
     #@param instanciate bool : If true, the records are returned as instances, else they are returned as dict
79
     #@return list
91
     #@return list
80
     #@todo Implement the relations
92
     #@todo Implement the relations
81
-    def select(self, target, field_list, filters, rel_filters=None, order=None, group=None, limit=None, offset=0):
93
+    def select(self, target, field_list, filters = None, rel_filters=None, order=None, group=None, limit=None, offset=0):
94
+        # Default arg init
95
+        filters = [] if filters is None else filters
96
+        rel_filters = [] if rel_filters is None else rel_filters
97
+
82
         collection_name = object_collection_name(target)
98
         collection_name = object_collection_name(target)
83
         collection = self.database[collection_name]
99
         collection = self.database[collection_name]
84
         query_filters = self.__process_filters(
100
         query_filters = self.__process_filters(

Loading…
Cancel
Save