Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Removed the mysql_old backend. It smells bad and has no friends.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@7949 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit c681f4070c2095eae9635d13233e8d5fad5240f1 1 parent d261c1d
Malcolm Tredinnick malcolmt authored
0  django/db/backends/mysql_old/__init__.py
No changes.
215 django/db/backends/mysql_old/base.py
... ... @@ -1,215 +0,0 @@
1   -"""
2   -MySQL database backend for Django.
3   -
4   -Requires MySQLdb: http://sourceforge.net/projects/mysql-python
5   -"""
6   -
7   -from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseOperations, util
8   -from django.utils.encoding import force_unicode
9   -try:
10   - import MySQLdb as Database
11   -except ImportError, e:
12   - from django.core.exceptions import ImproperlyConfigured
13   - raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
14   -from MySQLdb.converters import conversions
15   -from MySQLdb.constants import FIELD_TYPE
16   -import types
17   -import re
18   -
19   -DatabaseError = Database.DatabaseError
20   -IntegrityError = Database.IntegrityError
21   -
22   -django_conversions = conversions.copy()
23   -django_conversions.update({
24   - types.BooleanType: util.rev_typecast_boolean,
25   - FIELD_TYPE.DATETIME: util.typecast_timestamp,
26   - FIELD_TYPE.DATE: util.typecast_date,
27   - FIELD_TYPE.TIME: util.typecast_time,
28   - FIELD_TYPE.DECIMAL: util.typecast_decimal,
29   - FIELD_TYPE.STRING: force_unicode,
30   - FIELD_TYPE.VAR_STRING: force_unicode,
31   - # Note: We don't add a convertor for BLOB here. Doesn't seem to be required.
32   -})
33   -
34   -# This should match the numerical portion of the version numbers (we can treat
35   -# versions like 5.0.24 and 5.0.24a as the same). Based on the list of version
36   -# at http://dev.mysql.com/doc/refman/4.1/en/news.html and
37   -# http://dev.mysql.com/doc/refman/5.0/en/news.html .
38   -server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
39   -
40   -# This is an extra debug layer over MySQL queries, to display warnings.
41   -# It's only used when DEBUG=True.
42   -class MysqlDebugWrapper:
43   - def __init__(self, cursor):
44   - self.cursor = cursor
45   -
46   - def execute(self, sql, params=()):
47   - try:
48   - return self.cursor.execute(sql, params)
49   - except Database.Warning, w:
50   - self.cursor.execute("SHOW WARNINGS")
51   - raise Database.Warning("%s: %s" % (w, self.cursor.fetchall()))
52   -
53   - def executemany(self, sql, param_list):
54   - try:
55   - return self.cursor.executemany(sql, param_list)
56   - except Database.Warning, w:
57   - self.cursor.execute("SHOW WARNINGS")
58   - raise Database.Warning("%s: %s" % (w, self.cursor.fetchall()))
59   -
60   - def __getattr__(self, attr):
61   - if attr in self.__dict__:
62   - return self.__dict__[attr]
63   - else:
64   - return getattr(self.cursor, attr)
65   -
66   -class DatabaseFeatures(BaseDatabaseFeatures):
67   - inline_fk_references = False
68   - empty_fetchmany_value = ()
69   - update_can_self_select = False
70   - supports_usecs = False
71   -
72   -class DatabaseOperations(BaseDatabaseOperations):
73   - def date_extract_sql(self, lookup_type, field_name):
74   - # http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
75   - return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
76   -
77   - def date_trunc_sql(self, lookup_type, field_name):
78   - fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
79   - format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
80   - format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
81   - try:
82   - i = fields.index(lookup_type) + 1
83   - except ValueError:
84   - sql = field_name
85   - else:
86   - format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
87   - sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
88   - return sql
89   -
90   - def drop_foreignkey_sql(self):
91   - return "DROP FOREIGN KEY"
92   -
93   - def fulltext_search_sql(self, field_name):
94   - return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name
95   -
96   - def no_limit_value(self):
97   - # 2**64 - 1, as recommended by the MySQL documentation
98   - return 18446744073709551615L
99   -
100   - def quote_name(self, name):
101   - if name.startswith("`") and name.endswith("`"):
102   - return name # Quoting once is enough.
103   - return "`%s`" % name
104   -
105   - def random_function_sql(self):
106   - return 'RAND()'
107   -
108   - def sql_flush(self, style, tables, sequences):
109   - # NB: The generated SQL below is specific to MySQL
110   - # 'TRUNCATE x;', 'TRUNCATE y;', 'TRUNCATE z;'... style SQL statements
111   - # to clear all tables of all data
112   - if tables:
113   - sql = ['SET FOREIGN_KEY_CHECKS = 0;']
114   - for table in tables:
115   - sql.append('%s %s;' % (style.SQL_KEYWORD('TRUNCATE'), style.SQL_FIELD(self.quote_name(table))))
116   - sql.append('SET FOREIGN_KEY_CHECKS = 1;')
117   -
118   - # 'ALTER TABLE table AUTO_INCREMENT = 1;'... style SQL statements
119   - # to reset sequence indices
120   - sql.extend(["%s %s %s %s %s;" % \
121   - (style.SQL_KEYWORD('ALTER'),
122   - style.SQL_KEYWORD('TABLE'),
123   - style.SQL_TABLE(self.quote_name(sequence['table'])),
124   - style.SQL_KEYWORD('AUTO_INCREMENT'),
125   - style.SQL_FIELD('= 1'),
126   - ) for sequence in sequences])
127   - return sql
128   - else:
129   - return []
130   -
131   -class DatabaseWrapper(BaseDatabaseWrapper):
132   - features = DatabaseFeatures()
133   - ops = DatabaseOperations()
134   - operators = {
135   - 'exact': '= BINARY %s',
136   - 'iexact': 'LIKE %s',
137   - 'contains': 'LIKE BINARY %s',
138   - 'icontains': 'LIKE %s',
139   - 'regex': 'REGEXP BINARY %s',
140   - 'iregex': 'REGEXP %s',
141   - 'gt': '> %s',
142   - 'gte': '>= %s',
143   - 'lt': '< %s',
144   - 'lte': '<= %s',
145   - 'startswith': 'LIKE BINARY %s',
146   - 'endswith': 'LIKE BINARY %s',
147   - 'istartswith': 'LIKE %s',
148   - 'iendswith': 'LIKE %s',
149   - }
150   -
151   - def __init__(self, **kwargs):
152   - super(DatabaseWrapper, self).__init__(**kwargs)
153   - self.server_version = None
154   -
155   - def _valid_connection(self):
156   - if self.connection is not None:
157   - try:
158   - self.connection.ping()
159   - return True
160   - except DatabaseError:
161   - self.connection.close()
162   - self.connection = None
163   - return False
164   -
165   - def _cursor(self, settings):
166   - if not self._valid_connection():
167   - kwargs = {
168   - # Note: use_unicode intentonally not set to work around some
169   - # backwards-compat issues. We do it manually.
170   - 'user': settings.DATABASE_USER,
171   - 'db': settings.DATABASE_NAME,
172   - 'passwd': settings.DATABASE_PASSWORD,
173   - 'conv': django_conversions,
174   - }
175   - if settings.DATABASE_HOST.startswith('/'):
176   - kwargs['unix_socket'] = settings.DATABASE_HOST
177   - else:
178   - kwargs['host'] = settings.DATABASE_HOST
179   - if settings.DATABASE_PORT:
180   - kwargs['port'] = int(settings.DATABASE_PORT)
181   - kwargs.update(self.options)
182   - self.connection = Database.connect(**kwargs)
183   - cursor = self.connection.cursor()
184   - if self.connection.get_server_info() >= '4.1' and not self.connection.character_set_name().startswith('utf8'):
185   - if hasattr(self.connection, 'charset'):
186   - # MySQLdb < 1.2.1 backwards-compat hacks.
187   - conn = self.connection
188   - cursor.execute("SET NAMES 'utf8'")
189   - cursor.execute("SET CHARACTER SET 'utf8'")
190   - to_str = lambda u, dummy=None, c=conn: c.literal(u.encode('utf-8'))
191   - conn.converter[unicode] = to_str
192   - else:
193   - self.connection.set_character_set('utf8')
194   - else:
195   - cursor = self.connection.cursor()
196   - return cursor
197   -
198   - def make_debug_cursor(self, cursor):
199   - return BaseDatabaseWrapper.make_debug_cursor(self, MysqlDebugWrapper(cursor))
200   -
201   - def _rollback(self):
202   - try:
203   - BaseDatabaseWrapper._rollback(self)
204   - except Database.NotSupportedError:
205   - pass
206   -
207   - def get_server_version(self):
208   - if not self.server_version:
209   - if not self._valid_connection():
210   - self.cursor()
211   - m = server_version_re.match(self.connection.get_server_info())
212   - if not m:
213   - raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info())
214   - self.server_version = tuple([int(x) for x in m.groups()])
215   - return self.server_version
14 django/db/backends/mysql_old/client.py
... ... @@ -1,14 +0,0 @@
1   -from django.conf import settings
2   -import os
3   -
4   -def runshell():
5   - args = ['']
6   - args += ["--user=%s" % settings.DATABASE_USER]
7   - if settings.DATABASE_PASSWORD:
8   - args += ["--password=%s" % settings.DATABASE_PASSWORD]
9   - if settings.DATABASE_HOST:
10   - args += ["--host=%s" % settings.DATABASE_HOST]
11   - if settings.DATABASE_PORT:
12   - args += ["--port=%s" % settings.DATABASE_PORT]
13   - args += [settings.DATABASE_NAME]
14   - os.execvp('mysql', args)
28 django/db/backends/mysql_old/creation.py
... ... @@ -1,28 +0,0 @@
1   -# This dictionary maps Field objects to their associated MySQL column
2   -# types, as strings. Column-type strings can contain format strings; they'll
3   -# be interpolated against the values of Field.__dict__ before being output.
4   -# If a column type is set to None, it won't be included in the output.
5   -DATA_TYPES = {
6   - 'AutoField': 'integer AUTO_INCREMENT',
7   - 'BooleanField': 'bool',
8   - 'CharField': 'varchar(%(max_length)s)',
9   - 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
10   - 'DateField': 'date',
11   - 'DateTimeField': 'datetime',
12   - 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
13   - 'FileField': 'varchar(%(max_length)s)',
14   - 'FilePathField': 'varchar(%(max_length)s)',
15   - 'FloatField': 'double precision',
16   - 'IntegerField': 'integer',
17   - 'IPAddressField': 'char(15)',
18   - 'NullBooleanField': 'bool',
19   - 'OneToOneField': 'integer',
20   - 'PhoneNumberField': 'varchar(20)',
21   - 'PositiveIntegerField': 'integer UNSIGNED',
22   - 'PositiveSmallIntegerField': 'smallint UNSIGNED',
23   - 'SlugField': 'varchar(%(max_length)s)',
24   - 'SmallIntegerField': 'smallint',
25   - 'TextField': 'longtext',
26   - 'TimeField': 'time',
27   - 'USStateField': 'varchar(2)',
28   -}
96 django/db/backends/mysql_old/introspection.py
... ... @@ -1,96 +0,0 @@
1   -from django.db.backends.mysql_old.base import DatabaseOperations
2   -from MySQLdb import ProgrammingError, OperationalError
3   -from MySQLdb.constants import FIELD_TYPE
4   -import re
5   -
6   -quote_name = DatabaseOperations().quote_name
7   -foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
8   -
9   -def get_table_list(cursor):
10   - "Returns a list of table names in the current database."
11   - cursor.execute("SHOW TABLES")
12   - return [row[0] for row in cursor.fetchall()]
13   -
14   -def get_table_description(cursor, table_name):
15   - "Returns a description of the table, with the DB-API cursor.description interface."
16   - cursor.execute("SELECT * FROM %s LIMIT 1" % quote_name(table_name))
17   - return cursor.description
18   -
19   -def _name_to_index(cursor, table_name):
20   - """
21   - Returns a dictionary of {field_name: field_index} for the given table.
22   - Indexes are 0-based.
23   - """
24   - return dict([(d[0], i) for i, d in enumerate(get_table_description(cursor, table_name))])
25   -
26   -def get_relations(cursor, table_name):
27   - """
28   - Returns a dictionary of {field_index: (field_index_other_table, other_table)}
29   - representing all relationships to the given table. Indexes are 0-based.
30   - """
31   - my_field_dict = _name_to_index(cursor, table_name)
32   - constraints = []
33   - relations = {}
34   - try:
35   - # This should work for MySQL 5.0.
36   - cursor.execute("""
37   - SELECT column_name, referenced_table_name, referenced_column_name
38   - FROM information_schema.key_column_usage
39   - WHERE table_name = %s
40   - AND table_schema = DATABASE()
41   - AND referenced_table_name IS NOT NULL
42   - AND referenced_column_name IS NOT NULL""", [table_name])
43   - constraints.extend(cursor.fetchall())
44   - except (ProgrammingError, OperationalError):
45   - # Fall back to "SHOW CREATE TABLE", for previous MySQL versions.
46   - # Go through all constraints and save the equal matches.
47   - cursor.execute("SHOW CREATE TABLE %s" % quote_name(table_name))
48   - for row in cursor.fetchall():
49   - pos = 0
50   - while True:
51   - match = foreign_key_re.search(row[1], pos)
52   - if match == None:
53   - break
54   - pos = match.end()
55   - constraints.append(match.groups())
56   -
57   - for my_fieldname, other_table, other_field in constraints:
58   - other_field_index = _name_to_index(cursor, other_table)[other_field]
59   - my_field_index = my_field_dict[my_fieldname]
60   - relations[my_field_index] = (other_field_index, other_table)
61   -
62   - return relations
63   -
64   -def get_indexes(cursor, table_name):
65   - """
66   - Returns a dictionary of fieldname -> infodict for the given table,
67   - where each infodict is in the format:
68   - {'primary_key': boolean representing whether it's the primary key,
69   - 'unique': boolean representing whether it's a unique index}
70   - """
71   - cursor.execute("SHOW INDEX FROM %s" % quote_name(table_name))
72   - indexes = {}
73   - for row in cursor.fetchall():
74   - indexes[row[4]] = {'primary_key': (row[2] == 'PRIMARY'), 'unique': not bool(row[1])}
75   - return indexes
76   -
77   -DATA_TYPES_REVERSE = {
78   - FIELD_TYPE.BLOB: 'TextField',
79   - FIELD_TYPE.CHAR: 'CharField',
80   - FIELD_TYPE.DECIMAL: 'DecimalField',
81   - FIELD_TYPE.DATE: 'DateField',
82   - FIELD_TYPE.DATETIME: 'DateTimeField',
83   - FIELD_TYPE.DOUBLE: 'FloatField',
84   - FIELD_TYPE.FLOAT: 'FloatField',
85   - FIELD_TYPE.INT24: 'IntegerField',
86   - FIELD_TYPE.LONG: 'IntegerField',
87   - FIELD_TYPE.LONGLONG: 'IntegerField',
88   - FIELD_TYPE.SHORT: 'IntegerField',
89   - FIELD_TYPE.STRING: 'TextField',
90   - FIELD_TYPE.TIMESTAMP: 'DateTimeField',
91   - FIELD_TYPE.TINY: 'IntegerField',
92   - FIELD_TYPE.TINY_BLOB: 'TextField',
93   - FIELD_TYPE.MEDIUM_BLOB: 'TextField',
94   - FIELD_TYPE.LONG_BLOB: 'TextField',
95   - FIELD_TYPE.VAR_STRING: 'CharField',
96   -}
1  django/test/utils.py
@@ -140,7 +140,6 @@ def create_test_db(verbosity=1, autoclobber=False):
140 140 'postgresql': get_postgresql_create_suffix,
141 141 'postgresql_psycopg2': get_postgresql_create_suffix,
142 142 'mysql': get_mysql_create_suffix,
143   - 'mysql_old': get_mysql_create_suffix,
144 143 }.get(settings.DATABASE_ENGINE, lambda: '')()
145 144 if settings.TEST_DATABASE_NAME:
146 145 TEST_DATABASE_NAME = settings.TEST_DATABASE_NAME
10 docs/settings.txt
@@ -278,8 +278,8 @@ DATABASE_ENGINE
278 278 Default: ``''`` (Empty string)
279 279
280 280 The database backend to use. The build-in database backends are
281   -``'postgresql_psycopg2'``, ``'postgresql'``, ``'mysql'``, ``'mysql_old'``,
282   -``'sqlite3'``, and ``'oracle'``.
  281 +``'postgresql_psycopg2'``, ``'postgresql'``, ``'mysql'``, ``'sqlite3'``, and
  282 +``'oracle'``.
