mirror of
				https://github.com/django/django.git
				synced 2025-10-29 08:36:09 +00:00 
			
		
		
		
	Refactored quote_name() to DatabaseOperations.quote_name(). Refs #5106
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5967 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -1,6 +1,6 @@ | |||||||
| from django.core import validators | from django.core import validators | ||||||
| from django.core.exceptions import ImproperlyConfigured | from django.core.exceptions import ImproperlyConfigured | ||||||
| from django.db import backend, connection, models | from django.db import connection, models | ||||||
| from django.contrib.contenttypes.models import ContentType | from django.contrib.contenttypes.models import ContentType | ||||||
| from django.utils.encoding import smart_str | from django.utils.encoding import smart_str | ||||||
| from django.utils.translation import ugettext_lazy as _ | from django.utils.translation import ugettext_lazy as _ | ||||||
| @@ -203,6 +203,7 @@ class User(models.Model): | |||||||
|             #         AND gp."group_id" = ug."group_id" |             #         AND gp."group_id" = ug."group_id" | ||||||
|             #         AND ct."id" = p."content_type_id" |             #         AND ct."id" = p."content_type_id" | ||||||
|             #         AND ug."user_id" = %s, [self.id]) |             #         AND ug."user_id" = %s, [self.id]) | ||||||
|  |             qn = connection.ops.quote_name | ||||||
|             sql = """ |             sql = """ | ||||||
|                 SELECT ct.%s, p.%s |                 SELECT ct.%s, p.%s | ||||||
|                 FROM %s p, %s gp, %s ug, %s ct |                 FROM %s p, %s gp, %s ug, %s ct | ||||||
| @@ -210,13 +211,13 @@ class User(models.Model): | |||||||
|                     AND gp.%s = ug.%s |                     AND gp.%s = ug.%s | ||||||
|                     AND ct.%s = p.%s |                     AND ct.%s = p.%s | ||||||
|                     AND ug.%s = %%s""" % ( |                     AND ug.%s = %%s""" % ( | ||||||
|                 backend.quote_name('app_label'), backend.quote_name('codename'), |                 qn('app_label'), qn('codename'), | ||||||
|                 backend.quote_name('auth_permission'), backend.quote_name('auth_group_permissions'), |                 qn('auth_permission'), qn('auth_group_permissions'), | ||||||
|                 backend.quote_name('auth_user_groups'), backend.quote_name('django_content_type'), |                 qn('auth_user_groups'), qn('django_content_type'), | ||||||
|                 backend.quote_name('id'), backend.quote_name('permission_id'), |                 qn('id'), qn('permission_id'), | ||||||
|                 backend.quote_name('group_id'), backend.quote_name('group_id'), |                 qn('group_id'), qn('group_id'), | ||||||
|                 backend.quote_name('id'), backend.quote_name('content_type_id'), |                 qn('id'), qn('content_type_id'), | ||||||
|                 backend.quote_name('user_id'),) |                 qn('user_id'),) | ||||||
|             cursor.execute(sql, [self.id]) |             cursor.execute(sql, [self.id]) | ||||||
|             self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) |             self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) | ||||||
|         return self._group_perm_cache |         return self._group_perm_cache | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ Classes allowing "generic" relations through ContentType and object-id fields. | |||||||
|  |  | ||||||
| from django import oldforms | from django import oldforms | ||||||
| from django.core.exceptions import ObjectDoesNotExist | from django.core.exceptions import ObjectDoesNotExist | ||||||
| from django.db import backend | from django.db import connection | ||||||
| from django.db.models import signals | from django.db.models import signals | ||||||
| from django.db.models.fields.related import RelatedField, Field, ManyToManyRel | from django.db.models.fields.related import RelatedField, Field, ManyToManyRel | ||||||
| from django.db.models.loading import get_model | from django.db.models.loading import get_model | ||||||
| @@ -163,13 +163,15 @@ class ReverseGenericRelatedObjectsDescriptor(object): | |||||||
|         superclass = rel_model._default_manager.__class__ |         superclass = rel_model._default_manager.__class__ | ||||||
|         RelatedManager = create_generic_related_manager(superclass) |         RelatedManager = create_generic_related_manager(superclass) | ||||||
|  |  | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|  |  | ||||||
|         manager = RelatedManager( |         manager = RelatedManager( | ||||||
|             model = rel_model, |             model = rel_model, | ||||||
|             instance = instance, |             instance = instance, | ||||||
|             symmetrical = (self.field.rel.symmetrical and instance.__class__ == rel_model), |             symmetrical = (self.field.rel.symmetrical and instance.__class__ == rel_model), | ||||||
|             join_table = backend.quote_name(self.field.m2m_db_table()), |             join_table = qn(self.field.m2m_db_table()), | ||||||
|             source_col_name = backend.quote_name(self.field.m2m_column_name()), |             source_col_name = qn(self.field.m2m_column_name()), | ||||||
|             target_col_name = backend.quote_name(self.field.m2m_reverse_name()), |             target_col_name = qn(self.field.m2m_reverse_name()), | ||||||
|             content_type = ContentType.objects.get_for_model(self.field.model), |             content_type = ContentType.objects.get_for_model(self.field.model), | ||||||
|             content_type_field_name = self.field.content_type_field_name, |             content_type_field_name = self.field.content_type_field_name, | ||||||
|             object_id_field_name = self.field.object_id_field_name |             object_id_field_name = self.field.object_id_field_name | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ class Command(LabelCommand): | |||||||
|     requires_model_validation = False |     requires_model_validation = False | ||||||
|  |  | ||||||
|     def handle_label(self, tablename, **options): |     def handle_label(self, tablename, **options): | ||||||
|         from django.db import backend, connection, transaction, models |         from django.db import connection, transaction, models | ||||||
|         fields = ( |         fields = ( | ||||||
|             # "key" is a reserved word in MySQL, so use "cache_key" instead. |             # "key" is a reserved word in MySQL, so use "cache_key" instead. | ||||||
|             models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), |             models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), | ||||||
| @@ -17,8 +17,9 @@ class Command(LabelCommand): | |||||||
|         ) |         ) | ||||||
|         table_output = [] |         table_output = [] | ||||||
|         index_output = [] |         index_output = [] | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|         for f in fields: |         for f in fields: | ||||||
|             field_output = [backend.quote_name(f.name), f.db_type()] |             field_output = [qn(f.name), f.db_type()] | ||||||
|             field_output.append("%sNULL" % (not f.null and "NOT " or "")) |             field_output.append("%sNULL" % (not f.null and "NOT " or "")) | ||||||
|             if f.unique: |             if f.unique: | ||||||
|                 field_output.append("UNIQUE") |                 field_output.append("UNIQUE") | ||||||
| @@ -27,10 +28,10 @@ class Command(LabelCommand): | |||||||
|             if f.db_index: |             if f.db_index: | ||||||
|                 unique = f.unique and "UNIQUE " or "" |                 unique = f.unique and "UNIQUE " or "" | ||||||
|                 index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ |                 index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ | ||||||
|                     (unique, tablename, f.name, backend.quote_name(tablename), |                     (unique, tablename, f.name, qn(tablename), | ||||||
|                     backend.quote_name(f.name))) |                     qn(f.name))) | ||||||
|             table_output.append(" ".join(field_output)) |             table_output.append(" ".join(field_output)) | ||||||
|         full_statement = ["CREATE TABLE %s (" % backend.quote_name(tablename)] |         full_statement = ["CREATE TABLE %s (" % qn(tablename)] | ||||||
|         for i, line in enumerate(table_output): |         for i, line in enumerate(table_output): | ||||||
|             full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) |             full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) | ||||||
|         full_statement.append(');') |         full_statement.append(');') | ||||||
|   | |||||||
| @@ -116,6 +116,7 @@ def sql_delete(app, style): | |||||||
|         table_name_converter = lambda x: x |         table_name_converter = lambda x: x | ||||||
|  |  | ||||||
|     output = [] |     output = [] | ||||||
|  |     qn = connection.ops.quote_name | ||||||
|  |  | ||||||
|     # Output DROP TABLE statements for standard application tables. |     # Output DROP TABLE statements for standard application tables. | ||||||
|     to_delete = set() |     to_delete = set() | ||||||
| @@ -136,7 +137,7 @@ def sql_delete(app, style): | |||||||
|         if cursor and table_name_converter(model._meta.db_table) in table_names: |         if cursor and table_name_converter(model._meta.db_table) in table_names: | ||||||
|             # Drop the table now |             # Drop the table now | ||||||
|             output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'), |             output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'), | ||||||
|                 style.SQL_TABLE(backend.quote_name(model._meta.db_table)))) |                 style.SQL_TABLE(qn(model._meta.db_table)))) | ||||||
|             if backend.supports_constraints and model in references_to_delete: |             if backend.supports_constraints and model in references_to_delete: | ||||||
|                 for rel_class, f in references_to_delete[model]: |                 for rel_class, f in references_to_delete[model]: | ||||||
|                     table = rel_class._meta.db_table |                     table = rel_class._meta.db_table | ||||||
| @@ -146,7 +147,7 @@ def sql_delete(app, style): | |||||||
|                     r_name = '%s_refs_%s_%x' % (col, r_col, abs(hash((table, r_table)))) |                     r_name = '%s_refs_%s_%x' % (col, r_col, abs(hash((table, r_table)))) | ||||||
|                     output.append('%s %s %s %s;' % \ |                     output.append('%s %s %s %s;' % \ | ||||||
|                         (style.SQL_KEYWORD('ALTER TABLE'), |                         (style.SQL_KEYWORD('ALTER TABLE'), | ||||||
|                         style.SQL_TABLE(backend.quote_name(table)), |                         style.SQL_TABLE(qn(table)), | ||||||
|                         style.SQL_KEYWORD(connection.ops.drop_foreignkey_sql()), |                         style.SQL_KEYWORD(connection.ops.drop_foreignkey_sql()), | ||||||
|                         style.SQL_FIELD(truncate_name(r_name, connection.ops.max_name_length())))) |                         style.SQL_FIELD(truncate_name(r_name, connection.ops.max_name_length())))) | ||||||
|                 del references_to_delete[model] |                 del references_to_delete[model] | ||||||
| @@ -159,7 +160,7 @@ def sql_delete(app, style): | |||||||
|         for f in opts.many_to_many: |         for f in opts.many_to_many: | ||||||
|             if cursor and table_name_converter(f.m2m_db_table()) in table_names: |             if cursor and table_name_converter(f.m2m_db_table()) in table_names: | ||||||
|                 output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'), |                 output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'), | ||||||
|                     style.SQL_TABLE(backend.quote_name(f.m2m_db_table())))) |                     style.SQL_TABLE(qn(f.m2m_db_table())))) | ||||||
|                 if hasattr(backend, 'get_drop_sequence'): |                 if hasattr(backend, 'get_drop_sequence'): | ||||||
|                     output.append(backend.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column))) |                     output.append(backend.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column))) | ||||||
|  |  | ||||||
| @@ -219,6 +220,7 @@ def sql_model_create(model, style, known_models=set()): | |||||||
|     final_output = [] |     final_output = [] | ||||||
|     table_output = [] |     table_output = [] | ||||||
|     pending_references = {} |     pending_references = {} | ||||||
|  |     qn = connection.ops.quote_name | ||||||
|     for f in opts.fields: |     for f in opts.fields: | ||||||
|         col_type = f.db_type() |         col_type = f.db_type() | ||||||
|         tablespace = f.db_tablespace or opts.db_tablespace |         tablespace = f.db_tablespace or opts.db_tablespace | ||||||
| @@ -227,7 +229,7 @@ def sql_model_create(model, style, known_models=set()): | |||||||
|             # database columns in this table. |             # database columns in this table. | ||||||
|             continue |             continue | ||||||
|         # Make the definition (e.g. 'foo VARCHAR(30)') for this field. |         # Make the definition (e.g. 'foo VARCHAR(30)') for this field. | ||||||
|         field_output = [style.SQL_FIELD(backend.quote_name(f.column)), |         field_output = [style.SQL_FIELD(qn(f.column)), | ||||||
|             style.SQL_COLTYPE(col_type)] |             style.SQL_COLTYPE(col_type)] | ||||||
|         field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) |         field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) | ||||||
|         if f.unique and (not f.primary_key or backend.allows_unique_and_pk): |         if f.unique and (not f.primary_key or backend.allows_unique_and_pk): | ||||||
| @@ -241,8 +243,8 @@ def sql_model_create(model, style, known_models=set()): | |||||||
|         if f.rel: |         if f.rel: | ||||||
|             if f.rel.to in known_models: |             if f.rel.to in known_models: | ||||||
|                 field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ |                 field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ | ||||||
|                     style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \ |                     style.SQL_TABLE(qn(f.rel.to._meta.db_table)) + ' (' + \ | ||||||
|                     style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + |                     style.SQL_FIELD(qn(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + | ||||||
|                     connection.ops.deferrable_sql() |                     connection.ops.deferrable_sql() | ||||||
|                 ) |                 ) | ||||||
|             else: |             else: | ||||||
| @@ -251,14 +253,14 @@ def sql_model_create(model, style, known_models=set()): | |||||||
|                 pr = pending_references.setdefault(f.rel.to, []).append((model, f)) |                 pr = pending_references.setdefault(f.rel.to, []).append((model, f)) | ||||||
|         table_output.append(' '.join(field_output)) |         table_output.append(' '.join(field_output)) | ||||||
|     if opts.order_with_respect_to: |     if opts.order_with_respect_to: | ||||||
|         table_output.append(style.SQL_FIELD(backend.quote_name('_order')) + ' ' + \ |         table_output.append(style.SQL_FIELD(qn('_order')) + ' ' + \ | ||||||
|             style.SQL_COLTYPE(models.IntegerField().db_type()) + ' ' + \ |             style.SQL_COLTYPE(models.IntegerField().db_type()) + ' ' + \ | ||||||
|             style.SQL_KEYWORD('NULL')) |             style.SQL_KEYWORD('NULL')) | ||||||
|     for field_constraints in opts.unique_together: |     for field_constraints in opts.unique_together: | ||||||
|         table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ |         table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ | ||||||
|             ", ".join([backend.quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints])) |             ", ".join([qn(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints])) | ||||||
|  |  | ||||||
|     full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(backend.quote_name(opts.db_table)) + ' ('] |     full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(qn(opts.db_table)) + ' ('] | ||||||
|     for i, line in enumerate(table_output): # Combine and add commas. |     for i, line in enumerate(table_output): # Combine and add commas. | ||||||
|         full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) |         full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) | ||||||
|     full_statement.append(')') |     full_statement.append(')') | ||||||
| @@ -283,6 +285,7 @@ def sql_for_pending_references(model, style, pending_references): | |||||||
|     from django.db import backend, connection |     from django.db import backend, connection | ||||||
|     from django.db.backends.util import truncate_name |     from django.db.backends.util import truncate_name | ||||||
|  |  | ||||||
|  |     qn = connection.ops.quote_name | ||||||
|     final_output = [] |     final_output = [] | ||||||
|     if backend.supports_constraints: |     if backend.supports_constraints: | ||||||
|         opts = model._meta |         opts = model._meta | ||||||
| @@ -297,8 +300,8 @@ def sql_for_pending_references(model, style, pending_references): | |||||||
|                 # So we are careful with character usage here. |                 # So we are careful with character usage here. | ||||||
|                 r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table)))) |                 r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table)))) | ||||||
|                 final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \ |                 final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \ | ||||||
|                     (backend.quote_name(r_table), truncate_name(r_name, connection.ops.max_name_length()), |                     (qn(r_table), truncate_name(r_name, connection.ops.max_name_length()), | ||||||
|                     backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col), |                     qn(r_col), qn(table), qn(col), | ||||||
|                     connection.ops.deferrable_sql())) |                     connection.ops.deferrable_sql())) | ||||||
|             del pending_references[model] |             del pending_references[model] | ||||||
|     return final_output |     return final_output | ||||||
| @@ -309,6 +312,7 @@ def many_to_many_sql_for_model(model, style): | |||||||
|  |  | ||||||
|     opts = model._meta |     opts = model._meta | ||||||
|     final_output = [] |     final_output = [] | ||||||
|  |     qn = connection.ops.quote_name | ||||||
|     for f in opts.many_to_many: |     for f in opts.many_to_many: | ||||||
|         if not isinstance(f.rel, generic.GenericRel): |         if not isinstance(f.rel, generic.GenericRel): | ||||||
|             tablespace = f.db_tablespace or opts.db_tablespace |             tablespace = f.db_tablespace or opts.db_tablespace | ||||||
| @@ -317,30 +321,30 @@ def many_to_many_sql_for_model(model, style): | |||||||
|             else: |             else: | ||||||
|                 tablespace_sql = '' |                 tablespace_sql = '' | ||||||
|             table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ |             table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ | ||||||
|                 style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' ('] |                 style.SQL_TABLE(qn(f.m2m_db_table())) + ' ('] | ||||||
|             table_output.append('    %s %s %s%s,' % \ |             table_output.append('    %s %s %s%s,' % \ | ||||||
|                 (style.SQL_FIELD(backend.quote_name('id')), |                 (style.SQL_FIELD(qn('id')), | ||||||
|                 style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()), |                 style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()), | ||||||
|                 style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), |                 style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), | ||||||
|                 tablespace_sql)) |                 tablespace_sql)) | ||||||
|             table_output.append('    %s %s %s %s (%s)%s,' % \ |             table_output.append('    %s %s %s %s (%s)%s,' % \ | ||||||
|                 (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), |                 (style.SQL_FIELD(qn(f.m2m_column_name())), | ||||||
|                 style.SQL_COLTYPE(models.ForeignKey(model).db_type()), |                 style.SQL_COLTYPE(models.ForeignKey(model).db_type()), | ||||||
|                 style.SQL_KEYWORD('NOT NULL REFERENCES'), |                 style.SQL_KEYWORD('NOT NULL REFERENCES'), | ||||||
|                 style.SQL_TABLE(backend.quote_name(opts.db_table)), |                 style.SQL_TABLE(qn(opts.db_table)), | ||||||
|                 style.SQL_FIELD(backend.quote_name(opts.pk.column)), |                 style.SQL_FIELD(qn(opts.pk.column)), | ||||||
|                 connection.ops.deferrable_sql())) |                 connection.ops.deferrable_sql())) | ||||||
|             table_output.append('    %s %s %s %s (%s)%s,' % \ |             table_output.append('    %s %s %s %s (%s)%s,' % \ | ||||||
|                 (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), |                 (style.SQL_FIELD(qn(f.m2m_reverse_name())), | ||||||
|                 style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), |                 style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), | ||||||
|                 style.SQL_KEYWORD('NOT NULL REFERENCES'), |                 style.SQL_KEYWORD('NOT NULL REFERENCES'), | ||||||
|                 style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)), |                 style.SQL_TABLE(qn(f.rel.to._meta.db_table)), | ||||||
|                 style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)), |                 style.SQL_FIELD(qn(f.rel.to._meta.pk.column)), | ||||||
|                 connection.ops.deferrable_sql())) |                 connection.ops.deferrable_sql())) | ||||||
|             table_output.append('    %s (%s, %s)%s' % \ |             table_output.append('    %s (%s, %s)%s' % \ | ||||||
|                 (style.SQL_KEYWORD('UNIQUE'), |                 (style.SQL_KEYWORD('UNIQUE'), | ||||||
|                 style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), |                 style.SQL_FIELD(qn(f.m2m_column_name())), | ||||||
|                 style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), |                 style.SQL_FIELD(qn(f.m2m_reverse_name())), | ||||||
|                 tablespace_sql)) |                 tablespace_sql)) | ||||||
|             table_output.append(')') |             table_output.append(')') | ||||||
|             if opts.db_tablespace and backend.supports_tablespaces: |             if opts.db_tablespace and backend.supports_tablespaces: | ||||||
| @@ -350,7 +354,7 @@ def many_to_many_sql_for_model(model, style): | |||||||
|             final_output.append('\n'.join(table_output)) |             final_output.append('\n'.join(table_output)) | ||||||
|  |  | ||||||
|             # Add any extra SQL needed to support auto-incrementing PKs |             # Add any extra SQL needed to support auto-incrementing PKs | ||||||
|             autoinc_sql = backend.get_autoinc_sql(f.m2m_db_table()) |             autoinc_sql = connection.ops.autoinc_sql(f.m2m_db_table()) | ||||||
|             if autoinc_sql: |             if autoinc_sql: | ||||||
|                 for stmt in autoinc_sql: |                 for stmt in autoinc_sql: | ||||||
|                     final_output.append(stmt) |                     final_output.append(stmt) | ||||||
| @@ -389,6 +393,7 @@ def sql_indexes_for_model(model, style): | |||||||
|     from django.db import backend, connection |     from django.db import backend, connection | ||||||
|     output = [] |     output = [] | ||||||
|  |  | ||||||
|  |     qn = connection.ops.quote_name | ||||||
|     for f in model._meta.fields: |     for f in model._meta.fields: | ||||||
|         if f.db_index and not ((f.primary_key or f.unique) and backend.autoindexes_primary_keys): |         if f.db_index and not ((f.primary_key or f.unique) and backend.autoindexes_primary_keys): | ||||||
|             unique = f.unique and 'UNIQUE ' or '' |             unique = f.unique and 'UNIQUE ' or '' | ||||||
| @@ -399,10 +404,10 @@ def sql_indexes_for_model(model, style): | |||||||
|                 tablespace_sql = '' |                 tablespace_sql = '' | ||||||
|             output.append( |             output.append( | ||||||
|                 style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ |                 style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ | ||||||
|                 style.SQL_TABLE(backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ |                 style.SQL_TABLE(qn('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ | ||||||
|                 style.SQL_KEYWORD('ON') + ' ' + \ |                 style.SQL_KEYWORD('ON') + ' ' + \ | ||||||
|                 style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \ |                 style.SQL_TABLE(qn(model._meta.db_table)) + ' ' + \ | ||||||
|                 "(%s)" % style.SQL_FIELD(backend.quote_name(f.column)) + \ |                 "(%s)" % style.SQL_FIELD(qn(f.column)) + \ | ||||||
|                 "%s;" % tablespace_sql |                 "%s;" % tablespace_sql | ||||||
|             ) |             ) | ||||||
|     return output |     return output | ||||||
|   | |||||||
| @@ -134,6 +134,13 @@ class BaseDatabaseOperations(object): | |||||||
|         """ |         """ | ||||||
|         return 'DEFAULT' |         return 'DEFAULT' | ||||||
|  |  | ||||||
|  |     def quote_name(self, name): | ||||||
|  |         """ | ||||||
|  |         Returns a quoted version of the given table, index or column name. Does | ||||||
|  |         not quote the given name if it's already been quoted. | ||||||
|  |         """ | ||||||
|  |         raise NotImplementedError() | ||||||
|  |  | ||||||
|     def random_function_sql(self): |     def random_function_sql(self): | ||||||
|         """ |         """ | ||||||
|         Returns a SQL expression that returns a random value. |         Returns a SQL expression that returns a random value. | ||||||
|   | |||||||
| @@ -67,11 +67,16 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|         cursor.execute("SELECT %s FROM %s WHERE %s = @@IDENTITY" % (pk_name, table_name, pk_name)) |         cursor.execute("SELECT %s FROM %s WHERE %s = @@IDENTITY" % (pk_name, table_name, pk_name)) | ||||||
|         return cursor.fetchone()[0] |         return cursor.fetchone()[0] | ||||||
|  |  | ||||||
|  |     def quote_name(self, name): | ||||||
|  |         if name.startswith('[') and name.endswith(']'): | ||||||
|  |             return name # Quoting once is enough. | ||||||
|  |         return '[%s]' % name | ||||||
|  |  | ||||||
|     def random_function_sql(self): |     def random_function_sql(self): | ||||||
|         return 'RAND()' |         return 'RAND()' | ||||||
|  |  | ||||||
|     def tablespace_sql(self, tablespace, inline=False): |     def tablespace_sql(self, tablespace, inline=False): | ||||||
|         return "ON %s" % quote_name(tablespace) |         return "ON %s" % self.quote_name(tablespace) | ||||||
|  |  | ||||||
| class DatabaseWrapper(BaseDatabaseWrapper): | class DatabaseWrapper(BaseDatabaseWrapper): | ||||||
|     ops = DatabaseOperations() |     ops = DatabaseOperations() | ||||||
| @@ -97,11 +102,6 @@ supports_constraints = True | |||||||
| supports_tablespaces = True | supports_tablespaces = True | ||||||
| uses_case_insensitive_names = False | uses_case_insensitive_names = False | ||||||
|  |  | ||||||
| def quote_name(name): |  | ||||||
|     if name.startswith('[') and name.endswith(']'): |  | ||||||
|         return name # Quoting once is enough. |  | ||||||
|     return '[%s]' % name |  | ||||||
|  |  | ||||||
| dictfetchone = util.dictfetchone | dictfetchone = util.dictfetchone | ||||||
| dictfetchmany = util.dictfetchmany | dictfetchmany = util.dictfetchmany | ||||||
| dictfetchall  = util.dictfetchall | dictfetchall  = util.dictfetchall | ||||||
|   | |||||||
| @@ -39,7 +39,6 @@ class DatabaseWrapper(object): | |||||||
|  |  | ||||||
| supports_constraints = False | supports_constraints = False | ||||||
| supports_tablespaces = False | supports_tablespaces = False | ||||||
| quote_name = complain |  | ||||||
| dictfetchone = complain | dictfetchone = complain | ||||||
| dictfetchmany = complain | dictfetchmany = complain | ||||||
| dictfetchall = complain | dictfetchall = complain | ||||||
|   | |||||||
| @@ -84,6 +84,11 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|             sql += "%s," % offset |             sql += "%s," % offset | ||||||
|         return sql + str(limit) |         return sql + str(limit) | ||||||
|  |  | ||||||
|  |     def quote_name(self, name): | ||||||
|  |         if name.startswith("`") and name.endswith("`"): | ||||||
|  |             return name # Quoting once is enough. | ||||||
|  |         return "`%s`" % name | ||||||
|  |  | ||||||
|     def random_function_sql(self): |     def random_function_sql(self): | ||||||
|         return 'RAND()' |         return 'RAND()' | ||||||
|  |  | ||||||
| @@ -94,7 +99,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|         if tables: |         if tables: | ||||||
|             sql = ['SET FOREIGN_KEY_CHECKS = 0;'] |             sql = ['SET FOREIGN_KEY_CHECKS = 0;'] | ||||||
|             for table in tables: |             for table in tables: | ||||||
|                 sql.append('%s %s;' % (style.SQL_KEYWORD('TRUNCATE'), style.SQL_FIELD(quote_name(table)))) |                 sql.append('%s %s;' % (style.SQL_KEYWORD('TRUNCATE'), style.SQL_FIELD(self.quote_name(table)))) | ||||||
|             sql.append('SET FOREIGN_KEY_CHECKS = 1;') |             sql.append('SET FOREIGN_KEY_CHECKS = 1;') | ||||||
|  |  | ||||||
|             # 'ALTER TABLE table AUTO_INCREMENT = 1;'... style SQL statements |             # 'ALTER TABLE table AUTO_INCREMENT = 1;'... style SQL statements | ||||||
| @@ -102,7 +107,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|             sql.extend(["%s %s %s %s %s;" % \ |             sql.extend(["%s %s %s %s %s;" % \ | ||||||
|                 (style.SQL_KEYWORD('ALTER'), |                 (style.SQL_KEYWORD('ALTER'), | ||||||
|                  style.SQL_KEYWORD('TABLE'), |                  style.SQL_KEYWORD('TABLE'), | ||||||
|                  style.SQL_TABLE(quote_name(sequence['table'])), |                  style.SQL_TABLE(self.quote_name(sequence['table'])), | ||||||
|                  style.SQL_KEYWORD('AUTO_INCREMENT'), |                  style.SQL_KEYWORD('AUTO_INCREMENT'), | ||||||
|                  style.SQL_FIELD('= 1'), |                  style.SQL_FIELD('= 1'), | ||||||
|                 ) for sequence in sequences]) |                 ) for sequence in sequences]) | ||||||
| @@ -179,11 +184,6 @@ supports_constraints = True | |||||||
| supports_tablespaces = False | supports_tablespaces = False | ||||||
| uses_case_insensitive_names = False | uses_case_insensitive_names = False | ||||||
|  |  | ||||||
| def quote_name(name): |  | ||||||
|     if name.startswith("`") and name.endswith("`"): |  | ||||||
|         return name # Quoting once is enough. |  | ||||||
|     return "`%s`" % name |  | ||||||
|  |  | ||||||
| dictfetchone = util.dictfetchone | dictfetchone = util.dictfetchone | ||||||
| dictfetchmany = util.dictfetchmany | dictfetchmany = util.dictfetchmany | ||||||
| dictfetchall  = util.dictfetchall | dictfetchall  = util.dictfetchall | ||||||
|   | |||||||
| @@ -1,8 +1,9 @@ | |||||||
| from django.db.backends.mysql.base import quote_name | from django.db.backends.mysql.base import DatabaseOperations | ||||||
| from MySQLdb import ProgrammingError, OperationalError | from MySQLdb import ProgrammingError, OperationalError | ||||||
| from MySQLdb.constants import FIELD_TYPE | from MySQLdb.constants import FIELD_TYPE | ||||||
| import re | import re | ||||||
|  |  | ||||||
|  | quote_name = DatabaseOperations().quote_name | ||||||
| foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") | foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") | ||||||
|  |  | ||||||
| def get_table_list(cursor): | def get_table_list(cursor): | ||||||
|   | |||||||
| @@ -94,6 +94,11 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|             sql += "%s," % offset |             sql += "%s," % offset | ||||||
|         return sql + str(limit) |         return sql + str(limit) | ||||||
|  |  | ||||||
|  |     def quote_name(self, name): | ||||||
|  |         if name.startswith("`") and name.endswith("`"): | ||||||
|  |             return name # Quoting once is enough. | ||||||
|  |         return "`%s`" % name | ||||||
|  |  | ||||||
|     def random_function_sql(self): |     def random_function_sql(self): | ||||||
|         return 'RAND()' |         return 'RAND()' | ||||||
|  |  | ||||||
| @@ -104,7 +109,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|         if tables: |         if tables: | ||||||
|             sql = ['SET FOREIGN_KEY_CHECKS = 0;'] |             sql = ['SET FOREIGN_KEY_CHECKS = 0;'] | ||||||
|             for table in tables: |             for table in tables: | ||||||
|                 sql.append('%s %s;' % (style.SQL_KEYWORD('TRUNCATE'), style.SQL_FIELD(quote_name(table)))) |                 sql.append('%s %s;' % (style.SQL_KEYWORD('TRUNCATE'), style.SQL_FIELD(self.quote_name(table)))) | ||||||
|             sql.append('SET FOREIGN_KEY_CHECKS = 1;') |             sql.append('SET FOREIGN_KEY_CHECKS = 1;') | ||||||
|  |  | ||||||
|             # 'ALTER TABLE table AUTO_INCREMENT = 1;'... style SQL statements |             # 'ALTER TABLE table AUTO_INCREMENT = 1;'... style SQL statements | ||||||
| @@ -112,7 +117,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|             sql.extend(["%s %s %s %s %s;" % \ |             sql.extend(["%s %s %s %s %s;" % \ | ||||||
|                 (style.SQL_KEYWORD('ALTER'), |                 (style.SQL_KEYWORD('ALTER'), | ||||||
|                  style.SQL_KEYWORD('TABLE'), |                  style.SQL_KEYWORD('TABLE'), | ||||||
|                  style.SQL_TABLE(quote_name(sequence['table'])), |                  style.SQL_TABLE(self.quote_name(sequence['table'])), | ||||||
|                  style.SQL_KEYWORD('AUTO_INCREMENT'), |                  style.SQL_KEYWORD('AUTO_INCREMENT'), | ||||||
|                  style.SQL_FIELD('= 1'), |                  style.SQL_FIELD('= 1'), | ||||||
|                 ) for sequence in sequences]) |                 ) for sequence in sequences]) | ||||||
| @@ -198,11 +203,6 @@ supports_constraints = True | |||||||
| supports_tablespaces = False | supports_tablespaces = False | ||||||
| uses_case_insensitive_names = False | uses_case_insensitive_names = False | ||||||
|  |  | ||||||
| def quote_name(name): |  | ||||||
|     if name.startswith("`") and name.endswith("`"): |  | ||||||
|         return name # Quoting once is enough. |  | ||||||
|     return "`%s`" % name |  | ||||||
|  |  | ||||||
| dictfetchone = util.dictfetchone | dictfetchone = util.dictfetchone | ||||||
| dictfetchmany = util.dictfetchmany | dictfetchmany = util.dictfetchmany | ||||||
| dictfetchall  = util.dictfetchall | dictfetchall  = util.dictfetchall | ||||||
|   | |||||||
| @@ -1,8 +1,9 @@ | |||||||
| from django.db.backends.mysql_old.base import quote_name | from django.db.backends.mysql_old.base import DatabaseOperations | ||||||
| from MySQLdb import ProgrammingError, OperationalError | from MySQLdb import ProgrammingError, OperationalError | ||||||
| from MySQLdb.constants import FIELD_TYPE | from MySQLdb.constants import FIELD_TYPE | ||||||
| import re | import re | ||||||
|  |  | ||||||
|  | quote_name = DatabaseOperations().quote_name | ||||||
| foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") | foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") | ||||||
|  |  | ||||||
| def get_table_list(cursor): | def get_table_list(cursor): | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|             WHEN (new.id IS NULL) |             WHEN (new.id IS NULL) | ||||||
|                 BEGIN |                 BEGIN | ||||||
|                     SELECT %s.nextval INTO :new.id FROM dual; |                     SELECT %s.nextval INTO :new.id FROM dual; | ||||||
|                 END;/""" % (tr_name, quote_name(table), sq_name) |                 END;/""" % (tr_name, self.quote_name(table), sq_name) | ||||||
|         return sequence_sql, trigger_sql |         return sequence_sql, trigger_sql | ||||||
|  |  | ||||||
|     def date_extract_sql(self, lookup_type, field_name): |     def date_extract_sql(self, lookup_type, field_name): | ||||||
| @@ -70,6 +70,15 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|     def max_name_length(self): |     def max_name_length(self): | ||||||
|         return 30 |         return 30 | ||||||
|  |  | ||||||
|  |     def quote_name(self, name): | ||||||
|  |         # SQL92 requires delimited (quoted) names to be case-sensitive.  When | ||||||
|  |         # not quoted, Oracle has case-insensitive behavior for identifiers, but | ||||||
|  |         # always defaults to uppercase. | ||||||
|  |         # We simplify things by making Oracle identifiers always uppercase. | ||||||
|  |         if not name.startswith('"') and not name.endswith('"'): | ||||||
|  |             name = '"%s"' % util.truncate_name(name.upper(), DatabaseOperations().max_name_length()) | ||||||
|  |         return name.upper() | ||||||
|  |  | ||||||
|     def random_function_sql(self): |     def random_function_sql(self): | ||||||
|         return "DBMS_RANDOM.RANDOM" |         return "DBMS_RANDOM.RANDOM" | ||||||
|  |  | ||||||
| @@ -82,14 +91,14 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|             sql = ['%s %s %s;' % \ |             sql = ['%s %s %s;' % \ | ||||||
|                     (style.SQL_KEYWORD('DELETE'), |                     (style.SQL_KEYWORD('DELETE'), | ||||||
|                      style.SQL_KEYWORD('FROM'), |                      style.SQL_KEYWORD('FROM'), | ||||||
|                      style.SQL_FIELD(quote_name(table)) |                      style.SQL_FIELD(self.quote_name(table)) | ||||||
|                      ) for table in tables] |                      ) for table in tables] | ||||||
|             # Since we've just deleted all the rows, running our sequence |             # Since we've just deleted all the rows, running our sequence | ||||||
|             # ALTER code will reset the sequence to 0. |             # ALTER code will reset the sequence to 0. | ||||||
|             for sequence_info in sequences: |             for sequence_info in sequences: | ||||||
|                 table_name = sequence_info['table'] |                 table_name = sequence_info['table'] | ||||||
|                 seq_name = get_sequence_name(table_name) |                 seq_name = get_sequence_name(table_name) | ||||||
|                 query = _get_sequence_reset_sql() % {'sequence':seq_name, 'table':quote_name(table_name)} |                 query = _get_sequence_reset_sql() % {'sequence': seq_name, 'table': self.quote_name(table_name)} | ||||||
|                 sql.append(query) |                 sql.append(query) | ||||||
|             return sql |             return sql | ||||||
|         else: |         else: | ||||||
| @@ -116,7 +125,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|         return '' |         return '' | ||||||
|  |  | ||||||
|     def tablespace_sql(self, tablespace, inline=False): |     def tablespace_sql(self, tablespace, inline=False): | ||||||
|         return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), quote_name(tablespace)) |         return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), self.quote_name(tablespace)) | ||||||
|  |  | ||||||
| class DatabaseWrapper(BaseDatabaseWrapper): | class DatabaseWrapper(BaseDatabaseWrapper): | ||||||
|     ops = DatabaseOperations() |     ops = DatabaseOperations() | ||||||
| @@ -215,15 +224,6 @@ def to_unicode(s): | |||||||
|         return force_unicode(s) |         return force_unicode(s) | ||||||
|     return s |     return s | ||||||
|  |  | ||||||
| def quote_name(name): |  | ||||||
|     # SQL92 requires delimited (quoted) names to be case-sensitive.  When |  | ||||||
|     # not quoted, Oracle has case-insensitive behavior for identifiers, but |  | ||||||
|     # always defaults to uppercase. |  | ||||||
|     # We simplify things by making Oracle identifiers always uppercase. |  | ||||||
|     if not name.startswith('"') and not name.endswith('"'): |  | ||||||
|         name = '"%s"' % util.truncate_name(name.upper(), DatabaseOperations().max_name_length()) |  | ||||||
|     return name.upper() |  | ||||||
|  |  | ||||||
| dictfetchone = util.dictfetchone | dictfetchone = util.dictfetchone | ||||||
| dictfetchmany = util.dictfetchmany | dictfetchmany = util.dictfetchmany | ||||||
| dictfetchall  = util.dictfetchall | dictfetchall  = util.dictfetchall | ||||||
| @@ -235,7 +235,7 @@ def get_field_cast_sql(db_type): | |||||||
|         return "%s%s" |         return "%s%s" | ||||||
|  |  | ||||||
| def get_drop_sequence(table): | def get_drop_sequence(table): | ||||||
|     return "DROP SEQUENCE %s;" % quote_name(get_sequence_name(table)) |     return "DROP SEQUENCE %s;" % DatabaseOperations().quote_name(get_sequence_name(table)) | ||||||
|  |  | ||||||
| def _get_sequence_reset_sql(): | def _get_sequence_reset_sql(): | ||||||
|     # TODO: colorize this SQL code with style.SQL_KEYWORD(), etc. |     # TODO: colorize this SQL code with style.SQL_KEYWORD(), etc. | ||||||
| @@ -328,9 +328,10 @@ def get_query_set_class(DefaultQuerySet): | |||||||
|                 handle_legacy_orderlist, orderfield2column |                 handle_legacy_orderlist, orderfield2column | ||||||
|  |  | ||||||
|             opts = self.model._meta |             opts = self.model._meta | ||||||
|  |             qn = connection.ops.quote_name | ||||||
|  |  | ||||||
|             # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z. |             # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z. | ||||||
|             select = ["%s.%s" % (backend.quote_name(opts.db_table), backend.quote_name(f.column)) for f in opts.fields] |             select = ["%s.%s" % (qn(opts.db_table), qn(f.column)) for f in opts.fields] | ||||||
|             tables = [quote_only_if_word(t) for t in self._tables] |             tables = [quote_only_if_word(t) for t in self._tables] | ||||||
|             joins = SortedDict() |             joins = SortedDict() | ||||||
|             where = self._where[:] |             where = self._where[:] | ||||||
| @@ -348,10 +349,10 @@ def get_query_set_class(DefaultQuerySet): | |||||||
|  |  | ||||||
|             # Add any additional SELECTs. |             # Add any additional SELECTs. | ||||||
|             if self._select: |             if self._select: | ||||||
|                 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()]) |                 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), qn(s[0])) for s in self._select.items()]) | ||||||
|  |  | ||||||
|             # Start composing the body of the SQL statement. |             # Start composing the body of the SQL statement. | ||||||
|             sql = [" FROM", backend.quote_name(opts.db_table)] |             sql = [" FROM", qn(opts.db_table)] | ||||||
|  |  | ||||||
|             # Compose the join dictionary into SQL describing the joins. |             # Compose the join dictionary into SQL describing the joins. | ||||||
|             if joins: |             if joins: | ||||||
| @@ -384,15 +385,15 @@ def get_query_set_class(DefaultQuerySet): | |||||||
|                         order = "ASC" |                         order = "ASC" | ||||||
|                     if "." in col_name: |                     if "." in col_name: | ||||||
|                         table_prefix, col_name = col_name.split('.', 1) |                         table_prefix, col_name = col_name.split('.', 1) | ||||||
|                         table_prefix = backend.quote_name(table_prefix) + '.' |                         table_prefix = qn(table_prefix) + '.' | ||||||
|                     else: |                     else: | ||||||
|                         # Use the database table as a column prefix if it wasn't given, |                         # Use the database table as a column prefix if it wasn't given, | ||||||
|                         # and if the requested column isn't a custom SELECT. |                         # and if the requested column isn't a custom SELECT. | ||||||
|                         if "." not in col_name and col_name not in (self._select or ()): |                         if "." not in col_name and col_name not in (self._select or ()): | ||||||
|                             table_prefix = backend.quote_name(opts.db_table) + '.' |                             table_prefix = qn(opts.db_table) + '.' | ||||||
|                         else: |                         else: | ||||||
|                             table_prefix = '' |                             table_prefix = '' | ||||||
|                     order_by.append('%s%s %s' % (table_prefix, backend.quote_name(orderfield2column(col_name, opts)), order)) |                     order_by.append('%s%s %s' % (table_prefix, qn(orderfield2column(col_name, opts)), order)) | ||||||
|             if order_by: |             if order_by: | ||||||
|                 sql.append("ORDER BY " + ", ".join(order_by)) |                 sql.append("ORDER BY " + ", ".join(order_by)) | ||||||
|  |  | ||||||
| @@ -417,8 +418,7 @@ def get_query_set_class(DefaultQuerySet): | |||||||
|                 #Oracle's row_number() function always requires an order-by clause. |                 #Oracle's row_number() function always requires an order-by clause. | ||||||
|                 #So we need to define a default order-by, since none was provided. |                 #So we need to define a default order-by, since none was provided. | ||||||
|                 order_by_clause = " OVER (ORDER BY %s.%s)" % \ |                 order_by_clause = " OVER (ORDER BY %s.%s)" % \ | ||||||
|                     (backend.quote_name(opts.db_table), |                     (qn(opts.db_table), qn(opts.fields[0].db_column or opts.fields[0].column)) | ||||||
|                     backend.quote_name(opts.fields[0].db_column or opts.fields[0].column)) |  | ||||||
|             # limit_and_offset_clause |             # limit_and_offset_clause | ||||||
|             if self._limit is None: |             if self._limit is None: | ||||||
|                 assert self._offset is None, "'offset' is not allowed without 'limit'" |                 assert self._offset is None, "'offset' is not allowed without 'limit'" | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| from django.db.backends.oracle.base import quote_name | from django.db.backends.oracle.base import DatabaseOperations | ||||||
| import re | import re | ||||||
| import cx_Oracle | import cx_Oracle | ||||||
|  |  | ||||||
|  | quote_name = DatabaseOperations().quote_name | ||||||
| foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") | foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") | ||||||
|  |  | ||||||
| def get_table_list(cursor): | def get_table_list(cursor): | ||||||
|   | |||||||
| @@ -73,6 +73,11 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|         cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name)) |         cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name)) | ||||||
|         return cursor.fetchone()[0] |         return cursor.fetchone()[0] | ||||||
|  |  | ||||||
|  |     def quote_name(self, name): | ||||||
|  |         if name.startswith('"') and name.endswith('"'): | ||||||
|  |             return name # Quoting once is enough. | ||||||
|  |         return '"%s"' % name | ||||||
|  |  | ||||||
|     def sql_flush(self, style, tables, sequences): |     def sql_flush(self, style, tables, sequences): | ||||||
|         if tables: |         if tables: | ||||||
|             if postgres_version[0] >= 8 and postgres_version[1] >= 1: |             if postgres_version[0] >= 8 and postgres_version[1] >= 1: | ||||||
| @@ -82,7 +87,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                 # statement. |                 # statement. | ||||||
|                 sql = ['%s %s;' % \ |                 sql = ['%s %s;' % \ | ||||||
|                     (style.SQL_KEYWORD('TRUNCATE'), |                     (style.SQL_KEYWORD('TRUNCATE'), | ||||||
|                      style.SQL_FIELD(', '.join([quote_name(table) for table in tables])) |                      style.SQL_FIELD(', '.join([self.quote_name(table) for table in tables])) | ||||||
|                 )] |                 )] | ||||||
|             else: |             else: | ||||||
|                 # Older versions of Postgres can't do TRUNCATE in a single call, so |                 # Older versions of Postgres can't do TRUNCATE in a single call, so | ||||||
| @@ -90,7 +95,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                 sql = ['%s %s %s;' % \ |                 sql = ['%s %s %s;' % \ | ||||||
|                         (style.SQL_KEYWORD('DELETE'), |                         (style.SQL_KEYWORD('DELETE'), | ||||||
|                          style.SQL_KEYWORD('FROM'), |                          style.SQL_KEYWORD('FROM'), | ||||||
|                          style.SQL_FIELD(quote_name(table)) |                          style.SQL_FIELD(self.quote_name(table)) | ||||||
|                          ) for table in tables] |                          ) for table in tables] | ||||||
|  |  | ||||||
|             # 'ALTER SEQUENCE sequence_name RESTART WITH 1;'... style SQL statements |             # 'ALTER SEQUENCE sequence_name RESTART WITH 1;'... style SQL statements | ||||||
| @@ -103,7 +108,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                     sql.append("%s %s %s %s %s %s;" % \ |                     sql.append("%s %s %s %s %s %s;" % \ | ||||||
|                         (style.SQL_KEYWORD('ALTER'), |                         (style.SQL_KEYWORD('ALTER'), | ||||||
|                         style.SQL_KEYWORD('SEQUENCE'), |                         style.SQL_KEYWORD('SEQUENCE'), | ||||||
|                         style.SQL_FIELD(quote_name('%s_%s_seq' % (table_name, column_name))), |                         style.SQL_FIELD(self.quote_name('%s_%s_seq' % (table_name, column_name))), | ||||||
|                         style.SQL_KEYWORD('RESTART'), |                         style.SQL_KEYWORD('RESTART'), | ||||||
|                         style.SQL_KEYWORD('WITH'), |                         style.SQL_KEYWORD('WITH'), | ||||||
|                         style.SQL_FIELD('1') |                         style.SQL_FIELD('1') | ||||||
| @@ -114,7 +119,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                     sql.append("%s %s %s %s %s %s;" % \ |                     sql.append("%s %s %s %s %s %s;" % \ | ||||||
|                         (style.SQL_KEYWORD('ALTER'), |                         (style.SQL_KEYWORD('ALTER'), | ||||||
|                          style.SQL_KEYWORD('SEQUENCE'), |                          style.SQL_KEYWORD('SEQUENCE'), | ||||||
|                          style.SQL_FIELD(quote_name('%s_id_seq' % table_name)), |                          style.SQL_FIELD(self.quote_name('%s_id_seq' % table_name)), | ||||||
|                          style.SQL_KEYWORD('RESTART'), |                          style.SQL_KEYWORD('RESTART'), | ||||||
|                          style.SQL_KEYWORD('WITH'), |                          style.SQL_KEYWORD('WITH'), | ||||||
|                          style.SQL_FIELD('1') |                          style.SQL_FIELD('1') | ||||||
| @@ -127,6 +132,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|     def sequence_reset_sql(self, style, model_list): |     def sequence_reset_sql(self, style, model_list): | ||||||
|         from django.db import models |         from django.db import models | ||||||
|         output = [] |         output = [] | ||||||
|  |         qn = self.quote_name | ||||||
|         for model in model_list: |         for model in model_list: | ||||||
|             # Use `coalesce` to set the sequence for each model to the max pk value if there are records, |             # Use `coalesce` to set the sequence for each model to the max pk value if there are records, | ||||||
|             # or 1 if there are none. Set the `is_called` property (the third argument to `setval`) to true |             # or 1 if there are none. Set the `is_called` property (the third argument to `setval`) to true | ||||||
| @@ -135,19 +141,19 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                 if isinstance(f, models.AutoField): |                 if isinstance(f, models.AutoField): | ||||||
|                     output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ |                     output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ | ||||||
|                         (style.SQL_KEYWORD('SELECT'), |                         (style.SQL_KEYWORD('SELECT'), | ||||||
|                         style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))), |                         style.SQL_FIELD(qn('%s_%s_seq' % (model._meta.db_table, f.column))), | ||||||
|                         style.SQL_FIELD(quote_name(f.column)), |                         style.SQL_FIELD(qn(f.column)), | ||||||
|                         style.SQL_FIELD(quote_name(f.column)), |                         style.SQL_FIELD(qn(f.column)), | ||||||
|                         style.SQL_KEYWORD('IS NOT'), |                         style.SQL_KEYWORD('IS NOT'), | ||||||
|                         style.SQL_KEYWORD('FROM'), |                         style.SQL_KEYWORD('FROM'), | ||||||
|                         style.SQL_TABLE(quote_name(model._meta.db_table)))) |                         style.SQL_TABLE(qn(model._meta.db_table)))) | ||||||
|                     break # Only one AutoField is allowed per model, so don't bother continuing. |                     break # Only one AutoField is allowed per model, so don't bother continuing. | ||||||
|             for f in model._meta.many_to_many: |             for f in model._meta.many_to_many: | ||||||
|                 output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ |                 output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ | ||||||
|                     (style.SQL_KEYWORD('SELECT'), |                     (style.SQL_KEYWORD('SELECT'), | ||||||
|                     style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())), |                     style.SQL_FIELD(qn('%s_id_seq' % f.m2m_db_table())), | ||||||
|                     style.SQL_FIELD(quote_name('id')), |                     style.SQL_FIELD(qn('id')), | ||||||
|                     style.SQL_FIELD(quote_name('id')), |                     style.SQL_FIELD(qn('id')), | ||||||
|                     style.SQL_KEYWORD('IS NOT'), |                     style.SQL_KEYWORD('IS NOT'), | ||||||
|                     style.SQL_KEYWORD('FROM'), |                     style.SQL_KEYWORD('FROM'), | ||||||
|                     style.SQL_TABLE(f.m2m_db_table()))) |                     style.SQL_TABLE(f.m2m_db_table()))) | ||||||
| @@ -194,11 +200,6 @@ supports_constraints = True | |||||||
| supports_tablespaces = False | supports_tablespaces = False | ||||||
| uses_case_insensitive_names = False | uses_case_insensitive_names = False | ||||||
|  |  | ||||||
| def quote_name(name): |  | ||||||
|     if name.startswith('"') and name.endswith('"'): |  | ||||||
|         return name # Quoting once is enough. |  | ||||||
|     return '"%s"' % name |  | ||||||
|  |  | ||||||
| def dictfetchone(cursor): | def dictfetchone(cursor): | ||||||
|     "Returns a row from the cursor as a dict" |     "Returns a row from the cursor as a dict" | ||||||
|     return cursor.dictfetchone() |     return cursor.dictfetchone() | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
| from django.db.backends.postgresql.base import quote_name | from django.db.backends.postgresql.base import DatabaseOperations | ||||||
|  |  | ||||||
|  | quote_name = DatabaseOperations().quote_name | ||||||
|  |  | ||||||
| def get_table_list(cursor): | def get_table_list(cursor): | ||||||
|     "Returns a list of table names in the current database." |     "Returns a list of table names in the current database." | ||||||
|   | |||||||
| @@ -35,7 +35,13 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|         cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name)) |         cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name)) | ||||||
|         return cursor.fetchone()[0] |         return cursor.fetchone()[0] | ||||||
|  |  | ||||||
|  |     def quote_name(self, name): | ||||||
|  |         if name.startswith('"') and name.endswith('"'): | ||||||
|  |             return name # Quoting once is enough. | ||||||
|  |         return '"%s"' % name | ||||||
|  |  | ||||||
|     def sql_flush(self, style, tables, sequences): |     def sql_flush(self, style, tables, sequences): | ||||||
|  |         qn = self.quote_name | ||||||
|         if tables: |         if tables: | ||||||
|             if postgres_version[0] >= 8 and postgres_version[1] >= 1: |             if postgres_version[0] >= 8 and postgres_version[1] >= 1: | ||||||
|                 # Postgres 8.1+ can do 'TRUNCATE x, y, z...;'. In fact, it *has to* |                 # Postgres 8.1+ can do 'TRUNCATE x, y, z...;'. In fact, it *has to* | ||||||
| @@ -44,7 +50,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                 # statement. |                 # statement. | ||||||
|                 sql = ['%s %s;' % \ |                 sql = ['%s %s;' % \ | ||||||
|                     (style.SQL_KEYWORD('TRUNCATE'), |                     (style.SQL_KEYWORD('TRUNCATE'), | ||||||
|                      style.SQL_FIELD(', '.join([quote_name(table) for table in tables])) |                      style.SQL_FIELD(', '.join([qn(table) for table in tables])) | ||||||
|                 )] |                 )] | ||||||
|             else: |             else: | ||||||
|                 # Older versions of Postgres can't do TRUNCATE in a single call, so |                 # Older versions of Postgres can't do TRUNCATE in a single call, so | ||||||
| @@ -52,7 +58,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                 sql = ['%s %s %s;' % \ |                 sql = ['%s %s %s;' % \ | ||||||
|                         (style.SQL_KEYWORD('DELETE'), |                         (style.SQL_KEYWORD('DELETE'), | ||||||
|                          style.SQL_KEYWORD('FROM'), |                          style.SQL_KEYWORD('FROM'), | ||||||
|                          style.SQL_FIELD(quote_name(table)) |                          style.SQL_FIELD(qn(table)) | ||||||
|                          ) for table in tables] |                          ) for table in tables] | ||||||
|  |  | ||||||
|             # 'ALTER SEQUENCE sequence_name RESTART WITH 1;'... style SQL statements |             # 'ALTER SEQUENCE sequence_name RESTART WITH 1;'... style SQL statements | ||||||
| @@ -65,7 +71,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                     sql.append("%s %s %s %s %s %s;" % \ |                     sql.append("%s %s %s %s %s %s;" % \ | ||||||
|                         (style.SQL_KEYWORD('ALTER'), |                         (style.SQL_KEYWORD('ALTER'), | ||||||
|                         style.SQL_KEYWORD('SEQUENCE'), |                         style.SQL_KEYWORD('SEQUENCE'), | ||||||
|                         style.SQL_FIELD(quote_name('%s_%s_seq' % (table_name, column_name))), |                         style.SQL_FIELD(qn('%s_%s_seq' % (table_name, column_name))), | ||||||
|                         style.SQL_KEYWORD('RESTART'), |                         style.SQL_KEYWORD('RESTART'), | ||||||
|                         style.SQL_KEYWORD('WITH'), |                         style.SQL_KEYWORD('WITH'), | ||||||
|                         style.SQL_FIELD('1') |                         style.SQL_FIELD('1') | ||||||
| @@ -76,7 +82,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                     sql.append("%s %s %s %s %s %s;" % \ |                     sql.append("%s %s %s %s %s %s;" % \ | ||||||
|                         (style.SQL_KEYWORD('ALTER'), |                         (style.SQL_KEYWORD('ALTER'), | ||||||
|                          style.SQL_KEYWORD('SEQUENCE'), |                          style.SQL_KEYWORD('SEQUENCE'), | ||||||
|                          style.SQL_FIELD(quote_name('%s_id_seq' % table_name)), |                          style.SQL_FIELD(qn('%s_id_seq' % table_name)), | ||||||
|                          style.SQL_KEYWORD('RESTART'), |                          style.SQL_KEYWORD('RESTART'), | ||||||
|                          style.SQL_KEYWORD('WITH'), |                          style.SQL_KEYWORD('WITH'), | ||||||
|                          style.SQL_FIELD('1') |                          style.SQL_FIELD('1') | ||||||
| @@ -88,6 +94,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|  |  | ||||||
|     def sequence_reset_sql(self, style, model_list): |     def sequence_reset_sql(self, style, model_list): | ||||||
|         from django.db import models |         from django.db import models | ||||||
|  |         qn = self.quote_name | ||||||
|         output = [] |         output = [] | ||||||
|         for model in model_list: |         for model in model_list: | ||||||
|             # Use `coalesce` to set the sequence for each model to the max pk value if there are records, |             # Use `coalesce` to set the sequence for each model to the max pk value if there are records, | ||||||
| @@ -97,19 +104,19 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|                 if isinstance(f, models.AutoField): |                 if isinstance(f, models.AutoField): | ||||||
|                     output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ |                     output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ | ||||||
|                         (style.SQL_KEYWORD('SELECT'), |                         (style.SQL_KEYWORD('SELECT'), | ||||||
|                         style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))), |                         style.SQL_FIELD(qn('%s_%s_seq' % (model._meta.db_table, f.column))), | ||||||
|                         style.SQL_FIELD(quote_name(f.column)), |                         style.SQL_FIELD(qn(f.column)), | ||||||
|                         style.SQL_FIELD(quote_name(f.column)), |                         style.SQL_FIELD(qn(f.column)), | ||||||
|                         style.SQL_KEYWORD('IS NOT'), |                         style.SQL_KEYWORD('IS NOT'), | ||||||
|                         style.SQL_KEYWORD('FROM'), |                         style.SQL_KEYWORD('FROM'), | ||||||
|                         style.SQL_TABLE(quote_name(model._meta.db_table)))) |                         style.SQL_TABLE(qn(model._meta.db_table)))) | ||||||
|                     break # Only one AutoField is allowed per model, so don't bother continuing. |                     break # Only one AutoField is allowed per model, so don't bother continuing. | ||||||
|             for f in model._meta.many_to_many: |             for f in model._meta.many_to_many: | ||||||
|                 output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ |                 output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ | ||||||
|                     (style.SQL_KEYWORD('SELECT'), |                     (style.SQL_KEYWORD('SELECT'), | ||||||
|                     style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())), |                     style.SQL_FIELD(qn('%s_id_seq' % f.m2m_db_table())), | ||||||
|                     style.SQL_FIELD(quote_name('id')), |                     style.SQL_FIELD(qn('id')), | ||||||
|                     style.SQL_FIELD(quote_name('id')), |                     style.SQL_FIELD(qn('id')), | ||||||
|                     style.SQL_KEYWORD('IS NOT'), |                     style.SQL_KEYWORD('IS NOT'), | ||||||
|                     style.SQL_KEYWORD('FROM'), |                     style.SQL_KEYWORD('FROM'), | ||||||
|                     style.SQL_TABLE(f.m2m_db_table()))) |                     style.SQL_TABLE(f.m2m_db_table()))) | ||||||
| @@ -156,11 +163,6 @@ supports_constraints = True | |||||||
| supports_tablespaces = False | supports_tablespaces = False | ||||||
| uses_case_insensitive_names = False | uses_case_insensitive_names = False | ||||||
|  |  | ||||||
| def quote_name(name): |  | ||||||
|     if name.startswith('"') and name.endswith('"'): |  | ||||||
|         return name # Quoting once is enough. |  | ||||||
|     return '"%s"' % name |  | ||||||
|  |  | ||||||
| dictfetchone = util.dictfetchone | dictfetchone = util.dictfetchone | ||||||
| dictfetchmany = util.dictfetchmany | dictfetchmany = util.dictfetchmany | ||||||
| dictfetchall = util.dictfetchall | dictfetchall = util.dictfetchall | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
| from django.db.backends.postgresql_psycopg2.base import quote_name | from django.db.backends.postgresql_psycopg2.base import DatabaseOperations | ||||||
|  |  | ||||||
|  | quote_name = DatabaseOperations().quote_name | ||||||
|  |  | ||||||
| def get_table_list(cursor): | def get_table_list(cursor): | ||||||
|     "Returns a list of table names in the current database." |     "Returns a list of table names in the current database." | ||||||
|   | |||||||
| @@ -51,6 +51,11 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|     def pk_default_value(self): |     def pk_default_value(self): | ||||||
|         return 'NULL' |         return 'NULL' | ||||||
|  |  | ||||||
|  |     def quote_name(self, name): | ||||||
|  |         if name.startswith('"') and name.endswith('"'): | ||||||
|  |             return name # Quoting once is enough. | ||||||
|  |         return '"%s"' % name | ||||||
|  |  | ||||||
|     def sql_flush(self, style, tables, sequences): |     def sql_flush(self, style, tables, sequences): | ||||||
|         # NB: The generated SQL below is specific to SQLite |         # NB: The generated SQL below is specific to SQLite | ||||||
|         # Note: The DELETE FROM... SQL generated below works for SQLite databases |         # Note: The DELETE FROM... SQL generated below works for SQLite databases | ||||||
| @@ -58,7 +63,7 @@ class DatabaseOperations(BaseDatabaseOperations): | |||||||
|         sql = ['%s %s %s;' % \ |         sql = ['%s %s %s;' % \ | ||||||
|                 (style.SQL_KEYWORD('DELETE'), |                 (style.SQL_KEYWORD('DELETE'), | ||||||
|                  style.SQL_KEYWORD('FROM'), |                  style.SQL_KEYWORD('FROM'), | ||||||
|                  style.SQL_FIELD(quote_name(table)) |                  style.SQL_FIELD(self.quote_name(table)) | ||||||
|                  ) for table in tables] |                  ) for table in tables] | ||||||
|         # Note: No requirement for reset of auto-incremented indices (cf. other |         # Note: No requirement for reset of auto-incremented indices (cf. other | ||||||
|         # sql_flush() implementations). Just return SQL at this point |         # sql_flush() implementations). Just return SQL at this point | ||||||
| @@ -115,11 +120,6 @@ supports_constraints = False | |||||||
| supports_tablespaces = False | supports_tablespaces = False | ||||||
| uses_case_insensitive_names = False | uses_case_insensitive_names = False | ||||||
|  |  | ||||||
| def quote_name(name): |  | ||||||
|     if name.startswith('"') and name.endswith('"'): |  | ||||||
|         return name # Quoting once is enough. |  | ||||||
|     return '"%s"' % name |  | ||||||
|  |  | ||||||
| dictfetchone = util.dictfetchone | dictfetchone = util.dictfetchone | ||||||
| dictfetchmany = util.dictfetchmany | dictfetchmany = util.dictfetchmany | ||||||
| dictfetchall  = util.dictfetchall | dictfetchall  = util.dictfetchall | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
| from django.db.backends.sqlite3.base import quote_name | from django.db.backends.sqlite3.base import DatabaseOperations | ||||||
|  |  | ||||||
|  | quote_name = DatabaseOperations().quote_name | ||||||
|  |  | ||||||
| def get_table_list(cursor): | def get_table_list(cursor): | ||||||
|     "Returns a list of table names in the current database." |     "Returns a list of table names in the current database." | ||||||
|   | |||||||
| @@ -207,6 +207,8 @@ class Model(object): | |||||||
|         non_pks = [f for f in self._meta.fields if not f.primary_key] |         non_pks = [f for f in self._meta.fields if not f.primary_key] | ||||||
|         cursor = connection.cursor() |         cursor = connection.cursor() | ||||||
|  |  | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|  |  | ||||||
|         # First, try an UPDATE. If that doesn't update anything, do an INSERT. |         # First, try an UPDATE. If that doesn't update anything, do an INSERT. | ||||||
|         pk_val = self._get_pk_val() |         pk_val = self._get_pk_val() | ||||||
|         # Note: the comparison with '' is required for compatibility with |         # Note: the comparison with '' is required for compatibility with | ||||||
| @@ -216,21 +218,21 @@ class Model(object): | |||||||
|         if pk_set: |         if pk_set: | ||||||
|             # Determine whether a record with the primary key already exists. |             # Determine whether a record with the primary key already exists. | ||||||
|             cursor.execute("SELECT 1 FROM %s WHERE %s=%%s" % \ |             cursor.execute("SELECT 1 FROM %s WHERE %s=%%s" % \ | ||||||
|                 (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), |                 (qn(self._meta.db_table), qn(self._meta.pk.column)), | ||||||
|                 self._meta.pk.get_db_prep_lookup('exact', pk_val)) |                 self._meta.pk.get_db_prep_lookup('exact', pk_val)) | ||||||
|             # If it does already exist, do an UPDATE. |             # If it does already exist, do an UPDATE. | ||||||
|             if cursor.fetchone(): |             if cursor.fetchone(): | ||||||
|                 db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False)) for f in non_pks] |                 db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False)) for f in non_pks] | ||||||
|                 if db_values: |                 if db_values: | ||||||
|                     cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \ |                     cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \ | ||||||
|                         (backend.quote_name(self._meta.db_table), |                         (qn(self._meta.db_table), | ||||||
|                         ','.join(['%s=%%s' % backend.quote_name(f.column) for f in non_pks]), |                         ','.join(['%s=%%s' % qn(f.column) for f in non_pks]), | ||||||
|                         backend.quote_name(self._meta.pk.column)), |                         qn(self._meta.pk.column)), | ||||||
|                         db_values + self._meta.pk.get_db_prep_lookup('exact', pk_val)) |                         db_values + self._meta.pk.get_db_prep_lookup('exact', pk_val)) | ||||||
|             else: |             else: | ||||||
|                 record_exists = False |                 record_exists = False | ||||||
|         if not pk_set or not record_exists: |         if not pk_set or not record_exists: | ||||||
|             field_names = [backend.quote_name(f.column) for f in self._meta.fields if not isinstance(f, AutoField)] |             field_names = [qn(f.column) for f in self._meta.fields if not isinstance(f, AutoField)] | ||||||
|             db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if not isinstance(f, AutoField)] |             db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if not isinstance(f, AutoField)] | ||||||
|             # If the PK has been manually set, respect that. |             # If the PK has been manually set, respect that. | ||||||
|             if pk_set: |             if pk_set: | ||||||
| @@ -238,20 +240,19 @@ class Model(object): | |||||||
|                 db_values += [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if isinstance(f, AutoField)] |                 db_values += [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if isinstance(f, AutoField)] | ||||||
|             placeholders = ['%s'] * len(field_names) |             placeholders = ['%s'] * len(field_names) | ||||||
|             if self._meta.order_with_respect_to: |             if self._meta.order_with_respect_to: | ||||||
|                 field_names.append(backend.quote_name('_order')) |                 field_names.append(qn('_order')) | ||||||
|                 # TODO: This assumes the database supports subqueries. |                 # TODO: This assumes the database supports subqueries. | ||||||
|                 placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \ |                 placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \ | ||||||
|                     (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.order_with_respect_to.column))) |                     (qn(self._meta.db_table), qn(self._meta.order_with_respect_to.column))) | ||||||
|                 db_values.append(getattr(self, self._meta.order_with_respect_to.attname)) |                 db_values.append(getattr(self, self._meta.order_with_respect_to.attname)) | ||||||
|             if db_values: |             if db_values: | ||||||
|                 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \ |                 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \ | ||||||
|                     (backend.quote_name(self._meta.db_table), ','.join(field_names), |                     (qn(self._meta.db_table), ','.join(field_names), | ||||||
|                     ','.join(placeholders)), db_values) |                     ','.join(placeholders)), db_values) | ||||||
|             else: |             else: | ||||||
|                 # Create a new record with defaults for everything. |                 # Create a new record with defaults for everything. | ||||||
|                 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % |                 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % | ||||||
|                     (backend.quote_name(self._meta.db_table), |                     (qn(self._meta.db_table), qn(self._meta.pk.column), | ||||||
|                      backend.quote_name(self._meta.pk.column), |  | ||||||
|                      connection.ops.pk_default_value())) |                      connection.ops.pk_default_value())) | ||||||
|             if self._meta.has_auto_field and not pk_set: |             if self._meta.has_auto_field and not pk_set: | ||||||
|                 setattr(self, self._meta.pk.attname, connection.ops.last_insert_id(cursor, self._meta.db_table, self._meta.pk.column)) |                 setattr(self, self._meta.pk.attname, connection.ops.last_insert_id(cursor, self._meta.db_table, self._meta.pk.column)) | ||||||
| @@ -326,10 +327,11 @@ class Model(object): | |||||||
|         return force_unicode(dict(field.choices).get(value, value), strings_only=True) |         return force_unicode(dict(field.choices).get(value, value), strings_only=True) | ||||||
|  |  | ||||||
|     def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs): |     def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs): | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|         op = is_next and '>' or '<' |         op = is_next and '>' or '<' | ||||||
|         where = '(%s %s %%s OR (%s = %%s AND %s.%s %s %%s))' % \ |         where = '(%s %s %%s OR (%s = %%s AND %s.%s %s %%s))' % \ | ||||||
|             (backend.quote_name(field.column), op, backend.quote_name(field.column), |             (qn(field.column), op, qn(field.column), | ||||||
|             backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column), op) |             qn(self._meta.db_table), qn(self._meta.pk.column), op) | ||||||
|         param = smart_str(getattr(self, field.attname)) |         param = smart_str(getattr(self, field.attname)) | ||||||
|         q = self.__class__._default_manager.filter(**kwargs).order_by((not is_next and '-' or '') + field.name, (not is_next and '-' or '') + self._meta.pk.name) |         q = self.__class__._default_manager.filter(**kwargs).order_by((not is_next and '-' or '') + field.name, (not is_next and '-' or '') + self._meta.pk.name) | ||||||
|         q._where.append(where) |         q._where.append(where) | ||||||
| @@ -340,14 +342,15 @@ class Model(object): | |||||||
|             raise self.DoesNotExist, "%s matching query does not exist." % self.__class__._meta.object_name |             raise self.DoesNotExist, "%s matching query does not exist." % self.__class__._meta.object_name | ||||||
|  |  | ||||||
|     def _get_next_or_previous_in_order(self, is_next): |     def _get_next_or_previous_in_order(self, is_next): | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|         cachename = "__%s_order_cache" % is_next |         cachename = "__%s_order_cache" % is_next | ||||||
|         if not hasattr(self, cachename): |         if not hasattr(self, cachename): | ||||||
|             op = is_next and '>' or '<' |             op = is_next and '>' or '<' | ||||||
|             order_field = self._meta.order_with_respect_to |             order_field = self._meta.order_with_respect_to | ||||||
|             where = ['%s %s (SELECT %s FROM %s WHERE %s=%%s)' % \ |             where = ['%s %s (SELECT %s FROM %s WHERE %s=%%s)' % \ | ||||||
|                 (backend.quote_name('_order'), op, backend.quote_name('_order'), |                 (qn('_order'), op, qn('_order'), | ||||||
|                 backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), |                 qn(self._meta.db_table), qn(self._meta.pk.column)), | ||||||
|                 '%s=%%s' % backend.quote_name(order_field.column)] |                 '%s=%%s' % qn(order_field.column)] | ||||||
|             params = [self._get_pk_val(), getattr(self, order_field.attname)] |             params = [self._get_pk_val(), getattr(self, order_field.attname)] | ||||||
|             obj = self._default_manager.order_by('_order').extra(where=where, params=params)[:1].get() |             obj = self._default_manager.order_by('_order').extra(where=where, params=params)[:1].get() | ||||||
|             setattr(self, cachename, obj) |             setattr(self, cachename, obj) | ||||||
| @@ -429,24 +432,26 @@ class Model(object): | |||||||
| # ORDERING METHODS ######################### | # ORDERING METHODS ######################### | ||||||
|  |  | ||||||
| def method_set_order(ordered_obj, self, id_list): | def method_set_order(ordered_obj, self, id_list): | ||||||
|  |     qn = connection.ops.quote_name | ||||||
|     cursor = connection.cursor() |     cursor = connection.cursor() | ||||||
|     # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s" |     # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s" | ||||||
|     sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \ |     sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \ | ||||||
|         (backend.quote_name(ordered_obj._meta.db_table), backend.quote_name('_order'), |         (qn(ordered_obj._meta.db_table), qn('_order'), | ||||||
|         backend.quote_name(ordered_obj._meta.order_with_respect_to.column), |         qn(ordered_obj._meta.order_with_respect_to.column), | ||||||
|         backend.quote_name(ordered_obj._meta.pk.column)) |         qn(ordered_obj._meta.pk.column)) | ||||||
|     rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) |     rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) | ||||||
|     cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)]) |     cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)]) | ||||||
|     transaction.commit_unless_managed() |     transaction.commit_unless_managed() | ||||||
|  |  | ||||||
| def method_get_order(ordered_obj, self): | def method_get_order(ordered_obj, self): | ||||||
|  |     qn = connection.ops.quote_name | ||||||
|     cursor = connection.cursor() |     cursor = connection.cursor() | ||||||
|     # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order" |     # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order" | ||||||
|     sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \ |     sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \ | ||||||
|         (backend.quote_name(ordered_obj._meta.pk.column), |         (qn(ordered_obj._meta.pk.column), | ||||||
|         backend.quote_name(ordered_obj._meta.db_table), |         qn(ordered_obj._meta.db_table), | ||||||
|         backend.quote_name(ordered_obj._meta.order_with_respect_to.column), |         qn(ordered_obj._meta.order_with_respect_to.column), | ||||||
|         backend.quote_name('_order')) |         qn('_order')) | ||||||
|     rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) |     rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) | ||||||
|     cursor.execute(sql, [rel_val]) |     cursor.execute(sql, [rel_val]) | ||||||
|     return [r[0] for r in cursor.fetchall()] |     return [r[0] for r in cursor.fetchall()] | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| from django.db import backend, transaction | from django.db import backend, connection, transaction | ||||||
| from django.db.models import signals, get_model | from django.db.models import signals, get_model | ||||||
| from django.db.models.fields import AutoField, Field, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, get_ul_class | from django.db.models.fields import AutoField, Field, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, get_ul_class | ||||||
| from django.db.models.related import RelatedObject | from django.db.models.related import RelatedObject | ||||||
| @@ -319,7 +319,6 @@ def create_many_related_manager(superclass): | |||||||
|             # source_col_name: the PK colname in join_table for the source object |             # source_col_name: the PK colname in join_table for the source object | ||||||
|             # target_col_name: the PK colname in join_table for the target object |             # target_col_name: the PK colname in join_table for the target object | ||||||
|             # *objs - objects to add. Either object instances, or primary keys of object instances. |             # *objs - objects to add. Either object instances, or primary keys of object instances. | ||||||
|             from django.db import connection |  | ||||||
|  |  | ||||||
|             # If there aren't any objects, there is nothing to do. |             # If there aren't any objects, there is nothing to do. | ||||||
|             if objs: |             if objs: | ||||||
| @@ -350,7 +349,6 @@ def create_many_related_manager(superclass): | |||||||
|             # source_col_name: the PK colname in join_table for the source object |             # source_col_name: the PK colname in join_table for the source object | ||||||
|             # target_col_name: the PK colname in join_table for the target object |             # target_col_name: the PK colname in join_table for the target object | ||||||
|             # *objs - objects to remove |             # *objs - objects to remove | ||||||
|             from django.db import connection |  | ||||||
|  |  | ||||||
|             # If there aren't any objects, there is nothing to do. |             # If there aren't any objects, there is nothing to do. | ||||||
|             if objs: |             if objs: | ||||||
| @@ -371,7 +369,6 @@ def create_many_related_manager(superclass): | |||||||
|  |  | ||||||
|         def _clear_items(self, source_col_name): |         def _clear_items(self, source_col_name): | ||||||
|             # source_col_name: the PK colname in join_table for the source object |             # source_col_name: the PK colname in join_table for the source object | ||||||
|             from django.db import connection |  | ||||||
|             cursor = connection.cursor() |             cursor = connection.cursor() | ||||||
|             cursor.execute("DELETE FROM %s WHERE %s = %%s" % \ |             cursor.execute("DELETE FROM %s WHERE %s = %%s" % \ | ||||||
|                 (self.join_table, source_col_name), |                 (self.join_table, source_col_name), | ||||||
| @@ -400,7 +397,7 @@ class ManyRelatedObjectsDescriptor(object): | |||||||
|         superclass = rel_model._default_manager.__class__ |         superclass = rel_model._default_manager.__class__ | ||||||
|         RelatedManager = create_many_related_manager(superclass) |         RelatedManager = create_many_related_manager(superclass) | ||||||
|  |  | ||||||
|         qn = backend.quote_name |         qn = connection.ops.quote_name | ||||||
|         manager = RelatedManager( |         manager = RelatedManager( | ||||||
|             model=rel_model, |             model=rel_model, | ||||||
|             core_filters={'%s__pk' % self.related.field.name: instance._get_pk_val()}, |             core_filters={'%s__pk' % self.related.field.name: instance._get_pk_val()}, | ||||||
| @@ -441,7 +438,7 @@ class ReverseManyRelatedObjectsDescriptor(object): | |||||||
|         superclass = rel_model._default_manager.__class__ |         superclass = rel_model._default_manager.__class__ | ||||||
|         RelatedManager = create_many_related_manager(superclass) |         RelatedManager = create_many_related_manager(superclass) | ||||||
|  |  | ||||||
|         qn = backend.quote_name |         qn = connection.ops.quote_name | ||||||
|         manager = RelatedManager( |         manager = RelatedManager( | ||||||
|             model=rel_model, |             model=rel_model, | ||||||
|             core_filters={'%s__pk' % self.field.related_query_name(): instance._get_pk_val()}, |             core_filters={'%s__pk' % self.field.related_query_name(): instance._get_pk_val()}, | ||||||
|   | |||||||
| @@ -64,23 +64,24 @@ def orderfield2column(f, opts): | |||||||
|         return f |         return f | ||||||
|  |  | ||||||
| def orderlist2sql(order_list, opts, prefix=''): | def orderlist2sql(order_list, opts, prefix=''): | ||||||
|  |     qn = connection.ops.quote_name | ||||||
|     if prefix.endswith('.'): |     if prefix.endswith('.'): | ||||||
|         prefix = backend.quote_name(prefix[:-1]) + '.' |         prefix = qn(prefix[:-1]) + '.' | ||||||
|     output = [] |     output = [] | ||||||
|     for f in handle_legacy_orderlist(order_list): |     for f in handle_legacy_orderlist(order_list): | ||||||
|         if f.startswith('-'): |         if f.startswith('-'): | ||||||
|             output.append('%s%s DESC' % (prefix, backend.quote_name(orderfield2column(f[1:], opts)))) |             output.append('%s%s DESC' % (prefix, qn(orderfield2column(f[1:], opts)))) | ||||||
|         elif f == '?': |         elif f == '?': | ||||||
|             output.append(connection.ops.random_function_sql()) |             output.append(connection.ops.random_function_sql()) | ||||||
|         else: |         else: | ||||||
|             output.append('%s%s ASC' % (prefix, backend.quote_name(orderfield2column(f, opts)))) |             output.append('%s%s ASC' % (prefix, qn(orderfield2column(f, opts)))) | ||||||
|     return ', '.join(output) |     return ', '.join(output) | ||||||
|  |  | ||||||
| def quote_only_if_word(word): | def quote_only_if_word(word): | ||||||
|     if re.search('\W', word): # Don't quote if there are spaces or non-word chars. |     if re.search('\W', word): # Don't quote if there are spaces or non-word chars. | ||||||
|         return word |         return word | ||||||
|     else: |     else: | ||||||
|         return backend.quote_name(word) |         return connection.ops.quote_name(word) | ||||||
|  |  | ||||||
| class _QuerySet(object): | class _QuerySet(object): | ||||||
|     "Represents a lazy database lookup for a set of objects" |     "Represents a lazy database lookup for a set of objects" | ||||||
| @@ -235,8 +236,8 @@ class _QuerySet(object): | |||||||
|  |  | ||||||
|         cursor = connection.cursor() |         cursor = connection.cursor() | ||||||
|         if self._distinct: |         if self._distinct: | ||||||
|             id_col = "%s.%s" % (backend.quote_name(self.model._meta.db_table), |             id_col = "%s.%s" % (connection.ops.quote_name(self.model._meta.db_table), | ||||||
|                     backend.quote_name(self.model._meta.pk.column)) |                     connection.ops.quote_name(self.model._meta.pk.column)) | ||||||
|             cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params) |             cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params) | ||||||
|         else: |         else: | ||||||
|             cursor.execute("SELECT COUNT(*)" + sql, params) |             cursor.execute("SELECT COUNT(*)" + sql, params) | ||||||
| @@ -308,11 +309,12 @@ class _QuerySet(object): | |||||||
|         assert self._limit is None and self._offset is None, \ |         assert self._limit is None and self._offset is None, \ | ||||||
|                 "Cannot use 'limit' or 'offset' with in_bulk" |                 "Cannot use 'limit' or 'offset' with in_bulk" | ||||||
|         assert isinstance(id_list, (tuple,  list)), "in_bulk() must be provided with a list of IDs." |         assert isinstance(id_list, (tuple,  list)), "in_bulk() must be provided with a list of IDs." | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|         id_list = list(id_list) |         id_list = list(id_list) | ||||||
|         if id_list == []: |         if id_list == []: | ||||||
|             return {} |             return {} | ||||||
|         qs = self._clone() |         qs = self._clone() | ||||||
|         qs._where.append("%s.%s IN (%s)" % (backend.quote_name(self.model._meta.db_table), backend.quote_name(self.model._meta.pk.column), ",".join(['%s'] * len(id_list)))) |         qs._where.append("%s.%s IN (%s)" % (qn(self.model._meta.db_table), qn(self.model._meta.pk.column), ",".join(['%s'] * len(id_list)))) | ||||||
|         qs._params.extend(id_list) |         qs._params.extend(id_list) | ||||||
|         return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()]) |         return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()]) | ||||||
|  |  | ||||||
| @@ -481,10 +483,11 @@ class _QuerySet(object): | |||||||
|         return self._result_cache |         return self._result_cache | ||||||
|  |  | ||||||
|     def _get_sql_clause(self): |     def _get_sql_clause(self): | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|         opts = self.model._meta |         opts = self.model._meta | ||||||
|  |  | ||||||
|         # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z. |         # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z. | ||||||
|         select = ["%s.%s" % (backend.quote_name(opts.db_table), backend.quote_name(f.column)) for f in opts.fields] |         select = ["%s.%s" % (qn(opts.db_table), qn(f.column)) for f in opts.fields] | ||||||
|         tables = [quote_only_if_word(t) for t in self._tables] |         tables = [quote_only_if_word(t) for t in self._tables] | ||||||
|         joins = SortedDict() |         joins = SortedDict() | ||||||
|         where = self._where[:] |         where = self._where[:] | ||||||
| @@ -505,10 +508,10 @@ class _QuerySet(object): | |||||||
|  |  | ||||||
|         # Add any additional SELECTs. |         # Add any additional SELECTs. | ||||||
|         if self._select: |         if self._select: | ||||||
|             select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()]) |             select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), qn(s[0])) for s in self._select.items()]) | ||||||
|  |  | ||||||
|         # Start composing the body of the SQL statement. |         # Start composing the body of the SQL statement. | ||||||
|         sql = [" FROM", backend.quote_name(opts.db_table)] |         sql = [" FROM", qn(opts.db_table)] | ||||||
|  |  | ||||||
|         # Compose the join dictionary into SQL describing the joins. |         # Compose the join dictionary into SQL describing the joins. | ||||||
|         if joins: |         if joins: | ||||||
| @@ -541,15 +544,15 @@ class _QuerySet(object): | |||||||
|                     order = "ASC" |                     order = "ASC" | ||||||
|                 if "." in col_name: |                 if "." in col_name: | ||||||
|                     table_prefix, col_name = col_name.split('.', 1) |                     table_prefix, col_name = col_name.split('.', 1) | ||||||
|                     table_prefix = backend.quote_name(table_prefix) + '.' |                     table_prefix = qn(table_prefix) + '.' | ||||||
|                 else: |                 else: | ||||||
|                     # Use the database table as a column prefix if it wasn't given, |                     # Use the database table as a column prefix if it wasn't given, | ||||||
|                     # and if the requested column isn't a custom SELECT. |                     # and if the requested column isn't a custom SELECT. | ||||||
|                     if "." not in col_name and col_name not in (self._select or ()): |                     if "." not in col_name and col_name not in (self._select or ()): | ||||||
|                         table_prefix = backend.quote_name(opts.db_table) + '.' |                         table_prefix = qn(opts.db_table) + '.' | ||||||
|                     else: |                     else: | ||||||
|                         table_prefix = '' |                         table_prefix = '' | ||||||
|                 order_by.append('%s%s %s' % (table_prefix, backend.quote_name(orderfield2column(col_name, opts)), order)) |                 order_by.append('%s%s %s' % (table_prefix, qn(orderfield2column(col_name, opts)), order)) | ||||||
|         if order_by: |         if order_by: | ||||||
|             sql.append("ORDER BY " + ", ".join(order_by)) |             sql.append("ORDER BY " + ", ".join(order_by)) | ||||||
|  |  | ||||||
| @@ -579,6 +582,8 @@ class ValuesQuerySet(QuerySet): | |||||||
|         except EmptyResultSet: |         except EmptyResultSet: | ||||||
|             raise StopIteration |             raise StopIteration | ||||||
|  |  | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|  |  | ||||||
|         # self._select is a dictionary, and dictionaries' key order is |         # self._select is a dictionary, and dictionaries' key order is | ||||||
|         # undefined, so we convert it to a list of tuples. |         # undefined, so we convert it to a list of tuples. | ||||||
|         extra_select = self._select.items() |         extra_select = self._select.items() | ||||||
| @@ -605,9 +610,9 @@ class ValuesQuerySet(QuerySet): | |||||||
|             field_names = [f.attname for f in fields] |             field_names = [f.attname for f in fields] | ||||||
|  |  | ||||||
|         columns = [f.column for f in fields] |         columns = [f.column for f in fields] | ||||||
|         select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] |         select = ['%s.%s' % (qn(self.model._meta.db_table), qn(c)) for c in columns] | ||||||
|         if extra_select: |         if extra_select: | ||||||
|             select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in extra_select]) |             select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), qn(s[0])) for s in extra_select]) | ||||||
|             field_names.extend([f[0] for f in extra_select]) |             field_names.extend([f[0] for f in extra_select]) | ||||||
|  |  | ||||||
|         cursor = connection.cursor() |         cursor = connection.cursor() | ||||||
| @@ -632,17 +637,19 @@ class DateQuerySet(QuerySet): | |||||||
|     def iterator(self): |     def iterator(self): | ||||||
|         from django.db.backends.util import typecast_timestamp |         from django.db.backends.util import typecast_timestamp | ||||||
|         from django.db.models.fields import DateTimeField |         from django.db.models.fields import DateTimeField | ||||||
|  |  | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|         self._order_by = () # Clear this because it'll mess things up otherwise. |         self._order_by = () # Clear this because it'll mess things up otherwise. | ||||||
|         if self._field.null: |         if self._field.null: | ||||||
|             self._where.append('%s.%s IS NOT NULL' % \ |             self._where.append('%s.%s IS NOT NULL' % \ | ||||||
|                 (backend.quote_name(self.model._meta.db_table), backend.quote_name(self._field.column))) |                 (qn(self.model._meta.db_table), qn(self._field.column))) | ||||||
|         try: |         try: | ||||||
|             select, sql, params = self._get_sql_clause() |             select, sql, params = self._get_sql_clause() | ||||||
|         except EmptyResultSet: |         except EmptyResultSet: | ||||||
|             raise StopIteration |             raise StopIteration | ||||||
|  |  | ||||||
|         table_name = backend.quote_name(self.model._meta.db_table) |         table_name = qn(self.model._meta.db_table) | ||||||
|         field_name = backend.quote_name(self._field.column) |         field_name = qn(self._field.column) | ||||||
|  |  | ||||||
|         if backend.allows_group_by_ordinal: |         if backend.allows_group_by_ordinal: | ||||||
|             group_by = '1' |             group_by = '1' | ||||||
| @@ -650,8 +657,8 @@ class DateQuerySet(QuerySet): | |||||||
|             group_by = connection.ops.date_trunc_sql(self._kind, '%s.%s' % (table_name, field_name)) |             group_by = connection.ops.date_trunc_sql(self._kind, '%s.%s' % (table_name, field_name)) | ||||||
|  |  | ||||||
|         sql = 'SELECT %s %s GROUP BY %s ORDER BY 1 %s' % \ |         sql = 'SELECT %s %s GROUP BY %s ORDER BY 1 %s' % \ | ||||||
|             (connection.ops.date_trunc_sql(self._kind, '%s.%s' % (backend.quote_name(self.model._meta.db_table), |             (connection.ops.date_trunc_sql(self._kind, '%s.%s' % (qn(self.model._meta.db_table), | ||||||
|             backend.quote_name(self._field.column))), sql, group_by, self._order) |             qn(self._field.column))), sql, group_by, self._order) | ||||||
|         cursor = connection.cursor() |         cursor = connection.cursor() | ||||||
|         cursor.execute(sql, params) |         cursor.execute(sql, params) | ||||||
|  |  | ||||||
| @@ -778,8 +785,8 @@ class QNot(Q): | |||||||
|  |  | ||||||
| def get_where_clause(lookup_type, table_prefix, field_name, value, db_type): | def get_where_clause(lookup_type, table_prefix, field_name, value, db_type): | ||||||
|     if table_prefix.endswith('.'): |     if table_prefix.endswith('.'): | ||||||
|         table_prefix = backend.quote_name(table_prefix[:-1])+'.' |         table_prefix = connection.ops.quote_name(table_prefix[:-1])+'.' | ||||||
|     field_name = backend.quote_name(field_name) |     field_name = connection.ops.quote_name(field_name) | ||||||
|     if type(value) == datetime.datetime and connection.ops.datetime_cast_sql(): |     if type(value) == datetime.datetime and connection.ops.datetime_cast_sql(): | ||||||
|         cast_sql = connection.ops.datetime_cast_sql() |         cast_sql = connection.ops.datetime_cast_sql() | ||||||
|     else: |     else: | ||||||
| @@ -849,7 +856,7 @@ def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen, | |||||||
|     if max_depth and cur_depth > max_depth: |     if max_depth and cur_depth > max_depth: | ||||||
|         return None |         return None | ||||||
|  |  | ||||||
|     qn = backend.quote_name |     qn = connection.ops.quote_name | ||||||
|     for f in opts.fields: |     for f in opts.fields: | ||||||
|         if f.rel and not f.null: |         if f.rel and not f.null: | ||||||
|             db_table = f.rel.to._meta.db_table |             db_table = f.rel.to._meta.db_table | ||||||
| @@ -947,7 +954,7 @@ def field_choices(field_list, related_query): | |||||||
|     return choices |     return choices | ||||||
|  |  | ||||||
| def lookup_inner(path, lookup_type, value, opts, table, column): | def lookup_inner(path, lookup_type, value, opts, table, column): | ||||||
|     qn = backend.quote_name |     qn = connection.ops.quote_name | ||||||
|     joins, where, params = SortedDict(), [], [] |     joins, where, params = SortedDict(), [], [] | ||||||
|     current_opts = opts |     current_opts = opts | ||||||
|     current_table = table |     current_table = table | ||||||
| @@ -1113,7 +1120,7 @@ def lookup_inner(path, lookup_type, value, opts, table, column): | |||||||
|  |  | ||||||
| def delete_objects(seen_objs): | def delete_objects(seen_objs): | ||||||
|     "Iterate through a list of seen classes, and remove any instances that are referred to" |     "Iterate through a list of seen classes, and remove any instances that are referred to" | ||||||
|     qn = backend.quote_name |     qn = connection.ops.quote_name | ||||||
|     ordered_classes = seen_objs.keys() |     ordered_classes = seen_objs.keys() | ||||||
|     ordered_classes.reverse() |     ordered_classes.reverse() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -118,13 +118,15 @@ def create_test_db(verbosity=1, autoclobber=False): | |||||||
|         else: |         else: | ||||||
|             TEST_DATABASE_NAME = TEST_DATABASE_PREFIX + settings.DATABASE_NAME |             TEST_DATABASE_NAME = TEST_DATABASE_PREFIX + settings.DATABASE_NAME | ||||||
|  |  | ||||||
|  |         qn = connection.ops.quote_name | ||||||
|  |  | ||||||
|         # Create the test database and connect to it. We need to autocommit |         # Create the test database and connect to it. We need to autocommit | ||||||
|         # if the database supports it because PostgreSQL doesn't allow |         # if the database supports it because PostgreSQL doesn't allow | ||||||
|         # CREATE/DROP DATABASE statements within transactions. |         # CREATE/DROP DATABASE statements within transactions. | ||||||
|         cursor = connection.cursor() |         cursor = connection.cursor() | ||||||
|         _set_autocommit(connection) |         _set_autocommit(connection) | ||||||
|         try: |         try: | ||||||
|             cursor.execute("CREATE DATABASE %s %s" % (backend.quote_name(TEST_DATABASE_NAME), suffix)) |             cursor.execute("CREATE DATABASE %s %s" % (qn(TEST_DATABASE_NAME), suffix)) | ||||||
|         except Exception, e: |         except Exception, e: | ||||||
|             sys.stderr.write("Got an error creating the test database: %s\n" % e) |             sys.stderr.write("Got an error creating the test database: %s\n" % e) | ||||||
|             if not autoclobber: |             if not autoclobber: | ||||||
| @@ -133,10 +135,10 @@ def create_test_db(verbosity=1, autoclobber=False): | |||||||
|                 try: |                 try: | ||||||
|                     if verbosity >= 1: |                     if verbosity >= 1: | ||||||
|                         print "Destroying old test database..." |                         print "Destroying old test database..." | ||||||
|                     cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME)) |                     cursor.execute("DROP DATABASE %s" % qn(TEST_DATABASE_NAME)) | ||||||
|                     if verbosity >= 1: |                     if verbosity >= 1: | ||||||
|                         print "Creating test database..." |                         print "Creating test database..." | ||||||
|                     cursor.execute("CREATE DATABASE %s %s" % (backend.quote_name(TEST_DATABASE_NAME), suffix)) |                     cursor.execute("CREATE DATABASE %s %s" % (qn(TEST_DATABASE_NAME), suffix)) | ||||||
|                 except Exception, e: |                 except Exception, e: | ||||||
|                     sys.stderr.write("Got an error recreating the test database: %s\n" % e) |                     sys.stderr.write("Got an error recreating the test database: %s\n" % e) | ||||||
|                     sys.exit(2) |                     sys.exit(2) | ||||||
| @@ -180,5 +182,5 @@ def destroy_test_db(old_database_name, verbosity=1): | |||||||
|         cursor = connection.cursor() |         cursor = connection.cursor() | ||||||
|         _set_autocommit(connection) |         _set_autocommit(connection) | ||||||
|         time.sleep(1) # To avoid "database is being accessed by other users" errors. |         time.sleep(1) # To avoid "database is being accessed by other users" errors. | ||||||
|         cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME)) |         cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(TEST_DATABASE_NAME)) | ||||||
|         connection.close() |         connection.close() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user