mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	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:
		| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user