Skip to content

Commit

Permalink
Refactored get_sql_sequence_reset() to DatabaseOperations.sequence_re…
Browse files Browse the repository at this point in the history
…set_sql(). Refs #5106

git-svn-id: http://code.djangoproject.com/svn/django/trunk@5964 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
adrianholovaty committed Aug 20, 2007
1 parent aaed6e0 commit 147e99a
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 103 deletions.
4 changes: 2 additions & 2 deletions django/core/management/commands/loaddata.py
Expand Up @@ -15,7 +15,7 @@ class Command(BaseCommand):
def handle(self, *fixture_labels, **options): def handle(self, *fixture_labels, **options):
from django.db.models import get_apps from django.db.models import get_apps
from django.core import serializers from django.core import serializers
from django.db import connection, transaction, backend from django.db import connection, transaction
from django.conf import settings from django.conf import settings


self.style = no_style() self.style = no_style()
Expand Down Expand Up @@ -105,7 +105,7 @@ def handle(self, *fixture_labels, **options):
(format, fixture_name, humanize(fixture_dir)) (format, fixture_name, humanize(fixture_dir))


if count[0] > 0: if count[0] > 0:
sequence_sql = backend.get_sql_sequence_reset(self.style, models) sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
if sequence_sql: if sequence_sql:
if verbosity > 1: if verbosity > 1:
print "Resetting sequences" print "Resetting sequences"
Expand Down
4 changes: 2 additions & 2 deletions django/core/management/commands/sqlsequencereset.py
Expand Up @@ -5,5 +5,5 @@ class Command(AppCommand):
output_transaction = True output_transaction = True


def handle_app(self, app, **options): def handle_app(self, app, **options):
from django.db import backend, models from django.db import connection, models
return '\n'.join(backend.get_sql_sequence_reset(self.style, models.get_models(app))) return '\n'.join(connection.ops.sequence_reset_sql(self.style, models.get_models(app)))
10 changes: 10 additions & 0 deletions django/db/backends/__init__.py
Expand Up @@ -150,3 +150,13 @@ def sql_flush(self, style, tables, sequences):
color_style() or no_style() in django.core.management.color. color_style() or no_style() in django.core.management.color.
""" """
raise NotImplementedError() raise NotImplementedError()

def sequence_reset_sql(self, style, model_list):
"""
Returns a list of the SQL statements required to reset sequences for
the given models.
The `style` argument is a Style object as returned by either
color_style() or no_style() in django.core.management.color.
"""
return [] # No sequence reset required by default.
5 changes: 0 additions & 5 deletions django/db/backends/ado_mssql/base.py
Expand Up @@ -109,11 +109,6 @@ def get_start_transaction_sql():
def get_tablespace_sql(tablespace, inline=False): def get_tablespace_sql(tablespace, inline=False):
return "ON %s" % quote_name(tablespace) return "ON %s" % quote_name(tablespace)


def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# No sequence reset required
return []

OPERATOR_MAPPING = { OPERATOR_MAPPING = {
'exact': '= %s', 'exact': '= %s',
'iexact': 'LIKE %s', 'iexact': 'LIKE %s',
Expand Down
1 change: 0 additions & 1 deletion django/db/backends/dummy/base.py
Expand Up @@ -44,6 +44,5 @@ def close(self):
dictfetchmany = complain dictfetchmany = complain
dictfetchall = complain dictfetchall = complain
get_start_transaction_sql = complain get_start_transaction_sql = complain
get_sql_sequence_reset = complain


OPERATOR_MAPPING = {} OPERATOR_MAPPING = {}
5 changes: 0 additions & 5 deletions django/db/backends/mysql/base.py
Expand Up @@ -191,11 +191,6 @@ def quote_name(name):
def get_start_transaction_sql(): def get_start_transaction_sql():
return "BEGIN;" return "BEGIN;"


def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# No sequence reset required
return []

OPERATOR_MAPPING = { OPERATOR_MAPPING = {
'exact': '= %s', 'exact': '= %s',
'iexact': 'LIKE %s', 'iexact': 'LIKE %s',
Expand Down
5 changes: 0 additions & 5 deletions django/db/backends/mysql_old/base.py
Expand Up @@ -210,11 +210,6 @@ def quote_name(name):
def get_start_transaction_sql(): def get_start_transaction_sql():
return "BEGIN;" return "BEGIN;"


def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# No sequence reset required
return []

OPERATOR_MAPPING = { OPERATOR_MAPPING = {
'exact': '= %s', 'exact': '= %s',
'iexact': 'LIKE %s', 'iexact': 'LIKE %s',
Expand Down
35 changes: 17 additions & 18 deletions django/db/backends/oracle/base.py
Expand Up @@ -95,6 +95,23 @@ def sql_flush(self, style, tables, sequences):
else: else:
return [] return []


def sequence_reset_sql(self, style, model_list):
from django.db import models
output = []
query = _get_sequence_reset_sql()
for model in model_list:
for f in model._meta.fields:
if isinstance(f, models.AutoField):
sequence_name = get_sequence_name(model._meta.db_table)
output.append(query % {'sequence':sequence_name,
'table':model._meta.db_table})
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
sequence_name = get_sequence_name(f.m2m_db_table())
output.append(query % {'sequence':sequence_name,
'table':f.m2m_db_table()})
return output

class DatabaseWrapper(BaseDatabaseWrapper): class DatabaseWrapper(BaseDatabaseWrapper):
ops = DatabaseOperations() ops = DatabaseOperations()


Expand Down Expand Up @@ -244,24 +261,6 @@ def get_sequence_name(table):
name_length = DatabaseOperations().max_name_length() - 3 name_length = DatabaseOperations().max_name_length() - 3
return '%s_SQ' % util.truncate_name(table, name_length).upper() return '%s_SQ' % util.truncate_name(table, name_length).upper()


def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
from django.db import models
output = []
query = _get_sequence_reset_sql()
for model in model_list:
for f in model._meta.fields:
if isinstance(f, models.AutoField):
sequence_name = get_sequence_name(model._meta.db_table)
output.append(query % {'sequence':sequence_name,
'table':model._meta.db_table})
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
sequence_name = get_sequence_name(f.m2m_db_table())
output.append(query % {'sequence':sequence_name,
'table':f.m2m_db_table()})
return output

def get_trigger_name(table): def get_trigger_name(table):
name_length = DatabaseOperations().max_name_length() - 3 name_length = DatabaseOperations().max_name_length() - 3
return '%s_TR' % util.truncate_name(table, name_length).upper() return '%s_TR' % util.truncate_name(table, name_length).upper()
Expand Down
59 changes: 29 additions & 30 deletions django/db/backends/postgresql/base.py
Expand Up @@ -124,6 +124,35 @@ def sql_flush(self, style, tables, sequences):
else: else:
return [] return []


def sequence_reset_sql(self, style, model_list):
from django.db import models
output = []
for model in model_list:
# 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
# if there are records (as the max pk value is already in use), otherwise set it to false.
for f in model._meta.fields:
if isinstance(f, models.AutoField):
output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(quote_name(model._meta.db_table))))
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())),
style.SQL_FIELD(quote_name('id')),
style.SQL_FIELD(quote_name('id')),
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table())))
return output