283 283
284 284 In the Django development version, you can use a database backend that doesn't
285 285 ship with Django by setting ``DATABASE_ENGINE`` to a fully-qualified path (i.e.
@@ -1029,7 +1029,7 @@ The character set encoding used to create the test database. The value of this
1029 1029 string is passed directly through to the database, so its format is
1030 1030 backend-specific.
1031 1031
1032   -Supported for the PostgreSQL_ (``postgresql``, ``postgresql_psycopg2``) and MySQL_ (``mysql``, ``mysql_old``) backends.
  1032 +Supported for the PostgreSQL_ (``postgresql``, ``postgresql_psycopg2``) and MySQL_ (``mysql``) backends.
1033 1033
1034 1034 .. _PostgreSQL: http://www.postgresql.org/docs/8.2/static/multibyte.html
1035 1035 .. _MySQL: http://www.mysql.org/doc/refman/5.0/en/charset-database.html
@@ -1044,8 +1044,8 @@ Default: ``None``
1044 1044 The collation order to use when creating the test database. This value is
1045 1045 passed directly to the backend, so its format is backend-specific.
1046 1046
1047   -Only supported for ``mysql`` and ``mysql_old`` backends (see `section 10.3.2`_
1048   -of the MySQL manual for details).
  1047 +Only supported for the ``mysql`` backend (see `section 10.3.2`_ of the MySQL
  1048 +manual for details).
1049 1049
1050 1050 .. _section 10.3.2: http://www.mysql.org/doc/refman/5.0/en/charset-database.html
1051 1051
2  tests/modeltests/fixtures/models.py
@@ -58,7 +58,7 @@ class Meta:
58 58
59 59 # Database flushing does not work on MySQL with the default storage engine
60 60 # because it requires transaction support.
61   -if settings.DATABASE_ENGINE not in ('mysql', 'mysql_old'):
  61 +if settings.DATABASE_ENGINE != 'mysql':
62 62 __test__['API_TESTS'] += \
63 63 """
64 64 # Reset the database representation of this app. This will delete all data.
2  tests/modeltests/lookup/models.py
@@ -380,7 +380,7 @@ def __unicode__(self):
380 380 """}
381 381
382 382
383   -if settings.DATABASE_ENGINE not in ('mysql', 'mysql_old'):
  383 +if settings.DATABASE_ENGINE != 'mysql':
384 384 __test__['API_TESTS'] += r"""
385 385 # grouping and backreferences
386 386 >>> Article.objects.filter(headline__regex=r'b(.).*b\1')
2  tests/modeltests/transactions/models.py
@@ -25,7 +25,7 @@ def __unicode__(self):
25 25
26 26 building_docs = getattr(settings, 'BUILDING_DOCS', False)
27 27
28   -if building_docs or settings.DATABASE_ENGINE not in ('mysql', 'mysql_old'):
  28 +if building_docs or settings.DATABASE_ENGINE != 'mysql':
29 29 __test__['API_TESTS'] += """
30 30 # the default behavior is to autocommit after each save() action
31 31 >>> def create_a_reporter_then_fail(first, last):

0 comments on commit c681f40

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