Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Began implementing BaseDatabaseOperations class for every database ba…

…ckend. 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
  • Loading branch information...
commit 38b5d7f23d8f7a39646a9b298f10941a70585031 1 parent 7c41b19
Adrian Holovaty authored August 19, 2007
8  django/core/management/sql.py
@@ -213,7 +213,7 @@ def sql_model_create(model, style, known_models=set()):
213 213
     Returns the SQL required to create a single model, as a tuple of:
214 214
         (list_of_sql, pending_references_dict)
215 215
     """
216  
-    from django.db import backend, models
  216
+    from django.db import backend, connection, models
217 217
 
218 218
     opts = model._meta
219 219
     final_output = []
@@ -267,9 +267,9 @@ def sql_model_create(model, style, known_models=set()):
267 267
     full_statement.append(';')
268 268
     final_output.append('\n'.join(full_statement))
269 269
 
270  
-    if opts.has_auto_field and hasattr(backend, 'get_autoinc_sql'):
271  
-        # Add any extra SQL needed to support auto-incrementing primary keys
272  
-        autoinc_sql = backend.get_autoinc_sql(opts.db_table)
  270
+    if opts.has_auto_field:
  271
+        # Add any extra SQL needed to support auto-incrementing primary keys.
  272
+        autoinc_sql = connection.ops.autoinc_sql(opts.db_table)
273 273
         if autoinc_sql:
274 274
             for stmt in autoinc_sql:
275 275
                 final_output.append(stmt)
19  django/db/backends/__init__.py
@@ -6,6 +6,10 @@
6 6
     from django.utils._threading_local import local
7 7
 
8 8
 class BaseDatabaseWrapper(local):
  9
+    """
  10
+    Represents a database connection.
  11
+    """
  12
+    ops = None
9 13
     def __init__(self, **kwargs):
10 14
         self.connection = None
11 15
         self.queries = []
@@ -34,3 +38,18 @@ def cursor(self):
34 38
     def make_debug_cursor(self, cursor):
35 39
         from django.db.backends import util
36 40
         return util.CursorDebugWrapper(cursor, self)
  41
+
  42
+class BaseDatabaseOperations(object):
  43
+    """
  44
+    This class encapsulates all backend-specific differences, such as the way
  45
+    a backend performs ordering or calculates the ID of a recently-inserted
  46
+    row.
  47
+    """
  48
+    def autoinc_sql(self, table):
  49
+        """
  50
+        Returns any SQL needed to support auto-incrementing primary keys, or
  51
+        None if no SQL is necessary.
  52
+
  53
+        This SQL is executed when a table is created.
  54
+        """
  55
+        return None
10  django/db/backends/ado_mssql/base.py
@@ -4,7 +4,7 @@
4 4
 Requires adodbapi 2.0.1: http://adodbapi.sourceforge.net/
5 5
 """
6 6
 
7  
-from django.db.backends import BaseDatabaseWrapper, util
  7
+from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
8 8
 try:
9 9
     import adodbapi as Database
10 10
 except ImportError, e:
@@ -48,7 +48,12 @@ def variantToPython(variant, adType):
48 48
     return res
49 49
 Database.convertVariantToPython = variantToPython
50 50
 
  51
+class DatabaseOperations(BaseDatabaseOperations):
  52
+    pass
  53
+
51 54
 class DatabaseWrapper(BaseDatabaseWrapper):
  55
+    ops = DatabaseOperations()
  56
+
52 57
     def _cursor(self, settings):
53 58
         if self.connection is None:
54 59
             if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
@@ -130,9 +135,6 @@ def get_start_transaction_sql():
130 135
 def get_tablespace_sql(tablespace, inline=False):
131 136
     return "ON %s" % quote_name(tablespace)
132 137
 
133  
-def get_autoinc_sql(table):
134  
-    return None
135  
-
136 138
 def get_sql_flush(style, tables, sequences):
137 139
     """Return a list of SQL statements required to remove all data from
138 140
     all tables in the database (without actually removing the tables
8  django/db/backends/dummy/base.py
@@ -21,7 +21,12 @@ class DatabaseError(Exception):
21 21
 class IntegrityError(DatabaseError):
22 22
     pass
23 23
 
24  
-class DatabaseWrapper:
  24
+class DatabaseOperations(object):
  25
+    def __getattr__(self, *args, **kwargs):
  26
+        complain()
  27
+
  28
+class DatabaseWrapper(object):
  29
+    ops = DatabaseOperations()
25 30
     cursor = complain
26 31
     _commit = complain
27 32
     _rollback = ignore
@@ -50,7 +55,6 @@ def close(self):
50 55
 get_pk_default_value = complain
51 56
 get_max_name_length = ignore
52 57
 get_start_transaction_sql = complain
53  
-get_autoinc_sql = complain
54 58
 get_sql_flush = complain
55 59
 get_sql_sequence_reset = complain
56 60
 
10  django/db/backends/mysql/base.py
@@ -4,7 +4,7 @@
4 4
 Requires MySQLdb: http://sourceforge.net/projects/mysql-python
5 5
 """
