Ejemplo n.º 1
0
    def _find_non_wildcards(self, values):
        """Check if this should be a wildcard match.

        Further, this will raise an exception if the syntax is improperly
        defined.

        :return: The offset of the last value we need to match against.
        """
        if len(values) != len(self._definition):
            raise errors.InvalidValueForIndex()
        is_wildcard = False
        last = 0
        for idx, val in enumerate(values):
            if val.endswith('*'):
                if val != '*':
                    # We have an 'x*' style wildcard
                    if is_wildcard:
                        # We were already in wildcard mode, so this is invalid
                        raise errors.InvalidGlobbing
                    last = idx + 1
                is_wildcard = True
            else:
                if is_wildcard:
                    # We were in wildcard mode, we can't follow that with
                    # non-wildcard
                    raise errors.InvalidGlobbing
                last = idx + 1
        if not is_wildcard:
            return -1
        return last
Ejemplo n.º 2
0
 def get_from_index(self, index_name, *key_values):
     definition = self._get_index_definition(index_name)
     if len(key_values) != len(definition):
         raise errors.InvalidValueForIndex()
     statement, args = self._format_query(definition, key_values)
     c = self._db_handle.cursor()
     try:
         c.execute(statement, tuple(args))
     except dbapi2.OperationalError, e:
         raise dbapi2.OperationalError(str(e) +
             '\nstatement: %s\nargs: %s\n' % (statement, args))
Ejemplo n.º 3
0
    def get_count_from_index(self, index_name, *key_values):
        """
        Returns the count for a given combination of index_name
        and key values.

        Extension method made from similar methods in u1db version 13.09

        :param index_name: The index to query
        :type index_name: str
        :param key_values: values to match. eg, if you have
                           an index with 3 fields then you would have:
                           get_from_index(index_name, val1, val2, val3)
        :type key_values: tuple
        :return: count.
        :rtype: int
        """
        c = self._db_handle.cursor()
        definition = self._get_index_definition(index_name)

        if len(key_values) != len(definition):
            raise u1db_errors.InvalidValueForIndex()
        tables = ["document_fields d%d" % i for i in range(len(definition))]
        novalue_where = [
            "d.doc_id = d%d.doc_id"
            " AND d%d.field_name = ?" % (i, i) for i in range(len(definition))
        ]
        exact_where = [
            novalue_where[i] + (" AND d%d.value = ?" % (i, ))
            for i in range(len(definition))
        ]
        args = []
        where = []
        for idx, (field, value) in enumerate(zip(definition, key_values)):
            args.append(field)
            where.append(exact_where[idx])
            args.append(value)

        tables = ["document_fields d%d" % i for i in range(len(definition))]
        statement = ("SELECT COUNT(*) FROM document d, %s WHERE %s " % (
            ', '.join(tables),
            ' AND '.join(where),
        ))
        try:
            c.execute(statement, tuple(args))
        except dbapi2.OperationalError, e:
            raise dbapi2.OperationalError(
                str(e) + '\nstatement: %s\nargs: %s\n' % (statement, args))
