summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/django/db/backends/mysql
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/django/db/backends/mysql')
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/__init__.py0
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/base.py533
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/client.py40
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/compiler.py37
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/creation.py70
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/introspection.py119
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/validation.py16
7 files changed, 0 insertions, 815 deletions
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/__init__.py b/lib/python2.7/site-packages/django/db/backends/mysql/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/base.py b/lib/python2.7/site-packages/django/db/backends/mysql/base.py
deleted file mode 100644
index ea04a5e..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/base.py
+++ /dev/null
@@ -1,533 +0,0 @@
-"""
-MySQL database backend for Django.
-
-Requires MySQLdb: http://sourceforge.net/projects/mysql-python
-"""
-from __future__ import unicode_literals
-
-import datetime
-import re
-import sys
-import warnings
-
-try:
- import MySQLdb as Database
-except ImportError as e:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
-
-from django.utils.functional import cached_property
-
-# We want version (1, 2, 1, 'final', 2) or later. We can't just use
-# lexicographic ordering in this check because then (1, 2, 1, 'gamma')
-# inadvertently passes the version test.
-version = Database.version_info
-if (version < (1, 2, 1) or (version[:3] == (1, 2, 1) and
- (len(version) < 5 or version[3] != 'final' or version[4] < 2))):
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
-
-from MySQLdb.converters import conversions, Thing2Literal
-from MySQLdb.constants import FIELD_TYPE, CLIENT
-
-try:
- import pytz
-except ImportError:
- pytz = None
-
-from django.conf import settings
-from django.db import utils
-from django.db.backends import *
-from django.db.backends.mysql.client import DatabaseClient
-from django.db.backends.mysql.creation import DatabaseCreation
-from django.db.backends.mysql.introspection import DatabaseIntrospection
-from django.db.backends.mysql.validation import DatabaseValidation
-from django.utils.encoding import force_str, force_text
-from django.utils.safestring import SafeBytes, SafeText
-from django.utils import six
-from django.utils import timezone
-
-# Raise exceptions for database warnings if DEBUG is on
-if settings.DEBUG:
- warnings.filterwarnings("error", category=Database.Warning)
-
-DatabaseError = Database.DatabaseError
-IntegrityError = Database.IntegrityError
-
-# It's impossible to import datetime_or_None directly from MySQLdb.times
-parse_datetime = conversions[FIELD_TYPE.DATETIME]
-
-def parse_datetime_with_timezone_support(value):
- dt = parse_datetime(value)
- # Confirm that dt is naive before overwriting its tzinfo.
- if dt is not None and settings.USE_TZ and timezone.is_naive(dt):
- dt = dt.replace(tzinfo=timezone.utc)
- return dt
-
-def adapt_datetime_with_timezone_support(value, conv):
- # Equivalent to DateTimeField.get_db_prep_value. Used only by raw SQL.
- if settings.USE_TZ:
- if timezone.is_naive(value):
- warnings.warn("MySQL received a naive datetime (%s)"
- " while time zone support is active." % value,
- RuntimeWarning)
- default_timezone = timezone.get_default_timezone()
- value = timezone.make_aware(value, default_timezone)
- value = value.astimezone(timezone.utc).replace(tzinfo=None)
- return Thing2Literal(value.strftime("%Y-%m-%d %H:%M:%S"), conv)
-
-# MySQLdb-1.2.1 returns TIME columns as timedelta -- they are more like
-# timedelta in terms of actual behavior as they are signed and include days --
-# and Django expects time, so we still need to override that. We also need to
-# add special handling for SafeText and SafeBytes as MySQLdb's type
-# checking is too tight to catch those (see Django ticket #6052).
-# Finally, MySQLdb always returns naive datetime objects. However, when
-# timezone support is active, Django expects timezone-aware datetime objects.
-django_conversions = conversions.copy()
-django_conversions.update({
- FIELD_TYPE.TIME: util.typecast_time,
- FIELD_TYPE.DECIMAL: util.typecast_decimal,
- FIELD_TYPE.NEWDECIMAL: util.typecast_decimal,
- FIELD_TYPE.DATETIME: parse_datetime_with_timezone_support,
- datetime.datetime: adapt_datetime_with_timezone_support,
-})
-
-# This should match the numerical portion of the version numbers (we can treat
-# versions like 5.0.24 and 5.0.24a as the same). Based on the list of version
-# at http://dev.mysql.com/doc/refman/4.1/en/news.html and
-# http://dev.mysql.com/doc/refman/5.0/en/news.html .
-server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
-
-# MySQLdb-1.2.1 and newer automatically makes use of SHOW WARNINGS on
-# MySQL-4.1 and newer, so the MysqlDebugWrapper is unnecessary. Since the
-# point is to raise Warnings as exceptions, this can be done with the Python
-# warning module, and this is setup when the connection is created, and the
-# standard util.CursorDebugWrapper can be used. Also, using sql_mode
-# TRADITIONAL will automatically cause most warnings to be treated as errors.
-
-class CursorWrapper(object):
- """
- A thin wrapper around MySQLdb's normal cursor class so that we can catch
- particular exception instances and reraise them with the right types.
-
- Implemented as a wrapper, rather than a subclass, so that we aren't stuck
- to the particular underlying representation returned by Connection.cursor().
- """
- codes_for_integrityerror = (1048,)
-
- def __init__(self, cursor):
- self.cursor = cursor
-
- def execute(self, query, args=None):
- try:
- # args is None means no string interpolation
- return self.cursor.execute(query, args)
- except Database.OperationalError as e:
- # Map some error codes to IntegrityError, since they seem to be
- # misclassified and Django would prefer the more logical place.
- if e.args[0] in self.codes_for_integrityerror:
- six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
- raise
-
- def executemany(self, query, args):
- try:
- return self.cursor.executemany(query, args)
- except Database.OperationalError as e:
- # Map some error codes to IntegrityError, since they seem to be
- # misclassified and Django would prefer the more logical place.
- if e.args[0] in self.codes_for_integrityerror:
- six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
- raise
-
- def __getattr__(self, attr):
- if attr in self.__dict__:
- return self.__dict__[attr]
- else:
- return getattr(self.cursor, attr)
-
- def __iter__(self):
- return iter(self.cursor)
-
-class DatabaseFeatures(BaseDatabaseFeatures):
- empty_fetchmany_value = ()
- update_can_self_select = False
- allows_group_by_pk = True
- related_fields_match_type = True
- allow_sliced_subqueries = False
- has_bulk_insert = True
- has_select_for_update = True
- has_select_for_update_nowait = False
- supports_forward_references = False
- supports_long_model_names = False
- supports_microsecond_precision = False
- supports_regex_backreferencing = False
- supports_date_lookup_using_string = False
- supports_timezones = False
- requires_explicit_null_ordering_when_grouping = True
- allows_primary_key_0 = False
- uses_savepoints = True
- atomic_transactions = False
-
- def __init__(self, connection):
- super(DatabaseFeatures, self).__init__(connection)
-
- @cached_property
- def _mysql_storage_engine(self):
- "Internal method used in Django tests. Don't rely on this from your code"
- cursor = self.connection.cursor()
- cursor.execute('CREATE TABLE INTROSPECT_TEST (X INT)')
- # This command is MySQL specific; the second column
- # will tell you the default table type of the created
- # table. Since all Django's test tables will have the same
- # table type, that's enough to evaluate the feature.
- cursor.execute("SHOW TABLE STATUS WHERE Name='INTROSPECT_TEST'")
- result = cursor.fetchone()
- cursor.execute('DROP TABLE INTROSPECT_TEST')
- return result[1]
-
- @cached_property
- def can_introspect_foreign_keys(self):
- "Confirm support for introspected foreign keys"
- return self._mysql_storage_engine != 'MyISAM'
-
- @cached_property
- def has_zoneinfo_database(self):
- # MySQL accepts full time zones names (eg. Africa/Nairobi) but rejects
- # abbreviations (eg. EAT). When pytz isn't installed and the current
- # time zone is LocalTimezone (the only sensible value in this
- # context), the current time zone name will be an abbreviation. As a
- # consequence, MySQL cannot perform time zone conversions reliably.
- if pytz is None:
- return False
-
- # Test if the time zone definitions are installed.
- cursor = self.connection.cursor()
- cursor.execute("SELECT 1 FROM mysql.time_zone LIMIT 1")
- return cursor.fetchone() is not None
-
-class DatabaseOperations(BaseDatabaseOperations):
- compiler_module = "django.db.backends.mysql.compiler"
-
- def date_extract_sql(self, lookup_type, field_name):
- # http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
- if lookup_type == 'week_day':
- # DAYOFWEEK() returns an integer, 1-7, Sunday=1.
- # Note: WEEKDAY() returns 0-6, Monday=0.
- return "DAYOFWEEK(%s)" % field_name
- else:
- return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
-
- def date_trunc_sql(self, lookup_type, field_name):
- fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
- format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
- format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
- try:
- i = fields.index(lookup_type) + 1
- except ValueError:
- sql = field_name
- else:
- format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
- sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
- return sql
-
- def datetime_extract_sql(self, lookup_type, field_name, tzname):
- if settings.USE_TZ:
- field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
- params = [tzname]
- else:
- params = []
- # http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
- if lookup_type == 'week_day':
- # DAYOFWEEK() returns an integer, 1-7, Sunday=1.
- # Note: WEEKDAY() returns 0-6, Monday=0.
- sql = "DAYOFWEEK(%s)" % field_name
- else:
- sql = "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
- return sql, params
-
- def datetime_trunc_sql(self, lookup_type, field_name, tzname):
- if settings.USE_TZ:
- field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
- params = [tzname]
- else:
- params = []
- fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
- format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
- format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
- try:
- i = fields.index(lookup_type) + 1
- except ValueError:
- sql = field_name
- else:
- format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
- sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
- return sql, params
-
- def date_interval_sql(self, sql, connector, timedelta):
- return "(%s %s INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND)" % (sql, connector,
- timedelta.days, timedelta.seconds, timedelta.microseconds)
-
- def drop_foreignkey_sql(self):
- return "DROP FOREIGN KEY"
-
- def force_no_ordering(self):
- """
- "ORDER BY NULL" prevents MySQL from implicitly ordering by grouped
- columns. If no ordering would otherwise be applied, we don't want any
- implicit sorting going on.
- """
- return ["NULL"]
-
- def fulltext_search_sql(self, field_name):
- return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name
-
- def last_executed_query(self, cursor, sql, params):
- # With MySQLdb, cursor objects have an (undocumented) "_last_executed"
- # attribute where the exact query sent to the database is saved.
- # See MySQLdb/cursors.py in the source distribution.
- return force_text(getattr(cursor, '_last_executed', None), errors='replace')
-
- def no_limit_value(self):
- # 2**64 - 1, as recommended by the MySQL documentation
- return 18446744073709551615
-
- def quote_name(self, name):
- if name.startswith("`") and name.endswith("`"):
- return name # Quoting once is enough.
- return "`%s`" % name
-
- def random_function_sql(self):
- return 'RAND()'
-
- def sql_flush(self, style, tables, sequences, allow_cascade=False):
- # NB: The generated SQL below is specific to MySQL
- # 'TRUNCATE x;', 'TRUNCATE y;', 'TRUNCATE z;'... style SQL statements
- # to clear all tables of all data
- if tables:
- sql = ['SET FOREIGN_KEY_CHECKS = 0;']
- for table in tables:
- sql.append('%s %s;' % (
- style.SQL_KEYWORD('TRUNCATE'),
- style.SQL_FIELD(self.quote_name(table)),
- ))
- sql.append('SET FOREIGN_KEY_CHECKS = 1;')
- sql.extend(self.sequence_reset_by_name_sql(style, sequences))
- return sql
- else:
- return []
-
- def sequence_reset_by_name_sql(self, style, sequences):
- # Truncate already resets the AUTO_INCREMENT field from
- # MySQL version 5.0.13 onwards. Refs #16961.
- if self.connection.mysql_version < (5, 0, 13):
- return ["%s %s %s %s %s;" % \
- (style.SQL_KEYWORD('ALTER'),
- style.SQL_KEYWORD('TABLE'),
- style.SQL_TABLE(self.quote_name(sequence['table'])),
- style.SQL_KEYWORD('AUTO_INCREMENT'),
- style.SQL_FIELD('= 1'),
- ) for sequence in sequences]
- else:
- return []
-
- def validate_autopk_value(self, value):
- # MySQLism: zero in AUTO_INCREMENT field does not work. Refs #17653.
- if value == 0:
- raise ValueError('The database backend does not accept 0 as a '
- 'value for AutoField.')
- return value
-
- def value_to_db_datetime(self, value):
- if value is None:
- return None
-
- # MySQL doesn't support tz-aware datetimes
- if timezone.is_aware(value):
- if settings.USE_TZ:
- value = value.astimezone(timezone.utc).replace(tzinfo=None)
- else:
- raise ValueError("MySQL backend does not support timezone-aware datetimes when USE_TZ is False.")
-
- # MySQL doesn't support microseconds
- return six.text_type(value.replace(microsecond=0))
-
- def value_to_db_time(self, value):
- if value is None:
- return None
-
- # MySQL doesn't support tz-aware times
- if timezone.is_aware(value):
- raise ValueError("MySQL backend does not support timezone-aware times.")
-
- # MySQL doesn't support microseconds
- return six.text_type(value.replace(microsecond=0))
-
- def year_lookup_bounds_for_datetime_field(self, value):
- # Again, no microseconds
- first, second = super(DatabaseOperations, self).year_lookup_bounds_for_datetime_field(value)
- return [first.replace(microsecond=0), second.replace(microsecond=0)]
-
- def max_name_length(self):
- return 64
-
- def bulk_insert_sql(self, fields, num_values):
- items_sql = "(%s)" % ", ".join(["%s"] * len(fields))
- return "VALUES " + ", ".join([items_sql] * num_values)
-
-class DatabaseWrapper(BaseDatabaseWrapper):
- vendor = 'mysql'
- operators = {
- 'exact': '= %s',
- 'iexact': 'LIKE %s',
- 'contains': 'LIKE BINARY %s',
- 'icontains': 'LIKE %s',
- 'regex': 'REGEXP BINARY %s',
- 'iregex': 'REGEXP %s',
- 'gt': '> %s',
- 'gte': '>= %s',
- 'lt': '< %s',
- 'lte': '<= %s',
- 'startswith': 'LIKE BINARY %s',
- 'endswith': 'LIKE BINARY %s',
- 'istartswith': 'LIKE %s',
- 'iendswith': 'LIKE %s',
- }
-
- Database = Database
-
- def __init__(self, *args, **kwargs):
- super(DatabaseWrapper, self).__init__(*args, **kwargs)
-
- self.features = DatabaseFeatures(self)
- self.ops = DatabaseOperations(self)
- self.client = DatabaseClient(self)
- self.creation = DatabaseCreation(self)
- self.introspection = DatabaseIntrospection(self)
- self.validation = DatabaseValidation(self)
-
- def get_connection_params(self):
- kwargs = {
- 'conv': django_conversions,
- 'charset': 'utf8',
- }
- if six.PY2:
- kwargs['use_unicode'] = True
- settings_dict = self.settings_dict
- if settings_dict['USER']:
- kwargs['user'] = settings_dict['USER']
- if settings_dict['NAME']:
- kwargs['db'] = settings_dict['NAME']
- if settings_dict['PASSWORD']:
- kwargs['passwd'] = force_str(settings_dict['PASSWORD'])
- if settings_dict['HOST'].startswith('/'):
- kwargs['unix_socket'] = settings_dict['HOST']
- elif settings_dict['HOST']:
- kwargs['host'] = settings_dict['HOST']
- if settings_dict['PORT']:
- kwargs['port'] = int(settings_dict['PORT'])
- # We need the number of potentially affected rows after an
- # "UPDATE", not the number of changed rows.
- kwargs['client_flag'] = CLIENT.FOUND_ROWS
- kwargs.update(settings_dict['OPTIONS'])
- return kwargs
-
- def get_new_connection(self, conn_params):
- conn = Database.connect(**conn_params)
- conn.encoders[SafeText] = conn.encoders[six.text_type]
- conn.encoders[SafeBytes] = conn.encoders[bytes]
- return conn
-
- def init_connection_state(self):
- cursor = self.connection.cursor()
- # SQL_AUTO_IS_NULL in MySQL controls whether an AUTO_INCREMENT column
- # on a recently-inserted row will return when the field is tested for
- # NULL. Disabling this value brings this aspect of MySQL in line with
- # SQL standards.
- cursor.execute('SET SQL_AUTO_IS_NULL = 0')
- cursor.close()
-
- def create_cursor(self):
- cursor = self.connection.cursor()
- return CursorWrapper(cursor)
-
- def _rollback(self):
- try:
- BaseDatabaseWrapper._rollback(self)
- except Database.NotSupportedError:
- pass
-
- def _set_autocommit(self, autocommit):
- with self.wrap_database_errors:
- self.connection.autocommit(autocommit)
-
- def disable_constraint_checking(self):
- """
- Disables foreign key checks, primarily for use in adding rows with forward references. Always returns True,
- to indicate constraint checks need to be re-enabled.
- """
- self.cursor().execute('SET foreign_key_checks=0')
- return True
-
- def enable_constraint_checking(self):
- """
- Re-enable foreign key checks after they have been disabled.
- """
- # Override needs_rollback in case constraint_checks_disabled is
- # nested inside transaction.atomic.
- self.needs_rollback, needs_rollback = False, self.needs_rollback
- try:
- self.cursor().execute('SET foreign_key_checks=1')
- finally:
- self.needs_rollback = needs_rollback
-
- def check_constraints(self, table_names=None):
- """
- Checks each table name in `table_names` for rows with invalid foreign key references. This method is
- intended to be used in conjunction with `disable_constraint_checking()` and `enable_constraint_checking()`, to
- determine if rows with invalid references were entered while constraint checks were off.
-
- Raises an IntegrityError on the first invalid foreign key reference encountered (if any) and provides
- detailed information about the invalid reference in the error message.
-
- Backends can override this method if they can more directly apply constraint checking (e.g. via "SET CONSTRAINTS
- ALL IMMEDIATE")
- """
- cursor = self.cursor()
- if table_names is None:
- table_names = self.introspection.table_names(cursor)
- for table_name in table_names:
- primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name)
- if not primary_key_column_name:
- continue
- key_columns = self.introspection.get_key_columns(cursor, table_name)
- for column_name, referenced_table_name, referenced_column_name in key_columns:
- cursor.execute("""
- SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
- LEFT JOIN `%s` as REFERRED
- ON (REFERRING.`%s` = REFERRED.`%s`)
- WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL"""
- % (primary_key_column_name, column_name, table_name, referenced_table_name,
- column_name, referenced_column_name, column_name, referenced_column_name))
- for bad_row in cursor.fetchall():
- raise utils.IntegrityError("The row in table '%s' with primary key '%s' has an invalid "
- "foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s."
- % (table_name, bad_row[0],
- table_name, column_name, bad_row[1],
- referenced_table_name, referenced_column_name))
-
- def is_usable(self):
- try:
- self.connection.ping()
- except Database.Error:
- return False
- else:
- return True
-
- @cached_property
- def mysql_version(self):
- with self.temporary_connection():
- server_info = self.connection.get_server_info()
- match = server_version_re.match(server_info)
- if not match:
- raise Exception('Unable to determine MySQL version from version string %r' % server_info)
- return tuple([int(x) for x in match.groups()])
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/client.py b/lib/python2.7/site-packages/django/db/backends/mysql/client.py
deleted file mode 100644
index 1cf8cee..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/client.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import os
-import sys
-
-from django.db.backends import BaseDatabaseClient
-
-class DatabaseClient(BaseDatabaseClient):
- executable_name = 'mysql'
-
- def runshell(self):
- settings_dict = self.connection.settings_dict
- args = [self.executable_name]
- db = settings_dict['OPTIONS'].get('db', settings_dict['NAME'])
- user = settings_dict['OPTIONS'].get('user', settings_dict['USER'])
- passwd = settings_dict['OPTIONS'].get('passwd', settings_dict['PASSWORD'])
- host = settings_dict['OPTIONS'].get('host', settings_dict['HOST'])
- port = settings_dict['OPTIONS'].get('port', settings_dict['PORT'])
- defaults_file = settings_dict['OPTIONS'].get('read_default_file')
- # Seems to be no good way to set sql_mode with CLI.
-
- if defaults_file:
- args += ["--defaults-file=%s" % defaults_file]
- if user:
- args += ["--user=%s" % user]
- if passwd:
- args += ["--password=%s" % passwd]
- if host:
- if '/' in host:
- args += ["--socket=%s" % host]
- else:
- args += ["--host=%s" % host]
- if port:
- args += ["--port=%s" % port]
- if db:
- args += [db]
-
- if os.name == 'nt':
- sys.exit(os.system(" ".join(args)))
- else:
- os.execvp(self.executable_name, args)
-
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/compiler.py b/lib/python2.7/site-packages/django/db/backends/mysql/compiler.py
deleted file mode 100644
index d3439bf..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/compiler.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from django.db.models.sql import compiler
-from django.utils.six.moves import zip_longest
-
-
-class SQLCompiler(compiler.SQLCompiler):
- def resolve_columns(self, row, fields=()):
- values = []
- index_extra_select = len(self.query.extra_select)
- for value, field in zip_longest(row[index_extra_select:], fields):
- if (field and field.get_internal_type() in ("BooleanField", "NullBooleanField") and
- value in (0, 1)):
- value = bool(value)
- values.append(value)
- return row[:index_extra_select] + tuple(values)
-
- def as_subquery_condition(self, alias, columns, qn):
- qn2 = self.connection.ops.quote_name
- sql, params = self.as_sql()
- return '(%s) IN (%s)' % (', '.join(['%s.%s' % (qn(alias), qn2(column)) for column in columns]), sql), params
-
-class SQLInsertCompiler(compiler.SQLInsertCompiler, SQLCompiler):
- pass
-
-class SQLDeleteCompiler(compiler.SQLDeleteCompiler, SQLCompiler):
- pass
-
-class SQLUpdateCompiler(compiler.SQLUpdateCompiler, SQLCompiler):
- pass
-
-class SQLAggregateCompiler(compiler.SQLAggregateCompiler, SQLCompiler):
- pass
-
-class SQLDateCompiler(compiler.SQLDateCompiler, SQLCompiler):
- pass
-
-class SQLDateTimeCompiler(compiler.SQLDateTimeCompiler, SQLCompiler):
- pass
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/creation.py b/lib/python2.7/site-packages/django/db/backends/mysql/creation.py
deleted file mode 100644
index 3a57c29..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/creation.py
+++ /dev/null
@@ -1,70 +0,0 @@
-from django.db.backends.creation import BaseDatabaseCreation
-
-class DatabaseCreation(BaseDatabaseCreation):
- # This dictionary maps Field objects to their associated MySQL column
- # types, as strings. Column-type strings can contain format strings; they'll
- # be interpolated against the values of Field.__dict__ before being output.
- # If a column type is set to None, it won't be included in the output.
- data_types = {
- 'AutoField': 'integer AUTO_INCREMENT',
- 'BinaryField': 'longblob',
- 'BooleanField': 'bool',
- 'CharField': 'varchar(%(max_length)s)',
- 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
- 'DateField': 'date',
- 'DateTimeField': 'datetime',
- 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
- 'FileField': 'varchar(%(max_length)s)',
- 'FilePathField': 'varchar(%(max_length)s)',
- 'FloatField': 'double precision',
- 'IntegerField': 'integer',
- 'BigIntegerField': 'bigint',
- 'IPAddressField': 'char(15)',
- 'GenericIPAddressField': 'char(39)',
- 'NullBooleanField': 'bool',
- 'OneToOneField': 'integer',
- 'PositiveIntegerField': 'integer UNSIGNED',
- 'PositiveSmallIntegerField': 'smallint UNSIGNED',
- 'SlugField': 'varchar(%(max_length)s)',
- 'SmallIntegerField': 'smallint',
- 'TextField': 'longtext',
- 'TimeField': 'time',
- }
-
- def sql_table_creation_suffix(self):
- suffix = []
- if self.connection.settings_dict['TEST_CHARSET']:
- suffix.append('CHARACTER SET %s' % self.connection.settings_dict['TEST_CHARSET'])
- if self.connection.settings_dict['TEST_COLLATION']:
- suffix.append('COLLATE %s' % self.connection.settings_dict['TEST_COLLATION'])
- return ' '.join(suffix)
-
- def sql_for_inline_foreign_key_references(self, model, field, known_models, style):
- "All inline references are pending under MySQL"
- return [], True
-
- def sql_destroy_indexes_for_fields(self, model, fields, style):
- if len(fields) == 1 and fields[0].db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(fields[0].db_tablespace)
- elif model._meta.db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
- else:
- tablespace_sql = ""
- if tablespace_sql:
- tablespace_sql = " " + tablespace_sql
-
- field_names = []
- qn = self.connection.ops.quote_name
- for f in fields:
- field_names.append(style.SQL_FIELD(qn(f.column)))
-
- index_name = "%s_%s" % (model._meta.db_table, self._digest([f.name for f in fields]))
-
- from ..util import truncate_name
-
- return [
- style.SQL_KEYWORD("DROP INDEX") + " " +
- style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + " " +
- style.SQL_KEYWORD("ON") + " " +
- style.SQL_TABLE(qn(model._meta.db_table)) + ";",
- ]
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/introspection.py b/lib/python2.7/site-packages/django/db/backends/mysql/introspection.py
deleted file mode 100644
index 548877e..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/introspection.py
+++ /dev/null
@@ -1,119 +0,0 @@
-import re
-from .base import FIELD_TYPE
-
-from django.db.backends import BaseDatabaseIntrospection, FieldInfo
-from django.utils.encoding import force_text
-
-
-foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
-
-class DatabaseIntrospection(BaseDatabaseIntrospection):
- data_types_reverse = {
- FIELD_TYPE.BLOB: 'TextField',
- FIELD_TYPE.CHAR: 'CharField',
- FIELD_TYPE.DECIMAL: 'DecimalField',
- FIELD_TYPE.NEWDECIMAL: 'DecimalField',
- FIELD_TYPE.DATE: 'DateField',
- FIELD_TYPE.DATETIME: 'DateTimeField',
- FIELD_TYPE.DOUBLE: 'FloatField',
- FIELD_TYPE.FLOAT: 'FloatField',
- FIELD_TYPE.INT24: 'IntegerField',
- FIELD_TYPE.LONG: 'IntegerField',
- FIELD_TYPE.LONGLONG: 'BigIntegerField',
- FIELD_TYPE.SHORT: 'IntegerField',
- FIELD_TYPE.STRING: 'CharField',
- FIELD_TYPE.TIME: 'TimeField',
- FIELD_TYPE.TIMESTAMP: 'DateTimeField',
- FIELD_TYPE.TINY: 'IntegerField',
- FIELD_TYPE.TINY_BLOB: 'TextField',
- FIELD_TYPE.MEDIUM_BLOB: 'TextField',
- FIELD_TYPE.LONG_BLOB: 'TextField',
- FIELD_TYPE.VAR_STRING: 'CharField',
- }
-
- def get_table_list(self, cursor):
- "Returns a list of table names in the current database."
- cursor.execute("SHOW TABLES")
- return [row[0] for row in cursor.fetchall()]
-
- def get_table_description(self, cursor, table_name):
- """
- Returns a description of the table, with the DB-API cursor.description interface."
- """
- # varchar length returned by cursor.description is an internal length,
- # not visible length (#5725), use information_schema database to fix this
- cursor.execute("""
- SELECT column_name, character_maximum_length FROM information_schema.columns
- WHERE table_name = %s AND table_schema = DATABASE()
- AND character_maximum_length IS NOT NULL""", [table_name])
- length_map = dict(cursor.fetchall())
-
- # Also getting precision and scale from information_schema (see #5014)
- cursor.execute("""
- SELECT column_name, numeric_precision, numeric_scale FROM information_schema.columns
- WHERE table_name = %s AND table_schema = DATABASE()
- AND data_type='decimal'""", [table_name])
- numeric_map = dict([(line[0], tuple([int(n) for n in line[1:]])) for line in cursor.fetchall()])
-
- cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
- return [FieldInfo(*((force_text(line[0]),)
- + line[1:3]
- + (length_map.get(line[0], line[3]),)
- + numeric_map.get(line[0], line[4:6])
- + (line[6],)))
- for line in cursor.description]
-
- def _name_to_index(self, cursor, table_name):
- """
- Returns a dictionary of {field_name: field_index} for the given table.
- Indexes are 0-based.
- """
- return dict([(d[0], i) for i, d in enumerate(self.get_table_description(cursor, table_name))])
-
- def get_relations(self, cursor, table_name):
- """
- Returns a dictionary of {field_index: (field_index_other_table, other_table)}
- representing all relationships to the given table. Indexes are 0-based.
- """
- my_field_dict = self._name_to_index(cursor, table_name)
- constraints = self.get_key_columns(cursor, table_name)
- relations = {}
- for my_fieldname, other_table, other_field in constraints:
- other_field_index = self._name_to_index(cursor, other_table)[other_field]
- my_field_index = my_field_dict[my_fieldname]
- relations[my_field_index] = (other_field_index, other_table)
- return relations
-
- def get_key_columns(self, cursor, table_name):
- """
- Returns a list of (column_name, referenced_table_name, referenced_column_name) for all
- key columns in given table.
- """
- key_columns = []
- cursor.execute("""
- SELECT column_name, referenced_table_name, referenced_column_name
- FROM information_schema.key_column_usage
- WHERE table_name = %s
- AND table_schema = DATABASE()
- AND referenced_table_name IS NOT NULL
- AND referenced_column_name IS NOT NULL""", [table_name])
- key_columns.extend(cursor.fetchall())
- return key_columns
-
- def get_indexes(self, cursor, table_name):
- cursor.execute("SHOW INDEX FROM %s" % self.connection.ops.quote_name(table_name))
- # Do a two-pass search for indexes: on first pass check which indexes
- # are multicolumn, on second pass check which single-column indexes
- # are present.
- rows = list(cursor.fetchall())
- multicol_indexes = set()
- for row in rows:
- if row[3] > 1:
- multicol_indexes.add(row[2])
- indexes = {}
- for row in rows:
- if row[2] in multicol_indexes:
- continue
- indexes[row[4]] = {'primary_key': (row[2] == 'PRIMARY'), 'unique': not bool(row[1])}
- return indexes
-
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/validation.py b/lib/python2.7/site-packages/django/db/backends/mysql/validation.py
deleted file mode 100644
index 2ce957c..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/validation.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from django.db.backends import BaseDatabaseValidation
-
-class DatabaseValidation(BaseDatabaseValidation):
- def validate_field(self, errors, opts, f):
- """
- MySQL has the following field length restriction:
- No character (varchar) fields can have a length exceeding 255
- characters if they have a unique index on them.
- """
- from django.db import models
- varchar_fields = (models.CharField, models.CommaSeparatedIntegerField,
- models.SlugField)
- if (isinstance(f, varchar_fields) and f.unique
- and (f.max_length is None or int(f.max_length) > 255)):
- msg = '"%(name)s": %(cls)s cannot have a "max_length" greater than 255 when using "unique=True".'
- errors.add(opts, msg % {'name': f.name, 'cls': f.__class__.__name__})