Quellcode durchsuchen

Added a _split_query method to _LeObject

This method split a string in a tuple(FIELD, OPERATOR, VALUE)
Yann Weber vor 9 Jahren
Ursprung
Commit
24aa04a913
3 geänderte Dateien mit 93 neuen und 39 gelöschten Zeilen
  1. 45
    39
      leobject/leobject.py
  2. 0
    0
      leobject/test/__init__.py
  3. 48
    0
      leobject/test/test_leobject.py

+ 45
- 39
leobject/leobject.py Datei anzeigen

@@ -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

+ 0
- 0
leobject/test/__init__.py Datei anzeigen


+ 48
- 0
leobject/test/test_leobject.py Datei anzeigen

@@ -0,0 +1,48 @@
1
+"""
2
+    Tests for _LeObject
3
+"""
4
+
5
+import os
6
+import unittest
7
+from unittest import TestCase
8
+
9
+from leobject.leobject import _LeObject
10
+
11
+class _LeObjectTestCase(TestCase):
12
+    
13
+    def test_split_query_filter(self):
14
+        """ Tests the _split_filter() classmethod """
15
+        query_results = {
16
+            'Hello = world' : ('Hello', '=', 'world'),
17
+            'hello <= "world"': ('hello', '<=', '"world"'),
18
+            '_he42_ll-o >= \'world"': ('_he42_ll-o', '>=', '\'world"'),
19
+            'foo in ["foo", 42, \'bar\']': ('foo', ' in ', '["foo", 42, \'bar\']'),
20
+            ' bar42              < 42': ('bar42', '<', '42'),
21
+            ' _hidden > 1337': ('_hidden', '>', '1337'),
22
+            '_42 not in foobar': ('_42', ' not in ', 'foobar'),
23
+            'hello                       in      foo':('hello', ' in ', 'foo'),
24
+            "\t\t\thello\t\t\nin\nfoo\t\t\n\t":('hello', ' in ', 'foo'),
25
+            "hello \nnot\tin \nfoo":('hello', ' not in ', 'foo'),
26
+            'hello != bar':('hello', '!=', 'bar'),
27
+            'hello = "world>= <= != in not in"': ('hello', '=', '"world>= <= != in not in"'),
28
+        }
29
+        for query, result in query_results.items():
30
+            res = _LeObject._split_filter(query)
31
+            self.assertEqual(res, result, "When parsing the query : '%s' the returned value is different from the expected '%s'"%(query, result))
32
+
33
+    def test_invalid_split_query_filter(self):
34
+        """ Testing the _split_filter() method with invalid queries """
35
+        invalid_queries = [
36
+            '42 = 42',
37
+            '4hello = foo',
38
+            'foo == bar',
39
+            'hello >> world',
40
+            'hello =    ',
41
+            ' = world',
42
+            '=',
43
+            '42',
44
+            '"hello" = world',
45
+        ]
46
+        for query in invalid_queries:
47
+            with self.assertRaises(ValueError, msg='But the query was not valid : "%s"'%query):
48
+                _LeObject._split_filter(query)

Laden…
Abbrechen
Speichern