def test_or(self): where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'exact', "foo"), AND) where.add((Constraint("givenName", "givenName", CharField()), 'exact', "bar"), OR) self.assertEquals(where_as_ldap(where), ("(|(cn=foo)(givenName=bar))", []))
def test_char_field_exact(self): where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'exact', "test"), AND) self.assertEquals(where_as_ldap(where), ("(cn=test)", [])) where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'exact', "(test)"), AND) self.assertEquals(where_as_ldap(where), ("(cn=\\28test\\29)", []))
def test_char_field_contains(self): where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'contains', "test"), AND) self.assertEquals(where_as_ldap(where), ("(cn=*test*)", [])) where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'contains', "te*st"), AND) self.assertEquals(where_as_ldap(where), ("(cn=*te\\2ast*)", []))
def test_char_field_in(self): where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'in', ["foo", "bar"]), AND) self.assertEquals(where_as_ldap(where), ("(|(cn=foo)(cn=bar))", [])) where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'in', ["(foo)", "(bar)"]), AND) self.assertEquals(where_as_ldap(where), ("(|(cn=\\28foo\\29)(cn=\\28bar\\29))", []))
def test_list_field_contains(self): where = WhereNode() where.add((Constraint("memberUid", "memberUid", ListField()), 'contains', 'foouser'), AND) self.assertEquals(where_as_ldap(where), ("(memberUid=foouser)", [])) where = WhereNode() where.add((Constraint("memberUid", "memberUid", ListField()), 'contains', '(foouser)'), AND) self.assertEquals(where_as_ldap(where), ("(memberUid=\\28foouser\\29)", []))
def test_char_field_endswith(self): where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'endswith', "test"), AND) self.assertEquals(where.as_sql(), ("(cn=*test)", [])) where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'endswith', "te*st"), AND) self.assertEquals(where.as_sql(), ("(cn=*te\\2ast)", []))
def test_char_field_startswith(self): where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'startswith', "test"), AND) self.assertEqual(where_as_ldap(where), ("(cn=test*)", [])) where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'startswith', "te*st"), AND) self.assertEqual(where_as_ldap(where), ("(cn=te\\2ast*)", []))
def test_integer_field(self): where = WhereNode() where.add((Constraint("uid", "uid", IntegerField()), 'exact', 1), AND) self.assertEquals(where.as_sql(), ("(uid=1)", [])) where = WhereNode() where.add((Constraint("uid", "uid", IntegerField()), 'gte', 1), AND) self.assertEquals(where.as_sql(), ("(uid>=1)", [])) where = WhereNode() where.add((Constraint("uid", "uid", IntegerField()), 'lte', 1), AND) self.assertEquals(where.as_sql(), ("(uid<=1)", []))
def test_float_field(self): where = WhereNode() where.add((Constraint("uid", "uid", FloatField()), 'exact', 1.2), AND) self.assertEquals(where_as_ldap(where), ("(uid=1.2)", [])) where = WhereNode() where.add((Constraint("uid", "uid", FloatField()), 'gte', 1.2), AND) self.assertEquals(where_as_ldap(where), ("(uid>=1.2)", [])) where = WhereNode() where.add((Constraint("uid", "uid", FloatField()), 'lte', 1.2), AND) self.assertEquals(where_as_ldap(where), ("(uid<=1.2)", []))
def delete_qs(self, query, using): """ Delete the queryset in one SQL query (if possible). For simple queries this is done by copying the query.query.where to self.query, for complex queries by using subquery. """ innerq = query.query # Make sure the inner query has at least one table in use. innerq.get_initial_alias() # The same for our new query. self.get_initial_alias() innerq_used_tables = [t for t in innerq.tables if innerq.alias_refcount[t]] if ((not innerq_used_tables or innerq_used_tables == self.tables) and not len(innerq.having)): # There is only the base table in use in the query, and there are # no aggregate filtering going on. self.where = innerq.where else: pk = query.model._meta.pk if not connections[using].features.update_can_self_select: # We can't do the delete using subquery. values = list(query.values_list('pk', flat=True)) if not values: return self.delete_batch(values, using) return else: innerq.clear_select_clause() innerq.select = [SelectInfo((self.get_initial_alias(), pk.column), None)] values = innerq where = self.where_class() where.add((Constraint(None, pk.column, pk), 'in', values), AND) self.where = where self.get_compiler(using).execute_sql(None)
def get_extra_restriction(self, where_class, alias, remote_alias): field = self.rel.to._meta.get_field_by_name( self.content_type_field_name)[0] contenttype_pk = self.get_content_type().pk cond = where_class() cond.add((Constraint(remote_alias, field.column, field), 'exact', contenttype_pk), 'AND') return cond
def descendents_of(cls, instance): qs = cls.objects.all() #Add our own custom constraint type to mark this as an ancestor query #this is used in GAEQuery._decode_child and then switched for a custom filter #which is passed to GAEQuery.add_filter where we set the ancestor_key qs.query.where.add((Constraint( None, '__ancestor', instance._meta.pk), 'exact', instance), 'AND') return qs
def add_alias_constraints(queryset, alias, **kwargs): model, alias = alias clause = queryset.query.where_class() for lookup, value in kwargs.items(): field_name, lookup = lookup.split('__') field = model._meta.get_field(field_name) clause.add((Constraint(alias, field.column, field), lookup, value), AND) queryset.query.where.add(clause, AND)
def update_batch(self, pk_list, values, using): pk_field = self.model._meta.pk self.add_update_values(values) for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): self.where = self.where_class() self.where.add((Constraint(None, pk_field.column, pk_field), 'in', pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]), AND) self.get_compiler(using).execute_sql(None)
def delete_batch_related(self, pk_list, using): """ Set up and execute delete queries for all the objects related to the primary key values in pk_list. To delete the objects themselves, use the delete_batch() method. More than one physical query may be executed if there are a lot of values in pk_list. """ from django.contrib.contenttypes import generic cls = self.model for related in cls._meta.get_all_related_many_to_many_objects(): if not isinstance(related.field, generic.GenericRelation): for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): where = self.where_class() where.add( (Constraint(None, related.field.m2m_reverse_name(), related.field), 'in', pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]), AND) self.do_query(related.field.m2m_db_table(), where, using=using) for f in cls._meta.many_to_many: w1 = self.where_class() db_prep_value = None if isinstance(f, generic.GenericRelation): from django.contrib.contenttypes.models import ContentType ct_field = f.rel.to._meta.get_field(f.content_type_field_name) w1.add((Constraint(None, ct_field.column, ct_field), 'exact', ContentType.objects.get_for_model(cls).id), AND) id_field = f.rel.to._meta.get_field(f.object_id_field_name) db_prep_value = id_field.get_db_prep_value for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): where = self.where_class() where.add( (Constraint(None, f.m2m_column_name(), f), 'in', map(db_prep_value, pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE])), AND) if w1: where.add(w1, AND) self.do_query(f.m2m_db_table(), where, using=using)
def get_lookup_constraint(self, constraint_class, alias, targets, sources, lookups, raw_value): from django.db.models.sql.where import Constraint assert len(targets) == len(sources) if isinstance(lookups, basestring): lookup_type = lookups else: if len(lookups) > 1: raise exceptions.FieldError( 'UnixDateTimeField fields do not support nested lookups') lookup_type = lookups[0] if lookup_type == 'isnull' and self.zero_null and raw_value: return (Constraint(alias, targets[0].column, targets[0]), 'exact', None) else: return (Constraint(alias, targets[0].column, self), lookup_type, raw_value)
def wrapper(self, where_class, alias, lhs): cond = func(self, where_class, alias, lhs) from .models import PermanentModel if not issubclass(self.model, PermanentModel) or issubclass( where_class, AllWhereNode): return cond if issubclass(where_class, DeletedWhereNode): cond = cond or ~where_class() else: cond = cond or where_class() if django.VERSION < (1, 8, 0): field = self.model._meta.get_field_by_name(settings.FIELD)[0] else: field = self.model._meta.get_field(settings.FIELD) if django.VERSION < (1, 7, 0): from django.db.models.sql.where import Constraint if settings.FIELD_DEFAULT is None: lookup = Constraint(lhs, settings.FIELD, field), 'isnull', True else: lookup = Constraint(lhs, alias, field), 'exact', settings.FIELD_DEFAULT else: if django.VERSION < (1, 8, 0): from django.db.models.sql.datastructures import Col else: from django.db.models.expressions import Col if settings.FIELD_DEFAULT is None: lookup = field.get_lookup('isnull')(Col(lhs, field, field), True) else: lookup = field.get_lookup('exact')(Col(lhs, field, field), settings.FIELD_DEFAULT) cond.add(lookup, 'AND') return cond
def delete_batch(self, pk_list, using): """ Set up and execute delete queries for all the objects in pk_list. More than one physical query may be executed if there are a lot of values in pk_list. """ for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): where = self.where_class() field = self.model._meta.pk where.add((Constraint(None, field.column, field), 'in', pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]), AND) self.do_query(self.model._meta.db_table, where, using=using)
def clear_related(self, related_field, pk_list, using): """ Set up and execute an update query that clears related entries for the keys in pk_list. This is used by the QuerySet.delete_objects() method. """ for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): self.where = self.where_class() f = self.model._meta.pk self.where.add((Constraint(None, f.column, f), 'in', pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]), AND) self.values = [(related_field, None, None)] self.get_compiler(using).execute_sql(None)
def constraint_tuple(alias, col, field, lookup_type, value): return (Constraint(alias, col, field), lookup_type, value)
def test_and(self): where = WhereNode() where.add((Constraint("cn", "cn", CharField()), 'exact', "foo"), AND) where.add((Constraint("givenName", "givenName", CharField()), 'exact', "bar"), AND) self.assertEquals(where.as_sql(), ("(&(cn=foo)(givenName=bar))", []))
def test_date_field(self): where = WhereNode() where.add((Constraint("birthday", "birthday", DateField()), 'exact', '2013-09-03'), AND) self.assertEquals(where_as_ldap(where), ("(birthday=2013-09-03)", []))