def _set_without_ordering(self, skey): """ Final call for "non-ordered" looked up. We order by id anyway and this is done by redis (same as above). :returns: A Set of `id` """ # sort by id num, start = self._get_limit_and_offset() old_set_key = skey new_set_key = "%s#.%s" % (old_set_key, id(self)) self.db.sort(old_set_key, store=new_set_key, start=start, num=num) if old_set_key != self.key: Set(old_set_key, db=self.db).set_expire() new_list = List(new_set_key, db=self.db) new_list.set_expire() return new_list
def _set(self): # For performance reasons, only one zfilter is allowed. if hasattr(self, '_cached_set'): return self._cached_set if self._zfilters: self._cached_set = self._add_zfilters() return self._cached_set s = Set(self.key) self._expire_or_delete = [] if self._filters: s = self._add_set_filter(s) if self._exclusions: s = self._add_set_exclusions(s) n = self._order(s.key) self._cached_set = list(self._order(s.key)) for key in filter(lambda key: key != self.key, self._expire_or_delete): del self.db[key] return self._cached_set
def _set(self): """ This contains the list of ids that have been looked-up, filtered and ordered. This set is build hen we first access it and is cached for has long has the ModelSet exist. """ # For performance reasons, only one zfilter is allowed. if hasattr(self, '_cached_set'): return self._cached_set s = Set(self.key) if self._zfilters: s = self._add_zfilters(s) if self._filters: s = self._add_set_filter(s) if self._exclusions: s = self._add_set_exclusions(s) n = self._order(s.key) self._cached_set = n return self._cached_set
def _delete_membership(self, pipeline=None): """Removes the id of the object to the set of all objects of the same class. """ Set(self._key['all'], pipeline=pipeline).remove(self.id)
def _create_membership(self, pipeline=None): """Adds the id of the object to the set of all objects of the same class. """ Set(self._key['all'], pipeline=pipeline).add(self.id)
def _add_set_filter(self, s): """ This function is the internal of the `filter` function. It simply creates a new "intersection" of indexed keys (the filter) and the previous filtered keys (if any). .. Note:: This function uses the ``Set`` container class. :return: the new Set """ new_set = None _operator = self._filters.pop('_operator', 'and') for k, v in self._filters.iteritems(): indices = [] # check if we have double underscores in key, if it exists # we need to handle it by searching keys rather than indices try: k, key_operator = k.split('__') except ValueError: key_operator = None if k not in self.model_class._indices: #noqa raise AttributeNotIndexed( "Attribute %s is not indexed in %s class." % (k, self.model_class.__name__)) if not isinstance(v, (list, tuple)): v = [v] # check if we have key_operator, if we do need to go long route # and build the indices differently # XXX: optimise this!! if key_operator: if key_operator == 'endswith': v = map(lambda val: '*%s' % val, v) elif key_operator == 'startswith': v = map(lambda val: '%s*' % val, v) elif key_operator == 'contains': v = map(lambda val: '*%s*' % val, v) else: raise FilterOperatorError( 'Filter operator must be one of [endswith, startswith, contains]' ) # now do the search, there are two ways of doing this, # 1 - using KEYS # 2 - using SCAN # we will use SCAN for performance reason, though implementation of # KEYS is much easier, though good to know, if you are reading this! _indices = [ self._build_key_from_filter_item(k, ev) for ev in v ] for search_term in _indices: indices.extend(list(self.db.scan_iter(search_term, 500))) else: indices.extend( [self._build_key_from_filter_item(k, ev) for ev in v]) new_set_key = "~%s.%s" % ("+".join([self.key] + indices), id(self)) # filter operator is set to and, we need to filter withing current set # which has been already filtered if _operator == 'and': if not new_set: s.intersection(new_set_key, *[Set(n, db=self.db) for n in indices]) else: new_set.intersection( new_set_key, *[Set(n, db=self.db) for n in indices]) else: s.intersection(new_set_key, *[Set(n, db=self.db) for n in indices]) new_set = Set(new_set_key, db=self.db) new_set.set_expire() return new_set