Skip to content

Commit

Permalink
Replaced vendor checks by three feature flags.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaugustin committed May 8, 2014
1 parent 43a80f4 commit c70a61e
Show file tree
Hide file tree
Showing 7 changed files with 17 additions and 16 deletions.
6 changes: 6 additions & 0 deletions django/db/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ class BaseDatabaseFeatures(object):
can_return_id_from_insert = False
has_bulk_insert = False
uses_savepoints = False
can_release_savepoints = True
can_combine_inserts_with_and_without_auto_increment_pk = False

# If True, don't use integer foreign keys referring to, e.g., positive
Expand Down Expand Up @@ -512,6 +513,8 @@ class BaseDatabaseFeatures(object):
supports_subqueries_in_group_by = True
supports_bitwise_or = True

supports_binary_field = True

# Do time/datetime fields have microsecond precision?
supports_microsecond_precision = True

Expand Down Expand Up @@ -605,6 +608,9 @@ class BaseDatabaseFeatures(object):
# statements before executing them?
requires_sqlparse_for_splitting = True

# Suffix for backends that don't support "SELECT xxx;" queries.
bare_select_suffix = ''

def __init__(self, connection):
self.connection = connection

Expand Down
2 changes: 2 additions & 0 deletions django/db/backends/mysql/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ class DatabaseFeatures(BaseDatabaseFeatures):
has_select_for_update_nowait = False
supports_forward_references = False
supports_long_model_names = False
# XXX MySQL DB-API drivers currently fail on binary data on Python 3.
supports_binary_field = six.PY2
supports_microsecond_precision = False
supports_regex_backreferencing = False
supports_date_lookup_using_string = False
Expand Down
2 changes: 2 additions & 0 deletions django/db/backends/oracle/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
needs_datetime_string_cast = False
interprets_empty_strings_as_nulls = True
uses_savepoints = True
can_release_savepoints = False
has_select_for_update = True
has_select_for_update_nowait = True
can_return_id_from_insert = True
Expand All @@ -116,6 +117,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
requires_literal_defaults = True
connection_persists_old_columns = True
closed_cursor_error_class = InterfaceError
bare_select_suffix = " FROM DUAL"


class DatabaseOperations(BaseDatabaseOperations):
Expand Down
6 changes: 2 additions & 4 deletions tests/admin_views/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3937,8 +3937,7 @@ def test_user_permission_performance(self):
ContentType.objects.clear_cache()

expected_queries = 10
# Oracle doesn't implement "RELEASE SAVPOINT", see #20387.
if connection.vendor == 'oracle':
if not connection.features.can_release_savepoints:
expected_queries -= 1

with self.assertNumQueries(expected_queries):
Expand Down Expand Up @@ -3980,8 +3979,7 @@ def test_group_permission_performance(self):
g = Group.objects.create(name="test_group")

expected_queries = 8
# Oracle doesn't implement "RELEASE SAVPOINT", see #20387.
if connection.vendor == 'oracle':
if not connection.features.can_release_savepoints:
expected_queries -= 1

with self.assertNumQueries(expected_queries):
Expand Down
5 changes: 1 addition & 4 deletions tests/backends/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ def test_aggregation(self):
self.assertRaises(NotImplementedError,
models.Item.objects.all().aggregate, aggregate('last_modified'))


def test_convert_values_to_handle_null_value(self):
from django.db.backends.sqlite3.base import DatabaseOperations
convert_values = DatabaseOperations(connection).convert_values
Expand Down Expand Up @@ -464,9 +463,7 @@ class EscapingChecks(TestCase):
EscapingChecksDebug test case, to also test CursorDebugWrapper.
"""

# For Oracle, when you want to select a value, you need to specify the
# special pseudo-table 'dual'; a select with no from clause is invalid.
bare_select_suffix = " FROM DUAL" if connection.vendor == 'oracle' else ""
bare_select_suffix = connection.features.bare_select_suffix

def test_paramless_no_escaping(self):
cursor = connection.cursor()
Expand Down
5 changes: 1 addition & 4 deletions tests/model_fields/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ def test_delete_when_file_unset(self):
class BinaryFieldTests(test.TestCase):
binary_data = b'\x00\x46\xFE'

@test.skipUnlessDBFeature('supports_binary_field')
def test_set_and_retrieve(self):
data_set = (self.binary_data, six.memoryview(self.binary_data))
for bdata in data_set:
Expand All @@ -619,10 +620,6 @@ def test_set_and_retrieve(self):
# Test default value
self.assertEqual(bytes(dm.short_data), b'\x08')

if connection.vendor == 'mysql' and six.PY3:
# Existing MySQL DB-API drivers fail on binary data.
test_set_and_retrieve = unittest.expectedFailure(test_set_and_retrieve)

def test_max_length(self):
dm = DataModel(short_data=self.binary_data * 4)
self.assertRaises(ValidationError, dm.full_clean)
Expand Down
7 changes: 3 additions & 4 deletions tests/serializers_regress/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import datetime
import decimal
from unittest import skip, skipUnless
from unittest import skipUnless
import warnings

try:
Expand All @@ -24,7 +24,7 @@
from django.core.serializers.xml_serializer import DTDForbidden
from django.db import connection, models
from django.http import HttpResponse
from django.test import TestCase
from django.test import skipUnlessDBFeature, TestCase
from django.utils import six
from django.utils.functional import curry

Expand Down Expand Up @@ -481,8 +481,7 @@ def serializerTest(format, self):
for klass, count in instance_count.items():
self.assertEqual(count, klass.objects.count())

if connection.vendor == 'mysql' and six.PY3:
serializerTest = skip("Existing MySQL DB-API drivers fail on binary data.")(serializerTest)
serializerTest = skipUnlessDBFeature('supports_binary_field')(serializerTest)


def naturalKeySerializerTest(format, self):
Expand Down

0 comments on commit c70a61e

Please sign in to comment.