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:
parent
d4f218bd91
commit
221f99ed58
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue