|
@@ -67,6 +67,20 @@ class _LeObject(object):
|
67
|
67
|
letype.check_datas_or_raise(data, complete = True)
|
68
|
68
|
return cls._datasource.insert(letype, leclass, datas)
|
69
|
69
|
|
|
70
|
+ ## @brief Check if a LeType is a hierarchy root
|
|
71
|
+ @staticmethod
|
|
72
|
+ def is_root(leo):
|
|
73
|
+ if isinstance(leo, leobject.letype.LeType):
|
|
74
|
+ return False
|
|
75
|
+ elif isinstance(leo, LeRoot):
|
|
76
|
+ return True
|
|
77
|
+ raise ValueError("Invalid value for a LeType : %s"%leo)
|
|
78
|
+
|
|
79
|
+ ## @brief Return a LeRoot instance
|
|
80
|
+ @staticmethod
|
|
81
|
+ def get_root():
|
|
82
|
+ return LeRoot()
|
|
83
|
+
|
70
|
84
|
## @brief Delete LeObjects given filters
|
71
|
85
|
# @param cls
|
72
|
86
|
# @param letype LeType|str : LeType child class or name
|
|
@@ -216,6 +230,42 @@ class _LeObject(object):
|
216
|
230
|
|
217
|
231
|
return cls._datasource.del_related(lesup, lesub)
|
218
|
232
|
|
|
233
|
+ ## @brief Add a hierarchy relation between two LeObject
|
|
234
|
+ # @param lesup LeType|LeRoot : LeType child class instance
|
|
235
|
+ # @param lesub LeType : LeType child class instance
|
|
236
|
+ # @param nature str : The nature of the relation @ref EditorialModel.classtypes
|
|
237
|
+ # @param rank str|int : The relation rank. Can be 'last', 'first' or an integer
|
|
238
|
+ # @param replace_if_exists bool : if True delete the old superior and set the new one. If False and there is a superior raise an LeObjectQueryError
|
|
239
|
+ # @return The relation ID or False if fails
|
|
240
|
+ # @throw LeObjectQueryError replace_if_exists == False and there is a superior
|
|
241
|
+ @classmethod
|
|
242
|
+ def hierarchy_add(cls, lesup, lesub, nature, rank = 'last', replace_if_exists = False):
|
|
243
|
+ #Arguments check
|
|
244
|
+ if nature not in EditorialModel.classtypes.EmClassType.natures(lesub._classtype):
|
|
245
|
+ raise ValueError("Invalid nature '%s' for %s"%(nature, lesup.__class__.__name__))
|
|
246
|
+
|
|
247
|
+ if not cls.leo_is_root(lesup):
|
|
248
|
+ if nature not in EditorialModel.classtypes.EmClassType.natures(lesup._classtype):
|
|
249
|
+ raise ValueError("Invalid nature '%s' for %s"%(nature, lesup.__class__.__name__))
|
|
250
|
+ if lesup.__class__ not in lesub._superiors[nature]:
|
|
251
|
+ raise ValueError("%s is not a valid superior for %s"%(lesup.__class__, lesub.__class__))
|
|
252
|
+ #else:
|
|
253
|
+ # lesup is not a LeType but a hierarchy root
|
|
254
|
+
|
|
255
|
+ if rank not in ['first', 'last'] and not isinstance(rank, int):
|
|
256
|
+ raise ValueError("Allowed values for rank are integers and 'first' or 'last' but '%s' found"%rank)
|
|
257
|
+
|
|
258
|
+ superiors = cls.hierarchy_get(lesub, nature, leo_is_sup = False)
|
|
259
|
+ if lesup in len(superiors) > 0:
|
|
260
|
+ if not replace_if_exists:
|
|
261
|
+ raise LeObjectQueryError("The subordinate allready has a superior")
|
|
262
|
+ #remove existig superior
|
|
263
|
+ if not cls.hierarchy_del(superiors[0], lesub, nature):
|
|
264
|
+ raise RuntimeError("Unable to delete the previous superior")
|
|
265
|
+
|
|
266
|
+ return self._datasource.add_superior(lesup, lesub, nature, rank)
|
|
267
|
+
|
|
268
|
+
|
219
|
269
|
## @brief Prepare a field_list
|
220
|
270
|
# @param field_list list : List of string representing fields
|
221
|
271
|
# @param letype LeType : LeType child class
|
|
@@ -385,6 +435,11 @@ class _LeObject(object):
|
385
|
435
|
cls._query_re = re.compile('^\s*(?P<field>(((superior)|(subordinate))\.)?[a-z_][a-z0-9\-_]*)\s*'+op_re_piece+'\s*(?P<value>[^<>=!].*)\s*$', flags=re.IGNORECASE)
|
386
|
436
|
pass
|
387
|
437
|
|
|
438
|
+## @brief Class designed to represent the hierarchy roots
|
|
439
|
+# @see _LeObject.get_root() _LeObject.is_root()
|
|
440
|
+class LeRoot(object):
|
|
441
|
+ pass
|
|
442
|
+
|
388
|
443
|
class LeObjectError(Exception):
|
389
|
444
|
pass
|
390
|
445
|
|