6 6
 
7  
-from django.db.backends import BaseDatabaseWrapper, util
  7
+from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
8 8
 try:
9 9
     import MySQLdb as Database
10 10
 except ImportError, e:
@@ -53,7 +53,12 @@
53 53
 # standard util.CursorDebugWrapper can be used. Also, using sql_mode
54 54
 # TRADITIONAL will automatically cause most warnings to be treated as errors.
55 55
 
  56
+class DatabaseOperations(BaseDatabaseOperations):
  57
+    pass
  58
+
56 59
 class DatabaseWrapper(BaseDatabaseWrapper):
  60
+    ops = DatabaseOperations()
  61
+
57 62
     def __init__(self, **kwargs):
58 63
         super(DatabaseWrapper, self).__init__(**kwargs)
59 64
         self.server_version = None
@@ -181,9 +186,6 @@ def get_max_name_length():
181 186
 def get_start_transaction_sql():
182 187
     return "BEGIN;"
183 188
 
184  
-def get_autoinc_sql(table):
185  
-    return None
186  
-
187 189
 def get_sql_flush(style, tables, sequences):
188 190
     """Return a list of SQL statements required to remove all data from
189 191
     all tables in the database (without actually removing the tables
10  django/db/backends/mysql_old/base.py
@@ -4,7 +4,7 @@
4 4
 Requires MySQLdb: http://sourceforge.net/projects/mysql-python
5 5
 """
6 6
 
7  
-from django.db.backends import BaseDatabaseWrapper, util
  7
+from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
8 8
 from django.utils.encoding import force_unicode
9 9
 try:
10 10
     import MySQLdb as Database
@@ -63,7 +63,12 @@ def __getattr__(self, attr):
63 63
         else:
64 64
             return getattr(self.cursor, attr)
65 65
 
  66
+class DatabaseOperations(BaseDatabaseOperations):
  67
+    pass
  68
+
66 69
 class DatabaseWrapper(BaseDatabaseWrapper):
  70
+    ops = DatabaseOperations()
  71
+
67 72
     def __init__(self, **kwargs):
68 73
         super(DatabaseWrapper, self).__init__(**kwargs)
69 74
         self.server_version = None
@@ -200,9 +205,6 @@ def get_max_name_length():
200 205
 def get_start_transaction_sql():
201 206
     return "BEGIN;"
202 207
 
203  
-def get_autoinc_sql(table):
204  
-    return None
205  
-
206 208
 def get_sql_flush(style, tables, sequences):
207 209
     """Return a list of SQL statements required to remove all data from
208 210
     all tables in the database (without actually removing the tables
37  django/db/backends/oracle/base.py
@@ -4,7 +4,7 @@
4 4
 Requires cx_Oracle: http://www.python.net/crew/atuining/cx_Oracle/
5 5
 """
6 6
 
7  
-from django.db.backends import BaseDatabaseWrapper, util
  7
+from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
8 8
 from django.utils.datastructures import SortedDict
9 9
 from django.utils.encoding import smart_str, force_unicode
10 10
 import datetime
@@ -21,7 +21,26 @@
21 21
 DatabaseError = Database.Error
22 22
 IntegrityError = Database.IntegrityError
23 23
 
  24
+class DatabaseOperations(BaseDatabaseOperations):
  25
+    def autoinc_sql(self, table):
  26
+        # To simulate auto-incrementing primary keys in Oracle, we have to
  27
+        # create a sequence and a trigger.
  28
+        sq_name = get_sequence_name(table)
  29
+        tr_name = get_trigger_name(table)
  30
+        sequence_sql = 'CREATE SEQUENCE %s;' % sq_name
  31
+        trigger_sql = """
  32
+            CREATE OR REPLACE TRIGGER %s
  33
+            BEFORE INSERT ON %s
  34
+            FOR EACH ROW
  35
+            WHEN (new.id IS NULL)
  36
+                BEGIN
  37
+                    SELECT %s.nextval INTO :new.id FROM dual;
  38
+                END;/""" % (tr_name, quote_name(table), sq_name)
  39
+        return sequence_sql, trigger_sql
  40
+
24 41
 class DatabaseWrapper(BaseDatabaseWrapper):
  42
+    ops = DatabaseOperations()
  43
+
25 44
     def _valid_connection(self):
26 45
         return self.connection is not None
27 46
 
@@ -187,22 +206,6 @@ def get_start_transaction_sql():
187 206
 def get_tablespace_sql(tablespace, inline=False):
188 207
     return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), quote_name(tablespace))
189 208
 