Ejemplo n.º 4
0
 def _format_range_query(self, definition, start_value, end_value):
     tables = ["document_fields d%d" % i for i in range(len(definition))]
     novalue_where = [
         "d.doc_id = d%d.doc_id AND d%d.field_name = ?" % (i, i) for i in
         range(len(definition))]
     wildcard_where = [
         novalue_where[i] + (" AND d%d.value NOT NULL" % (i,)) for i in
         range(len(definition))]
     like_where = [
         novalue_where[i] + (
             " AND (d%d.value < ? OR d%d.value GLOB ?)" % (i, i)) for i in
         range(len(definition))]
     range_where_lower = [
         novalue_where[i] + (" AND d%d.value >= ?" % (i,)) for i in
         range(len(definition))]
     range_where_upper = [
         novalue_where[i] + (" AND d%d.value <= ?" % (i,)) for i in
         range(len(definition))]
     args = []
     where = []
     if start_value:
         if isinstance(start_value, basestring):
             start_value = (start_value,)
         if len(start_value) != len(definition):
             raise errors.InvalidValueForIndex()
         is_wildcard = False
         for idx, (field, value) in enumerate(zip(definition, start_value)):
             args.append(field)
             if value.endswith('*'):
                 if value == '*':
                     where.append(wildcard_where[idx])
                 else:
                     # This is a glob match
                     if is_wildcard:
                         # We can't have a partial wildcard following
                         # another wildcard
                         raise errors.InvalidGlobbing
                     where.append(range_where_lower[idx])
                     args.append(self._strip_glob(value))
                 is_wildcard = True
             else:
                 if is_wildcard:
                     raise errors.InvalidGlobbing
                 where.append(range_where_lower[idx])
                 args.append(value)
     if end_value:
         if isinstance(end_value, basestring):
             end_value = (end_value,)
         if len(end_value) != len(definition):
             raise errors.InvalidValueForIndex()
         is_wildcard = False
         for idx, (field, value) in enumerate(zip(definition, end_value)):
             args.append(field)
             if value.endswith('*'):
                 if value == '*':
                     where.append(wildcard_where[idx])
                 else:
                     # This is a glob match
                     if is_wildcard:
                         # We can't have a partial wildcard following
                         # another wildcard
                         raise errors.InvalidGlobbing
                     where.append(like_where[idx])
                     args.append(self._strip_glob(value))
                     args.append(value)
                 is_wildcard = True
             else:
                 if is_wildcard:
                     raise errors.InvalidGlobbing
                 where.append(range_where_upper[idx])
                 args.append(value)
     statement = (
         "SELECT d.doc_id, d.doc_rev, d.content, count(c.doc_rev) FROM "
         "document d, %s LEFT OUTER JOIN conflicts c ON c.doc_id = "
         "d.doc_id WHERE %s GROUP BY d.doc_id, d.doc_rev, d.content ORDER "
         "BY %s;" % (', '.join(tables), ' AND '.join(where), ', '.join(
             ['d%d.value' % i for i in range(len(definition))])))
     return statement, args
Ejemplo n.º 5
0
 def get_range_from_index(self,
                          index_name,
                          start_value=None,
                          end_value=None):
     """Return all documents with key values in the specified range."""
     definition = self._get_index_definition(index_name)
     tables = ["document_fields d%d" % i for i in range(len(definition))]
     novalue_where = [
         "d.doc_id = d%d.doc_id AND d%d.field_name = ?" % (i, i)
         for i in range(len(definition))
     ]
     wildcard_where = [
         novalue_where[i] + (" AND d%d.value NOT NULL" % (i, ))
         for i in range(len(definition))
     ]
     like_where = [
         novalue_where[i] +
         (" AND (d%d.value < ? OR d%d.value LIKE ? ESCAPE '.')" % (i, i))
         for i in range(len(definition))
     ]
     range_where_lower = [
         novalue_where[i] + (" AND d%d.value >= ?" % (i, ))
         for i in range(len(definition))
     ]
     range_where_upper = [
         novalue_where[i] + (" AND d%d.value <= ?" % (i, ))
         for i in range(len(definition))
     ]
     args = []
     where = []
     if start_value:
         if isinstance(start_value, basestring):
             start_value = (start_value, )
         if len(start_value) != len(definition):
             raise errors.InvalidValueForIndex()
         is_wildcard = False
         for idx, (field, value) in enumerate(zip(definition, start_value)):
             args.append(field)
             if value.endswith('*'):
                 if value == '*':
                     where.append(wildcard_where[idx])
                 else:
                     # This is a glob match
                     if is_wildcard:
                         # We can't have a partial wildcard following
                         # another wildcard
                         raise errors.InvalidGlobbing
                     where.append(range_where_lower[idx])
                     args.append(self._strip_glob(value))
                 is_wildcard = True
             else:
                 if is_wildcard:
                     raise errors.InvalidGlobbing
                 where.append(range_where_lower[idx])
                 args.append(value)
     if end_value:
         if isinstance(end_value, basestring):
             end_value = (end_value, )
         if len(end_value) != len(definition):
             raise errors.InvalidValueForIndex()
         is_wildcard = False
         for idx, (field, value) in enumerate(zip(definition, end_value)):
             args.append(field)
             if value.endswith('*'):
                 if value == '*':
                     where.append(wildcard_where[idx])
                 else:
                     # This is a glob match
                     if is_wildcard:
                         # We can't have a partial wildcard following
                         # another wildcard
                         raise errors.InvalidGlobbing
                     where.append(like_where[idx])
                     args.append(self._strip_glob(value))
                     args.append(self._transform_glob(value))
                 is_wildcard = True
             else:
                 if is_wildcard:
                     raise errors.InvalidGlobbing
                 where.append(range_where_upper[idx])
                 args.append(value)
     statement = (
         "SELECT d.doc_id, d.doc_rev, d.content FROM document d, %s "
         "WHERE %s ORDER BY %s;" %
         (', '.join(tables), ' AND '.join(where), ', '.join(
             ['d%d.value' % i for i in range(len(definition))])))
     c = self._db_handle.cursor()
     try:
         c.execute(statement, tuple(args))
     except dbapi2.OperationalError, e:
         raise dbapi2.OperationalError(
             str(e) + '\nstatement: %s\nargs: %s\n' % (statement, args))
