Преглед на файлове

First test on multi datasource queries + em_test update + query.py debug

- Modified again the em_test to fit with testing purpose
- First test on multi datasource query written
- debugging of query.py
Yann Weber преди 8 години
родител
ревизия
e55954d947
променени са 8 файла, в които са добавени 55 реда и са изтрити 47 реда
  1. 4
    32
      em_test.py
  2. Двоични данни
      examples/em_test.pickle
  3. 1
    1
      lodel/leapi/datahandlers/base_classes.py
  4. 1
    1
      lodel/leapi/leobject.py
  5. 22
    12
      lodel/leapi/query.py
  6. Двоични данни
      tests/editorial_model.pickle
  7. 26
    0
      tests/leapi/query/test_filtered.py
  8. 1
    1
      tests/tests_conf.d/lodel2.ini

+ 4
- 32
em_test.py Целия файл

@@ -321,49 +321,21 @@ index_value = index_abstract.new_field(
321 321
         'fre': 'valeur'},
322 322
     data_handler = 'varchar')
323 323
 
324
-index_text = em.new_class(
325
-    'indextext',
326
-    display_name = {
327
-        'eng': 'Index Text',
328
-        'fre': 'Index Texte'},
329
-    help_text = {
330
-        'eng': 'Represent a link between a text and an index',
331
-        'fre': 'Represente le lien entre une entrée d\'index et un texte'},
332
-    parents = None,
333
-    abstract = False,
334
-    datasource = 'default')
335
-
336
-bref_indextext_text = index_text.new_field(
337
-    'text',
338
-    display_name = {
339
-        'eng': 'Text with this index',
340
-        'fre': 'Texte comportant cet index'},
341
-    data_handler = 'link',
342
-    allowed_classes = [text],
343
-    group = index_group)
344
-
345
-bref_indextext_index = index_text.new_field(
346
-    'index',
347
-    display_name = {
348
-        'eng': 'Index within the referencend text',
349
-        'fre': 'Reference vers l\'index concerné'},
350
-    data_handler = 'link',
351
-    allowed_classes = [index_abstract],
352
-    group = index_group)
353
-
354 324
 text.new_field( 'indexes',
355 325
     display_name = {
356 326
         'eng': 'Indexes',
357 327
         'fre': 'Indexes'},
358 328
     data_handler = 'list',
359
-    back_reference = ('Indextext', 'text'))
329
+    back_reference = ('Indexabs', 'texts'),
330
+    allowed_classes = [index_abstract])
360 331
 
361 332
 index_abstract.new_field( 'texts',
362 333
     display_name = {
363 334
         'eng': 'Text referenced by this index',
364 335
         'fre': 'Texte contenant cette index'},
365 336
     data_handler = 'list',
366
-    back_reference = ('Indextext', 'index'))
337
+    back_reference = ('Text', 'indexes'),
338
+    allowed_classes = [text])
367 339
 
