From 14db37319bd2a73b796d4b1a078fa7f162fc25e8 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Mon, 20 Aug 2007 03:26:55 +0000 Subject: [PATCH] Refactored OPERATOR_MAPPING so that it exists as django.db.connection.operators instead of django.db.backend.OPERATOR_MAPPING. Refs #5106 git-svn-id: http://code.djangoproject.com/svn/django/trunk@5982 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/backends/ado_mssql/base.py | 29 +++++++------ django/db/backends/dummy/base.py | 5 +-- django/db/backends/mysql/base.py | 33 ++++++++------- django/db/backends/mysql_old/base.py | 33 ++++++++------- django/db/backends/oracle/base.py | 29 +++++++------ django/db/backends/postgresql/base.py | 33 ++++++++------- .../db/backends/postgresql_psycopg2/base.py | 33 ++++++++------- django/db/backends/sqlite3/base.py | 41 +++++++++---------- django/db/models/query.py | 4 +- 9 files changed, 116 insertions(+), 124 deletions(-) diff --git a/django/db/backends/ado_mssql/base.py b/django/db/backends/ado_mssql/base.py index 60109b72263..c8354570e4c 100644 --- a/django/db/backends/ado_mssql/base.py +++ b/django/db/backends/ado_mssql/base.py @@ -84,6 +84,20 @@ class DatabaseOperations(BaseDatabaseOperations): class DatabaseWrapper(BaseDatabaseWrapper): features = DatabaseFeatures() ops = DatabaseOperations() + operators = { + 'exact': '= %s', + 'iexact': 'LIKE %s', + 'contains': 'LIKE %s', + 'icontains': 'LIKE %s', + 'gt': '> %s', + 'gte': '>= %s', + 'lt': '< %s', + 'lte': '<= %s', + 'startswith': 'LIKE %s', + 'endswith': 'LIKE %s', + 'istartswith': 'LIKE %s', + 'iendswith': 'LIKE %s', + } def _cursor(self, settings): if self.connection is None: @@ -96,18 +110,3 @@ class DatabaseWrapper(BaseDatabaseWrapper): 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) self.connection = Database.connect(conn_string) return self.connection.cursor() - -OPERATOR_MAPPING = { - 'exact': '= %s', - 'iexact': 'LIKE %s', - 'contains': 'LIKE %s', - 'icontains': 'LIKE %s', - 'gt': '> %s', - 'gte': '>= %s', - 'lt': '< %s', - 'lte': '<= %s', - 'startswith': 'LIKE %s', - 'endswith': 'LIKE %s', - 'istartswith': 'LIKE %s', - 'iendswith': 'LIKE %s', -} diff --git a/django/db/backends/dummy/base.py b/django/db/backends/dummy/base.py index 671c9d72912..18ba02675ec 100644 --- a/django/db/backends/dummy/base.py +++ b/django/db/backends/dummy/base.py @@ -26,8 +26,9 @@ class ComplainOnGetattr(object): complain() class DatabaseWrapper(object): - ops = ComplainOnGetattr() features = ComplainOnGetattr() + ops = ComplainOnGetattr() + operators = {} cursor = complain _commit = complain _rollback = ignore @@ -37,5 +38,3 @@ class DatabaseWrapper(object): def close(self): pass # close() - -OPERATOR_MAPPING = {} diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 079bf36eb09..3b41d7cb8b9 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -121,6 +121,22 @@ class DatabaseOperations(BaseDatabaseOperations): class DatabaseWrapper(BaseDatabaseWrapper): features = DatabaseFeatures() ops = DatabaseOperations() + 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', + } def __init__(self, **kwargs): super(DatabaseWrapper, self).__init__(**kwargs) @@ -178,20 +194,3 @@ class DatabaseWrapper(BaseDatabaseWrapper): raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info()) self.server_version = tuple([int(x) for x in m.groups()]) return self.server_version - -OPERATOR_MAPPING = { - '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', -} diff --git a/django/db/backends/mysql_old/base.py b/django/db/backends/mysql_old/base.py index e4ff1c64b26..d536232f9dc 100644 --- a/django/db/backends/mysql_old/base.py +++ b/django/db/backends/mysql_old/base.py @@ -131,6 +131,22 @@ class DatabaseOperations(BaseDatabaseOperations): class DatabaseWrapper(BaseDatabaseWrapper): features = DatabaseFeatures() ops = DatabaseOperations() + 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', + } def __init__(self, **kwargs): super(DatabaseWrapper, self).__init__(**kwargs) @@ -197,20 +213,3 @@ class DatabaseWrapper(BaseDatabaseWrapper): raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info()) self.server_version = tuple([int(x) for x in m.groups()]) return self.server_version - -OPERATOR_MAPPING = { - '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', -} diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 9f602e5ab04..3f22755956b 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -385,6 +385,20 @@ class DatabaseOperations(BaseDatabaseOperations): class DatabaseWrapper(BaseDatabaseWrapper): features = DatabaseFeatures() ops = DatabaseOperations() + operators = { + 'exact': '= %s', + 'iexact': '= UPPER(%s)', + 'contains': "LIKE %s ESCAPE '\\'", + 'icontains': "LIKE UPPER(%s) ESCAPE '\\'", + 'gt': '> %s', + 'gte': '>= %s', + 'lt': '< %s', + 'lte': '<= %s', + 'startswith': "LIKE %s ESCAPE '\\'", + 'endswith': "LIKE %s ESCAPE '\\'", + 'istartswith': "LIKE UPPER(%s) ESCAPE '\\'", + 'iendswith': "LIKE UPPER(%s) ESCAPE '\\'", + } def _valid_connection(self): return self.connection is not None @@ -498,18 +512,3 @@ def get_sequence_name(table): def get_trigger_name(table): name_length = DatabaseOperations().max_name_length() - 3 return '%s_TR' % util.truncate_name(table, name_length).upper() - -OPERATOR_MAPPING = { - 'exact': '= %s', - 'iexact': '= UPPER(%s)', - 'contains': "LIKE %s ESCAPE '\\'", - 'icontains': "LIKE UPPER(%s) ESCAPE '\\'", - 'gt': '> %s', - 'gte': '>= %s', - 'lt': '< %s', - 'lte': '<= %s', - 'startswith': "LIKE %s ESCAPE '\\'", - 'endswith': "LIKE %s ESCAPE '\\'", - 'istartswith': "LIKE UPPER(%s) ESCAPE '\\'", - 'iendswith': "LIKE UPPER(%s) ESCAPE '\\'", -} diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index 755a34231ce..2b260aac362 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -62,6 +62,22 @@ class DatabaseFeatures(BaseDatabaseFeatures): class DatabaseWrapper(BaseDatabaseWrapper): features = DatabaseFeatures() ops = DatabaseOperations() + operators = { + 'exact': '= %s', + 'iexact': 'ILIKE %s', + 'contains': 'LIKE %s', + 'icontains': 'ILIKE %s', + 'regex': '~ %s', + 'iregex': '~* %s', + 'gt': '> %s', + 'gte': '>= %s', + 'lt': '< %s', + 'lte': '<= %s', + 'startswith': 'LIKE %s', + 'endswith': 'LIKE %s', + 'istartswith': 'ILIKE %s', + 'iendswith': 'ILIKE %s', + } def _cursor(self, settings): set_tz = False @@ -111,20 +127,3 @@ Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", util.typecast Database.register_type(Database.new_type((16,), "BOOLEAN", util.typecast_boolean)) Database.register_type(Database.new_type((1700,), "NUMERIC", util.typecast_decimal)) Database.register_type(Database.new_type(Database.types[1043].values, 'STRING', typecast_string)) - -OPERATOR_MAPPING = { - 'exact': '= %s', - 'iexact': 'ILIKE %s', - 'contains': 'LIKE %s', - 'icontains': 'ILIKE %s', - 'regex': '~ %s', - 'iregex': '~* %s', - 'gt': '> %s', - 'gte': '>= %s', - 'lt': '< %s', - 'lte': '<= %s', - 'startswith': 'LIKE %s', - 'endswith': 'LIKE %s', - 'istartswith': 'ILIKE %s', - 'iendswith': 'ILIKE %s', -} diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py index 0bcfd46ac4d..961a575129e 100644 --- a/django/db/backends/postgresql_psycopg2/base.py +++ b/django/db/backends/postgresql_psycopg2/base.py @@ -24,6 +24,22 @@ class DatabaseFeatures(BaseDatabaseFeatures): class DatabaseWrapper(BaseDatabaseWrapper): features = DatabaseFeatures() ops = DatabaseOperations() + operators = { + 'exact': '= %s', + 'iexact': 'ILIKE %s', + 'contains': 'LIKE %s', + 'icontains': 'ILIKE %s', + 'regex': '~ %s', + 'iregex': '~* %s', + 'gt': '> %s', + 'gte': '>= %s', + 'lt': '< %s', + 'lte': '<= %s', + 'startswith': 'LIKE %s', + 'endswith': 'LIKE %s', + 'istartswith': 'ILIKE %s', + 'iendswith': 'ILIKE %s', + } def _cursor(self, settings): set_tz = False @@ -52,20 +68,3 @@ class DatabaseWrapper(BaseDatabaseWrapper): cursor.execute("SELECT version()") self.ops.postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')] return cursor - -OPERATOR_MAPPING = { - 'exact': '= %s', - 'iexact': 'ILIKE %s', - 'contains': 'LIKE %s', - 'icontains': 'ILIKE %s', - 'regex': '~ %s', - 'iregex': '~* %s', - 'gt': '> %s', - 'gte': '>= %s', - 'lt': '< %s', - 'lte': '<= %s', - 'startswith': 'LIKE %s', - 'endswith': 'LIKE %s', - 'istartswith': 'ILIKE %s', - 'iendswith': 'ILIKE %s', -} diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 2ffdefa73ec..7919e1cc50c 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -76,6 +76,26 @@ class DatabaseWrapper(BaseDatabaseWrapper): features = DatabaseFeatures() ops = DatabaseOperations() + # SQLite requires LIKE statements to include an ESCAPE clause if the value + # being escaped has a percent or underscore in it. + # See http://www.sqlite.org/lang_expr.html for an explanation. + operators = { + 'exact': '= %s', + 'iexact': "LIKE %s ESCAPE '\\'", + 'contains': "LIKE %s ESCAPE '\\'", + 'icontains': "LIKE %s ESCAPE '\\'", + 'regex': 'REGEXP %s', + 'iregex': "REGEXP '(?i)' || %s", + 'gt': '> %s', + 'gte': '>= %s', + 'lt': '< %s', + 'lte': '<= %s', + 'startswith': "LIKE %s ESCAPE '\\'", + 'endswith': "LIKE %s ESCAPE '\\'", + 'istartswith': "LIKE %s ESCAPE '\\'", + 'iendswith': "LIKE %s ESCAPE '\\'", + } + def _cursor(self, settings): if self.connection is None: kwargs = { @@ -140,24 +160,3 @@ def _sqlite_regexp(re_pattern, re_string): return bool(re.search(re_pattern, re_string)) except: return False - -# SQLite requires LIKE statements to include an ESCAPE clause if the value -# being escaped has a percent or underscore in it. -# See http://www.sqlite.org/lang_expr.html for an explanation. -OPERATOR_MAPPING = { - 'exact': '= %s', - 'iexact': "LIKE %s ESCAPE '\\'", - 'contains': "LIKE %s ESCAPE '\\'", - 'icontains': "LIKE %s ESCAPE '\\'", - 'regex': 'REGEXP %s', - 'iregex': "REGEXP '(?i)' || %s", - 'gt': '> %s', - 'gte': '>= %s', - 'lt': '< %s', - 'lte': '<= %s', - 'startswith': "LIKE %s ESCAPE '\\'", - 'endswith': "LIKE %s ESCAPE '\\'", - 'istartswith': "LIKE %s ESCAPE '\\'", - 'iendswith': "LIKE %s ESCAPE '\\'", -} - diff --git a/django/db/models/query.py b/django/db/models/query.py index b0556ac2a3e..a750ef5550c 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.db import backend, connection, transaction +from django.db import connection, transaction from django.db.models.fields import DateField, FieldDoesNotExist from django.db.models import signals, loading from django.dispatch import dispatcher @@ -797,7 +797,7 @@ def get_where_clause(lookup_type, table_prefix, field_name, value, db_type): else: format = '%s %s' try: - return format % (field_sql, backend.OPERATOR_MAPPING[lookup_type] % cast_sql) + return format % (field_sql, connection.operators[lookup_type] % cast_sql) except KeyError: pass if lookup_type == 'in':