class DatabaseWrapper(BaseDatabaseWrapper): class DatabaseWrapper(BaseDatabaseWrapper):
ops = DatabaseOperations() ops = DatabaseOperations()


Expand Down Expand Up @@ -185,36 +214,6 @@ def dictfetchall(cursor):
def get_start_transaction_sql(): def get_start_transaction_sql():
return "BEGIN;" return "BEGIN;"


def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
from django.db import models
output = []
for model in model_list:
# 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
# if there are records (as the max pk value is already in use), otherwise set it to false.
for f in model._meta.fields:
if isinstance(f, models.AutoField):
output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(quote_name(model._meta.db_table))))
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())),
style.SQL_FIELD(quote_name('id')),
style.SQL_FIELD(quote_name('id')),
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table())))
return output

def typecast_string(s): def typecast_string(s):
""" """
Cast all returned strings to unicode strings. Cast all returned strings to unicode strings.
Expand Down
59 changes: 29 additions & 30 deletions django/db/backends/postgresql_psycopg2/base.py
Expand Up @@ -86,6 +86,35 @@ def sql_flush(self, style, tables, sequences):
else: else:
return [] return []


def sequence_reset_sql(self, style, model_list):
from django.db import models
output = []
for model in model_list:
# 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
# if there are records (as the max pk value is already in use), otherwise set it to false.
for f in model._meta.fields:
if isinstance(f, models.AutoField):
output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(quote_name(model._meta.db_table))))
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())),
style.SQL_FIELD(quote_name('id')),
style.SQL_FIELD(quote_name('id')),
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table())))
return output

class DatabaseWrapper(BaseDatabaseWrapper): class DatabaseWrapper(BaseDatabaseWrapper):
ops = DatabaseOperations() ops = DatabaseOperations()


Expand Down Expand Up @@ -139,36 +168,6 @@ def quote_name(name):
def get_start_transaction_sql(): def get_start_transaction_sql():
return "BEGIN;" return "BEGIN;"


def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
from django.db import models
output = []
for model in model_list:
# 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
# if there are records (as the max pk value is already in use), otherwise set it to false.
for f in model._meta.fields:
if isinstance(f, models.AutoField):
output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(quote_name(model._meta.db_table))))
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())),
style.SQL_FIELD(quote_name('id')),
style.SQL_FIELD(quote_name('id')),
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table())))
return output

OPERATOR_MAPPING = { OPERATOR_MAPPING = {
'exact': '= %s', 'exact': '= %s',
'iexact': 'ILIKE %s', 'iexact': 'ILIKE %s',
Expand Down
5 changes: 0 additions & 5 deletions django/db/backends/sqlite3/base.py
Expand Up @@ -134,11 +134,6 @@ def _sqlite_extract(lookup_type, dt):
def get_start_transaction_sql(): def get_start_transaction_sql():
return "BEGIN;" return "BEGIN;"


def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# No sequence reset required
return []

def _sqlite_date_trunc(lookup_type, dt): def _sqlite_date_trunc(lookup_type, dt):
try: try:
dt = util.typecast_timestamp(dt) dt = util.typecast_timestamp(dt)
Expand Down

0 comments on commit 147e99a

Please sign in to comment.