368 340
 index_theme = em.new_class(
369 341
     'indexTheme',

Двоични данни
examples/em_test.pickle Целия файл


+ 1
- 1
lodel/leapi/datahandlers/base_classes.py Целия файл

@@ -190,7 +190,7 @@ class Reference(DataHandler):
190 190
     # @param internal bool : if False, the field is not internal
191 191
     # @param **kwargs : other arguments
192 192
     def __init__(self, allowed_classes = None, back_reference = None, internal=False, **kwargs):
193
-        self.__allowed_classes = None if allowed_classes is None else set(allowed_classes)
193
+        self.__allowed_classes = [] if allowed_classes is None else set(allowed_classes)
194 194
         if back_reference is not None:
195 195
             if len(back_reference) != 2:
196 196
                 raise ValueError("A tuple (classname, fieldname) expected but got '%s'" % back_reference)

+ 1
- 1
lodel/leapi/leobject.py Целия файл

@@ -153,7 +153,7 @@ class LeObject(object):
153 153
         if not fieldname in cls._fields:
154 154
             raise NameError("No field named '%s' in %s" % (fieldname, cls.__name__))
155 155
         return cls._fields[fieldname]
156
- 
156
+    
157 157
     ##@brief Return a LeObject child class from a name
158 158
     # @warning This method has to be called from dynamically generated LeObjects
159 159
     # @param leobject_name str : LeObject name

+ 22
- 12
lodel/leapi/query.py Целия файл

@@ -212,9 +212,10 @@ class LeFilteredQuery(LeQuery):
212 212
                 for tclass, tfield in ref_dict.items():
213 213
                     query = LeGetQuery(
214 214
                         target_class = tclass,
215
-                        query_filter = [(rfield, op, value)],
215
+                        query_filter = [(tfield, op, value)],
216 216
                         field_list = [tfield])
217 217
                     subq.append((rfield, query))
218
+        self.subqueries = subq
218 219
     
219 220
     ##@return informations
220 221
     def dump_infos(self):
@@ -387,10 +388,10 @@ field to use for the relational filter"
387 388
     def _check_field(cls, target_class, fieldname):
388 389
         try:
389 390
             target_class.field(fieldname)
390
-        except NameError:
391
-            tc_name = target_class.__name__
392
-            return ValueError("No such field '%s' in %s" % (    fieldname,
393
-                                                                tc_name))
391
+        except NameError as e:
392
+            msg = "No field named '%s' in %s'"
393
+            msg %= (fieldname, target_class.__name__)
394
+            return NameError(msg)
394 395
 
395 396
     ##@brief Prepare a relational filter
396 397
     #
@@ -445,11 +446,13 @@ field to use for the relational filter"
445 446
                 if ref_field in ref_class.fieldnames(True):
446 447
                     ref_dict[ref_class] = ref_field
447 448
                 else:
448
-                    logger.debug("Warning the class %s is not considered in \
449
-the relational filter %s" % ref_class.__name__)
449
+                    msg = "Warning the class %s is not considered in \
450
+the relational filter %s"
451
+                    msg %= (ref_class.__name__, ref_field)
452
+                    logger.debug(msg)
450 453
         if len(ref_dict) == 0:
451
-            return NameError(   "No field named '%s' in referenced objects"
452
-                                % ref_field)
454
+            return NameError(   "No field named '%s' in referenced objects %s"
455
+                                % (ref_field, ref_class.__name__))
453 456
         return (fieldname, ref_dict)
454 457
  
455 458
 
@@ -668,8 +671,15 @@ class LeGetQuery(LeFilteredQuery):
668 671
         return ret
669 672
 
670 673
     def __repr__(self):
671
-        ret = "<LeGetQuery target={target_class} filter={query_filter} \
674
+        res = "<LeGetQuery target={target_class} filter={query_filter} \
672 675
 field_list={field_list} order={order} group={group} limit={limit} \
673
-offset={offset}>"
674
-        return ret.format(**self.dump_infos())
676
+offset={offset}"
677
+        res = res.format(**self.dump_infos())
678
+        if len(self.subqueries) > 0:
679
+            for n,subq in enumerate(self.subqueries):
680
+                res += "\n\tSubquerie %d : %s"
681
+                res %= (n, subq)
682
+        res += ">"
683
+        return res
684
+
675 685
 

Двоични данни
tests/editorial_model.pickle Целия файл


+ 26
- 0
tests/leapi/query/test_filtered.py Целия файл

@@ -104,3 +104,29 @@ class LeFilteredQueryTestCase(unittest.TestCase):
104 104
             qinfos = get_q.dump_infos()
105 105
             self.assertEqual(   qinfos['query_filter'],
106 106
                                 e_qfilter)
107
+
108
+class LeFilteredQueryMultiDataHandlerTestCase(unittest.TestCase):
109
+    """ Testing LeFilteredQuery behavior when relational fields implies
110
+        different datasources """
111
+
112
+    q_classes = [LeDeleteQuery, LeUpdateQuery, LeGetQuery]
113
+    
114
+    def test_basic(self):
115
+        """ Testing a LeGetQuery with a relationnal field implying another
116
+            datasource """
117
+        getq = LeGetQuery(
118
+            dyncode.Indextheme,
119
+            "texts.title = super titre !")
120
+        qinfos = getq.dump_infos()
121
+        # The single query filter should be in subquery
122
+        self.assertEqual(qinfos['query_filter'], ([],[]))
123
+        self.assertEqual(len(qinfos['subqueries']), 1)
124
+        rfield, subq = qinfos['subqueries'][0]
125
+        # Checking subquery
126
+        self.assertEqual(rfield, 'texts') # The reference field of the subquery
127
+        qinfos = subq.dump_infos()
128
+        self.assertEqual(qinfos['target_class'], dyncode.Text)
129
+        self.assertEqual(
130
+            qinfos['query_filter'],
131
+            ([('title', '=', 'super titre !')],[])) 
132
+        self.assertEqual(qinfos['field_list'], ['title'])

+ 1
- 1
tests/tests_conf.d/lodel2.ini Целия файл

@@ -10,7 +10,7 @@ filename = -
10 10
 context = False
11 11
 
12 12
 [lodel2.editorialmodel]
13
-groups = 
13
+groups = index_group
14 14
 emfile = examples/em_test.pickle
15 15
 dyncode = leapi_dyncode.py
16 16
 editormode = True

Loading…
Отказ
Запис