|
@@ -26,21 +26,23 @@ class LeObjectValues(object):
|
26
|
26
|
# @param set_callback method : The LeObject.set_datas() method of corresponding LeObject class
|
27
|
27
|
# @param get_callback method : The LeObject.get_datas() method of corresponding LeObject class
|
28
|
28
|
def __init__(self, fieldnames_callback, set_callback, get_callback):
|
29
|
|
- self.__setter = set_callback
|
30
|
|
- self.__getter = get_callback
|
|
29
|
+ self._setter = set_callback
|
|
30
|
+ self._getter = get_callback
|
31
|
31
|
|
32
|
32
|
##@brief Provide read access to datas values
|
33
|
33
|
# @note Read access should be provided for all fields
|
34
|
34
|
# @param fname str : Field name
|
35
|
35
|
def __getattribute__(self, fname):
|
36
|
|
- return self.__getter(fname)
|
|
36
|
+ getter = super().__getattribute__('_getter')
|
|
37
|
+ return getter(fname)
|
37
|
38
|
|
38
|
39
|
##@brief Provide write access to datas values
|
39
|
40
|
# @note Write acces shouldn't be provided for internal or immutable fields
|
40
|
41
|
# @param fname str : Field name
|
41
|
42
|
# @param fval * : the field value
|
42
|
43
|
def __setattribute__(self, fname, fval):
|
43
|
|
- return self.__setter(fname, fval)
|
|
44
|
+ setter = super().__getattribute__('_setter')
|
|
45
|
+ return setter(fname, fval)
|
44
|
46
|
|
45
|
47
|
|
46
|
48
|
class LeObject(object):
|
|
@@ -56,17 +58,26 @@ class LeObject(object):
|
56
|
58
|
##@breif Read & write datasource ( see @ref lodel2_datasources )
|
57
|
59
|
_rw_datasource = None
|
58
|
60
|
|
59
|
|
- ##@brief Construct an object representing an Editorial component
|
60
|
|
- # @note Can be considered as EmClass instance
|
61
|
|
- def __init__(self, **kwargs):
|
62
|
|
- if self._abstract:
|
63
|
|
- raise NotImplementedError("%s is abstract, you cannot instanciate it." % self.__class__.__name__ )
|
|
61
|
+ def __new__(cls, **kwargs):
|
|
62
|
+
|
|
63
|
+ self = object.__new__(cls)
|
64
|
64
|
##@brief A dict that stores fieldvalues indexed by fieldname
|
65
|
65
|
self.__datas = { fname:None for fname in self._fields }
|
66
|
66
|
##@brief Store a list of initianilized fields when instanciation not complete else store True
|
67
|
67
|
self.__initialized = list()
|
68
|
68
|
##@brief Datas accessor. Instance of @ref LeObjectValues
|
69
|
69
|
self.d = LeObjectValues(self.fieldnames, self.set_data, self.data)
|
|
70
|
+ for fieldname, fieldval in kwargs.items():
|
|
71
|
+ self.__datas[fieldname] = fieldval
|
|
72
|
+ self.__initialized.append(fieldname)
|
|
73
|
+ self.__set_initialized()
|
|
74
|
+ return self
|
|
75
|
+
|
|
76
|
+ ##@brief Construct an object representing an Editorial component
|
|
77
|
+ # @note Can be considered as EmClass instance
|
|
78
|
+ def __init__(self, **kwargs):
|
|
79
|
+ if self._abstract:
|
|
80
|
+ raise NotImplementedError("%s is abstract, you cannot instanciate it." % self.__class__.__name__ )
|
70
|
81
|
|
71
|
82
|
# Checks that uid is given
|
72
|
83
|
for uid_name in self._uid:
|
|
@@ -75,25 +86,24 @@ class LeObject(object):
|
75
|
86
|
self.__datas[uid_name] = kwargs[uid_name]
|
76
|
87
|
del(kwargs[uid_name])
|
77
|
88
|
self.__initialized.append(uid_name)
|
78
|
|
-
|
|
89
|
+
|
79
|
90
|
# Processing given fields
|
80
|
91
|
allowed_fieldnames = self.fieldnames(include_ro = False)
|
81
|
|
- err_list = list()
|
|
92
|
+ err_list = dict()
|
82
|
93
|
for fieldname, fieldval in kwargs.items():
|
83
|
94
|
if fieldname not in allowed_fieldnames:
|
84
|
95
|
if fieldname in self._fields:
|
85
|
|
- err_list.append(
|
86
|
|
- LeApiError("Value given for internal field : '%s'" % fieldname)
|
87
|
|
- )
|
|
96
|
+ err_list[fieldname] = LeApiError(
|
|
97
|
+ "Value given but the field is internal")
|
88
|
98
|
else:
|
89
|
|
- err_list.append(
|
90
|
|
- LeApiError("Unknown fieldname : '%s'" % fieldname)
|
91
|
|
- )
|
|
99
|
+ err_list[fieldname] = LeApiError(
|
|
100
|
+ "Unknown fieldname : '%s'" % fieldname)
|
92
|
101
|
else:
|
93
|
102
|
self.__datas[fieldname] = fieldval
|
94
|
103
|
self.__initialized.append(fieldname)
|
95
|
104
|
if len(err_list) > 0:
|
96
|
|
- raise LeApiErrors(err_list)
|
|
105
|
+ raise LeApiErrors(msg = "Unable to __init__ %s" % self.__class__,
|
|
106
|
+ exceptions = err_list)
|
97
|
107
|
self.__set_initialized()
|
98
|
108
|
|
99
|
109
|
#-----------------------------------#
|
|
@@ -537,43 +547,6 @@ raised when trying to import Datasource"
|
537
|
547
|
deleted += result
|
538
|
548
|
return deleted
|
539
|
549
|
|
540
|
|
-
|
541
|
|
- ## @brief Load an instance of LeObject
|
542
|
|
- #@param uid a list of tuple (uid_field_nane, value) ou a single value
|
543
|
|
- #@return an instance of a subclass of LeObject
|
544
|
|
- @classmethod
|
545
|
|
- def load(cls, uid_tuples):
|
546
|
|
- query_filter = list()
|
547
|
|
- uids = cls._uid
|
548
|
|
- if uids.isinstance(tuple):
|
549
|
|
- if not uid_tuples.isinstance(list):
|
550
|
|
- raise AttributeError ("In %s:load : uid must be a list of tuple" % cls.__name__)
|
551
|
|
- elif len(uid_tuples) != len(uids):
|
552
|
|
- raise AttributeError ("In %s:load : must have %d uid fields" % len(uids))
|
553
|
|
- for fieldname, fieldvalue in uid_tuples:
|
554
|
|
- if fieldname in uids:
|
555
|
|
- dhdl = cls.data_handler(fieldname)
|
556
|
|
- if dhdl.check_data_value(fieldvalue)[1] is None:
|
557
|
|
- query_filter.append((fieldname, '=', fieldvalue))
|
558
|
|
- else:
|
559
|
|
- raise AttributeError("n %s:load :%s not a valid value for %s" % (fieldvalue, fieldname))
|
560
|
|
- else:
|
561
|
|
- raise AttributeError ("In %s:load :%s not a uid field for class %s" % (fieldname, cls.__name__))
|
562
|
|
- else:
|
563
|
|
- dhdl = cls.data_handler(uids)
|
564
|
|
- if dhdl.check_data_value(uid_tuples)[1] is None:
|
565
|
|
- query_filter.append((uids, '=', uid_tuples))
|
566
|
|
- else:
|
567
|
|
- raise AttributeError("n %s:load :%s not a valid value for %s" % (uid_tuples, uids))
|
568
|
|
- query = LeGetQuery(cls, query_filter, limit = 1)
|
569
|
|
- try:
|
570
|
|
- result=query.execute()
|
571
|
|
- except LeQueryError as err:
|
572
|
|
- print("Unable to load object of type %s" % cls.__name__)
|
573
|
|
- raise err
|
574
|
|
-
|
575
|
|
- return cls.name2class(res[CLASS_IDENTIFIER])(result[0])
|
576
|
|
-
|
577
|
550
|
## @brief Get instances of LeObject
|
578
|
551
|
#
|
579
|
552
|
#@param target_class LeObject : class of object the query is about
|
|
@@ -589,16 +562,19 @@ raised when trying to import Datasource"
|
589
|
562
|
#@return a list of items (lists of (fieldname, fieldvalue))
|
590
|
563
|
@classmethod
|
591
|
564
|
def get(cls, query_filters, field_list=None, order=None, group=None, limit=None, offset=0):
|
592
|
|
- if isinstance(cls._uids, tuple):
|
593
|
|
- for uid in cls._uids:
|
594
|
|
- if uid not in field_list:
|
595
|
|
- raise AttributeError("In %s:get : Cannot instanciate a LeObject without it's identifier" % cls.__name__)
|
|
565
|
+ if field_list is None:
|
|
566
|
+ field_list = self.fieldnames(True)
|
596
|
567
|
else:
|
597
|
|
- if uid not in field_list:
|
598
|
|
- raise AttributeError("In %s:get : Cannot instanciate a LeObject without it's identifier" % cls.__name__)
|
599
|
|
-
|
|
568
|
+ for uid in [ uidname
|
|
569
|
+ for uidname in cls.uid_fieldname()
|
|
570
|
+ if uidname not in field_list ]:
|
|
571
|
+ field_list.append(uid)
|
|
572
|
+ if CLASS_ID_FIELDNAME not in field_list:
|
|
573
|
+ field_list.append(CLASS_ID_FIELDNAME)
|
600
|
574
|
try:
|
601
|
|
- query = LeGetQuery(cls, query_filter, field_list = field_list, order = order, group = group, limit = limit, offset = offset)
|
|
575
|
+ query = LeGetQuery(
|
|
576
|
+ cls, query_filters = query_filters, field_list = field_list,
|
|
577
|
+ order = order, group = group, limit = limit, offset = offset)
|
602
|
578
|
except ValueError as err:
|
603
|
579
|
raise err
|
604
|
580
|
|
|
@@ -609,7 +585,8 @@ raised when trying to import Datasource"
|
609
|
585
|
|
610
|
586
|
objects = list()
|
611
|
587
|
for res in result:
|
612
|
|
- inst = cls.name2class(res[CLASS_ID_FIELDNAME])(res)
|
|
588
|
+ res_cls = cls.name2class(res[CLASS_ID_FIELDNAME])
|
|
589
|
+ inst = res_cls.__new__(res_cls,**res)
|
613
|
590
|
objects.append(inst)
|
614
|
591
|
|
615
|
592
|
return objects
|