mirror of https://github.com/django/django.git
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:
|
Returns the SQL required to create a single model, as a tuple of:
|
||||||
(list_of_sql, pending_references_dict)
|
(list_of_sql, pending_references_dict)
|
||||||
"""
|
"""
|
||||||
from django.db import backend, models
|
from django.db import backend, connection, models
|
||||||
|
|
||||||
opts = model._meta
|
opts = model._meta
|
||||||
final_output = []
|
final_output = []
|
||||||
|
@ -267,9 +267,9 @@ def sql_model_create(model, style, known_models=set()):
|
||||||
full_statement.append(';')
|
full_statement.append(';')
|
||||||
final_output.append('\n'.join(full_statement))
|
final_output.append('\n'.join(full_statement))
|
||||||
|
|
||||||
if opts.has_auto_field and hasattr(backend, 'get_autoinc_sql'):
|
if opts.has_auto_field:
|
||||||
# Add any extra SQL needed to support auto-incrementing primary keys
|
# Add any extra SQL needed to support auto-incrementing primary keys.
|
||||||
autoinc_sql = backend.get_autoinc_sql(opts.db_table)
|
autoinc_sql = connection.ops.autoinc_sql(opts.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)
|
||||||
|
|
|
@ -6,6 +6,10 @@ except ImportError:
|
||||||
from django.utils._threading_local import local
|
from django.utils._threading_local import local
|
||||||
|
|
||||||
class BaseDatabaseWrapper(local):
|
class BaseDatabaseWrapper(local):
|
||||||
|
"""
|
||||||
|
Represents a database connection.
|
||||||
|
"""
|
||||||
|
ops = None
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.connection = None
|
self.connection = None
|
||||||
self.queries = []
|
self.queries = []
|
||||||
|
@ -34,3 +38,18 @@ class BaseDatabaseWrapper(local):
|
||||||
def make_debug_cursor(self, cursor):
|
def make_debug_cursor(self, cursor):
|
||||||
from django.db.backends import util
|
from django.db.backends import util
|
||||||
return util.CursorDebugWrapper(cursor, self)
|
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/
|
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:
|
try:
|
||||||
import adodbapi as Database
|
import adodbapi as Database
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
|
@ -48,7 +48,12 @@ def variantToPython(variant, adType):
|
||||||
return res
|
return res
|
||||||
Database.convertVariantToPython = variantToPython
|
Database.convertVariantToPython = variantToPython
|
||||||
|
|
||||||
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
pass
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
ops = DatabaseOperations()
|
||||||
|
|
||||||
def _cursor(self, settings):
|
def _cursor(self, settings):
|
||||||
if self.connection is None:
|
if self.connection is None:
|
||||||
if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
|
if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
|
||||||
|
@ -130,9 +135,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_autoinc_sql(table):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_sql_flush(style, tables, sequences):
|
def get_sql_flush(style, tables, sequences):
|
||||||
"""Return a list of SQL statements required to remove all data from
|
"""Return a list of SQL statements required to remove all data from
|
||||||
all tables in the database (without actually removing the tables
|
all tables in the database (without actually removing the tables
|
||||||
|
|
|
@ -21,7 +21,12 @@ class DatabaseError(Exception):
|
||||||
class IntegrityError(DatabaseError):
|
class IntegrityError(DatabaseError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class DatabaseWrapper:
|
class DatabaseOperations(object):
|
||||||
|
def __getattr__(self, *args, **kwargs):
|
||||||
|
complain()
|
||||||
|
|
||||||
|
class DatabaseWrapper(object):
|
||||||
|
ops = DatabaseOperations()
|
||||||
cursor = complain
|
cursor = complain
|
||||||
_commit = complain
|
_commit = complain
|
||||||
_rollback = ignore
|
_rollback = ignore
|
||||||
|
@ -50,7 +55,6 @@ get_drop_foreignkey_sql = complain
|
||||||
get_pk_default_value = complain
|
get_pk_default_value = complain
|
||||||
get_max_name_length = ignore
|
get_max_name_length = ignore
|
||||||
get_start_transaction_sql = complain
|
get_start_transaction_sql = complain
|
||||||
get_autoinc_sql = complain
|
|
||||||
get_sql_flush = complain
|
get_sql_flush = complain
|
||||||
get_sql_sequence_reset = complain
|
get_sql_sequence_reset = complain
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ MySQL database backend for Django.
|
||||||
Requires MySQLdb: http://sourceforge.net/projects/mysql-python
|
Requires MySQLdb: http://sourceforge.net/projects/mysql-python
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.db.backends import BaseDatabaseWrapper, util
|
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||||
try:
|
try:
|
||||||
import MySQLdb as Database
|
import MySQLdb as Database
|
||||||
except ImportError, e:
|
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
|
# standard util.CursorDebugWrapper can be used. Also, using sql_mode
|
||||||
# TRADITIONAL will automatically cause most warnings to be treated as errors.
|
# TRADITIONAL will automatically cause most warnings to be treated as errors.
|
||||||
|
|
||||||
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
pass
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
ops = DatabaseOperations()
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(DatabaseWrapper, self).__init__(**kwargs)
|
super(DatabaseWrapper, self).__init__(**kwargs)
|
||||||
self.server_version = None
|
self.server_version = None
|
||||||
|
@ -181,9 +186,6 @@ def get_max_name_length():
|
||||||
def get_start_transaction_sql():
|
def get_start_transaction_sql():
|
||||||
return "BEGIN;"
|
return "BEGIN;"
|
||||||
|
|
||||||
def get_autoinc_sql(table):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_sql_flush(style, tables, sequences):
|
def get_sql_flush(style, tables, sequences):
|
||||||
"""Return a list of SQL statements required to remove all data from
|
"""Return a list of SQL statements required to remove all data from
|
||||||
all tables in the database (without actually removing the tables
|
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
|
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
|
from django.utils.encoding import force_unicode
|
||||||
try:
|
try:
|
||||||
import MySQLdb as Database
|
import MySQLdb as Database
|
||||||
|
@ -63,7 +63,12 @@ class MysqlDebugWrapper:
|
||||||
else:
|
else:
|
||||||
return getattr(self.cursor, attr)
|
return getattr(self.cursor, attr)
|
||||||
|
|
||||||
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
pass
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
ops = DatabaseOperations()
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(DatabaseWrapper, self).__init__(**kwargs)
|
super(DatabaseWrapper, self).__init__(**kwargs)
|
||||||
self.server_version = None
|
self.server_version = None
|
||||||
|
@ -200,9 +205,6 @@ def get_max_name_length():
|
||||||
def get_start_transaction_sql():
|
def get_start_transaction_sql():
|
||||||
return "BEGIN;"
|
return "BEGIN;"
|
||||||
|
|
||||||
def get_autoinc_sql(table):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_sql_flush(style, tables, sequences):
|
def get_sql_flush(style, tables, sequences):
|
||||||
"""Return a list of SQL statements required to remove all data from
|
"""Return a list of SQL statements required to remove all data from
|
||||||
all tables in the database (without actually removing the tables
|
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/
|
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.datastructures import SortedDict
|
||||||
from django.utils.encoding import smart_str, force_unicode
|
from django.utils.encoding import smart_str, force_unicode
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -21,7 +21,26 @@ except ImportError, e:
|
||||||
DatabaseError = Database.Error
|
DatabaseError = Database.Error
|
||||||
IntegrityError = Database.IntegrityError
|
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):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
ops = DatabaseOperations()
|
||||||
|
|
||||||
def _valid_connection(self):
|
def _valid_connection(self):
|
||||||
return self.connection is not None
|
return self.connection is not None
|
||||||
|
|
||||||
|
@ -187,22 +206,6 @@ def get_start_transaction_sql():
|
||||||
def get_tablespace_sql(tablespace, inline=False):
|
def get_tablespace_sql(tablespace, inline=False):
|
||||||
return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), quote_name(tablespace))
|
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):
|
def get_drop_sequence(table):
|
||||||
return "DROP SEQUENCE %s;" % quote_name(get_sequence_name(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.utils.encoding import smart_str, smart_unicode
|
||||||
from django.db.backends import BaseDatabaseWrapper, util
|
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||||
try:
|
try:
|
||||||
import psycopg as Database
|
import psycopg as Database
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
|
@ -57,7 +57,12 @@ class UnicodeCursorWrapper(object):
|
||||||
|
|
||||||
postgres_version = None
|
postgres_version = None
|
||||||
|
|
||||||
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
pass
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
ops = DatabaseOperations()
|
||||||
|
|
||||||
def _cursor(self, settings):
|
def _cursor(self, settings):
|
||||||
set_tz = False
|
set_tz = False
|
||||||
if self.connection is None:
|
if self.connection is None:
|
||||||
|
@ -157,9 +162,6 @@ def get_max_name_length():
|
||||||
def get_start_transaction_sql():
|
def get_start_transaction_sql():
|
||||||
return "BEGIN;"
|
return "BEGIN;"
|
||||||
|
|
||||||
def get_autoinc_sql(table):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_sql_flush(style, tables, sequences):
|
def get_sql_flush(style, tables, sequences):
|
||||||
"""Return a list of SQL statements required to remove all data from
|
"""Return a list of SQL statements required to remove all data from
|
||||||
all tables in the database (without actually removing the tables
|
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
|
Requires psycopg 2: http://initd.org/projects/psycopg2
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.db.backends import BaseDatabaseWrapper, util
|
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
|
||||||
try:
|
try:
|
||||||
import psycopg2 as Database
|
import psycopg2 as Database
|
||||||
import psycopg2.extensions
|
import psycopg2.extensions
|
||||||
|
@ -19,7 +19,12 @@ psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
|
||||||
|
|
||||||
postgres_version = None
|
postgres_version = None
|
||||||
|
|
||||||
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
pass
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
ops = DatabaseOperations()
|
||||||
|
|
||||||
def _cursor(self, settings):
|
def _cursor(self, settings):
|
||||||
set_tz = False
|
set_tz = False
|
||||||
if self.connection is None:
|
if self.connection is None:
|
||||||
|
@ -111,9 +116,6 @@ def get_max_name_length():
|
||||||
def get_start_transaction_sql():
|
def get_start_transaction_sql():
|
||||||
return "BEGIN;"
|
return "BEGIN;"
|
||||||
|
|
||||||
def get_autoinc_sql(table):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_sql_flush(style, tables, sequences):
|
def get_sql_flush(style, tables, sequences):
|
||||||
"""Return a list of SQL statements required to remove all data from
|
"""Return a list of SQL statements required to remove all data from
|
||||||
all tables in the database (without actually removing the tables
|
all tables in the database (without actually removing the tables
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
SQLite3 backend for django. Requires pysqlite2 (http://pysqlite.org/).
|
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:
|
||||||
try:
|
try:
|
||||||
from sqlite3 import dbapi2 as Database
|
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_converter("decimal", util.typecast_decimal)
|
||||||
Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
|
Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
|
||||||
|
|
||||||
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
pass
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
ops = DatabaseOperations()
|
||||||
|
|
||||||
def _cursor(self, settings):
|
def _cursor(self, settings):
|
||||||
if self.connection is None:
|
if self.connection is None:
|
||||||
kwargs = {
|
kwargs = {
|
||||||
|
@ -143,9 +148,6 @@ def get_max_name_length():
|
||||||
def get_start_transaction_sql():
|
def get_start_transaction_sql():
|
||||||
return "BEGIN;"
|
return "BEGIN;"
|
||||||
|
|
||||||
def get_autoinc_sql(table):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_sql_flush(style, tables, sequences):
|
def get_sql_flush(style, tables, sequences):
|
||||||
"""
|
"""
|
||||||
Return a list of SQL statements required to remove all data from
|
Return a list of SQL statements required to remove all data from
|
||||||
|
|
Loading…
Reference in New Issue