示例#1
0
 def get_index_values(self, model_instance):
     filters = tuple([f[0].split(' ')[0]
                      for f in get_filters(*self.filters)])
     values = {}
     for property in set(self.properties + self.integrate + filters):
         instance = getattr(model_instance.__class__, property)
         if isinstance(instance, db.ReferenceProperty):
             value = instance.get_value_for_datastore(model_instance)
         else:
             value = getattr(model_instance, property)
         if property == self.properties[0] and \
                 isinstance(value, (list, tuple)):
             value = sorted(value)
         values[property] = value
     return values
示例#2
0
 def should_index(self, values):
     # Check if filter doesn't match
     for filter, value in get_filters(*self.filters):
         attr, op = filter.split(' ')
         op = op.lower()
         if (op == '=' and values[attr] != value or
                 op == '!=' and values[attr] == value or
                 op == 'in' and values[attr] not in value or
                 op == '<' and values[attr] >= value or
                 op == '<=' and values[attr] > value or
                 op == '>' and values[attr] <= value or
                 op == '>=' and values[attr] < value):
             return False
         elif op not in ('=', '!=', 'in', '<', '<=', '>=', '>'):
             raise ValueError('Invalid search index filter: %s %s' % (filter, value))
     return True
示例#3
0
    def generate_index_key_names(self, values):
        if self.filters and not self.should_index(values):
            return []

        # Remove unneeded values
        filters = tuple([f[0].split(' ')[0]
                         for f in get_filters(*self.filters)])
        for filter in filters:
            if filter not in (self.properties + self.integrate):
                del values[filter]
        key_names = []
        property_values = values[self.properties[0]]
        if not isinstance(property_values, (list, tuple)):
            property_values = (property_values,)
        for property_value in property_values:
            parts = []
            for property in sorted(values.keys()):
                if property == self.properties[0]:
                    parts.extend((property, unicode(property_value)))
                else:
                    parts.extend((property, unicode(values[property])))
            key_names.append((property_value, generate_key_name(*parts)))
        return key_names
示例#4
0
def make_paginated_filter(filters=(), order=(), bookmark=None,
                          descending=False, debug=False):
    # Get bookmark (marks last result entry which we can restart from).
    # The bookmark is a dictionary containing the values of the previous
    # page's last item.
    if order and not isinstance(order, (tuple, list)):
        order = (order,)
    
    order = list(order)
    filters = get_filters(*filters)
    inequality = [filter for filter in filters
                  if filter[0].strip().endswith(('!=', '>', '<', '>=', '<='))]
    
    if inequality and not order:
        order.append(inequality[0][0].split(' ')[0])
    
    if '__key__' not in order and '-__key__' not in order:
        order.append(descending and bookmark is not None
                     and '-__key__' or '__key__')
    
    if bookmark is None:
        return [(filters, order)]

    # Assert that all of the properties in the query are also in the bookmark.
    # We check sort order below.
    for filter in inequality:
        if filter[0].split(' ')[0] not in bookmark:
            raise ValueError('Property for filter %r not in bookmark!'
                             % (filter,))
    
    if '__key__' not in bookmark:
        raise ValueError('__key__ not in bookmark!')
    
    # Prepare the original query as a template for the derived queries
    for filter in inequality:
        filters.remove(filter)
    
    for property in order:
        property = property.lstrip('-')
        if property == '__key__':
            continue
        if property not in bookmark:
            raise ValueError('Sort order property %s not in bookmark!'
                             % property)
        filters.append((property + ' =', bookmark[property]))
    
    # order_backup gets used in for loop below
    order_backup = order[:]
    for index, property in enumerate(order[:]):
        if property.lstrip('-') != '__key__':
            if descending:
                if property.startswith('-'):
                    order_backup[index] = property.lstrip('-')
                else:
                    order_backup[index] = '-' + property
            order.remove(property)
    
    # Generate derived queries
    queries = []
    for property in reversed(order_backup):
        property_backup = property
        property = property.lstrip('-')
        
        if property != '__key__':
            filters.remove((property + ' =', bookmark[property]))
            order.insert(0, property_backup)
        
        filters_copy = filters[:]
        order_copy = order[:]
        
        if not property_backup.startswith('-'):
            op = ' >'
        else:
            op = ' <'
        filters_copy.append((property + op, bookmark[property]))
        
        # Add back inequality filter on property
        for filter in inequality:
            if filter[0].split(' ')[0] == property and \
                    filter[0].rstrip(' =') != property + op:
                filters_copy.append(filter)
        
        queries.append((filters_copy, order_copy))
    
    return queries