Example #1
0
    def setUp(self):
        add_special_index(User, "username", "iexact")

        User.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
        User.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
        User.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
        User.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
        User.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
Example #2
0
    def setUp(self):
        add_special_index(TestUser, "username", "iexact")

        self.u1 = TestUser.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
        self.u2 = TestUser.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
        TestUser.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
        TestUser.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())
        TestUser.objects.create(username="******", email="*****@*****.**", last_login=datetime.datetime.now().date())

        self.apple = TestFruit.objects.create(name="apple", color="red")
        self.banana = TestFruit.objects.create(name="banana", color="yellow")
Example #3
0
    def setUp(self):
        add_special_index(User, "username", "iexact")

        User.objects.create(username="******",
                            email="*****@*****.**",
                            last_login=datetime.datetime.now().date())
        User.objects.create(username="******",
                            email="*****@*****.**",
                            last_login=datetime.datetime.now().date())
        User.objects.create(username="******",
                            email="*****@*****.**",
                            last_login=datetime.datetime.now().date())
        User.objects.create(username="******",
                            email="*****@*****.**",
                            last_login=datetime.datetime.now().date())
        User.objects.create(username="******",
                            email="*****@*****.**",
                            last_login=datetime.datetime.now().date())
Example #4
0
def parse_constraint(child, connection, negated=False):
    #First, unpack the constraint
    constraint, op, annotation, value = child
    was_list = isinstance(value, (list, tuple))
    packed, value = constraint.process(op, value, connection)
    alias, column, db_type = packed

    if constraint.field.db_type(connection) in ("bytes", "text"):
        raise NotSupportedError("Text and Blob fields are not indexed by the datastore, so you can't filter on them")

    if op not in REQUIRES_SPECIAL_INDEXES:
        #Don't convert if this op requires special indexes, it will be handled there
        value = [ connection.ops.prep_lookup_value(constraint.field.model, x, constraint.field, constraint=constraint) for x in value]

        #Don't ask me why, but constraint.process on isnull wipes out the value (it returns an empty list)
        # so we have to special case this to use the annotation value instead
        if op == "isnull":
            value = [ annotation ]

            if constraint.field.primary_key and value[0]:
                raise EmptyResultSet()

        if not was_list:
            value = value[0]
    else:
        if negated:
            raise CouldBeSupportedError("Special indexing does not currently supported negated queries. See #80")

        if not was_list:
            value = value[0]

        add_special_index(constraint.field.model, column, op) #Add the index if we can (e.g. on dev_appserver)

        if op not in special_indexes_for_column(constraint.field.model, column):
            raise RuntimeError("There is a missing index in your djangaeidx.yaml - \n\n{0}:\n\t{1}: [{2}]".format(
                constraint.field.model, column, op)
            )

        indexer = REQUIRES_SPECIAL_INDEXES[op]
        column = indexer.indexed_column_name(column)
        value = indexer.prep_value_for_query(value)
        op = indexer.prep_query_operator(op)

    return column, op, value
Example #5
0
def parse_constraint(child, connection):
    #First, unpack the constraint
    constraint, op, annotation, value = child
    was_list = isinstance(value, (list, tuple))
    packed, value = constraint.process(op, value, connection)
    alias, column, db_type = packed

    if constraint.field.db_type(connection) in ("bytes", "text"):
        raise NotSupportedError("Text and Blob fields are not indexed by the datastore, so you can't filter on them")

    if op not in REQUIRES_SPECIAL_INDEXES:
        #Don't convert if this op requires special indexes, it will be handled there
        value = [ connection.ops.prep_lookup_value(constraint.field.model, x, constraint.field, constraint=constraint) for x in value]

        #Don't ask me why, but constraint.process on isnull wipes out the value (it returns an empty list)
        # so we have to special case this to use the annotation value instead
        if op == "isnull":
            value = [ annotation ]

        if not was_list:
            value = value[0]
    else:
        if not was_list:
            value = value[0]

        add_special_index(constraint.field.model, column, op) #Add the index if we can (e.g. on dev_appserver)

        if op not in special_indexes_for_column(constraint.field.model, column):
            raise RuntimeError("There is a missing index in your djangaeidx.yaml - \n\n{0}:\n\t{1}: [{2}]".format(
                constraint.field.model, column, op)
            )

        indexer = REQUIRES_SPECIAL_INDEXES[op]
        column = indexer.indexed_column_name(column)
        value = indexer.prep_value_for_query(value)
        op = indexer.prep_query_operator(op)

    return column, op, value
