Commits

Anonymous committed 2f3b1ef

added check against OR-queries and removed not needed filter conversions

Comments (0)

Files changed (1)

dbindexer/backends.py

 from djangotoolbox.fields import ListField
 from dbindexer.lookups import StandardLookup
 
+OR = 'OR'
+
 # TODO: optimize code (JOIN backend and in memory-JOINs are rather slow, cache?)
 class BaseResolver(object):
     def __init__(self):
         BaseResolver.convert_query(self, query)
         
     def _convert_filters(self, query, filters):
-        # TODO: instead of the following code resort the tree!
+        # or queries are not supported for in-memory-JOINs
+        if self.contains_OR(query.where, OR):
+            return
+        
         # start with the deepest JOIN level filter!
         all_filters = self.get_all_filters(query, filters)
         all_filters.sort(key=lambda item: self.get_field_chain(query, item[1][0]) and \
                          -len(self.get_field_chain(query, item[1][0])) or 0)
-
+        
         for filters, child, index in all_filters:
+            if not self.contains_child(query.where, child):
+                continue
             self.convert_filter(query, filters, child, index)
-        
+    
     def convert_filter(self, query, filters, child, index):
         constraint, lookup_type, annotation, value = child
         field_chain = self.get_field_chain(query, constraint)
         self._convert_filter(query, filters, child, index, 'in',
                              (pk for pk in pks), field_chain.split('__')[0])
         
+    def tree_contains(self, filters, to_find, func):
+        result = False
+        for index, child in enumerate(filters.children[:]):
+            if func(child, to_find):
+                result = True
+                break
+            if isinstance(child, Node):
+                 result = self.tree_contains(child, to_find, func)
+                 if result:
+                     break
+        return result
+    
+    def contains_OR(self, filters, or_):
+        return self.tree_contains(filters, or_,
+            lambda c, f: isinstance(c, Node) and c.connector == f)
+
+    def contains_child(self, filters, to_find):
+        return self.tree_contains(filters, to_find, lambda c, f: c is f)
+    
     def get_all_filters(self, query, filters):
         all_filters = []
         for index, child in enumerate(filters.children[:]):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.