Ejemplo n.º 6
0
 def get_from_index(self, index_name, *key_values):
     definition = self._get_index_definition(index_name)
     # First, build the definition. We join the document_fields table
     # against itself, as many times as the 'width' of our definition.
     # We then do a query for each key_value, one-at-a-time.
     # Note: All of these strings are static, we could cache them, etc.
     tables = ["document_fields d%d" % i for i in range(len(definition))]
     novalue_where = [
         "d.doc_id = d%d.doc_id"
         " AND d%d.field_name = ?" % (i, i) for i in range(len(definition))
     ]
     wildcard_where = [
         novalue_where[i] + (" AND d%d.value NOT NULL" % (i, ))
         for i in range(len(definition))
     ]
     exact_where = [
         novalue_where[i] + (" AND d%d.value = ?" % (i, ))
         for i in range(len(definition))
     ]
     like_where = [
         novalue_where[i] + (" AND d%d.value LIKE ? ESCAPE '.'" % (i, ))
         for i in range(len(definition))
     ]
     c = self._db_handle.cursor()
     is_wildcard = False
     # Merge the lists together, so that:
     # [field1, field2, field3], [val1, val2, val3]
     # Becomes:
     # (field1, val1, field2, val2, field3, val3)
     args = []
     where = []
     if len(key_values) != len(definition):
         raise errors.InvalidValueForIndex()
     for idx, (field, value) in enumerate(zip(definition, key_values)):
         args.append(field)
         if value.endswith('*'):
             if value == '*':
                 where.append(wildcard_where[idx])
             else:
                 # This is a glob match
                 if is_wildcard:
                     # We can't have a partial wildcard following
                     # another wildcard
                     raise errors.InvalidGlobbing
                 where.append(like_where[idx])
                 args.append(self._transform_glob(value))
             is_wildcard = True
         else:
             if is_wildcard:
                 raise errors.InvalidGlobbing
             where.append(exact_where[idx])
             args.append(value)
     statement = (
         "SELECT d.doc_id, d.doc_rev, d.content FROM document d, %s "
         "WHERE %s ORDER BY %s;" %
         (', '.join(tables), ' AND '.join(where), ', '.join(
             ['d%d.value' % i for i in range(len(definition))])))
     try:
         c.execute(statement, tuple(args))
     except dbapi2.OperationalError, e:
         raise dbapi2.OperationalError(
             str(e) + '\nstatement: %s\nargs: %s\n' % (statement, args))