|
@@ -1,8 +1,10 @@
|
1
|
1
|
#-*- coding: utf-8 -*-
|
2
|
2
|
|
3
|
|
-## Main class to handle objects defined by the types of an Editorial Model
|
|
3
|
+## @package EditorialModel::leobject::leobject
|
|
4
|
+# @brief Main class to handle objects defined by the types of an Editorial Model
|
4
|
5
|
# an instance of these objects is pedantically called LeObject !
|
5
|
6
|
|
|
7
|
+import re
|
6
|
8
|
from EditorialModel.types import EmType
|
7
|
9
|
|
8
|
10
|
class _LeObject(object):
|
|
@@ -11,6 +13,9 @@ class _LeObject(object):
|
11
|
13
|
_model = None
|
12
|
14
|
## @brief The datasource
|
13
|
15
|
_datasource = None
|
|
16
|
+
|
|
17
|
+ _query_re = None
|
|
18
|
+ _query_operators = ['=', '<=', '>=', '!=', '<', '>', ' in ', ' not in ']
|
14
|
19
|
|
15
|
20
|
## @brief Instantiate with a Model and a DataSource
|
16
|
21
|
# @param **kwargs dict : datas usefull to instanciate a _LeObject
|
|
@@ -65,11 +70,19 @@ class _LeObject(object):
|
65
|
70
|
return okay
|
66
|
71
|
|
67
|
72
|
## @brief make a search to retrieve a collection of LeObject
|
68
|
|
- # @param query_filters string | (string): list of string of query filters
|
|
73
|
+ # @param
|
|
74
|
+ # @param query_filters list : list of string of query filters (or tuple (FIELD, OPERATOR, VALUE) )
|
69
|
75
|
# @return responses ({string:*}): a list of dict with field:value
|
70
|
|
- def get(self, query_filters):
|
|
76
|
+ def get(self, query_filters, typename = None, classname = None):
|
|
77
|
+ filters = list()
|
|
78
|
+ for query in query_filters:
|
|
79
|
+ if len(query) == 3 and not isinstance(query, str):
|
|
80
|
+ filters.append(tuple(query))
|
|
81
|
+ else:
|
|
82
|
+ filters.append(self._split_filter(query))
|
|
83
|
+ #Now filters is a list of tuple (FIELD, OPERATOR, VALUE
|
|
84
|
+
|
71
|
85
|
try:
|
72
|
|
- datasource_filters = self._prepare_filters(query_filters)
|
73
|
86
|
responses = self.datasource.get(datasource_filters)
|
74
|
87
|
except:
|
75
|
88
|
raise
|
|
@@ -83,40 +96,33 @@ class _LeObject(object):
|
83
|
96
|
def _check_data(self, data):
|
84
|
97
|
checked_data = data
|
85
|
98
|
return checked_data
|
|
99
|
+
|
|
100
|
+ ## @brief Check and split a query filter
|
|
101
|
+ # @note The query_filter format is "FIELD OPERATOR VALUE"
|
|
102
|
+ # @param query_filter str : A query_filter string
|
|
103
|
+ # @return a tuple (FIELD, OPERATOR, VALUE)
|
|
104
|
+ @classmethod
|
|
105
|
+ def _split_filter(cls, query_filter):
|
|
106
|
+ if cls._query_re is None:
|
|
107
|
+ cls._compile_query_re()
|
86
|
108
|
|
87
|
|
- ## @brief check and prepare query for the datasource
|
88
|
|
- # @param query_filters (string): list of string of query filters
|
89
|
|
- # @todo implent !
|
90
|
|
- def _prepare_filters(self, query_filters):
|
91
|
|
- if query_filters is None:
|
92
|
|
- return ()
|
93
|
|
- elif isinstance(query_filters[0], str):
|
94
|
|
- query_filters = (query_filters)
|
95
|
|
-
|
96
|
|
- fields, operators, queries = zip(*query_filters)
|
97
|
|
-
|
98
|
|
- # find name of the type in filters
|
99
|
|
- try:
|
100
|
|
- type_index = fields.index('type')
|
101
|
|
- if operators[type_index] != '=':
|
102
|
|
- raise ValueError
|
103
|
|
- type_name = queries[type_index]
|
104
|
|
- del query_filters[type_index]
|
105
|
|
- except ValueError:
|
106
|
|
- print ("Le champ type est obligatoire dans une requête")
|
107
|
|
- raise
|
|
109
|
+ matches = cls._query_re.match(query_filter)
|
|
110
|
+ if not matches:
|
|
111
|
+ raise ValueError("The query_filter '%s' seems to be invalid"%query_filter)
|
|
112
|
+
|
|
113
|
+ result = (matches.group('field'), re.sub(r'\s', ' ', matches.group('operator'), count=0), matches.group('value').strip())
|
|
114
|
+ for r in result:
|
|
115
|
+ if len(r) == 0:
|
|
116
|
+ raise ValueError("The query_filter '%s' seems to be invalid"%query_filter)
|
|
117
|
+ return result
|
108
|
118
|
|
109
|
|
-
|
110
|
|
- comps = self.model.components(EmType)
|
111
|
|
- for comp in comps:
|
112
|
|
- if comp.name == type_name:
|
113
|
|
- em_type = comp
|
114
|
|
- break
|
115
|
|
-
|
116
|
|
- class_name = em_type.em_class.name
|
117
|
|
- fields = em_type.fields()
|
118
|
|
- field_list = [f.name for f in fields]
|
119
|
|
- print (em_type, class_name, type_name, fields, field_list)
|
120
|
|
-
|
121
|
|
- prepared_filters = query_filters
|
122
|
|
- return prepared_filters
|
|
119
|
+ ## @brief Compile the regex for query_filter processing
|
|
120
|
+ # @note Set _LeObject._query_re
|
|
121
|
+ @classmethod
|
|
122
|
+ def _compile_query_re(cls):
|
|
123
|
+ op_re_piece = '(?P<operator>(%s)'%cls._query_operators[0].replace(' ', '\s')
|
|
124
|
+ for operator in cls._query_operators[1:]:
|
|
125
|
+ op_re_piece += '|(%s)'%operator.replace(' ', '\s')
|
|
126
|
+ op_re_piece += ')'
|
|
127
|
+ cls._query_re = re.compile('^\s*(?P<field>[a-z_][a-z0-9\-_]*)\s*'+op_re_piece+'\s*(?P<value>[^<>=!].*)\s*$', flags=re.IGNORECASE)
|
|
128
|
+ pass
|