Пример #1
0
    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
Пример #2
0
 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
Пример #3
0
 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
Пример #4
0
 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)
Пример #5
0
 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)
Пример #6
0
    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