Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #7420 -- Abstracted some more database options into DatabaseFea…

…tures -- supports_usecs, time_field_needs_date, interprets_empty_strings_as_nulls and date_field_supports_time_value -- and changed various hard-coded 'if DATABASE_BACKEND == oracle' statements to use the new options. Thanks to ramiro for the patch

git-svn-id: http://code.djangoproject.com/svn/django/trunk@7643 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 06315375ce5c6477b7498026177b7e715372a7d1 1 parent 57311b5
Adrian Holovaty adrianholovaty authored
9 django/db/backends/__init__.py
View
@@ -52,6 +52,10 @@ class BaseDatabaseFeatures(object):
uses_custom_query_class = False
empty_fetchmany_value = []
update_can_self_select = True
+ supports_usecs = True
+ time_field_needs_date = False
+ interprets_empty_strings_as_nulls = False
+ date_field_supports_time_value = True
class BaseDatabaseOperations(object):
"""
@@ -266,3 +270,8 @@ def tablespace_sql(self, tablespace, inline=False):
tablespaces.
"""
return None
+
+ def prep_for_like_query(self, x):
+ """Prepares a value for use in a LIKE query."""
+ from django.utils.encoding import smart_unicode
+ return smart_unicode(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
1  django/db/backends/mysql/base.py
View
@@ -64,6 +64,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
inline_fk_references = False
empty_fetchmany_value = ()
update_can_self_select = False
+ supports_usecs = False
class DatabaseOperations(BaseDatabaseOperations):
def date_extract_sql(self, lookup_type, field_name):
1  django/db/backends/mysql_old/base.py
View
@@ -68,6 +68,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
inline_fk_references = False
empty_fetchmany_value = ()
update_can_self_select = False
+ supports_usecs = False
class DatabaseOperations(BaseDatabaseOperations):
def date_extract_sql(self, lookup_type, field_name):
3  django/db/backends/oracle/base.py
View
@@ -31,6 +31,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_tablespaces = True
uses_case_insensitive_names = True
uses_custom_query_class = True
+ time_field_needs_date = True
+ interprets_empty_strings_as_nulls = True
+ date_field_supports_time_value = False
class DatabaseOperations(BaseDatabaseOperations):
def autoinc_sql(self, table, column):
32 django/db/models/fields/__init__.py
View
@@ -7,7 +7,7 @@
except ImportError:
from django.utils import _decimal as decimal # for Python 2.3
-from django.db import get_creation_module
+from django.db import connection, get_creation_module
from django.db.models import signals
from django.db.models.query_utils import QueryWrapper
from django.dispatch import dispatcher
@@ -33,9 +33,6 @@ class NOT_PROVIDED:
BLANK_CHOICE_DASH = [("", "---------")]
BLANK_CHOICE_NONE = [("", "None")]
-# prepares a value for use in a LIKE query
-prep_for_like_query = lambda x: smart_unicode(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
-
# returns the <ul> class for a given radio_admin value
get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '')
@@ -97,7 +94,7 @@ def __init__(self, verbose_name=None, name=None, primary_key=False,
self.blank, self.null = blank, null
# Oracle treats the empty string ('') as null, so coerce the null
# option whenever '' is a possible value.
- if self.empty_strings_allowed and settings.DATABASE_ENGINE == 'oracle':
+ if self.empty_strings_allowed and connection.features.interprets_empty_strings_as_nulls:
self.null = True
self.core, self.rel, self.default = core, rel, default
self.editable = editable
@@ -235,13 +232,13 @@ def get_db_prep_lookup(self, lookup_type, value):
elif lookup_type in ('range', 'in'):
return value
elif lookup_type in ('contains', 'icontains'):
- return ["%%%s%%" % prep_for_like_query(value)]
+ return ["%%%s%%" % connection.ops.prep_for_like_query(value)]
elif lookup_type == 'iexact':
- return [prep_for_like_query(value)]
+ return [connection.ops.prep_for_like_query(value)]
elif lookup_type in ('startswith', 'istartswith'):
- return ["%s%%" % prep_for_like_query(value)]
+ return ["%s%%" % connection.ops.prep_for_like_query(value)]
elif lookup_type in ('endswith', 'iendswith'):
- return ["%%%s" % prep_for_like_query(value)]
+ return ["%%%s" % connection.ops.prep_for_like_query(value)]
elif lookup_type == 'isnull':
return []
elif lookup_type == 'year':
@@ -252,9 +249,12 @@ def get_db_prep_lookup(self, lookup_type, value):
if settings.DATABASE_ENGINE == 'sqlite3':
first = '%s-01-01'
second = '%s-12-31 23:59:59.999999'
- elif settings.DATABASE_ENGINE == 'oracle' and self.get_internal_type() == 'DateField':
+ elif not connection.features.date_field_supports_time_value and self.get_internal_type() == 'DateField':
first = '%s-01-01'
second = '%s-12-31'
+ elif not connection.features.supports_usecs:
+ first = '%s-01-01 00:00:00'
+ second = '%s-12-31 23:59:59.99'
else:
first = '%s-01-01 00:00:00'
second = '%s-12-31 23:59:59.999999'
@@ -271,7 +271,7 @@ def get_default(self):
if callable(self.default):
return self.default()
return force_unicode(self.default, strings_only=True)
- if not self.empty_strings_allowed or (self.null and settings.DATABASE_ENGINE != 'oracle'):
+ if not self.empty_strings_allowed or (self.null and not connection.features.interprets_empty_strings_as_nulls):
return None
return ""
@@ -629,7 +629,7 @@ def get_db_prep_save(self, value):
if value is not None:
# MySQL will throw a warning if microseconds are given, because it
# doesn't support microseconds.
- if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'):
+ if not connection.features.supports_usecs and hasattr(value, 'microsecond'):
value = value.replace(microsecond=0)
value = smart_unicode(value)
return Field.get_db_prep_save(self, value)
@@ -863,7 +863,7 @@ def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=
self.path, self.match, self.recursive = path, match, recursive
kwargs['max_length'] = kwargs.get('max_length', 100)
Field.__init__(self, verbose_name, name, **kwargs)
-
+
def formfield(self, **kwargs):
defaults = {
'path': self.path,
@@ -1071,7 +1071,7 @@ def get_internal_type(self):
return "TimeField"
def get_db_prep_lookup(self, lookup_type, value):
- if settings.DATABASE_ENGINE == 'oracle':
+ if connection.features.time_field_needs_date:
# Oracle requires a date in order to parse.
def prep(value):
if isinstance(value, datetime.time):
@@ -1098,9 +1098,9 @@ def get_db_prep_save(self, value):
if value is not None:
# MySQL will throw a warning if microseconds are given, because it
# doesn't support microseconds.
- if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'):
+ if not connection.features.supports_usecs and hasattr(value, 'microsecond'):
value = value.replace(microsecond=0)
- if settings.DATABASE_ENGINE == 'oracle':
+ if connection.features.time_field_needs_date:
# cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field.
if isinstance(value, datetime.time):
value = datetime.datetime(1900, 1, 1, value.hour, value.minute,
Please sign in to comment.
Something went wrong with that request. Please try again.