Ticket #5106: backend-refactoring-v2.patch

File backend-refactoring-v2.patch, 70.3 KB (added by (removed), 17 years ago)

version/stage 2 of the refactoring; api breaking, but molds existing old style layout into new automatically, and allows for actual OOP trickery.

  • django/contrib/auth/models.py

    === modified file 'django/contrib/auth/models.py'
     
    11from django.core import validators
    22from django.core.exceptions import ImproperlyConfigured
    3 from django.db import backend, connection, models
     3from django.db import connection, models
    44from django.contrib.contenttypes.models import ContentType
    55from django.utils.encoding import smart_str
    66from django.utils.translation import ugettext_lazy as _
     
    210210                    AND gp.%s = ug.%s
    211211                    AND ct.%s = p.%s
    212212                    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'),)
    220220            cursor.execute(sql, [self.id])
    221221            self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
    222222        return self._group_perm_cache
  • django/contrib/contenttypes/generic.py

    === modified file 'django/contrib/contenttypes/generic.py'
     
    44
    55from django import oldforms
    66from django.core.exceptions import ObjectDoesNotExist
    7 from django.db import backend
     7from django.db import connection
    88from django.db.models import signals
    99from django.db.models.fields.related import RelatedField, Field, ManyToManyRel
    1010from django.db.models.loading import get_model
     
    167167            model = rel_model,
    168168            instance = instance,
    169169            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()),
    173173            content_type = ContentType.objects.get_for_model(self.field.model),
    174174            content_type_field_name = self.field.content_type_field_name,
    175175            object_id_field_name = self.field.object_id_field_name
  • django/core/management.py

    === modified file 'django/core/management.py'
     
    5959
    6060def _get_installed_models(table_list):
    6161    "Gets a set of all models that are installed, given a list of existing tables"
    62     from django.db import backend, models
     62    from django.db import connection, models
    6363    all_models = []
    6464    for app in models.get_apps():
    6565        for model in models.get_models(app):
    6666            all_models.append(model)
    67     if backend.uses_case_insensitive_names:
    68         converter = lambda x: x.upper()
     67    if connection.capabilities.uses_case_insensitive_names:
     68        converter = lambda x:x.upper()
    6969    else:
    7070        converter = lambda x: x
    7171    return set([m for m in all_models if converter(m._meta.db_table) in map(converter, table_list)])
     
    152152
    153153    Returns list_of_sql, pending_references_dict
    154154    """
    155     from django.db import backend, models
     155    from django.db import connection, models
     156
     157    ops, capabilities = connection.ops, connection.capabilities
     158    quote_name = ops.quote_name
    156159
    157160    opts = model._meta
    158161    final_output = []
     
    166169            # database columns in this table.
    167170            continue
    168171        # Make the definition (e.g. 'foo VARCHAR(30)') for this field.
    169         field_output = [style.SQL_FIELD(backend.quote_name(f.column)),
     172        field_output = [style.SQL_FIELD(quote_name(f.column)),
    170173            style.SQL_COLTYPE(col_type)]
    171174        field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or '')))
    172         if f.unique and (not f.primary_key or backend.allows_unique_and_pk):
     175        if f.unique and (not f.primary_key or capabilities.allows_unique_and_pk):
    173176            field_output.append(style.SQL_KEYWORD('UNIQUE'))
    174177        if f.primary_key:
    175178            field_output.append(style.SQL_KEYWORD('PRIMARY KEY'))
    176         if tablespace and backend.supports_tablespaces and (f.unique or f.primary_key) and backend.autoindexes_primary_keys:
     179        if tablespace and capabilities.supports_tablespaces and (f.unique or f.primary_key) \
     180            and capabilities.autoindexes_primary_keys:
    177181            # We must specify the index tablespace inline, because we
    178182            # won't be generating a CREATE INDEX statement for this field.
    179             field_output.append(backend.get_tablespace_sql(tablespace, inline=True))
     183            field_output.append(ops.get_tablespace_sql(tablespace, inline=True))
    180184        if f.rel:
    181185            if f.rel.to in known_models:
    182186                field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \
    183                     style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \
    184                     style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' +
    185                     backend.get_deferrable_sql()
     187                    style.SQL_TABLE(quote_name(f.rel.to._meta.db_table)) + ' (' + \
     188                    style.SQL_FIELD(quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' +
     189                    ops.get_deferrable_sql()
    186190                )
    187191            else:
    188192                # We haven't yet created the table to which this field
     
    190194                pr = pending_references.setdefault(f.rel.to, []).append((model, f))
    191195        table_output.append(' '.join(field_output))
    192196    if opts.order_with_respect_to:
    193         table_output.append(style.SQL_FIELD(backend.quote_name('_order')) + ' ' + \
     197        table_output.append(style.SQL_FIELD(quote_name('_order')) + ' ' + \
    194198            style.SQL_COLTYPE(models.IntegerField().db_type()) + ' ' + \
    195199            style.SQL_KEYWORD('NULL'))
    196200    for field_constraints in opts.unique_together:
    197201        table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \
    198             ", ".join([backend.quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints]))
     202            ", ".join([quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints]))
    199203
    200     full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(backend.quote_name(opts.db_table)) + ' (']
     204    full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(quote_name(opts.db_table)) + ' (']
    201205    for i, line in enumerate(table_output): # Combine and add commas.
    202206        full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or ''))
    203207    full_statement.append(')')
    204     if opts.db_tablespace and backend.supports_tablespaces:
    205         full_statement.append(backend.get_tablespace_sql(opts.db_tablespace))
     208    if opts.db_tablespace and capabilities.supports_tablespaces:
     209        full_statement.append(ops.get_tablespace_sql(opts.db_tablespace))
    206210    full_statement.append(';')
    207211    final_output.append('\n'.join(full_statement))
    208212
    209     if opts.has_auto_field and hasattr(backend, 'get_autoinc_sql'):
     213    if opts.has_auto_field:
    210214        # Add any extra SQL needed to support auto-incrementing primary keys
    211         autoinc_sql = backend.get_autoinc_sql(opts.db_table)
     215        autoinc_sql = ops.get_autoinc_sql(opts.db_table)
    212216        if autoinc_sql:
    213217            for stmt in autoinc_sql:
    214218                final_output.append(stmt)
     
    219223    """
    220224    Get any ALTER TABLE statements to add constraints after the fact.
    221225    """
    222     from django.db import backend
     226    from django.db import connection
    223227    from django.db.backends.util import truncate_name
    224228
     229    ops = connection.ops
    225230    final_output = []
    226     if backend.supports_constraints:
     231    if connection.capabilities.supports_constraints:
    227232        opts = model._meta
    228233        if model in pending_references:
    229234            for rel_class, f in pending_references[model]:
     
    236241                # So we are careful with character usage here.
    237242                r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table))))
    238243                final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \
    239                     (backend.quote_name(r_table), truncate_name(r_name, backend.get_max_name_length()),
    240                     backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col),
    241                     backend.get_deferrable_sql()))
     244                    (ops.quote_name(r_table), truncate_name(r_name, ops.get_max_name_length()),
     245                    ops.quote_name(r_col), ops.quote_name(table), ops.quote_name(col),
     246                    ops.get_deferrable_sql()))
    242247            del pending_references[model]
    243248    return final_output
    244249
    245250def _get_many_to_many_sql_for_model(model):
    246     from django.db import backend, models
     251    from django.db import connection, models
    247252    from django.contrib.contenttypes import generic
    248253
     254    ops, capabilities = connection.ops, connection.capabilities
     255    quote_name = ops.quote_name
    249256    opts = model._meta
    250257    final_output = []
    251258    for f in opts.many_to_many:
    252259        if not isinstance(f.rel, generic.GenericRel):
    253260            tablespace = f.db_tablespace or opts.db_tablespace
    254             if tablespace and backend.supports_tablespaces and backend.autoindexes_primary_keys:
    255                 tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace, inline=True)
     261            if tablespace and capabilities.supports_tablespaces and capabilities.autoindexes_primary_keys:
     262                tablespace_sql = ' ' + ops.get_tablespace_sql(tablespace, inline=True)
    256263            else:
    257264                tablespace_sql = ''
    258265            table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \
    259                 style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' (']
     266                style.SQL_TABLE(quote_name(f.m2m_db_table())) + ' (']
    260267            table_output.append('    %s %s %s%s,' % \
    261                 (style.SQL_FIELD(backend.quote_name('id')),
     268                (style.SQL_FIELD(quote_name('id')),
    262269                style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()),
    263270                style.SQL_KEYWORD('NOT NULL PRIMARY KEY'),
    264271                tablespace_sql))
    265272            table_output.append('    %s %s %s %s (%s)%s,' % \
    266                 (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
     273                (style.SQL_FIELD(quote_name(f.m2m_column_name())),
    267274                style.SQL_COLTYPE(models.ForeignKey(model).db_type()),
    268275                style.SQL_KEYWORD('NOT NULL REFERENCES'),
    269                 style.SQL_TABLE(backend.quote_name(opts.db_table)),
    270                 style.SQL_FIELD(backend.quote_name(opts.pk.column)),
    271                 backend.get_deferrable_sql()))
     276                style.SQL_TABLE(quote_name(opts.db_table)),
     277                style.SQL_FIELD(quote_name(opts.pk.column)),
     278                ops.get_deferrable_sql()))
    272279            table_output.append('    %s %s %s %s (%s)%s,' % \
    273                 (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())),
     280                (style.SQL_FIELD(quote_name(f.m2m_reverse_name())),
    274281                style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()),
    275282                style.SQL_KEYWORD('NOT NULL REFERENCES'),
    276                 style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)),
    277                 style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)),
    278                 backend.get_deferrable_sql()))
     283                style.SQL_TABLE(quote_name(f.rel.to._meta.db_table)),
     284                style.SQL_FIELD(quote_name(f.rel.to._meta.pk.column)),
     285                ops.get_deferrable_sql()))
    279286            table_output.append('    %s (%s, %s)%s' % \
    280287                (style.SQL_KEYWORD('UNIQUE'),
    281                 style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
    282                 style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())),
     288                style.SQL_FIELD(quote_name(f.m2m_column_name())),
     289                style.SQL_FIELD(quote_name(f.m2m_reverse_name())),
    283290                tablespace_sql))
    284291            table_output.append(')')
    285             if opts.db_tablespace and backend.supports_tablespaces:
     292            if opts.db_tablespace and capabilities.supports_tablespaces:
    286293                # f.db_tablespace is only for indices, so ignore its value here.
    287                 table_output.append(backend.get_tablespace_sql(opts.db_tablespace))
     294                table_output.append(ops.get_tablespace_sql(opts.db_tablespace))
    288295            table_output.append(';')
    289296            final_output.append('\n'.join(table_output))
    290297
    291298            # Add any extra SQL needed to support auto-incrementing PKs
    292             autoinc_sql = backend.get_autoinc_sql(f.m2m_db_table())
     299            autoinc_sql = ops.get_autoinc_sql(f.m2m_db_table())
    293300            if autoinc_sql:
    294301                for stmt in autoinc_sql:
    295302                    final_output.append(stmt)
     
    298305
    299306def get_sql_delete(app):
    300307    "Returns a list of the DROP TABLE SQL statements for the given app."
    301     from django.db import backend, connection, models, get_introspection_module
     308    from django.db import connection, models, get_introspection_module
    302309    from django.db.backends.util import truncate_name
    303310    introspection = get_introspection_module()
    304311
     312    ops, capabilities = connection.ops, connections.capabilities
     313    quote_name = ops.quote_name
     314
    305315    # This should work even if a connection isn't available
    306316    try:
    307317        cursor = connection.cursor()
     
    313323        table_names = introspection.get_table_list(cursor)
    314324    else:
    315325        table_names = []
    316     if backend.uses_case_insensitive_names:
     326    if capabilities.uses_case_insensitive_names:
    317327        table_name_converter = str.upper
    318328    else:
    319329        table_name_converter = lambda x: x
     
    339349        if cursor and table_name_converter(model._meta.db_table) in table_names:
    340350            # Drop the table now
    341351            output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'),
    342                 style.SQL_TABLE(backend.quote_name(model._meta.db_table))))
    343             if backend.supports_constraints and model in references_to_delete:
     352                style.SQL_TABLE(quote_name(model._meta.db_table))))
     353            if capabilities.supports_constraints and model in references_to_delete:
    344354                for rel_class, f in references_to_delete[model]:
    345355                    table = rel_class._meta.db_table
    346356                    col = f.column
     
    349359                    r_name = '%s_refs_%s_%x' % (col, r_col, abs(hash((table, r_table))))
    350360                    output.append('%s %s %s %s;' % \
    351361                        (style.SQL_KEYWORD('ALTER TABLE'),
    352                         style.SQL_TABLE(backend.quote_name(table)),
    353                         style.SQL_KEYWORD(backend.get_drop_foreignkey_sql()),
    354                         style.SQL_FIELD(truncate_name(r_name, backend.get_max_name_length()))))
     362                        style.SQL_TABLE(quote_name(table)),
     363                        style.SQL_KEYWORD(ops.get_drop_foreignkey_sql()),
     364                        style.SQL_FIELD(truncate_name(r_name, ops.get_max_name_length()))))
    355365                del references_to_delete[model]
    356             if model._meta.has_auto_field and hasattr(backend, 'get_drop_sequence'):
    357                 output.append(backend.get_drop_sequence(model._meta.db_table))
     366            if model._meta.has_auto_field and hasattr(ops, 'get_drop_sequence'):
     367                output.append(ops.get_drop_sequence(model._meta.db_table))
    358368
    359369    # Output DROP TABLE statements for many-to-many tables.
    360370    for model in app_models:
     
    362372        for f in opts.many_to_many:
    363373            if cursor and table_name_converter(f.m2m_db_table()) in table_names:
    364374                output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'),
    365                     style.SQL_TABLE(backend.quote_name(f.m2m_db_table()))))
    366                 if hasattr(backend, 'get_drop_sequence'):
    367                     output.append(backend.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column)))
     375                    style.SQL_TABLE(quote_name(f.m2m_db_table()))))
     376                if hasattr(ops, 'get_drop_sequence'):
     377                    output.append(ops.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column)))
    368378
    369379
    370380    app_label = app_models[0]._meta.app_label
     
    387397
    388398def get_sql_flush():
    389399    "Returns a list of the SQL statements used to flush the database"
    390     from django.db import backend
    391     statements = backend.get_sql_flush(style, _get_table_list(), _get_sequence_list())
    392     return statements
     400    from django.db import connection
     401    return connection.ops.get_sql_flush(style, _get_table_list(), _get_sequence_list())
    393402get_sql_flush.help_doc = "Returns a list of the SQL statements required to return all tables in the database to the state they were in just after they were installed."
    394403get_sql_flush.args = ''
    395404
     
    443452
    444453def get_sql_sequence_reset(app):
    445454    "Returns a list of the SQL statements to reset sequences for the given app."
    446     from django.db import backend, models
    447     return backend.get_sql_sequence_reset(style, models.get_models(app))
     455    from django.db import connection, models
     456    return connection.ops.get_sql_sequence_reset(style, models.get_models(app))
    448457get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting sequences for the given app name(s)."
    449458get_sql_sequence_reset.args = APP_ARGS
    450459
     
    460469
    461470def get_sql_indexes_for_model(model):
    462471    "Returns the CREATE INDEX SQL statements for a single model"
    463     from django.db import backend
     472    from django.db import connection
    464473    output = []
    465474
     475    ops, capabilities = connection.ops, connection.capabilities
     476
    466477    for f in model._meta.fields:
    467         if f.db_index and not ((f.primary_key or f.unique) and backend.autoindexes_primary_keys):
     478        if f.db_index and not ((f.primary_key or f.unique) and capabilities.autoindexes_primary_keys):
    468479            unique = f.unique and 'UNIQUE ' or ''
    469480            tablespace = f.db_tablespace or model._meta.db_tablespace
    470             if tablespace and backend.supports_tablespaces:
    471                 tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace)
     481            if tablespace and capabilities.supports_tablespaces:
     482                tablespace_sql = ' ' + ops.get_tablespace_sql(tablespace)
    472483            else:
    473484                tablespace_sql = ''
    474485            output.append(
    475486                style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \
    476                 style.SQL_TABLE(backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \
     487                style.SQL_TABLE(ops.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \
    477488                style.SQL_KEYWORD('ON') + ' ' + \
    478                 style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \
    479                 "(%s)" % style.SQL_FIELD(backend.quote_name(f.column)) + \
     489                style.SQL_TABLE(ops.quote_name(model._meta.db_table)) + ' ' + \
     490                "(%s)" % style.SQL_FIELD(ops.quote_name(f.column)) + \
    480491                "%s;" % tablespace_sql
    481492            )
    482493    return output
     
    501512
    502513def syncdb(verbosity=1, interactive=True):
    503514    "Creates the database tables for all apps in INSTALLED_APPS whose tables haven't already been created."
    504     from django.db import backend, connection, transaction, models
     515    from django.db import connection, transaction, models
    505516    from django.conf import settings
    506517
    507518    disable_termcolors()
     
    522533    # Get a list of all existing database tables,
    523534    # so we know what needs to be added.
    524535    table_list = _get_table_list()
    525     if backend.uses_case_insensitive_names:
     536    if connection.capabilities.uses_case_insensitive_names:
    526537        table_name_converter = str.upper
    527538    else:
    528539        table_name_converter = lambda x: x
     
    12491260
    12501261def createcachetable(tablename):
    12511262    "Creates the table needed to use the SQL cache backend"
    1252     from django.db import backend, connection, transaction, models
     1263    from django.db import connection, transaction, models
     1264    quote_name = connection.ops.quote_name
    12531265    fields = (
    12541266        # "key" is a reserved word in MySQL, so use "cache_key" instead.
    12551267        models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True),
     
    12591271    table_output = []
    12601272    index_output = []
    12611273    for f in fields:
    1262         field_output = [backend.quote_name(f.name), f.db_type()]
     1274        field_output = [quote_name(f.name), f.db_type()]
    12631275        field_output.append("%sNULL" % (not f.null and "NOT " or ""))
    12641276        if f.unique:
    12651277            field_output.append("UNIQUE")
     
    12681280        if f.db_index:
    12691281            unique = f.unique and "UNIQUE " or ""
    12701282            index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \
    1271                 (unique, tablename, f.name, backend.quote_name(tablename),
    1272                 backend.quote_name(f.name)))
     1283                (unique, tablename, f.name, quote_name(tablename),
     1284                quote_name(f.name)))
    12731285        table_output.append(" ".join(field_output))
    1274     full_statement = ["CREATE TABLE %s (" % backend.quote_name(tablename)]
     1286    full_statement = ["CREATE TABLE %s (" % quote_name(tablename)]
    12751287    for i, line in enumerate(table_output):
    12761288        full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or ''))
    12771289    full_statement.append(');')
     
    13611373    "Installs the provided fixture file(s) as data in the database."
    13621374    from django.db.models import get_apps
    13631375    from django.core import serializers
    1364     from django.db import connection, transaction, backend
     1376    from django.db import connection, transaction
    13651377    from django.conf import settings
    13661378    import sys
    13671379
     
    14501462                            (format, fixture_name, humanize(fixture_dir))
    14511463
    14521464    if count[0] > 0:
    1453         sequence_sql = backend.get_sql_sequence_reset(style, models)
     1465        sequence_sql = connection.ops.get_sql_sequence_reset(style, models)
    14541466        if sequence_sql:
    14551467            if verbosity > 1:
    14561468                print "Resetting sequences"
     
    16791691        if not mod_list:
    16801692            parser.print_usage_and_exit()
    16811693        if action not in NO_SQL_TRANSACTION:
    1682             from django.db import backend
    1683             if backend.get_start_transaction_sql():
    1684                 print style.SQL_KEYWORD(backend.get_start_transaction_sql())
     1694            from django.db import connection
     1695            if connection.ops.get_start_transaction_sql():
     1696                print style.SQL_KEYWORD(connections.ops.get_start_transaction_sql())
    16851697        for mod in mod_list:
    16861698            if action == 'reset':
    16871699                output = action_mapping[action](mod, options.interactive)
  • django/db/__init__.py

    === modified file 'django/db/__init__.py'
     
    88    settings.DATABASE_ENGINE = 'dummy'
    99
    1010try:
    11     backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, {}, {}, [''])
     11    backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, {}, {}, ['']).DatabaseWrapper
    1212except ImportError, e:
    1313    # The database backend wasn't found. Display a helpful error message
    1414    # listing all possible database backends.
     
    1616    import os
    1717    backend_dir = os.path.join(__path__[0], 'backends')
    1818    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" % \
     19    if settings.DATABASE_ENGINE in available_backends:
     20        raise # If there's some other error, this must be an error in Django itself.
     21   
     22    try:
     23        backend = __import__(settings.DATABASE_ENGINE, {}, {}, [''])
     24    except ImportError, e:
     25        available_backends.sort()
     26        raise ImproperlyConfigured, "%r isn't an available database backend. Available default options are: %s" % \
    2227            (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
     28
     29connection = backend(**settings.DATABASE_OPTIONS)
     30DatabaseError = connection.DatabaseError
     31IntegrityError = connection.IntegrityError
     32get_introspection_module = lambda: connection.introspection
     33get_creation_module = lambda: connection.creation
     34runshell = lambda: connection.runshell()
    3335
    3436# Register an event that closes the database connection
    3537# when a Django request is finished.
  • django/db/backends/__init__.py

    === modified file 'django/db/backends/__init__.py'
     
     1from django.utils.functional import curry
     2from django.db.backends import util
     3
     4try:
     5    # Only exists in Python 2.4+
     6    from threading import local
     7except ImportError:
     8    # Import copy of _thread_local.py from Python 2.4
     9    from django.utils._threading_local import local
     10
     11
     12class 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
     63class 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
     75def _throw_unsupported(method, self, *args, **kwargs):
     76    raise NotImplemented(self, method)
     77
     78class BackendOps(object):
     79
     80    required_methods = ["%s_sql" % x for x in
     81        ('autoinc', 'date_extract', 'date_trunc', 'datetime_cast',
     82        'deferrable', 'drop_foreignkey', 'fulltext_search', 'limit_offset',
     83        'random_function', 'start_transaction', 'tablespace')]
     84    required_methods += ['last_insert_id', 'max_name_length',
     85        'pk_default_value', 'sequence_name', 'get_trigger_name']
     86    required_methods = ["get_%s" % x for x in required_methods]
     87    required_methods = tuple(required_methods)
     88    # listcomps leak variables; we don't need 'x' in the namespace
     89    targets = [curry(_throw_unsupported, x) for x in required_methods]
     90    locals().update(zip(required_methods, targets))
     91    for x in ('sequence_reset', 'flush'):
     92        x = 'get_sql_%s' % x
     93        required_methods += (x,)
     94        locals()[x] = curry(_throw_unsupported, x)
     95
     96    del x, targets
     97
     98    def quote_name(name):
     99        if name.startswith(self.start_quote) and name.endswith(self.end_quote):
     100            return name # already quoted.
     101        return '%s%s%s' % (self.start_quote, name, self.end_quote)
     102
     103    quote_name = staticmethod(quote_name)
     104
     105    dictfetchone = staticmethod(util.dictfetchone)
     106    dictfetchmany = staticmethod(util.dictfetchmany)
     107    dictfetchall = staticmethod(util.dictfetchall)
     108
     109    # list of methods to pull from old style db layout
     110    methods = required_methods + ('get_drop_sequence', 'quote_name',
     111       'dictfetchone', 'dictfetchmany', 'dictfetchall',)
     112
     113    def __init__(self, quote_chars='""'):
     114        self.start_quote, self.end_quote = quote_chars[0:2]
     115
     116
     117class OldLayoutBaseDatabaseWrapper(BaseDatabaseWrapper):
     118
     119    """
     120    Convenience class used for mapping <=0.96 style backend
     121    layouts into current form.
     122   
     123    Generally speaking, you want BaseDatabaseWrapper, not this class.
     124    """
     125
     126    def __init__(self, *args, **kwargs):
     127        super(OldLayoutBaseDatabaseWrapper, self).__init__(*args, **kwargs)
     128        mod = __import__(self.__class__.__module__, {}, {}, [''])
     129        d = BackendCapabilities.defaults.copy()
     130        for k, v in d.iteritems():
     131            if hasattr(mod, k):
     132                d[k] = getattr(mod, k)
     133        # generate a few mappings via inspection of the module.
     134        self.capabilities = BackendCapabilities(**d)
     135        self.orm_map = mod.OPERATOR_MAPPING.copy()
     136        self.ops = ops = BackendOps()
     137        for op in ops.methods:
     138            if hasattr(mod, op):
     139                setattr(ops, op, getattr(mod, op))
     140        self.DatabaseError = mod.DatabaseError
     141        self.IntegrityError = mod.IntegrityError
     142
     143
     144    def _base_namespace(self):
     145        # when py2.4 is the default, convert this to a rsplit limit=1
     146        return '.'.join(self.__class__.__module__.split(".")[:-1])
     147
     148    def introspection(self):
     149        return __import__(self._base_namespace + '.introspection', {}, {}, [''])
     150
     151    def creation(self):
     152        return __import__(self._base_namespace + '.creation', {}, {}, [''])
     153
     154    def runshell(self):
     155        return __import__(self._base_namespace + '.client', {}, {}, ['']).runshell
     156
     157    _base_namespace, introspection, creation, runshell = map(property,
     158        (_base_namespace, introspection, creation, runshell))
  • django/db/backends/ado_mssql/base.py

    === modified file 'django/db/backends/ado_mssql/base.py'
     
    4848    return res
    4949Database.convertVariantToPython = variantToPython
    5050
    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
     51from django.db.backends import OldLayoutBaseDatabaseWrapper
     52
     53class DatabaseWrapper(OldLayoutBaseDatabaseWrapper):
     54
     55    def _cursor(self, settings):
    6556        if self.connection is None:
    6657            if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
    6758                from django.core.exceptions import ImproperlyConfigured
     
    7162            # TODO: Handle DATABASE_PORT.
    7263            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)
    7364            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
    9167
    9268allows_group_by_ordinal = True
    9369allows_unique_and_pk = True
  • django/db/backends/mysql/base.py

    === modified file 'django/db/backends/mysql/base.py'
     
    5353# standard util.CursorDebugWrapper can be used. Also, using sql_mode
    5454# TRADITIONAL will automatically cause most warnings to be treated as errors.
    5555
    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 local
    62 
    63 class DatabaseWrapper(local):
     56
     57from django.db.backends import OldLayoutBaseDatabaseWrapper
     58
     59class DatabaseWrapper(OldLayoutBaseDatabaseWrapper):
     60
     61    DatabaseError = Database.DatabaseError
     62    IntegrityError = Database.IntegrityError
     63
    6464    def __init__(self, **kwargs):
    65         self.connection = None
    66         self.queries = []
     65        super(DatabaseWrapper, self).__init__(**kwargs)
    6766        self.server_version = None
    68         self.options = kwargs
    6967
    7068    def _valid_connection(self):
    7169        if self.connection is not None:
     
    7775                self.connection = None
    7876        return False
    7977
    80     def cursor(self):
    81         from django.conf import settings
     78    def _cursor(self, settings):
    8279        from warnings import filterwarnings
    8380        if not self._valid_connection():
    8481            kwargs = {
     
    10097                kwargs['port'] = int(settings.DATABASE_PORT)
    10198            kwargs.update(self.options)
    10299            self.connection = Database.connect(**kwargs)
    103             cursor = self.connection.cursor()
    104         else:
    105             cursor = self.connection.cursor()
     100        cursor = self.connection.cursor()
    106101        if settings.DEBUG:
    107102            filterwarnings("error", category=Database.Warning)
    108             return util.CursorDebugWrapper(cursor, self)
    109103        return cursor
    110104
    111     def _commit(self):
    112         if self.connection is not None:
    113             self.connection.commit()
    114 
    115105    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
    126110
    127111    def get_server_version(self):
    128112        if not self.server_version:
  • django/db/backends/mysql_old/base.py

    === modified file 'django/db/backends/mysql_old/base.py'
     
    6363        else:
    6464            return getattr(self.cursor, attr)
    6565
    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
     66from django.db.backends import OldLayoutBaseDatabaseWrapper
    7267
    73 class DatabaseWrapper(local):
     68class DatabaseWrapper(OldLayoutBaseDatabaseWrapper):
    7469    def __init__(self, **kwargs):
    75         self.connection = None
    76         self.queries = []
     70        super(DatabaseWrapper, self).__init__(**kwargs)
    7771        self.server_version = None
    78         self.options = kwargs
    7972
    8073    def _valid_connection(self):
    8174        if self.connection is not None:
     
    8780                self.connection = None
    8881        return False
    8982
    90     def cursor(self):
    91         from django.conf import settings
     83    def _cursor(self, settings):
    9284        if not self._valid_connection():
    9385            kwargs = {
    9486                # Note: use_unicode intentonally not set to work around some
     
    119111                    self.connection.set_character_set('utf8')
    120112        else:
    121113            cursor = self.connection.cursor()
    122         if settings.DEBUG:
    123             return util.CursorDebugWrapper(MysqlDebugWrapper(cursor), self)
     114       
    124115        return cursor
    125116
    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))
    129119
    130120    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
    141125
    142126    def get_server_version(self):
    143127        if not self.server_version:
  • django/db/backends/oracle/base.py

    === modified file 'django/db/backends/oracle/base.py'
     
    2323DatabaseError = Database.Error
    2424IntegrityError = Database.IntegrityError
    2525
    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
     26from django.db.backends import OldLayoutBaseDatabaseWrapper
    3227
    33 class DatabaseWrapper(local):
    34     def __init__(self, **kwargs):
    35         self.connection = None
    36         self.queries = []
    37         self.options = kwargs
     28class DatabaseWrapper(OldLayoutBaseDatabaseWrapper):
    3829
    3930    def _valid_connection(self):
    4031        return self.connection is not None
    4132
    42     def cursor(self):
     33    def _cursor(self, settings):
    4334        if not self._valid_connection():
    4435            if len(settings.DATABASE_HOST.strip()) == 0:
    4536                settings.DATABASE_HOST = 'localhost'
     
    5546        # Set oracle date to ansi date format.
    5647        cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'")
    5748        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)
    6049        return cursor
    6150
    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 = None
    7451
    7552allows_group_by_ordinal = False
    7653allows_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'
     
    1515DatabaseError = Database.DatabaseError
    1616IntegrityError = Database.IntegrityError
    1717
    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
     18from django.db.backends import OldLayoutBaseDatabaseWrapper
    2419
    2520class UnicodeCursorWrapper(object):
    2621    """
     
    6459
    6560postgres_version = None
    6661
    67 class DatabaseWrapper(local):
    68     def __init__(self, **kwargs):
    69         self.connection = None
    70         self.queries = []
    71         self.options = kwargs
     62class DatabaseWrapper(OldLayoutBaseDatabaseWrapper):
    7263
    73     def cursor(self):
    74         from django.conf import settings
     64    def _cursor(self, settings):
    7565        set_tz = False
    7666        if self.connection is None:
    7767            set_tz = True
     
    9888        if not postgres_version:
    9989            cursor.execute("SELECT version()")
    10090            postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')]
    101         if settings.DEBUG:
    102             return util.CursorDebugWrapper(cursor, self)
    10391        return cursor
    10492
    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 = None
    117 
    11893allows_group_by_ordinal = True
    11994allows_unique_and_pk = True
    12095autoindexes_primary_keys = True
  • django/db/backends/postgresql_psycopg2/base.py

    === modified file 'django/db/backends/postgresql_psycopg2/base.py'
     
    55"""
    66
    77from django.db.backends import util
     8from django.db.backends import OldLayoutBaseDatabaseWrapper
     9
    810try:
    911    import psycopg2 as Database
    1012    import psycopg2.extensions
     
    1517DatabaseError = Database.DatabaseError
    1618IntegrityError = Database.IntegrityError
    1719
    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
    24 
    2520psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
    2621
    2722postgres_version = None
    2823
    29 class DatabaseWrapper(local):
    30     def __init__(self, **kwargs):
    31         self.connection = None
    32         self.queries = []
    33         self.options = kwargs
     24class DatabaseWrapper(OldLayoutBaseDatabaseWrapper):
    3425
    35     def cursor(self):
    36         from django.conf import settings
     26    def _cursor(self, settings):
    3727        set_tz = False
    3828        if self.connection is None:
    3929            set_tz = True
     
    6050        if not postgres_version:
    6151            cursor.execute("SELECT version()")
    6252            postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')]
    63         if settings.DEBUG:
    64             return util.CursorDebugWrapper(cursor, self)
    6553        return cursor
    6654
    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 = None
    7955
    8056allows_group_by_ordinal = True
    8157allows_unique_and_pk = True
  • django/db/backends/sqlite3/base.py

    === modified file 'django/db/backends/sqlite3/base.py'
     
    3434Database.register_converter("decimal", util.typecast_decimal)
    3535Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
    3636
    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
     37from django.db.backends import OldLayoutBaseDatabaseWrapper
     38
     39class DatabaseWrapper(OldLayoutBaseDatabaseWrapper):
     40
     41    def _cursor(self, settings):
    5242        if self.connection is None:
    5343            kwargs = {
    5444                'database': settings.DATABASE_NAME,
     
    6050            self.connection.create_function("django_extract", 2, _sqlite_extract)
    6151            self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc)
    6252            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)
    7654
    7755    def close(self):
    7856        from django.conf import settings
    7957        # If database is in memory, closing the connection destroys the
    8058        # database.  To prevent accidental data loss, ignore close requests on
    8159        # an in-memory db.
    82         if self.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
    8563
    8664class SQLiteCursorWrapper(Database.Cursor):
    8765    """
  • django/db/models/base.py

    === modified file 'django/db/models/base.py'
     
    66from django.db.models.fields.related import OneToOneRel, ManyToOneRel
    77from django.db.models.query import delete_objects
    88from django.db.models.options import Options, AdminOptions
    9 from django.db import connection, backend, transaction
     9from django.db import connection, transaction
    1010from django.db.models import signals
    1111from django.db.models.loading import register_models, get_model
    1212from django.dispatch import dispatcher
     
    207207        non_pks = [f for f in self._meta.fields if not f.primary_key]
    208208        cursor = connection.cursor()
    209209
     210        ops = connection.ops
     211        quote_name = ops.quote_name
    210212        # First, try an UPDATE. If that doesn't update anything, do an INSERT.
    211213        pk_val = self._get_pk_val()
    212214        pk_set = bool(pk_val)
     
    214216        if pk_set:
    215217            # Determine whether a record with the primary key already exists.
    216218            cursor.execute("SELECT COUNT(*) 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)),
    218220                self._meta.pk.get_db_prep_lookup('exact', pk_val))
    219221            # If it does already exist, do an UPDATE.
    220222            if cursor.fetchone()[0] > 0:
    221223                db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False)) for f in non_pks]
    222224                if db_values:
    223225                    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)),
    227229                        db_values + self._meta.pk.get_db_prep_lookup('exact', pk_val))
    228230            else:
    229231                record_exists = False
    230232        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)]
    232234            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)]
    233235            # If the PK has been manually set, respect that.
    234236            if pk_set:
     
    236238                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)]
    237239            placeholders = ['%s'] * len(field_names)
    238240            if self._meta.order_with_respect_to:
    239                 field_names.append(backend.quote_name('_order'))
     241                field_names.append(quote_name('_order'))
    240242                # TODO: This assumes the database supports subqueries.
    241243                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)))
    243245                db_values.append(getattr(self, self._meta.order_with_respect_to.attname))
    244246            if db_values:
    245247                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),
    247249                    ','.join(placeholders)), db_values)
    248250            else:
    249251                # Create a new record with defaults for everything.
    250252                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()))
    254256            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))
    256258        transaction.commit_unless_managed()
    257259
    258260        # Run any post-save hooks.
     
    326328    def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs):
    327329        op = is_next and '>' or '<'
    328330        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)
    331333        param = smart_str(getattr(self, field.attname))
    332334        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)
    333335        q._where.append(where)
     
    343345            op = is_next and '>' or '<'
    344346            order_field = self._meta.order_with_respect_to
    345347            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)]
    349351            params = [self._get_pk_val(), getattr(self, order_field.attname)]
    350352            obj = self._default_manager.order_by('_order').extra(where=where, params=params)[:1].get()
    351353            setattr(self, cachename, obj)
     
    430432    cursor = connection.cursor()
    431433    # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s"
    432434    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))
    436438    rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
    437439    cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)])
    438440    transaction.commit_unless_managed()
     
    441443    cursor = connection.cursor()
    442444    # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order"
    443445    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'))
    448450    rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
    449451    cursor.execute(sql, [rel_val])
    450452    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, transaction
     1from django.db import connection, transaction
    22from django.db.models import signals, get_model
    33from django.db.models.fields import AutoField, Field, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, get_ul_class
    44from django.db.models.related import RelatedObject
     
    400400        superclass = rel_model._default_manager.__class__
    401401        RelatedManager = create_many_related_manager(superclass)
    402402
    403         qn = backend.quote_name
     403        qn = connection.ops.quote_name
    404404        manager = RelatedManager(
    405405            model=rel_model,
    406406            core_filters={'%s__pk' % self.related.field.name: instance._get_pk_val()},
     
    441441        superclass = rel_model._default_manager.__class__
    442442        RelatedManager = create_many_related_manager(superclass)
    443443
    444         qn = backend.quote_name
     444        qn = connection.ops.quote_name
    445445        manager = RelatedManager(
    446446            model=rel_model,
    447447            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'
     
    6363        del self.meta
    6464
    6565    def _prepare(self, model):
    66         from django.db import backend
     66        from django.db import connection
    6767        from django.db.backends.util import truncate_name
    6868        if self.order_with_respect_to:
    6969            self.order_with_respect_to = self.get_field(self.order_with_respect_to)
     
    8080        if not self.db_table:
    8181            self.db_table = "%s_%s" % (self.app_label, self.module_name)
    8282            self.db_table = truncate_name(self.db_table,
    83                                           backend.get_max_name_length())
     83                                          connection.ops.get_max_name_length())
    8484
    8585    def add_field(self, field):
    8686        # 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'
     
    6464        return f
    6565
    6666def orderlist2sql(order_list, opts, prefix=''):
     67    quote_name = connection.ops.quote_name
     68    get_rand_sql = connection.ops.get_random_function_sql
    6769    if prefix.endswith('.'):
    68         prefix = backend.quote_name(prefix[:-1]) + '.'
     70        prefix = quote_name(prefix[:-1]) + '.'
    6971    output = []
    7072    for f in handle_legacy_orderlist(order_list):
    7173        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))))
    7375        elif f == '?':
    74             output.append(backend.get_random_function_sql())
     76            output.append(get_rand_sql())
    7577        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))))
    7779    return ', '.join(output)
    7880
    7981def quote_only_if_word(word):
    8082    if re.search('\W', word): # Don't quote if there are spaces or non-word chars.
    8183        return word
    8284    else:
    83         return backend.quote_name(word)
     85        return connection.ops.quote_name(word)
    8486
    8587class _QuerySet(object):
    8688    "Represents a lazy database lookup for a set of objects"
     
    235237
    236238        cursor = connection.cursor()
    237239        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))
    240242            cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params)
    241243        else:
    242244            cursor.execute("SELECT COUNT(*)" + sql, params)
     
    312314        if id_list == []:
    313315            return {}
    314316        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))))
    316319        qs._params.extend(id_list)
    317320        return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()])
    318321
     
    483486    def _get_sql_clause(self):
    484487        opts = self.model._meta
    485488
     489        quote_name = connection.ops.quote_name
    486490        # 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]
    488492        tables = [quote_only_if_word(t) for t in self._tables]
    489493        joins = SortedDict()
    490494        where = self._where[:]
     
    505509
    506510        # Add any additional SELECTs.
    507511        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()])
    509513
    510514        # 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)]
    512516
    513517        # Compose the join dictionary into SQL describing the joins.
    514518        if joins:
     
    531535            ordering_to_use = opts.ordering
    532536        for f in handle_legacy_orderlist(ordering_to_use):
    533537            if f == '?': # Special case.
    534                 order_by.append(backend.get_random_function_sql())
     538                order_by.append(connection.ops.get_random_function_sql())
    535539            else:
    536540                if f.startswith('-'):
    537541                    col_name = f[1:]
     
    541545                    order = "ASC"
    542546                if "." in col_name:
    543547                    table_prefix, col_name = col_name.split('.', 1)
    544                     table_prefix = backend.quote_name(table_prefix) + '.'
     548                    table_prefix = quote_name(table_prefix) + '.'
    545549                else:
    546550                    # Use the database table as a column prefix if it wasn't given,
    547551                    # and if the requested column isn't a custom SELECT.
    548552                    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) + '.'
    550554                    else:
    551555                        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))
    553557        if order_by:
    554558            sql.append("ORDER BY " + ", ".join(order_by))
    555559
    556560        # LIMIT and OFFSET clauses
    557561        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))
    559563        else:
    560564            assert self._offset is None, "'offset' is not allowed without 'limit'"
    561565
    562566        return select, " ".join(sql), params
    563567
    564568# 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)
     569if hasattr(connection.ops, 'get_query_set_class'):
     570    QuerySet = connection.ops.get_query_set_class(_QuerySet)
    567571else:
    568572    QuerySet = _QuerySet
    569573
     
    605609            field_names = [f.attname for f in fields]
    606610
    607611        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]
    609613        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])
    611615            field_names.extend([f[0] for f in extra_select])
    612616
    613617        cursor = connection.cursor()
     
    635639        self._order_by = () # Clear this because it'll mess things up otherwise.
    636640        if self._field.null:
    637641            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)))
    639643        try:
    640644            select, sql, params = self._get_sql_clause()
    641645        except EmptyResultSet:
    642646            raise StopIteration
    643647
    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)
    646650
    647         if backend.allows_group_by_ordinal:
     651        if connection.capabilities.allows_group_by_ordinal:
    648652            group_by = '1'
    649653        else:
    650             group_by = backend.get_date_trunc_sql(self._kind,
     654            group_by = connection.ops.get_date_trunc_sql(self._kind,
    651655                                                  '%s.%s' % (table_name, field_name))
    652656
    653657        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)
    656660        cursor = connection.cursor()
    657661        cursor.execute(sql, params)
    658662
    659663        has_resolve_columns = hasattr(self, 'resolve_columns')
    660         needs_datetime_string_cast = backend.needs_datetime_string_cast
     664        needs_datetime_string_cast = connection.capabilities.needs_datetime_string_cast
    661665        dates = []
    662666        # It would be better to use self._field here instead of DateTimeField(),
    663667        # but in Oracle that will result in a list of datetime.date instead of
     
    779783
    780784def get_where_clause(lookup_type, table_prefix, field_name, value):
    781785    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()
    786790    else:
    787791        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:
    789793        format = 'UPPER(%s%s) %s'
    790794    else:
    791795        format = '%s%s %s'
    792796    try:
    793797        return format % (table_prefix, field_name,
    794                          backend.OPERATOR_MAPPING[lookup_type] % cast_sql)
     798                         connection.orm_map[lookup_type] % cast_sql)
    795799    except KeyError:
    796800        pass
    797801    if lookup_type == 'in':
     
    803807    elif lookup_type in ('range', 'year'):
    804808        return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name)
    805809    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)
    807811    elif lookup_type == 'isnull':
    808812        return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or ''))
    809813    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)
    811815    elif lookup_type in ('regex', 'iregex'):
    812816        if settings.DATABASE_ENGINE == 'oracle':
    813817            if lookup_type == 'regex':
     
    846850    if max_depth and cur_depth > max_depth:
    847851        return None
    848852
    849     qn = backend.quote_name
     853    qn = connection.ops.quote_name
    850854    for f in opts.fields:
    851855        if f.rel and not f.null:
    852856            db_table = f.rel.to._meta.db_table
     
    944948    return choices
    945949
    946950def lookup_inner(path, lookup_type, value, opts, table, column):
    947     qn = backend.quote_name
     951    qn = connection.ops.quote_name
    948952    joins, where, params = SortedDict(), [], []
    949953    current_opts = opts
    950954    current_table = table
     
    11081112
    11091113def delete_objects(seen_objs):
    11101114    "Iterate through a list of seen classes, and remove any instances that are referred to"
    1111     qn = backend.quote_name
     1115    qn = connection.ops.quote_name
    11121116    ordered_classes = seen_objs.keys()
    11131117    ordered_classes.reverse()
    11141118
  • django/test/utils.py

    === modified file 'django/test/utils.py'
     
    119119        cursor = connection.cursor()
    120120        _set_autocommit(connection)
    121121        try:
    122             cursor.execute("CREATE DATABASE %s %s" % (backend.quote_name(TEST_DATABASE_NAME), suffix))
     122            cursor.execute("CREATE DATABASE %s %s" % (connection.ops.quote_name(TEST_DATABASE_NAME), suffix))
    123123        except Exception, e:           
    124124            sys.stderr.write("Got an error creating the test database: %s\n" % e)
    125125            if not autoclobber:
     
    128128                try:
    129129                    if verbosity >= 1:
    130130                        print "Destroying old test database..."               
    131                     cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))
     131                    cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(TEST_DATABASE_NAME))
    132132                    if verbosity >= 1:
    133133                        print "Creating test database..."
    134                     cursor.execute("CREATE DATABASE %s %s" % (backend.quote_name(TEST_DATABASE_NAME), suffix))
     134                    cursor.execute("CREATE DATABASE %s %s" % (connection.ops.quote_name(TEST_DATABASE_NAME), suffix))
    135135                except Exception, e:
    136136                    sys.stderr.write("Got an error recreating the test database: %s\n" % e)
    137137                    sys.exit(2)
     
    173173        cursor = connection.cursor()
    174174        _set_autocommit(connection)
    175175        time.sleep(1) # To avoid "database is being accessed by other users" errors.
    176         cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))
     176        cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(TEST_DATABASE_NAME))
    177177        connection.close()
Back to Top