Author: Alex Date: 2010-06-21 11:11:17 -0500 (Mon, 21 Jun 2010) New Revision: 13368
Modified: django/branches/soc2010/query-refactor/django/contrib/mongodb/base.py django/branches/soc2010/query-refactor/django/contrib/mongodb/compiler.py django/branches/soc2010/query-refactor/django/db/models/sql/query.py django/branches/soc2010/query-refactor/django/db/models/sql/where.py django/branches/soc2010/query-refactor/tests/regressiontests/mongodb/tests.py Log: [soc2010/query-refactor] Cleaned up implementation of negation in MongoDB, and no longer rely on a feature from MongoDB unstable version. Modified: django/branches/soc2010/query-refactor/django/contrib/mongodb/base.py =================================================================== --- django/branches/soc2010/query-refactor/django/contrib/mongodb/base.py 2010-06-21 15:49:56 UTC (rev 13367) +++ django/branches/soc2010/query-refactor/django/contrib/mongodb/base.py 2010-06-21 16:11:17 UTC (rev 13368) @@ -10,6 +10,7 @@ class DatabaseFeatures(object): interprets_empty_strings_as_nulls = False typed_columns = False + sql_nulls = False class DatabaseOperations(object): Modified: django/branches/soc2010/query-refactor/django/contrib/mongodb/compiler.py =================================================================== --- django/branches/soc2010/query-refactor/django/contrib/mongodb/compiler.py 2010-06-21 15:49:56 UTC (rev 13367) +++ django/branches/soc2010/query-refactor/django/contrib/mongodb/compiler.py 2010-06-21 16:11:17 UTC (rev 13368) @@ -1,3 +1,6 @@ +from django.db.models.sql.datastructures import FullResultSet + + # TODO: ... class SQLCompiler(object): def __init__(self, query, connection, using): @@ -5,7 +8,7 @@ self.connection = connection self.using = using - def get_filters(self, where, correct=False): + def get_filters(self, where): assert where.connector == "AND" filters = {} for child in where.children: @@ -15,13 +18,15 @@ if k in filters: v = {"$and": [filters[k], v]} if where.negated: - v = {"$not": v} - filters[k] = v + filters.update(self.negate(k, v)) + else: + filters[k] = v else: - field, val = self.make_atom(*child, **{"negated": where.negated}) - filters[field] = val - if correct: - self.correct_filters(filters) + try: + field, val = self.make_atom(*child, **{"negated": where.negated}) + filters[field] = val + except FullResultSet: + pass return filters def make_atom(self, lhs, lookup_type, value_annotation, params_or_value, negated): @@ -48,17 +53,10 @@ val = {"$not": val} return column, val elif lookup_type == "lt": + if negated: + return {"$gte": params[0]} return column, {"$lt": params[0]} - def correct_filters(self, filters): - for k, v in filters.items(): - if isinstance(v, dict) and v.keys() == ["$not"]: - if isinstance(v["$not"], dict) and v["$not"].keys() == ["$and"]: - del filters[k] - or_vals = [self.negate(k, v) for v in v["$not"]["$and"]] - assert "$or" not in filters - filters["$or"] = or_vals - def negate(self, k, v): if isinstance(v, dict): if v.keys() == ["$not"]: @@ -76,7 +74,7 @@ assert self.query.high_mark is None assert not self.query.order_by - filters = self.get_filters(self.query.where, correct=True) + filters = self.get_filters(self.query.where) return self.connection.db[self.query.model._meta.db_table].find(filters) def results_iter(self): Modified: django/branches/soc2010/query-refactor/django/db/models/sql/query.py =================================================================== --- django/branches/soc2010/query-refactor/django/db/models/sql/query.py 2010-06-21 15:49:56 UTC (rev 13367) +++ django/branches/soc2010/query-refactor/django/db/models/sql/query.py 2010-06-21 16:11:17 UTC (rev 13368) @@ -1077,7 +1077,11 @@ # it's short-circuited in the Where class. # We also need to handle the case where a subquery is provided entry = self.where_class() - entry.add((Constraint(alias, col, None), 'isnull', True), AND) + entry.add(( + Constraint(alias, col, None, eliminatable_if=lambda connection: not getattr(connection.features, "sql_nulls", True)), + 'isnull', + True + ), AND) entry.negate() self.where.add(entry, AND) Modified: django/branches/soc2010/query-refactor/django/db/models/sql/where.py =================================================================== --- django/branches/soc2010/query-refactor/django/db/models/sql/where.py 2010-06-21 15:49:56 UTC (rev 13367) +++ django/branches/soc2010/query-refactor/django/db/models/sql/where.py 2010-06-21 16:11:17 UTC (rev 13368) @@ -267,8 +267,9 @@ An object that can be passed to WhereNode.add() and knows how to pre-process itself prior to including in the WhereNode. """ - def __init__(self, alias, col, field): + def __init__(self, alias, col, field, eliminatable_if=None): self.alias, self.col, self.field = alias, col, field + self.elimintable_if = eliminatable_if def __getstate__(self): """Save the state of the Constraint for pickling. @@ -321,6 +322,9 @@ except ObjectDoesNotExist: raise EmptyShortCircuit + if self.elimintable_if and self.elimintable_if(connection): + raise FullResultSet + return (self.alias, self.col, db_type), params def relabel_aliases(self, change_map): Modified: django/branches/soc2010/query-refactor/tests/regressiontests/mongodb/tests.py =================================================================== --- django/branches/soc2010/query-refactor/tests/regressiontests/mongodb/tests.py 2010-06-21 15:49:56 UTC (rev 13367) +++ django/branches/soc2010/query-refactor/tests/regressiontests/mongodb/tests.py 2010-06-21 16:11:17 UTC (rev 13368) @@ -62,20 +62,8 @@ q = Group.objects.create(name="Queen", year_formed=1971) e = Group.objects.create(name="The E Street Band", year_formed=1972) - qs = Group.objects.exclude(year_formed=1972) - v = qs.query.get_compiler(qs.db).get_filters(qs.query.where, correct=True) - self.assertEqual(v, { - "$or": [ - {"year_formed": {"$ne": 1972}}, - {"year_formed": None}, - ] - }) - # A bug in MongoDB prevents this query from actually working, but test - # that we're at least generating the right query. - return - self.assertQuerysetEqual( - qs, [ + Group.objects.exclude(year_formed=1972), [ "Queen", ], lambda g: g.name, @@ -105,4 +93,10 @@ [], lambda g: g.name ) - + + self.assertQuerysetEqual( + Group.objects.exclude(year_formed__lt=1972), [ + "The E Street Band" + ], + lambda g: g.name, + ) -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-upda...@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.