190  
-def get_autoinc_sql(table):
191  
-    # To simulate auto-incrementing primary keys in Oracle, we have to
192  
-    # create a sequence and a trigger.
193  
-    sq_name = get_sequence_name(table)
194  
-    tr_name = get_trigger_name(table)
195  
-    sequence_sql = 'CREATE SEQUENCE %s;' % sq_name
196  
-    trigger_sql = """CREATE OR REPLACE TRIGGER %s
197  
-  BEFORE INSERT ON %s
198  
-  FOR EACH ROW
199  
-  WHEN (new.id IS NULL)
200  
-    BEGIN
201  
-      SELECT %s.nextval INTO :new.id FROM dual;
202  
-    END;
203  
-    /""" % (tr_name, quote_name(table), sq_name)
204  
-    return sequence_sql, trigger_sql
205  
-
206 209
 def get_drop_sequence(table):
207 210
     return "DROP SEQUENCE %s;" % quote_name(get_sequence_name(table))
208 211
 
10  django/db/backends/postgresql/base.py
@@ -5,7 +5,7 @@
5 5
 """
6 6
 
7 7
 from django.utils.encoding import smart_str, smart_unicode
8  
-from django.db.backends import BaseDatabaseWrapper, util
  8
+from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
9 9
 try:
10 10
     import psycopg as Database
11 11
 except ImportError, e:
@@ -57,7 +57,12 @@ def __getattr__(self, attr):
57 57
 
58 58
 postgres_version = None
59 59
 
  60
+class DatabaseOperations(BaseDatabaseOperations):
  61
+    pass
  62
+
60 63
 class DatabaseWrapper(BaseDatabaseWrapper):
  64
+    ops = DatabaseOperations()
  65
+
61 66
     def _cursor(self, settings):
62 67
         set_tz = False
63 68
         if self.connection is None:
@@ -157,9 +162,6 @@ def get_max_name_length():
157 162
 def get_start_transaction_sql():
158 163
     return "BEGIN;"
159 164
 
160  
-def get_autoinc_sql(table):
161  
-    return None
162  
-
163 165
 def get_sql_flush(style, tables, sequences):
164 166
     """Return a list of SQL statements required to remove all data from
165 167
     all tables in the database (without actually removing the tables
10  django/db/backends/postgresql_psycopg2/base.py
@@ -4,7 +4,7 @@
4 4
 Requires psycopg 2: http://initd.org/projects/psycopg2
5 5
 """
6 6
 
7  
-from django.db.backends import BaseDatabaseWrapper, util
  7
+from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
8 8
 try:
9 9
     import psycopg2 as Database
10 10
     import psycopg2.extensions
@@ -19,7 +19,12 @@
19 19
 
20 20
 postgres_version = None
21 21
 
  22
+class DatabaseOperations(BaseDatabaseOperations):
  23
+    pass
  24
+
22 25
 class DatabaseWrapper(BaseDatabaseWrapper):
  26
+    ops = DatabaseOperations()
  27
+
23 28
     def _cursor(self, settings):
24 29
         set_tz = False
25 30
         if self.connection is None:
@@ -111,9 +116,6 @@ def get_max_name_length():
111 116
 def get_start_transaction_sql():
112 117
     return "BEGIN;"
113 118
 
114  
-def get_autoinc_sql(table):
115  
-    return None
116  
-
117 119
 def get_sql_flush(style, tables, sequences):
118 120
     """Return a list of SQL statements required to remove all data from
119 121
     all tables in the database (without actually removing the tables
10  django/db/backends/sqlite3/base.py
@@ -2,7 +2,7 @@
2 2
 SQLite3 backend for django.  Requires pysqlite2 (http://pysqlite.org/).
3 3
 """
4 4
 
5  
-from django.db.backends import BaseDatabaseWrapper, util
  5
+from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
6 6
 try:
7 7
     try:
8 8
         from sqlite3 import dbapi2 as Database
@@ -34,7 +34,12 @@
34 34
 Database.register_converter("decimal", util.typecast_decimal)
35 35
 Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
36 36
 
  37
+class DatabaseOperations(BaseDatabaseOperations):
  38
+    pass
  39
+
37 40
 class DatabaseWrapper(BaseDatabaseWrapper):
  41
+    ops = DatabaseOperations()
  42
+
38 43
     def _cursor(self, settings):
39 44
         if self.connection is None:
40 45
             kwargs = {
@@ -143,9 +148,6 @@ def get_max_name_length():
143 148
 def get_start_transaction_sql():
144 149
     return "BEGIN;"
145 150
 
146  
-def get_autoinc_sql(table):
147  
-    return None
148  
-
149 151
 def get_sql_flush(style, tables, sequences):
150 152
     """
151 153
     Return a list of SQL statements required to remove all data from

0 notes on commit 38b5d7f

Please sign in to comment.
Something went wrong with that request. Please try again.