def query_function(key, expression): if key is None: return QuerySet( self, cls, store, self.get_pk_index(collection).get_all_keys() ) qs = QuerySet( self, cls, store, indexes[key].get_keys_for(expression) ) return qs
def filter(self, cls_or_collection, query, sort_by=None, limit=None, offset=None, initial_keys=None): if not isinstance(query, dict): raise AttributeError("Query parameters must be dict!") if not isinstance(cls_or_collection, str) and not isinstance( cls_or_collection, unicode): collection = self.get_collection_for_cls(cls_or_collection) cls = cls_or_collection else: collection = cls_or_collection cls = self.get_cls_for_collection(collection) store = self.get_collection_store(collection) indexes = self.get_collection_indexes(collection) compiled_query = self.compile_query(query) unindexed_queries = [] indexed_queries = [] indexes_by_key = dict([(idx.key, idx) for idx in indexes.values()]) for key, accessor, value in compiled_query: if key in indexes_by_key: indexed_queries.append([indexes_by_key[key], value]) else: unindexed_queries.append([accessor, value]) if indexed_queries: keys = None if initial_keys: keys = copy.copy(initial_keys) for index, value in indexed_queries: if not keys: keys = index.get_keys_for(value) else: keys = [ key for key in keys if key in index.get_keys_for(value) ] elif initial_keys: keys = copy.copy(initial_keys) else: #We fetch ALL keys from the primary index. keys = self.get_pk_index(collection).get_all_keys() for accessor, value in unindexed_queries: keys_to_remove = [] for key in keys: try: attributes = self.decode_attributes(store.get_blob(key)) except IOError: raise DatabaseIndexError try: if callable(value): if not value(accessor(attributes)): if not key in keys_to_remove: keys_to_remove.append(key) else: accessed_value = accessor(attributes) if isinstance(accessed_value, list): if value not in accessed_value: if not key in keys_to_remove: keys_to_remove.append(key) elif accessed_value != value: if not key in keys_to_remove: keys_to_remove.append(key) except (KeyError, IndexError): if not key in keys_to_remove: keys_to_remove.append(key) keys = [key for key in keys if not key in keys_to_remove] return QuerySet(self, cls, store, keys)
def index_collector(key, expressions): if (key not in indexes and key not in indexes_to_create and key is not None): indexes_to_create.append(key) return QuerySet(self, cls, store, [])