Ticket #5106: backend-refactoring-v2-correct-bitrot.patch
File backend-refactoring-v2-correct-bitrot.patch, 72.2 KB (added by , 17 years ago) |
---|
-
django/contrib/auth/models.py
=== modified file 'django/contrib/auth/models.py'
1 1 from django.core import validators 2 2 from django.core.exceptions import ImproperlyConfigured 3 from django.db import backend,connection, models3 from django.db import connection, models 4 4 from django.contrib.contenttypes.models import ContentType 5 5 from django.utils.encoding import smart_str 6 6 from django.utils.translation import ugettext_lazy as _ … … 210 210 AND gp.%s = ug.%s 211 211 AND ct.%s = p.%s 212 212 AND ug.%s = %%s""" % ( 213 backend.quote_name('app_label'), backend.quote_name('codename'),214 backend.quote_name('auth_permission'), backend.quote_name('auth_group_permissions'),215 backend.quote_name('auth_user_groups'), backend.quote_name('django_content_type'),216 backend.quote_name('id'), backend.quote_name('permission_id'),217 backend.quote_name('group_id'), backend.quote_name('group_id'),218 backend.quote_name('id'), backend.quote_name('content_type_id'),219 backend.quote_name('user_id'),)213 connection.ops.quote_name('app_label'), connection.ops.quote_name('codename'), 214 connection.ops.quote_name('auth_permission'), connection.ops.quote_name('auth_group_permissions'), 215 connection.ops.quote_name('auth_user_groups'), connection.ops.quote_name('django_content_type'), 216 connection.ops.quote_name('id'), connection.ops.quote_name('permission_id'), 217 connection.ops.quote_name('group_id'), connection.ops.quote_name('group_id'), 218 connection.ops.quote_name('id'), connection.ops.quote_name('content_type_id'), 219 connection.ops.quote_name('user_id'),) 220 220 cursor.execute(sql, [self.id]) 221 221 self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) 222 222 return self._group_perm_cache -
django/contrib/contenttypes/generic.py
=== modified file 'django/contrib/contenttypes/generic.py'
4 4 5 5 from django import oldforms 6 6 from django.core.exceptions import ObjectDoesNotExist 7 from django.db import backend7 from django.db import connection 8 8 from django.db.models import signals 9 9 from django.db.models.fields.related import RelatedField, Field, ManyToManyRel 10 10 from django.db.models.loading import get_model … … 167 167 model = rel_model, 168 168 instance = instance, 169 169 symmetrical = (self.field.rel.symmetrical and instance.__class__ == rel_model), 170 join_table = backend.quote_name(self.field.m2m_db_table()),171 source_col_name = backend.quote_name(self.field.m2m_column_name()),172 target_col_name = backend.quote_name(self.field.m2m_reverse_name()),170 join_table = connection.ops.quote_name(self.field.m2m_db_table()), 171 source_col_name = connection.ops.quote_name(self.field.m2m_column_name()), 172 target_col_name = connection.ops.quote_name(self.field.m2m_reverse_name()), 173 173 content_type = ContentType.objects.get_for_model(self.field.model), 174 174 content_type_field_name = self.field.content_type_field_name, 175 175 object_id_field_name = self.field.object_id_field_name -
django/core/management/base.py
=== modified file 'django/core/management/base.py'
34 34 if output: 35 35 if self.output_transaction: 36 36 # This needs to be imported here, because it relies on settings. 37 from django.db import backend 38 if backend.get_start_transaction_sql(): 39 print self.style.SQL_KEYWORD(backend.get_start_transaction_sql()) 37 from django.db import connection 38 s = connection.get_start_transaction_sql() 39 if s: 40 print self.style.SQL_KEYWORD(s) 40 41 print output 41 42 if self.output_transaction: 42 43 print self.style.SQL_KEYWORD("COMMIT;") -
django/core/management/commands/createcachetable.py
=== modified file 'django/core/management/commands/createcachetable.py'
8 8 requires_model_validation = False 9 9 10 10 def handle_label(self, tablename, **options): 11 from django.db import backend,connection, transaction, models11 from django.db import connection, transaction, models 12 12 fields = ( 13 13 # "key" is a reserved word in MySQL, so use "cache_key" instead. 14 14 models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), … … 18 18 table_output = [] 19 19 index_output = [] 20 20 for f in fields: 21 field_output = [ backend.quote_name(f.name), f.db_type()]21 field_output = [connection.ops.quote_name(f.name), f.db_type()] 22 22 field_output.append("%sNULL" % (not f.null and "NOT " or "")) 23 23 if f.unique: 24 24 field_output.append("UNIQUE") … … 27 27 if f.db_index: 28 28 unique = f.unique and "UNIQUE " or "" 29 29 index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ 30 (unique, tablename, f.name, backend.quote_name(tablename),31 backend.quote_name(f.name)))30 (unique, tablename, f.name, connection.ops.quote_name(tablename), 31 connection.ops.quote_name(f.name))) 32 32 table_output.append(" ".join(field_output)) 33 full_statement = ["CREATE TABLE %s (" % backend.quote_name(tablename)]33 full_statement = ["CREATE TABLE %s (" % connection.ops.quote_name(tablename)] 34 34 for i, line in enumerate(table_output): 35 35 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) 36 36 full_statement.append(');') -
django/core/management/commands/loaddata.py
=== modified file 'django/core/management/commands/loaddata.py'
15 15 def handle(self, *fixture_labels, **options): 16 16 from django.db.models import get_apps 17 17 from django.core import serializers 18 from django.db import connection, transaction, backend18 from django.db import connection, transaction, connection 19 19 from django.conf import settings 20 20 21 21 self.style = no_style() … … 105 105 (format, fixture_name, humanize(fixture_dir)) 106 106 107 107 if count[0] > 0: 108 sequence_sql = backend.get_sql_sequence_reset(self.style, models)108 sequence_sql = connection.ops.get_sql_sequence_reset(self.style, models) 109 109 if sequence_sql: 110 110 if verbosity > 1: 111 111 print "Resetting sequences" -
django/core/management/commands/sqlsequencereset.py
=== modified file 'django/core/management/commands/sqlsequencereset.py'
5 5 output_transaction = True 6 6 7 7 def handle_app(self, app, **options): 8 from django.db import backend, models9 return '\n'.join( backend.get_sql_sequence_reset(self.style, models.get_models(app)))8 from django.db import connection, models 9 return '\n'.join(connection.ops.get_sql_sequence_reset(self.style, models.get_models(app))) -
django/core/management/commands/syncdb.py
=== modified file 'django/core/management/commands/syncdb.py'
12 12 args = '[--verbosity] [--noinput]' 13 13 14 14 def handle_noargs(self, **options): 15 from django.db import backend,connection, transaction, models15 from django.db import connection, transaction, models 16 16 from django.conf import settings 17 17 from django.core.management.sql import table_list, installed_models, sql_model_create, sql_for_pending_references, many_to_many_sql_for_model, custom_sql_for_model, sql_indexes_for_model, emit_post_sync_signal 18 18 … … 34 34 # Get a list of all existing database tables, 35 35 # so we know what needs to be added. 36 36 table_list = table_list() 37 if backend.uses_case_insensitive_names:37 if connection.capabilities.uses_case_insensitive_names: 38 38 table_name_converter = str.upper 39 39 else: 40 40 table_name_converter = lambda x: x -
django/core/management/sql.py
=== modified file 'django/core/management/sql.py'
15 15 16 16 def installed_models(table_list): 17 17 "Returns a set of all models that are installed, given a list of existing table names." 18 from django.db import backend, models18 from django.db import connection, models 19 19 all_models = [] 20 20 for app in models.get_apps(): 21 21 for model in models.get_models(app): 22 22 all_models.append(model) 23 if backend.uses_case_insensitive_names:23 if connection.capabilities.uses_case_insensitive_names: 24 24 converter = lambda x: x.upper() 25 25 else: 26 26 converter = lambda x: x … … 95 95 96 96 def sql_delete(app, style): 97 97 "Returns a list of the DROP TABLE SQL statements for the given app." 98 from django.db import backend,connection, models, get_introspection_module98 from django.db import connection, models, get_introspection_module 99 99 from django.db.backends.util import truncate_name 100 100 introspection = get_introspection_module() 101 101 102 capabilities, ops = connection.capabilities, connection.ops 103 quote_name = ops 104 102 105 # This should work even if a connection isn't available 103 106 try: 104 107 cursor = connection.cursor() … … 110 113 table_names = introspection.get_table_list(cursor) 111 114 else: 112 115 table_names = [] 113 if backend.uses_case_insensitive_names:116 if connection.capabilities.uses_case_insensitive_names: 114 117 table_name_converter = str.upper 115 118 else: 116 119 table_name_converter = lambda x: x … … 136 139 if cursor and table_name_converter(model._meta.db_table) in table_names: 137 140 # Drop the table now 138 141 output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'), 139 style.SQL_TABLE( backend.quote_name(model._meta.db_table))))140 if backend.supports_constraints and model in references_to_delete:142 style.SQL_TABLE(quote_name(model._meta.db_table)))) 143 if capabilities.supports_constraints and model in references_to_delete: 141 144 for rel_class, f in references_to_delete[model]: 142 145 table = rel_class._meta.db_table 143 146 col = f.column … … 146 149 r_name = '%s_refs_%s_%x' % (col, r_col, abs(hash((table, r_table)))) 147 150 output.append('%s %s %s %s;' % \ 148 151 (style.SQL_KEYWORD('ALTER TABLE'), 149 style.SQL_TABLE( backend.quote_name(table)),150 style.SQL_KEYWORD( backend.get_drop_foreignkey_sql()),151 style.SQL_FIELD(truncate_name(r_name, backend.get_max_name_length()))))152 style.SQL_TABLE(quote_name(table)), 153 style.SQL_KEYWORD(ops.get_drop_foreignkey_sql()), 154 style.SQL_FIELD(truncate_name(r_name, ops.get_max_name_length())))) 152 155 del references_to_delete[model] 153 if model._meta.has_auto_field and hasattr( backend, 'get_drop_sequence'):154 output.append( backend.get_drop_sequence(model._meta.db_table))156 if model._meta.has_auto_field and hasattr(ops, 'get_drop_sequence'): 157 output.append(ops.get_drop_sequence(model._meta.db_table)) 155 158 156 159 # Output DROP TABLE statements for many-to-many tables. 157 160 for model in app_models: … … 159 162 for f in opts.many_to_many: 160 163 if cursor and table_name_converter(f.m2m_db_table()) in table_names: 161 164 output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'), 162 style.SQL_TABLE( backend.quote_name(f.m2m_db_table()))))163 if hasattr( backend, 'get_drop_sequence'):164 output.append( backend.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column)))165 style.SQL_TABLE(quote_name(f.m2m_db_table())))) 166 if hasattr(ops, 'get_drop_sequence'): 167 output.append(ops.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column))) 165 168 166 169 app_label = app_models[0]._meta.app_label 167 170 … … 179 182 180 183 def sql_flush(style): 181 184 "Returns a list of the SQL statements used to flush the database" 182 from django.db import backend 183 statements = backend.get_sql_flush(style, table_list(), sequence_list()) 184 return statements 185 from django.db import connection 186 return connection.ops.get_sql_flush(style, table_list(), sequence_list()) 185 187 186 188 def sql_custom(app): 187 189 "Returns a list of the custom table modifying SQL statements for the given app." … … 213 215 Returns the SQL required to create a single model, as a tuple of: 214 216 (list_of_sql, pending_references_dict) 215 217 """ 216 from django.db import backend, models 218 from django.db import connection, models 219 220 capabilities, ops = connection.capabilities, connection.ops 221 quote_name = ops.quote_name 217 222 218 223 opts = model._meta 219 224 final_output = [] … … 227 232 # database columns in this table. 228 233 continue 229 234 # Make the definition (e.g. 'foo VARCHAR(30)') for this field. 230 field_output = [style.SQL_FIELD( backend.quote_name(f.column)),235 field_output = [style.SQL_FIELD(quote_name(f.column)), 231 236 style.SQL_COLTYPE(col_type)] 232 237 field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) 233 if f.unique and (not f.primary_key or backend.allows_unique_and_pk):238 if f.unique and (not f.primary_key or capabilities.allows_unique_and_pk): 234 239 field_output.append(style.SQL_KEYWORD('UNIQUE')) 235 240 if f.primary_key: 236 241 field_output.append(style.SQL_KEYWORD('PRIMARY KEY')) 237 if tablespace and backend.supports_tablespaces and (f.unique or f.primary_key) and backend.autoindexes_primary_keys:242 if tablespace and capabilities.supports_tablespaces and (f.unique or f.primary_key) and capabilities.autoindexes_primary_keys: 238 243 # We must specify the index tablespace inline, because we 239 244 # won't be generating a CREATE INDEX statement for this field. 240 field_output.append( backend.get_tablespace_sql(tablespace, inline=True))245 field_output.append(ops.get_tablespace_sql(tablespace, inline=True)) 241 246 if f.rel: 242 247 if f.rel.to in known_models: 243 248 field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ 244 style.SQL_TABLE( backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \245 style.SQL_FIELD( backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' +246 backend.get_deferrable_sql()249 style.SQL_TABLE(quote_name(f.rel.to._meta.db_table)) + ' (' + \ 250 style.SQL_FIELD(quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + 251 ops.get_deferrable_sql() 247 252 ) 248 253 else: 249 254 # We haven't yet created the table to which this field … … 251 256 pr = pending_references.setdefault(f.rel.to, []).append((model, f)) 252 257 table_output.append(' '.join(field_output)) 253 258 if opts.order_with_respect_to: 254 table_output.append(style.SQL_FIELD( backend.quote_name('_order')) + ' ' + \259 table_output.append(style.SQL_FIELD(quote_name('_order')) + ' ' + \ 255 260 style.SQL_COLTYPE(models.IntegerField().db_type()) + ' ' + \ 256 261 style.SQL_KEYWORD('NULL')) 257 262 for field_constraints in opts.unique_together: 258 263 table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ 259 ", ".join([ backend.quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints]))264 ", ".join([quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints])) 260 265 261 full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE( backend.quote_name(opts.db_table)) + ' (']266 full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(quote_name(opts.db_table)) + ' ('] 262 267 for i, line in enumerate(table_output): # Combine and add commas. 263 268 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) 264 269 full_statement.append(')') 265 if opts.db_tablespace and backend.supports_tablespaces:266 full_statement.append( backend.get_tablespace_sql(opts.db_tablespace))270 if opts.db_tablespace and capabilities.supports_tablespaces: 271 full_statement.append(ops.get_tablespace_sql(opts.db_tablespace)) 267 272 full_statement.append(';') 268 273 final_output.append('\n'.join(full_statement)) 269 274 270 if opts.has_auto_field and hasattr(backend, 'get_autoinc_sql'):275 if opts.has_auto_field: 271 276 # Add any extra SQL needed to support auto-incrementing primary keys 272 autoinc_sql = backend.get_autoinc_sql(opts.db_table)277 autoinc_sql = ops.get_autoinc_sql(opts.db_table) 273 278 if autoinc_sql: 274 279 for stmt in autoinc_sql: 275 280 final_output.append(stmt) … … 280 285 """ 281 286 Returns any ALTER TABLE statements to add constraints after the fact. 282 287 """ 283 from django.db import backend288 from django.db import connection 284 289 from django.db.backends.util import truncate_name 285 290 291 ops = connection.ops 292 286 293 final_output = [] 287 if backend.supports_constraints:294 if connection.capabilities.supports_constraints: 288 295 opts = model._meta 289 296 if model in pending_references: 290 297 for rel_class, f in pending_references[model]: … … 297 304 # So we are careful with character usage here. 298 305 r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table)))) 299 306 final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \ 300 ( backend.quote_name(r_table), truncate_name(r_name, backend.get_max_name_length()),301 backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col),302 backend.get_deferrable_sql()))307 (ops.quote_name(r_table), truncate_name(r_name, ops.get_max_name_length()), 308 ops.quote_name(r_col), ops.quote_name(table), ops.quote_name(col), 309 ops.get_deferrable_sql())) 303 310 del pending_references[model] 304 311 return final_output 305 312 306 313 def many_to_many_sql_for_model(model, style): 307 from django.db import backend, models314 from django.db import connection, models 308 315 from django.contrib.contenttypes import generic 309 316 317 ops, capabilities = connection.ops, connection.capabilities 318 310 319 opts = model._meta 311 320 final_output = [] 312 321 for f in opts.many_to_many: 313 322 if not isinstance(f.rel, generic.GenericRel): 314 323 tablespace = f.db_tablespace or opts.db_tablespace 315 if tablespace and backend.supports_tablespaces and backend.autoindexes_primary_keys:316 tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace, inline=True)324 if tablespace and capabilities.supports_tablespaces and capabilities.autoindexes_primary_keys: 325 tablespace_sql = ' ' + ops.get_tablespace_sql(tablespace, inline=True) 317 326 else: 318 327 tablespace_sql = '' 319 328 table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ 320 style.SQL_TABLE( backend.quote_name(f.m2m_db_table())) + ' (']329 style.SQL_TABLE(ops.quote_name(f.m2m_db_table())) + ' ('] 321 330 table_output.append(' %s %s %s%s,' % \ 322 (style.SQL_FIELD( backend.quote_name('id')),331 (style.SQL_FIELD(ops.quote_name('id')), 323 332 style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()), 324 333 style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), 325 334 tablespace_sql)) 326 335 table_output.append(' %s %s %s %s (%s)%s,' % \ 327 (style.SQL_FIELD( backend.quote_name(f.m2m_column_name())),336 (style.SQL_FIELD(ops.quote_name(f.m2m_column_name())), 328 337 style.SQL_COLTYPE(models.ForeignKey(model).db_type()), 329 338 style.SQL_KEYWORD('NOT NULL REFERENCES'), 330 style.SQL_TABLE( backend.quote_name(opts.db_table)),331 style.SQL_FIELD( backend.quote_name(opts.pk.column)),332 backend.get_deferrable_sql()))339 style.SQL_TABLE(ops.quote_name(opts.db_table)), 340 style.SQL_FIELD(ops.quote_name(opts.pk.column)), 341 ops.get_deferrable_sql())) 333 342 table_output.append(' %s %s %s %s (%s)%s,' % \ 334 (style.SQL_FIELD( backend.quote_name(f.m2m_reverse_name())),343 (style.SQL_FIELD(ops.quote_name(f.m2m_reverse_name())), 335 344 style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), 336 345 style.SQL_KEYWORD('NOT NULL REFERENCES'), 337 style.SQL_TABLE( backend.quote_name(f.rel.to._meta.db_table)),338 style.SQL_FIELD( backend.quote_name(f.rel.to._meta.pk.column)),339 backend.get_deferrable_sql()))346 style.SQL_TABLE(ops.quote_name(f.rel.to._meta.db_table)), 347 style.SQL_FIELD(ops.quote_name(f.rel.to._meta.pk.column)), 348 ops.get_deferrable_sql())) 340 349 table_output.append(' %s (%s, %s)%s' % \ 341 350 (style.SQL_KEYWORD('UNIQUE'), 342 style.SQL_FIELD( backend.quote_name(f.m2m_column_name())),343 style.SQL_FIELD( backend.quote_name(f.m2m_reverse_name())),351 style.SQL_FIELD(ops.quote_name(f.m2m_column_name())), 352 style.SQL_FIELD(ops.quote_name(f.m2m_reverse_name())), 344 353 tablespace_sql)) 345 354 table_output.append(')') 346 if opts.db_tablespace and backend.supports_tablespaces:355 if opts.db_tablespace and capabilities.supports_tablespaces: 347 356 # f.db_tablespace is only for indices, so ignore its value here. 348 table_output.append( backend.get_tablespace_sql(opts.db_tablespace))357 table_output.append(ops.get_tablespace_sql(opts.db_tablespace)) 349 358 table_output.append(';') 350 359 final_output.append('\n'.join(table_output)) 351 360 352 361 # Add any extra SQL needed to support auto-incrementing PKs 353 autoinc_sql = backend.get_autoinc_sql(f.m2m_db_table())362 autoinc_sql = ops.get_autoinc_sql(f.m2m_db_table()) 354 363 if autoinc_sql: 355 364 for stmt in autoinc_sql: 356 365 final_output.append(stmt) … … 386 395 387 396 def sql_indexes_for_model(model, style): 388 397 "Returns the CREATE INDEX SQL statements for a single model" 389 from django.db import backend398 from django.db import connection 390 399 output = [] 400 401 ops, capabilities = connection.ops, connection.capabilities 391 402 392 403 for f in model._meta.fields: 393 if f.db_index and not ((f.primary_key or f.unique) and backend.autoindexes_primary_keys):404 if f.db_index and not ((f.primary_key or f.unique) and capabilities.autoindexes_primary_keys): 394 405 unique = f.unique and 'UNIQUE ' or '' 395 406 tablespace = f.db_tablespace or model._meta.db_tablespace 396 if tablespace and backend.supports_tablespaces:397 tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace)407 if tablespace and capabilities.supports_tablespaces: 408 tablespace_sql = ' ' + ops.get_tablespace_sql(tablespace) 398 409 else: 399 410 tablespace_sql = '' 400 411 output.append( 401 412 style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ 402 style.SQL_TABLE( backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \413 style.SQL_TABLE(ops.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ 403 414 style.SQL_KEYWORD('ON') + ' ' + \ 404 style.SQL_TABLE( backend.quote_name(model._meta.db_table)) + ' ' + \405 "(%s)" % style.SQL_FIELD( backend.quote_name(f.column)) + \415 style.SQL_TABLE(ops.quote_name(model._meta.db_table)) + ' ' + \ 416 "(%s)" % style.SQL_FIELD(ops.quote_name(f.column)) + \ 406 417 "%s;" % tablespace_sql 407 418 ) 408 419 return output -
django/db/__init__.py
=== modified file 'django/db/__init__.py'
4 4 5 5 __all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError') 6 6 7 def load_backend(engine): 8 try: 9 return __import__('django.db.backends.%s.base' % engine, {}, {}, ['']).DatabaseWrapper 10 except ImportError, e: 11 # The database backend wasn't found. Display a helpful error message 12 # listing all possible database backends. 13 from django.core.exceptions import ImproperlyConfigured 14 import os 15 backend_dir = os.path.join(__path__[0], 'backends') 16 available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.') and not f.endswith('.py') and not f.endswith('.pyc')] 17 if engine in available_backends: 18 raise # If there's some other error, this must be an error in Django itself. 19 20 try: 21 return __import__(engine, {}, {}, ['']) 22 except ImportError, e: 23 available_backends.sort() 24 raise ImproperlyConfigured, "%r isn't an available database backend. Available default options are: %s" % \ 25 (engine, ", ".join(map(repr, available_backends))) 26 7 27 if not settings.DATABASE_ENGINE: 8 28 settings.DATABASE_ENGINE = 'dummy' 9 29 10 try: 11 backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, {}, {}, ['']) 12 except ImportError, e: 13 # The database backend wasn't found. Display a helpful error message 14 # listing all possible database backends. 15 from django.core.exceptions import ImproperlyConfigured 16 import os 17 backend_dir = os.path.join(__path__[0], 'backends') 18 available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.') and not f.endswith('.py') and not f.endswith('.pyc')] 19 available_backends.sort() 20 if settings.DATABASE_ENGINE not in available_backends: 21 raise ImproperlyConfigured, "%r isn't an available database backend. Available options are: %s" % \ 22 (settings.DATABASE_ENGINE, ", ".join(map(repr, available_backends))) 23 else: 24 raise # If there's some other error, this must be an error in Django itself. 25 26 get_introspection_module = lambda: __import__('django.db.backends.%s.introspection' % settings.DATABASE_ENGINE, {}, {}, ['']) 27 get_creation_module = lambda: __import__('django.db.backends.%s.creation' % settings.DATABASE_ENGINE, {}, {}, ['']) 28 runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE_ENGINE, {}, {}, ['']).runshell() 29 30 connection = backend.DatabaseWrapper(**settings.DATABASE_OPTIONS) 31 DatabaseError = backend.DatabaseError 32 IntegrityError = backend.IntegrityError 30 backend = load_backend(settings.DATABASE_ENGINE) 31 connection = backend(**settings.DATABASE_OPTIONS) 32 DatabaseError = connection.DatabaseError 33 IntegrityError = connection.IntegrityError 34 get_introspection_module = lambda: connection.introspection 35 get_creation_module = lambda: connection.creation 36 runshell = lambda: connection.runshell() 33 37 34 38 # Register an event that closes the database connection 35 39 # when a Django request is finished. -
django/db/backends/__init__.py
=== modified file 'django/db/backends/__init__.py'
1 from django.utils.functional import curry 2 from django.db.backends import util 3 4 try: 5 # Only exists in Python 2.4+ 6 from threading import local 7 except ImportError: 8 # Import copy of _thread_local.py from Python 2.4 9 from django.utils._threading_local import local 10 11 12 class BaseDatabaseWrapper(local): 13 14 """base class for defining a new db connection wrapper 15 16 Derivatives should add a _cursor method, introspection property, 17 creation property, and a runshell method 18 """ 19 20 ops = capabilities = orm_map = DatabaseError = IntegrityError = None 21 22 def __init__(self, **kwargs): 23 self.connection = None 24 self.queries = [] 25 self.options = kwargs 26 27 def _commit(self): 28 if self.connection is not None: 29 return self.connection.commit() 30 31 def _rollback(self): 32 if self.connection is not None: 33 return self.connection.rollback() 34 35 def close(self): 36 if self.connection is not None: 37 self.connection.close() 38 self.connection = None 39 40 def cursor(self): 41 from django.conf import settings 42 cursor = self._cursor(settings) 43 if settings.DEBUG: 44 return self.make_debug_cursor(cursor) 45 return cursor 46 47 def make_debug_cursor(self, cursor): 48 from django.db.backends import util 49 return util.CursorDebugWrapper(cursor, self) 50 51 def introspection(self): 52 raise NotImplemented(self, 'introspection') 53 54 def creation(self): 55 raise NotImplemented(self, 'creation') 56 57 introspection, creation = map(property, (introspection, creation)) 58 59 def runshell(self): 60 raise NotImplemented(self, 'runshell') 61 62 63 class BackendCapabilities(object): 64 65 defaults = dict(allows_group_by_ordinal=True, allows_unique_and_pk=True, 66 autoindexes_primary_keys=True, needs_datetime_string_cast=True, 67 needs_upper_for_iops=False, supports_constraints=True, 68 supports_tablespaces=False, uses_case_insensitive_names=False) 69 70 def __init__(self, **kwargs): 71 self.__dict__.update(self.defaults) 72 self.__dict__.update(kwargs) 73 74 75 def _throw_unsupported(method, self, *args, **kwargs): 76 raise NotImplemented(self, method) 77 78 class BackendOps(object): 79 80 required_methods = ('get_autoinc_sql', 81 'get_date_extract_sql', 82 'get_date_trunc_sql', 83 'get_datetime_cast_sql', 84 'get_deferrable_sql', 85 'get_drop_foreignkey_sql', 86 'get_fulltext_search_sql', 87 'get_get_trigger_name', 88 'get_last_insert_id', 89 'get_limit_offset_sql', 90 'get_max_name_length', 91 'get_pk_default_value', 92 'get_random_function_sql', 93 'get_sequence_name', 94 'get_sql_flush', 95 'get_sql_sequence_reset', 96 'get_start_transaction_sql', 97 'get_tablespace_sql', 98 ) 99 100 # listcomps leak variables; we don't need 'x' in the namespace, thus 101 # the reuse and explicit del 102 targets = [curry(_throw_unsupported, x) for x in required_methods] 103 locals().update(zip(required_methods, targets)) 104 for x in ('get_sql_sequence_reset', 'get_sql_flush'): 105 required_methods += (x,) 106 locals()[x] = curry(_throw_unsupported, x) 107 108 del x, targets 109 110 def quote_name(name): 111 if name.startswith(self.start_quote) and name.endswith(self.end_quote): 112 return name # already quoted. 113 return '%s%s%s' % (self.start_quote, name, self.end_quote) 114 115 quote_name = staticmethod(quote_name) 116 117 dictfetchone = staticmethod(util.dictfetchone) 118 dictfetchmany = staticmethod(util.dictfetchmany) 119 dictfetchall = staticmethod(util.dictfetchall) 120 121 # list of methods to pull from old style db layout 122 methods = required_methods + ('get_drop_sequence', 'quote_name', 123 'dictfetchone', 'dictfetchmany', 'dictfetchall',) 124 125 def __init__(self, quote_chars='""'): 126 self.start_quote, self.end_quote = quote_chars[0:2] 127 128 129 class OldLayoutBaseDatabaseWrapper(BaseDatabaseWrapper): 130 131 """ 132 Convenience class used for mapping <=0.96 style backend 133 layouts into current form. 134 135 Generally speaking, you want BaseDatabaseWrapper, not this class. 136 """ 137 138 def __init__(self, *args, **kwargs): 139 super(OldLayoutBaseDatabaseWrapper, self).__init__(*args, **kwargs) 140 mod = __import__(self.__class__.__module__, {}, {}, ['']) 141 d = BackendCapabilities.defaults.copy() 142 for k, v in d.iteritems(): 143 if hasattr(mod, k): 144 d[k] = getattr(mod, k) 145 # generate a few mappings via inspection of the module. 146 self.capabilities = BackendCapabilities(**d) 147 self.orm_map = mod.OPERATOR_MAPPING.copy() 148 self.ops = ops = BackendOps() 149 for op in ops.methods: 150 if hasattr(mod, op): 151 setattr(ops, op, getattr(mod, op)) 152 self.DatabaseError = mod.DatabaseError 153 self.IntegrityError = mod.IntegrityError 154 155 156 def _base_namespace(self): 157 # when py2.4 is the default, convert this to a rsplit limit=1 158 return '.'.join(self.__class__.__module__.split(".")[:-1]) 159 160 def introspection(self): 161 return __import__(self._base_namespace + '.introspection', {}, {}, ['']) 162 163 def creation(self): 164 return __import__(self._base_namespace + '.creation', {}, {}, ['']) 165 166 def runshell(self): 167 return __import__(self._base_namespace + '.client', {}, {}, ['']).runshell 168 169 _base_namespace, introspection, creation, runshell = map(property, 170 (_base_namespace, introspection, creation, runshell)) -
django/db/backends/ado_mssql/base.py
=== modified file 'django/db/backends/ado_mssql/base.py'
48 48 return res 49 49 Database.convertVariantToPython = variantToPython 50 50 51 try: 52 # Only exists in Python 2.4+ 53 from threading import local 54 except ImportError: 55 # Import copy of _thread_local.py from Python 2.4 56 from django.utils._threading_local import local 57 58 class DatabaseWrapper(local): 59 def __init__(self, **kwargs): 60 self.connection = None 61 self.queries = [] 62 63 def cursor(self): 64 from django.conf import settings 51 from django.db.backends import OldLayoutBaseDatabaseWrapper 52 53 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 54 55 def _cursor(self, settings): 65 56 if self.connection is None: 66 57 if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '': 67 58 from django.core.exceptions import ImproperlyConfigured … … 71 62 # TODO: Handle DATABASE_PORT. 72 63 conn_string = "PROVIDER=SQLOLEDB;DATA SOURCE=%s;UID=%s;PWD=%s;DATABASE=%s" % (settings.DATABASE_HOST, settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME) 73 64 self.connection = Database.connect(conn_string) 74 cursor = self.connection.cursor() 75 if settings.DEBUG: 76 return util.CursorDebugWrapper(cursor, self) 77 return cursor 78 79 def _commit(self): 80 if self.connection is not None: 81 return self.connection.commit() 82 83 def _rollback(self): 84 if self.connection is not None: 85 return self.connection.rollback() 86 87 def close(self): 88 if self.connection is not None: 89 self.connection.close() 90 self.connection = None 65 return self.connection.cursor() 66 91 67 92 68 allows_group_by_ordinal = True 93 69 allows_unique_and_pk = True -
django/db/backends/mysql/base.py
=== modified file 'django/db/backends/mysql/base.py'
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 try: 57 # Only exists in Python 2.4+ 58 from threading import local 59 except ImportError:60 # Import copy of _thread_local.py from Python 2.4 61 from django.utils._threading_local import local62 63 class DatabaseWrapper(local): 56 57 from django.db.backends import OldLayoutBaseDatabaseWrapper 58 59 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 60 61 DatabaseError = Database.DatabaseError 62 IntegrityError = Database.IntegrityError 63 64 64 def __init__(self, **kwargs): 65 self.connection = None 66 self.queries = [] 65 super(DatabaseWrapper, self).__init__(**kwargs) 67 66 self.server_version = None 68 self.options = kwargs69 67 70 68 def _valid_connection(self): 71 69 if self.connection is not None: … … 77 75 self.connection = None 78 76 return False 79 77 80 def cursor(self): 81 from django.conf import settings 78 def _cursor(self, settings): 82 79 from warnings import filterwarnings 83 80 if not self._valid_connection(): 84 81 kwargs = { … … 100 97 kwargs['port'] = int(settings.DATABASE_PORT) 101 98 kwargs.update(self.options) 102 99 self.connection = Database.connect(**kwargs) 103 cursor = self.connection.cursor() 104 else: 105 cursor = self.connection.cursor() 100 cursor = self.connection.cursor() 106 101 if settings.DEBUG: 107 102 filterwarnings("error", category=Database.Warning) 108 return util.CursorDebugWrapper(cursor, self)109 103 return cursor 110 104 111 def _commit(self):112 if self.connection is not None:113 self.connection.commit()114 115 105 def _rollback(self): 116 if self.connection is not None: 117 try: 118 self.connection.rollback() 119 except Database.NotSupportedError: 120 pass 121 122 def close(self): 123 if self.connection is not None: 124 self.connection.close() 125 self.connection = None 106 try: 107 OldLayoutBaseDatabaseWrapper._rollback(self) 108 except Database.NotSupportedError: 109 pass 126 110 127 111 def get_server_version(self): 128 112 if not self.server_version: -
django/db/backends/mysql_old/base.py
=== modified file 'django/db/backends/mysql_old/base.py'
63 63 else: 64 64 return getattr(self.cursor, attr) 65 65 66 try: 67 # Only exists in Python 2.4+ 68 from threading import local 69 except ImportError: 70 # Import copy of _thread_local.py from Python 2.4 71 from django.utils._threading_local import local 66 from django.db.backends import OldLayoutBaseDatabaseWrapper 72 67 73 class DatabaseWrapper( local):68 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 74 69 def __init__(self, **kwargs): 75 self.connection = None 76 self.queries = [] 70 super(DatabaseWrapper, self).__init__(**kwargs) 77 71 self.server_version = None 78 self.options = kwargs79 72 80 73 def _valid_connection(self): 81 74 if self.connection is not None: … … 87 80 self.connection = None 88 81 return False 89 82 90 def cursor(self): 91 from django.conf import settings 83 def _cursor(self, settings): 92 84 if not self._valid_connection(): 93 85 kwargs = { 94 86 # Note: use_unicode intentonally not set to work around some … … 119 111 self.connection.set_character_set('utf8') 120 112 else: 121 113 cursor = self.connection.cursor() 122 if settings.DEBUG: 123 return util.CursorDebugWrapper(MysqlDebugWrapper(cursor), self) 114 124 115 return cursor 125 116 126 def _commit(self): 127 if self.connection is not None: 128 self.connection.commit() 117 def make_debug_cursor(self, cursor): 118 return OldLayoutBaseDatabaseWrapper.make_debug_cursor(self, MysqlDebugWrapper(cursor)) 129 119 130 120 def _rollback(self): 131 if self.connection is not None: 132 try: 133 self.connection.rollback() 134 except Database.NotSupportedError: 135 pass 136 137 def close(self): 138 if self.connection is not None: 139 self.connection.close() 140 self.connection = None 121 try: 122 OldLayoutBaseDatabaseWrapper._rollback(self) 123 except Database.NotSupportedError: 124 pass 141 125 142 126 def get_server_version(self): 143 127 if not self.server_version: -
django/db/backends/oracle/base.py
=== modified file 'django/db/backends/oracle/base.py'
23 23 DatabaseError = Database.Error 24 24 IntegrityError = Database.IntegrityError 25 25 26 try: 27 # Only exists in Python 2.4+ 28 from threading import local 29 except ImportError: 30 # Import copy of _thread_local.py from Python 2.4 31 from django.utils._threading_local import local 26 from django.db.backends import OldLayoutBaseDatabaseWrapper 32 27 33 class DatabaseWrapper(local): 34 def __init__(self, **kwargs): 35 self.connection = None 36 self.queries = [] 37 self.options = kwargs 28 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 38 29 39 30 def _valid_connection(self): 40 31 return self.connection is not None 41 32 42 def cursor(self):33 def _cursor(self, settings): 43 34 if not self._valid_connection(): 44 35 if len(settings.DATABASE_HOST.strip()) == 0: 45 36 settings.DATABASE_HOST = 'localhost' … … 55 46 # Set oracle date to ansi date format. 56 47 cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'") 57 48 cursor.execute("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") 58 if settings.DEBUG:59 return util.CursorDebugWrapper(cursor, self)60 49 return cursor 61 50 62 def _commit(self):63 if self.connection is not None:64 return self.connection.commit()65 66 def _rollback(self):67 if self.connection is not None:68 return self.connection.rollback()69 70 def close(self):71 if self.connection is not None:72 self.connection.close()73 self.connection = None74 51 75 52 allows_group_by_ordinal = False 76 53 allows_unique_and_pk = False # Suppress UNIQUE/PK for Oracle (ORA-02259) -
django/db/backends/postgresql/base.py
=== modified file 'django/db/backends/postgresql/base.py'
15 15 DatabaseError = Database.DatabaseError 16 16 IntegrityError = Database.IntegrityError 17 17 18 try: 19 # Only exists in Python 2.4+ 20 from threading import local 21 except ImportError: 22 # Import copy of _thread_local.py from Python 2.4 23 from django.utils._threading_local import local 18 from django.db.backends import OldLayoutBaseDatabaseWrapper 24 19 25 20 class UnicodeCursorWrapper(object): 26 21 """ … … 64 59 65 60 postgres_version = None 66 61 67 class DatabaseWrapper(local): 68 def __init__(self, **kwargs): 69 self.connection = None 70 self.queries = [] 71 self.options = kwargs 62 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 72 63 73 def cursor(self): 74 from django.conf import settings 64 def _cursor(self, settings): 75 65 set_tz = False 76 66 if self.connection is None: 77 67 set_tz = True … … 98 88 if not postgres_version: 99 89 cursor.execute("SELECT version()") 100 90 postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')] 101 if settings.DEBUG:102 return util.CursorDebugWrapper(cursor, self)103 91 return cursor 104 92 105 def _commit(self):106 if self.connection is not None:107 return self.connection.commit()108 109 def _rollback(self):110 if self.connection is not None:111 return self.connection.rollback()112 113 def close(self):114 if self.connection is not None:115 self.connection.close()116 self.connection = None117 118 93 allows_group_by_ordinal = True 119 94 allows_unique_and_pk = True 120 95 autoindexes_primary_keys = True -
django/db/backends/postgresql_psycopg2/base.py
=== modified file 'django/db/backends/postgresql_psycopg2/base.py'
5 5 """ 6 6 7 7 from django.db.backends import util 8 from django.db.backends import OldLayoutBaseDatabaseWrapper 9 8 10 try: 9 11 import psycopg2 as Database 10 12 import psycopg2.extensions … … 15 17 DatabaseError = Database.DatabaseError 16 18 IntegrityError = Database.IntegrityError 17 19 18 try:19 # Only exists in Python 2.4+20 from threading import local21 except ImportError:22 # Import copy of _thread_local.py from Python 2.423 from django.utils._threading_local import local24 25 20 psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) 26 21 27 22 postgres_version = None 28 23 29 class DatabaseWrapper(local): 30 def __init__(self, **kwargs): 31 self.connection = None 32 self.queries = [] 33 self.options = kwargs 24 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 34 25 35 def cursor(self): 36 from django.conf import settings 26 def _cursor(self, settings): 37 27 set_tz = False 38 28 if self.connection is None: 39 29 set_tz = True … … 60 50 if not postgres_version: 61 51 cursor.execute("SELECT version()") 62 52 postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')] 63 if settings.DEBUG:64 return util.CursorDebugWrapper(cursor, self)65 53 return cursor 66 54 67 def _commit(self):68 if self.connection is not None:69 return self.connection.commit()70 71 def _rollback(self):72 if self.connection is not None:73 return self.connection.rollback()74 75 def close(self):76 if self.connection is not None:77 self.connection.close()78 self.connection = None79 55 80 56 allows_group_by_ordinal = True 81 57 allows_unique_and_pk = True -
django/db/backends/sqlite3/base.py
=== modified file 'django/db/backends/sqlite3/base.py'
34 34 Database.register_converter("decimal", util.typecast_decimal) 35 35 Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal) 36 36 37 try: 38 # Only exists in Python 2.4+ 39 from threading import local 40 except ImportError: 41 # Import copy of _thread_local.py from Python 2.4 42 from django.utils._threading_local import local 43 44 class DatabaseWrapper(local): 45 def __init__(self, **kwargs): 46 self.connection = None 47 self.queries = [] 48 self.options = kwargs 49 50 def cursor(self): 51 from django.conf import settings 37 from django.db.backends import OldLayoutBaseDatabaseWrapper 38 39 class DatabaseWrapper(OldLayoutBaseDatabaseWrapper): 40 41 def _cursor(self, settings): 52 42 if self.connection is None: 53 43 kwargs = { 54 44 'database': settings.DATABASE_NAME, … … 60 50 self.connection.create_function("django_extract", 2, _sqlite_extract) 61 51 self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc) 62 52 self.connection.create_function("regexp", 2, _sqlite_regexp) 63 cursor = self.connection.cursor(factory=SQLiteCursorWrapper) 64 if settings.DEBUG: 65 return util.CursorDebugWrapper(cursor, self) 66 else: 67 return cursor 68 69 def _commit(self): 70 if self.connection is not None: 71 self.connection.commit() 72 73 def _rollback(self): 74 if self.connection is not None: 75 self.connection.rollback() 53 return self.connection.cursor(factory=SQLiteCursorWrapper) 76 54 77 55 def close(self): 78 56 from django.conf import settings 79 57 # If database is in memory, closing the connection destroys the 80 58 # database. To prevent accidental data loss, ignore close requests on 81 59 # an in-memory db. 82 if se lf.connection is not None and settings.DATABASE_NAME != ":memory:":83 self.connection.close()84 self.connection = None 60 if settings.DATABASE_NAME != ':memory:': 61 OldLayoutBaseDatabaseWrapper.close(self) 62 85 63 86 64 class SQLiteCursorWrapper(Database.Cursor): 87 65 """ -
django/db/models/base.py
=== modified file 'django/db/models/base.py'
6 6 from django.db.models.fields.related import OneToOneRel, ManyToOneRel 7 7 from django.db.models.query import delete_objects 8 8 from django.db.models.options import Options, AdminOptions 9 from django.db import connection, backend,transaction9 from django.db import connection, transaction 10 10 from django.db.models import signals 11 11 from django.db.models.loading import register_models, get_model 12 12 from django.dispatch import dispatcher … … 207 207 non_pks = [f for f in self._meta.fields if not f.primary_key] 208 208 cursor = connection.cursor() 209 209 210 ops = connection.ops 211 quote_name = ops.quote_name 210 212 # First, try an UPDATE. If that doesn't update anything, do an INSERT. 211 213 pk_val = self._get_pk_val() 212 214 pk_set = bool(pk_val) … … 214 216 if pk_set: 215 217 # Determine whether a record with the primary key already exists. 216 218 cursor.execute("SELECT 1 FROM %s WHERE %s=%%s" % \ 217 ( backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)),219 (quote_name(self._meta.db_table), quote_name(self._meta.pk.column)), 218 220 self._meta.pk.get_db_prep_lookup('exact', pk_val)) 219 221 # If it does already exist, do an UPDATE. 220 222 if cursor.fetchone(): 221 223 db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False)) for f in non_pks] 222 224 if db_values: 223 225 cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \ 224 ( backend.quote_name(self._meta.db_table),225 ','.join(['%s=%%s' % backend.quote_name(f.column) for f in non_pks]),226 backend.quote_name(self._meta.pk.column)),226 (quote_name(self._meta.db_table), 227 ','.join(['%s=%%s' % quote_name(f.column) for f in non_pks]), 228 quote_name(self._meta.pk.column)), 227 229 db_values + self._meta.pk.get_db_prep_lookup('exact', pk_val)) 228 230 else: 229 231 record_exists = False 230 232 if not pk_set or not record_exists: 231 field_names = [ backend.quote_name(f.column) for f in self._meta.fields if not isinstance(f, AutoField)]233 field_names = [quote_name(f.column) for f in self._meta.fields if not isinstance(f, AutoField)] 232 234 db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if not isinstance(f, AutoField)] 233 235 # If the PK has been manually set, respect that. 234 236 if pk_set: … … 236 238 db_values += [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True)) for f in self._meta.fields if isinstance(f, AutoField)] 237 239 placeholders = ['%s'] * len(field_names) 238 240 if self._meta.order_with_respect_to: 239 field_names.append( backend.quote_name('_order'))241 field_names.append(quote_name('_order')) 240 242 # TODO: This assumes the database supports subqueries. 241 243 placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \ 242 ( backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.order_with_respect_to.column)))244 (quote_name(self._meta.db_table), quote_name(self._meta.order_with_respect_to.column))) 243 245 db_values.append(getattr(self, self._meta.order_with_respect_to.attname)) 244 246 if db_values: 245 247 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \ 246 ( backend.quote_name(self._meta.db_table), ','.join(field_names),248 (quote_name(self._meta.db_table), ','.join(field_names), 247 249 ','.join(placeholders)), db_values) 248 250 else: 249 251 # Create a new record with defaults for everything. 250 252 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % 251 ( backend.quote_name(self._meta.db_table),252 backend.quote_name(self._meta.pk.column),253 backend.get_pk_default_value()))253 (quote_name(self._meta.db_table), 254 quote_name(self._meta.pk.column), 255 ops.get_pk_default_value())) 254 256 if self._meta.has_auto_field and not pk_set: 255 setattr(self, self._meta.pk.attname, backend.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column))257 setattr(self, self._meta.pk.attname, ops.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column)) 256 258 transaction.commit_unless_managed() 257 259 258 260 # Run any post-save hooks. … … 326 328 def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs): 327 329 op = is_next and '>' or '<' 328 330 where = '(%s %s %%s OR (%s = %%s AND %s.%s %s %%s))' % \ 329 ( backend.quote_name(field.column), op, backend.quote_name(field.column),330 backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column), op)331 (connection.ops.quote_name(field.column), op, connection.ops.quote_name(field.column), 332 connection.ops.quote_name(self._meta.db_table), connection.ops.quote_name(self._meta.pk.column), op) 331 333 param = smart_str(getattr(self, field.attname)) 332 334 q = self.__class__._default_manager.filter(**kwargs).order_by((not is_next and '-' or '') + field.name, (not is_next and '-' or '') + self._meta.pk.name) 333 335 q._where.append(where) … … 343 345 op = is_next and '>' or '<' 344 346 order_field = self._meta.order_with_respect_to 345 347 where = ['%s %s (SELECT %s FROM %s WHERE %s=%%s)' % \ 346 ( backend.quote_name('_order'), op, backend.quote_name('_order'),347 backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)),348 '%s=%%s' % backend.quote_name(order_field.column)]348 (connection.ops.quote_name('_order'), op, connection.ops.quote_name('_order'), 349 connection.ops.quote_name(self._meta.db_table), connection.ops.quote_name(self._meta.pk.column)), 350 '%s=%%s' % connection.ops.quote_name(order_field.column)] 349 351 params = [self._get_pk_val(), getattr(self, order_field.attname)] 350 352 obj = self._default_manager.order_by('_order').extra(where=where, params=params)[:1].get() 351 353 setattr(self, cachename, obj) … … 430 432 cursor = connection.cursor() 431 433 # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s" 432 434 sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \ 433 ( backend.quote_name(ordered_obj._meta.db_table), backend.quote_name('_order'),434 backend.quote_name(ordered_obj._meta.order_with_respect_to.column),435 backend.quote_name(ordered_obj._meta.pk.column))435 (connection.ops.quote_name(ordered_obj._meta.db_table), connection.ops.quote_name('_order'), 436 connection.ops.quote_name(ordered_obj._meta.order_with_respect_to.column), 437 connection.ops.quote_name(ordered_obj._meta.pk.column)) 436 438 rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) 437 439 cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)]) 438 440 transaction.commit_unless_managed() … … 441 443 cursor = connection.cursor() 442 444 # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order" 443 445 sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \ 444 ( backend.quote_name(ordered_obj._meta.pk.column),445 backend.quote_name(ordered_obj._meta.db_table),446 backend.quote_name(ordered_obj._meta.order_with_respect_to.column),447 backend.quote_name('_order'))446 (connection.ops.quote_name(ordered_obj._meta.pk.column), 447 connection.ops.quote_name(ordered_obj._meta.db_table), 448 connection.ops.quote_name(ordered_obj._meta.order_with_respect_to.column), 449 connection.ops.quote_name('_order')) 448 450 rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) 449 451 cursor.execute(sql, [rel_val]) 450 452 return [r[0] for r in cursor.fetchall()] -
django/db/models/fields/related.py
=== modified file 'django/db/models/fields/related.py'
1 from django.db import backend, transaction1 from django.db import connection, transaction 2 2 from django.db.models import signals, get_model 3 3 from django.db.models.fields import AutoField, Field, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, get_ul_class 4 4 from django.db.models.related import RelatedObject … … 400 400 superclass = rel_model._default_manager.__class__ 401 401 RelatedManager = create_many_related_manager(superclass) 402 402 403 qn = backend.quote_name403 qn = connection.ops.quote_name 404 404 manager = RelatedManager( 405 405 model=rel_model, 406 406 core_filters={'%s__pk' % self.related.field.name: instance._get_pk_val()}, … … 441 441 superclass = rel_model._default_manager.__class__ 442 442 RelatedManager = create_many_related_manager(superclass) 443 443 444 qn = backend.quote_name444 qn = connection.ops.quote_name 445 445 manager = RelatedManager( 446 446 model=rel_model, 447 447 core_filters={'%s__pk' % self.field.related_query_name(): instance._get_pk_val()}, -
django/db/models/options.py
=== modified file 'django/db/models/options.py'
63 63 del self.meta 64 64 65 65 def _prepare(self, model): 66 from django.db import backend66 from django.db import connection 67 67 from django.db.backends.util import truncate_name 68 68 if self.order_with_respect_to: 69 69 self.order_with_respect_to = self.get_field(self.order_with_respect_to) … … 80 80 if not self.db_table: 81 81 self.db_table = "%s_%s" % (self.app_label, self.module_name) 82 82 self.db_table = truncate_name(self.db_table, 83 backend.get_max_name_length())83 connection.ops.get_max_name_length()) 84 84 85 85 def add_field(self, field): 86 86 # Insert the given field in the order in which it was created, using -
django/db/models/query.py
=== modified file 'django/db/models/query.py'
64 64 return f 65 65 66 66 def orderlist2sql(order_list, opts, prefix=''): 67 quote_name = connection.ops.quote_name 68 get_rand_sql = connection.ops.get_random_function_sql 67 69 if prefix.endswith('.'): 68 prefix = backend.quote_name(prefix[:-1]) + '.'70 prefix = quote_name(prefix[:-1]) + '.' 69 71 output = [] 70 72 for f in handle_legacy_orderlist(order_list): 71 73 if f.startswith('-'): 72 output.append('%s%s DESC' % (prefix, backend.quote_name(orderfield2column(f[1:], opts))))74 output.append('%s%s DESC' % (prefix, quote_name(orderfield2column(f[1:], opts)))) 73 75 elif f == '?': 74 output.append( backend.get_random_function_sql())76 output.append(get_rand_sql()) 75 77 else: 76 output.append('%s%s ASC' % (prefix, backend.quote_name(orderfield2column(f, opts))))78 output.append('%s%s ASC' % (prefix, quote_name(orderfield2column(f, opts)))) 77 79 return ', '.join(output) 78 80 79 81 def quote_only_if_word(word): 80 82 if re.search('\W', word): # Don't quote if there are spaces or non-word chars. 81 83 return word 82 84 else: 83 return backend.quote_name(word)85 return connection.ops.quote_name(word) 84 86 85 87 class _QuerySet(object): 86 88 "Represents a lazy database lookup for a set of objects" … … 235 237 236 238 cursor = connection.cursor() 237 239 if self._distinct: 238 id_col = "%s.%s" % ( backend.quote_name(self.model._meta.db_table),239 backend.quote_name(self.model._meta.pk.column))240 id_col = "%s.%s" % (connection.ops.quote_name(self.model._meta.db_table), 241 connection.ops.quote_name(self.model._meta.pk.column)) 240 242 cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params) 241 243 else: 242 244 cursor.execute("SELECT COUNT(*)" + sql, params) … … 312 314 if id_list == []: 313 315 return {} 314 316 qs = self._clone() 315 qs._where.append("%s.%s IN (%s)" % (backend.quote_name(self.model._meta.db_table), backend.quote_name(self.model._meta.pk.column), ",".join(['%s'] * len(id_list)))) 317 qs._where.append("%s.%s IN (%s)" % (connection.ops.quote_name(self.model._meta.db_table), 318 connection.ops.quote_name(self.model._meta.pk.column), ",".join(['%s'] * len(id_list)))) 316 319 qs._params.extend(id_list) 317 320 return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()]) 318 321 … … 483 486 def _get_sql_clause(self): 484 487 opts = self.model._meta 485 488 489 quote_name = connection.ops.quote_name 486 490 # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z. 487 select = ["%s.%s" % ( backend.quote_name(opts.db_table), backend.quote_name(f.column)) for f in opts.fields]491 select = ["%s.%s" % (quote_name(opts.db_table), quote_name(f.column)) for f in opts.fields] 488 492 tables = [quote_only_if_word(t) for t in self._tables] 489 493 joins = SortedDict() 490 494 where = self._where[:] … … 505 509 506 510 # Add any additional SELECTs. 507 511 if self._select: 508 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()])512 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), quote_name(s[0])) for s in self._select.items()]) 509 513 510 514 # Start composing the body of the SQL statement. 511 sql = [" FROM", backend.quote_name(opts.db_table)]515 sql = [" FROM", quote_name(opts.db_table)] 512 516 513 517 # Compose the join dictionary into SQL describing the joins. 514 518 if joins: … … 531 535 ordering_to_use = opts.ordering 532 536 for f in handle_legacy_orderlist(ordering_to_use): 533 537 if f == '?': # Special case. 534 order_by.append( backend.get_random_function_sql())538 order_by.append(connection.ops.get_random_function_sql()) 535 539 else: 536 540 if f.startswith('-'): 537 541 col_name = f[1:] … … 541 545 order = "ASC" 542 546 if "." in col_name: 543 547 table_prefix, col_name = col_name.split('.', 1) 544 table_prefix = backend.quote_name(table_prefix) + '.'548 table_prefix = quote_name(table_prefix) + '.' 545 549 else: 546 550 # Use the database table as a column prefix if it wasn't given, 547 551 # and if the requested column isn't a custom SELECT. 548 552 if "." not in col_name and col_name not in (self._select or ()): 549 table_prefix = backend.quote_name(opts.db_table) + '.'553 table_prefix = quote_name(opts.db_table) + '.' 550 554 else: 551 555 table_prefix = '' 552 order_by.append('%s%s %s' % (table_prefix, backend.quote_name(orderfield2column(col_name, opts)), order))556 order_by.append('%s%s %s' % (table_prefix, quote_name(orderfield2column(col_name, opts)), order)) 553 557 if order_by: 554 558 sql.append("ORDER BY " + ", ".join(order_by)) 555 559 556 560 # LIMIT and OFFSET clauses 557 561 if self._limit is not None: 558 sql.append("%s " % backend.get_limit_offset_sql(self._limit, self._offset))562 sql.append("%s " % connection.ops.get_limit_offset_sql(self._limit, self._offset)) 559 563 else: 560 564 assert self._offset is None, "'offset' is not allowed without 'limit'" 561 565 562 566 return select, " ".join(sql), params 563 567 564 568 # Use the backend's QuerySet class if it defines one, otherwise use _QuerySet. 565 if hasattr( backend, 'get_query_set_class'):566 QuerySet = backend.get_query_set_class(_QuerySet)569 if hasattr(connection.ops, 'get_query_set_class'): 570 QuerySet = connection.ops.get_query_set_class(_QuerySet) 567 571 else: 568 572 QuerySet = _QuerySet 569 573 … … 605 609 field_names = [f.attname for f in fields] 606 610 607 611 columns = [f.column for f in fields] 608 select = ['%s.%s' % ( backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns]612 select = ['%s.%s' % (connection.ops.quote_name(self.model._meta.db_table), connection.ops.quote_name(c)) for c in columns] 609 613 if extra_select: 610 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in extra_select])614 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), connection.ops.quote_name(s[0])) for s in extra_select]) 611 615 field_names.extend([f[0] for f in extra_select]) 612 616 613 617 cursor = connection.cursor() … … 635 639 self._order_by = () # Clear this because it'll mess things up otherwise. 636 640 if self._field.null: 637 641 self._where.append('%s.%s IS NOT NULL' % \ 638 ( backend.quote_name(self.model._meta.db_table), backend.quote_name(self._field.column)))642 (connection.ops.quote_name(self.model._meta.db_table), connection.ops.quote_name(self._field.column))) 639 643 try: 640 644 select, sql, params = self._get_sql_clause() 641 645 except EmptyResultSet: 642 646 raise StopIteration 643 647 644 table_name = backend.quote_name(self.model._meta.db_table)645 field_name = backend.quote_name(self._field.column)648 table_name = connection.ops.quote_name(self.model._meta.db_table) 649 field_name = connection.ops.quote_name(self._field.column) 646 650 647 if backend.allows_group_by_ordinal:651 if connection.capabilities.allows_group_by_ordinal: 648 652 group_by = '1' 649 653 else: 650 group_by = backend.get_date_trunc_sql(self._kind,654 group_by = connection.ops.get_date_trunc_sql(self._kind, 651 655 '%s.%s' % (table_name, field_name)) 652 656 653 657 sql = 'SELECT %s %s GROUP BY %s ORDER BY 1 %s' % \ 654 ( backend.get_date_trunc_sql(self._kind, '%s.%s' % (backend.quote_name(self.model._meta.db_table),655 backend.quote_name(self._field.column))), sql, group_by, self._order)658 (connection.ops.get_date_trunc_sql(self._kind, '%s.%s' % (connection.ops.quote_name(self.model._meta.db_table), 659 connection.ops.quote_name(self._field.column))), sql, group_by, self._order) 656 660 cursor = connection.cursor() 657 661 cursor.execute(sql, params) 658 662 659 663 has_resolve_columns = hasattr(self, 'resolve_columns') 660 needs_datetime_string_cast = backend.needs_datetime_string_cast664 needs_datetime_string_cast = connection.capabilities.needs_datetime_string_cast 661 665 dates = [] 662 666 # It would be better to use self._field here instead of DateTimeField(), 663 667 # but in Oracle that will result in a list of datetime.date instead of … … 779 783 780 784 def get_where_clause(lookup_type, table_prefix, field_name, value): 781 785 if table_prefix.endswith('.'): 782 table_prefix = backend.quote_name(table_prefix[:-1])+'.'783 field_name = backend.quote_name(field_name)784 if type(value) == datetime.datetime and backend.get_datetime_cast_sql():785 cast_sql = backend.get_datetime_cast_sql()786 table_prefix = connection.ops.quote_name(table_prefix[:-1])+'.' 787 field_name = connection.ops.quote_name(field_name) 788 if type(value) == datetime.datetime and connection.ops.get_datetime_cast_sql(): 789 cast_sql = connection.ops.get_datetime_cast_sql() 786 790 else: 787 791 cast_sql = '%s' 788 if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and backend.needs_upper_for_iops:792 if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and connection.capabilities.needs_upper_for_iops: 789 793 format = 'UPPER(%s%s) %s' 790 794 else: 791 795 format = '%s%s %s' 792 796 try: 793 797 return format % (table_prefix, field_name, 794 backend.OPERATOR_MAPPING[lookup_type] % cast_sql)798 connection.orm_map[lookup_type] % cast_sql) 795 799 except KeyError: 796 800 pass 797 801 if lookup_type == 'in': … … 803 807 elif lookup_type in ('range', 'year'): 804 808 return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name) 805 809 elif lookup_type in ('month', 'day'): 806 return "%s = %%s" % backend.get_date_extract_sql(lookup_type, table_prefix + field_name)810 return "%s = %%s" % connection.ops.get_date_extract_sql(lookup_type, table_prefix + field_name) 807 811 elif lookup_type == 'isnull': 808 812 return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or '')) 809 813 elif lookup_type == 'search': 810 return backend.get_fulltext_search_sql(table_prefix + field_name)814 return connection.ops.get_fulltext_search_sql(table_prefix + field_name) 811 815 elif lookup_type in ('regex', 'iregex'): 812 816 if settings.DATABASE_ENGINE == 'oracle': 813 817 if lookup_type == 'regex': … … 846 850 if max_depth and cur_depth > max_depth: 847 851 return None 848 852 849 qn = backend.quote_name853 qn = connection.ops.quote_name 850 854 for f in opts.fields: 851 855 if f.rel and not f.null: 852 856 db_table = f.rel.to._meta.db_table … … 944 948 return choices 945 949 946 950 def lookup_inner(path, lookup_type, value, opts, table, column): 947 qn = backend.quote_name951 qn = connection.ops.quote_name 948 952 joins, where, params = SortedDict(), [], [] 949 953 current_opts = opts 950 954 current_table = table … … 1108 1112 1109 1113 def delete_objects(seen_objs): 1110 1114 "Iterate through a list of seen classes, and remove any instances that are referred to" 1111 qn = backend.quote_name1115 qn = connection.ops.quote_name 1112 1116 ordered_classes = seen_objs.keys() 1113 1117 ordered_classes.reverse() 1114 1118 -
django/test/utils.py
=== modified file 'django/test/utils.py'
124 124 cursor = connection.cursor() 125 125 _set_autocommit(connection) 126 126 try: 127 cursor.execute("CREATE DATABASE %s %s" % ( backend.quote_name(TEST_DATABASE_NAME), suffix))127 cursor.execute("CREATE DATABASE %s %s" % (connection.ops.quote_name(TEST_DATABASE_NAME), suffix)) 128 128 except Exception, e: 129 129 sys.stderr.write("Got an error creating the test database: %s\n" % e) 130 130 if not autoclobber: … … 133 133 try: 134 134 if verbosity >= 1: 135 135 print "Destroying old test database..." 136 cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))136 cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(TEST_DATABASE_NAME)) 137 137 if verbosity >= 1: 138 138 print "Creating test database..." 139 cursor.execute("CREATE DATABASE %s %s" % ( backend.quote_name(TEST_DATABASE_NAME), suffix))139 cursor.execute("CREATE DATABASE %s %s" % (connection.ops.quote_name(TEST_DATABASE_NAME), suffix)) 140 140 except Exception, e: 141 141 sys.stderr.write("Got an error recreating the test database: %s\n" % e) 142 142 sys.exit(2) … … 180 180 cursor = connection.cursor() 181 181 _set_autocommit(connection) 182 182 time.sleep(1) # To avoid "database is being accessed by other users" errors. 183 cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))183 cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(TEST_DATABASE_NAME)) 184 184 connection.close()