Example #6
0
def parse_constraint(child, connection, negated=False):
    if isinstance(child, tuple):
        # First, unpack the constraint
        constraint, op, annotation, value = child
        was_list = isinstance(value, (list, tuple))
        if isinstance(value, query.Query):
            value = value.get_compiler(connection.alias).as_sql()[0].execute()
        else:
            packed, value = constraint.process(op, value, connection)
        alias, column, db_type = packed
        field = constraint.field
    else:
        # Django 1.7+
        field = child.lhs.target
        column = child.lhs.target.column
        op = child.lookup_name
        value = child.rhs
        annotation = value
        was_list = isinstance(value, (list, tuple))

        if isinstance(value, query.Query):
            value = value.get_compiler(connection.alias).as_sql()[0].execute()
        elif value != []:
            value = child.lhs.output_field.get_db_prep_lookup(
                child.lookup_name, child.rhs, connection, prepared=True)


    is_pk = field and field.primary_key

    if column == "id" and op == "iexact" and is_pk and isinstance(field, AutoField):
        # When new instance is created, automatic primary key 'id' does not generate '_idx_iexact_id'.
        # As the primary key 'id' (AutoField) is integer and is always case insensitive, we can deal with 'id_iexact=' query by using 'exact' rather than 'iexact'.
        op = "exact"

    if field and field.db_type(connection) in ("bytes", "text"):
        raise NotSupportedError("Text and Blob fields are not indexed by the datastore, so you can't filter on them")

    if op not in REQUIRES_SPECIAL_INDEXES:
        # Don't convert if this op requires special indexes, it will be handled there
        if field:
            value = [ connection.ops.prep_lookup_value(field.model, x, field, column=column) for x in value]

        # Don't ask me why, but on Django 1.6 constraint.process on isnull wipes out the value (it returns an empty list)
        # so we have to special case this to use the annotation value instead
        if op == "isnull":
            if annotation is not None:
                value = [ annotation ]

            if is_pk and value[0]:
                raise EmptyResultSet()

        if not was_list:
            value = value[0]
    else:
        if negated:
            raise CouldBeSupportedError("Special indexing does not currently supported negated queries. See #80")

        if not was_list:
            value = value[0]

        add_special_index(field.model, column, op)  # Add the index if we can (e.g. on dev_appserver)

        if op not in special_indexes_for_column(field.model, column):
            raise RuntimeError("There is a missing index in your djangaeidx.yaml - \n\n{0}:\n\t{1}: [{2}]".format(
                field.model, column, op)
            )

        indexer = REQUIRES_SPECIAL_INDEXES[op]
        value = indexer.prep_value_for_query(value)
        column = indexer.indexed_column_name(column, value=value)
        op = indexer.prep_query_operator(op)

    return column, op, value
Example #7
0
    def _build_gae_query(self):
        """ Build and return the Datstore Query object. """
        combined_filters = []

        query_kwargs = {}

        if self.keys_only:
            query_kwargs["keys_only"] = self.keys_only
        elif self.projection:
            query_kwargs["projection"] = self.projection

        query = Query(
            self.db_table,
            **query_kwargs
        )

        if has_concrete_parents(self.model) and not self.model._meta.proxy:
            query["class ="] = self.model._meta.db_table

        DJANGAE_LOG.debug("Select query: {0}, {1}".format(self.model.__name__, self.where))
        for column, op, value in self.where:
            if column == self.pk_col:
                column = "__key__"

            final_op = OPERATORS_MAP.get(op)
            if final_op is None:
                if op in REQUIRES_SPECIAL_INDEXES:
                    add_special_index(self.model, column, op) #Add the index if we can (e.g. on dev_appserver)

                    if op not in special_indexes_for_column(self.model, column):
                        raise RuntimeError("There is a missing index in your djangaeidx.yaml - \n\n{0}:\n\t{1}: [{2}]".format(
                            self.model, column, op)
                        )

                    indexer = REQUIRES_SPECIAL_INDEXES[op]
                    column = indexer.indexed_column_name(column)
                    value = indexer.prep_value_for_query(value)
                    query["%s =" % column] = value
                else:
                    if op == "in":
                        combined_filters.append((column, op, value))
                    elif op == "gt_and_lt":
                        combined_filters.append((column, op, value))
                    elif op == "isnull":
                        query["%s =" % column] = None
                    elif op == "startswith":
                        #You can emulate starts with by adding the last unicode char
                        #to the value, then doing <=. Genius.
                        query["%s >=" % column] = value
                        if isinstance(value, str):
                            value = value.decode("utf-8")
                        value += u'\ufffd'
                        query["%s <=" % column] = value
                    else:
                        raise NotImplementedError("Unimplemented operator {0}".format(op))
            else:
                query["%s %s" % (column, final_op)] = value

        ordering = []
        for order in self.ordering:
            if isinstance(order, int):
                direction = datastore.Query.ASCENDING if order == 1 else datastore.Query.DESCENDING
                order = self.queried_fields[0]
            else:
                direction = datastore.Query.DESCENDING if order.startswith("-") else datastore.Query.ASCENDING
                order = order.lstrip("-")

            if order == self.model._meta.pk.column:
                order = "__key__"
            ordering.append((order, direction))

        if combined_filters:
            queries = [ query ]
            for column, op, value in combined_filters:
                new_queries = []
                for query in queries:
                    if op == "in":
                        for val in value:
                            new_query = datastore.Query(self.model._meta.db_table)
                            new_query.update(query)
                            new_query["%s =" % column] = val
                            new_queries.append(new_query)
                    elif op == "gt_and_lt":
                        for tmp_op in ("<", ">"):
                            new_query = datastore.Query(self.model._meta.db_table)
                            new_query.update(query)
                            new_query["%s %s" % (column, tmp_op)] = value
                            new_queries.append(new_query)
                queries = new_queries

            query = datastore.MultiQuery(queries, ordering)
        elif ordering:
            query.Order(*ordering)
        return query