Began implementing BaseDatabaseOperations class for every database backend. This class will be used to hold the database-specific methods that currently live at the module level in each backend. Only autoinc_sql() has been implemented so far.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5950 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
7c41b19c8a
commit
38b5d7f23d
|
@ -213,7 +213,7 @@ def sql_model_create(model, style, known_models=set()):
|
|||
Returns the SQL required to create a single model, as a tuple of:
|
||||
(list_of_sql, pending_references_dict)
|
||||
"""
|
||||
from django.db import backend, models
|
||||
from django.db import backend, connection, models
|
||||
|
||||
opts = model._meta
|
||||
final_output = []
|
||||
|
@ -267,9 +267,9 @@ def sql_model_create(model, style, known_models=set()):
|
|||
full_statement.append(';')
|
||||
final_output.append('\n'.join(full_statement))
|
||||
|
||||
if opts.has_auto_field and hasattr(backend, 'get_autoinc_sql'):
|
||||
# Add any extra SQL needed to support auto-incrementing primary keys
|
||||
autoinc_sql = backend.get_autoinc_sql(opts.db_table)
|
||||
if opts.has_auto_field:
|
||||
# Add any extra SQL needed to support auto-incrementing primary keys.
|
||||
autoinc_sql = connection.ops.autoinc_sql(opts.db_table)
|
||||
if autoinc_sql:
|
||||
for stmt in autoinc_sql:
|
||||
final_output.append(stmt)
|
||||
|
|
|
@ -6,6 +6,10 @@ except ImportError:
|
|||
from django.utils._threading_local import local
|
||||
|
||||
class BaseDatabaseWrapper(local):
|
||||
"""
|
||||
Represents a database connection.
|
||||
"""
|
||||
ops = None
|
||||
def __init__(self, **kwargs):
|
||||
self.connection = None
|
||||
self.queries = []
|
||||
|
@ -34,3 +38,18 @@ class BaseDatabaseWrapper(local):
|
|||
def make_debug_cursor(self, cursor):
|
||||
from django.db.backends import util
|
||||
return util.CursorDebugWrapper(cursor, self)
|
||||
|
||||
class BaseDatabaseOperations(object):
|
||||
"""
|
||||
This class encapsulates all backend-specific differences, such as the way
|
||||
a backend performs ordering or calculates the ID of a recently-inserted
|
||||
row.
|
||||
"""
|
||||
def autoinc_sql(self, table):
|
||||
"""
|
||||
Returns any SQL needed to support auto-incrementing primary keys, or
|
||||
None if no SQL is necessary.
|
||||
|
||||
This SQL is executed when a table is created.
|
||||
"""
|
||||
return None
|
||||
|
|
|
@ -4,7 +4,7 @@ ADO MSSQL database backend for Django.
|
|||
Requires adodbapi 2.0.1: http://adodbapi.sourceforge.net/
|
||||
"""
|
||||
|
||||
from django.db.backends import BaseDatabaseWrapper, util
|
||||
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||
try:
|
||||
import adodbapi as Database
|
||||
except ImportError, e:
|
||||
|
@ -48,7 +48,12 @@ def variantToPython(variant, adType):
|
|||
return res
|
||||
Database.convertVariantToPython = variantToPython
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
pass
|
||||
|
||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
ops = DatabaseOperations()
|
||||
|
||||
def _cursor(self, settings):
|
||||
if self.connection is None:
|
||||
if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
|
||||
|
@ -130,9 +135,6 @@ def get_start_transaction_sql():
|
|||
def get_tablespace_sql(tablespace, inline=False):
|
||||
return "ON %s" % quote_name(tablespace)
|
||||
|
||||
def get_autoinc_sql(table):
|
||||
return None
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
|
|
|
@ -21,7 +21,12 @@ class DatabaseError(Exception):
|
|||
class IntegrityError(DatabaseError):
|
||||
pass
|
||||
|
||||
class DatabaseWrapper:
|
||||
class DatabaseOperations(object):
|
||||
def __getattr__(self, *args, **kwargs):
|
||||
complain()
|
||||
|
||||
class DatabaseWrapper(object):
|
||||
ops = DatabaseOperations()
|
||||
cursor = complain
|
||||
_commit = complain
|
||||
_rollback = ignore
|
||||
|
@ -50,7 +55,6 @@ get_drop_foreignkey_sql = complain
|
|||
get_pk_default_value = complain
|
||||
get_max_name_length = ignore
|
||||
get_start_transaction_sql = complain
|
||||
get_autoinc_sql = complain
|
||||
get_sql_flush = complain
|
||||
get_sql_sequence_reset = complain
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ MySQL database backend for Django.
|
|||
Requires MySQLdb: http://sourceforge.net/projects/mysql-python
|
||||
"""
|
||||
|
||||
from django.db.backends import BaseDatabaseWrapper, util
|
||||
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||
try:
|
||||
import MySQLdb as Database
|
||||
except ImportError, e:
|
||||
|
@ -53,7 +53,12 @@ server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
|
|||
# standard util.CursorDebugWrapper can be used. Also, using sql_mode
|
||||
# TRADITIONAL will automatically cause most warnings to be treated as errors.
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
pass
|
||||
|
||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
ops = DatabaseOperations()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(DatabaseWrapper, self).__init__(**kwargs)
|
||||
self.server_version = None
|
||||
|
@ -181,9 +186,6 @@ def get_max_name_length():
|
|||
def get_start_transaction_sql():
|
||||
return "BEGIN;"
|
||||
|
||||
def get_autoinc_sql(table):
|
||||
return None
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
|
|
|
@ -4,7 +4,7 @@ MySQL database backend for Django.
|
|||
Requires MySQLdb: http://sourceforge.net/projects/mysql-python
|
||||
"""
|
||||
|
||||
from django.db.backends import BaseDatabaseWrapper, util
|
||||
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||
from django.utils.encoding import force_unicode
|
||||
try:
|
||||
import MySQLdb as Database
|
||||
|
@ -63,7 +63,12 @@ class MysqlDebugWrapper:
|
|||
else:
|
||||
return getattr(self.cursor, attr)
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
pass
|
||||
|
||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
ops = DatabaseOperations()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(DatabaseWrapper, self).__init__(**kwargs)
|
||||
self.server_version = None
|
||||
|
@ -200,9 +205,6 @@ def get_max_name_length():
|
|||
def get_start_transaction_sql():
|
||||
return "BEGIN;"
|
||||
|
||||
def get_autoinc_sql(table):
|
||||
return None
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
|
|
|
@ -4,7 +4,7 @@ Oracle database backend for Django.
|
|||
Requires cx_Oracle: http://www.python.net/crew/atuining/cx_Oracle/
|
||||
"""
|
||||
|
||||
from django.db.backends import BaseDatabaseWrapper, util
|
||||
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||
from django.utils.datastructures import SortedDict
|
||||
from django.utils.encoding import smart_str, force_unicode
|
||||
import datetime
|
||||
|
@ -21,7 +21,26 @@ except ImportError, e:
|
|||
DatabaseError = Database.Error
|
||||
IntegrityError = Database.IntegrityError
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
def autoinc_sql(self, table):
|
||||
# To simulate auto-incrementing primary keys in Oracle, we have to
|
||||
# create a sequence and a trigger.
|
||||
sq_name = get_sequence_name(table)
|
||||
tr_name = get_trigger_name(table)
|
||||
sequence_sql = 'CREATE SEQUENCE %s;' % sq_name
|
||||
trigger_sql = """
|
||||
CREATE OR REPLACE TRIGGER %s
|
||||
BEFORE INSERT ON %s
|
||||
FOR EACH ROW
|
||||
WHEN (new.id IS NULL)
|
||||
BEGIN
|
||||
SELECT %s.nextval INTO :new.id FROM dual;
|
||||
END;/""" % (tr_name, quote_name(table), sq_name)
|
||||
return sequence_sql, trigger_sql
|
||||
|
||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
ops = DatabaseOperations()
|
||||
|
||||
def _valid_connection(self):
|
||||
return self.connection is not None
|
||||
|
||||
|
@ -187,22 +206,6 @@ def get_start_transaction_sql():
|
|||
def get_tablespace_sql(tablespace, inline=False):
|
||||
return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), quote_name(tablespace))
|
||||
|
||||
def get_autoinc_sql(table):
|
||||
# To simulate auto-incrementing primary keys in Oracle, we have to
|
||||
# create a sequence and a trigger.
|
||||
sq_name = get_sequence_name(table)
|
||||
tr_name = get_trigger_name(table)
|
||||
sequence_sql = 'CREATE SEQUENCE %s;' % sq_name
|
||||
trigger_sql = """CREATE OR REPLACE TRIGGER %s
|
||||
BEFORE INSERT ON %s
|
||||
FOR EACH ROW
|
||||
WHEN (new.id IS NULL)
|
||||
BEGIN
|
||||
SELECT %s.nextval INTO :new.id FROM dual;
|
||||
END;
|
||||
/""" % (tr_name, quote_name(table), sq_name)
|
||||
return sequence_sql, trigger_sql
|
||||
|
||||
def get_drop_sequence(table):
|
||||
return "DROP SEQUENCE %s;" % quote_name(get_sequence_name(table))
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ Requires psycopg 1: http://initd.org/projects/psycopg1
|
|||
"""
|
||||
|
||||
from django.utils.encoding import smart_str, smart_unicode
|
||||
from django.db.backends import BaseDatabaseWrapper, util
|
||||
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||
try:
|
||||
import psycopg as Database
|
||||
except ImportError, e:
|
||||
|
@ -57,7 +57,12 @@ class UnicodeCursorWrapper(object):
|
|||
|
||||
postgres_version = None
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
pass
|
||||
|
||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
ops = DatabaseOperations()
|
||||
|
||||
def _cursor(self, settings):
|
||||
set_tz = False
|
||||
if self.connection is None:
|
||||
|
@ -157,9 +162,6 @@ def get_max_name_length():
|
|||
def get_start_transaction_sql():
|
||||
return "BEGIN;"
|
||||
|
||||
def get_autoinc_sql(table):
|
||||
return None
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
|
|
|
@ -4,7 +4,7 @@ PostgreSQL database backend for Django.
|
|||
Requires psycopg 2: http://initd.org/projects/psycopg2
|
||||
"""
|
||||
|
||||
from django.db.backends import BaseDatabaseWrapper, util
|
||||
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||
try:
|
||||
import psycopg2 as Database
|
||||
import psycopg2.extensions
|
||||
|
@ -19,7 +19,12 @@ psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
|
|||
|
||||
postgres_version = None
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
pass
|
||||
|
||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
ops = DatabaseOperations()
|
||||
|
||||
def _cursor(self, settings):
|
||||
set_tz = False
|
||||
if self.connection is None:
|
||||
|
@ -111,9 +116,6 @@ def get_max_name_length():
|
|||
def get_start_transaction_sql():
|
||||
return "BEGIN;"
|
||||
|
||||
def get_autoinc_sql(table):
|
||||
return None
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
SQLite3 backend for django. Requires pysqlite2 (http://pysqlite.org/).
|
||||
"""
|
||||
|
||||
from django.db.backends import BaseDatabaseWrapper, util
|
||||
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||
try:
|
||||
try:
|
||||
from sqlite3 import dbapi2 as Database
|
||||
|
@ -34,7 +34,12 @@ Database.register_converter("TIMESTAMP", util.typecast_timestamp)
|
|||
Database.register_converter("decimal", util.typecast_decimal)
|
||||
Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
pass
|
||||
|
||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
ops = DatabaseOperations()
|
||||
|
||||
def _cursor(self, settings):
|
||||
if self.connection is None:
|
||||
kwargs = {
|
||||
|
@ -143,9 +148,6 @@ def get_max_name_length():
|
|||
def get_start_transaction_sql():
|
||||
return "BEGIN;"
|
||||
|
||||
def get_autoinc_sql(table):
|
||||
return None
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""
|
||||
Return a list of SQL statements required to remove all data from
|
||||
|
|
Loading…
Reference in New Issue