Exemple #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
Exemple #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))
Exemple #3
0
    def get_count_from_index(self, index_name, *key_values):
        """
        Return 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 sqlcipher_dbapi2.OperationalError as e:
            raise sqlcipher_dbapi2.OperationalError(
                str(e) + '\nstatement: %s\nargs: %s\n' % (statement, args))
        res = c.fetchall()
        return res[0][0]
Exemple #4
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 as e:
         raise dbapi2.OperationalError(
             str(e) +
             '\nstatement: %s\nargs: %s\n' % (statement, args))
     res = c.fetchall()
     results = []
     for row in res:
         doc = self._factory(row[0], row[1], row[2])
         doc.has_conflicts = row[3] > 0
         results.append(doc)
     return results
 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