Ticket #17291: ora_version.diff

File ora_version.diff, 6.1 KB (added by Anssi Kääriäinen, 12 years ago)
  • django/db/backends/__init__.py

    diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
    index dd24878..c89dcd9 100644
    a b class BaseDatabaseFeatures(object):  
    340340    # Do time/datetime fields have microsecond precision?
    341341    supports_microsecond_precision = True
    342342
     343    # Is there support for __regex lookups?
     344    supports_regex = True
     345
    343346    # Does the __regex lookup support backreferencing and grouping?
    344347    supports_regex_backreferencing = True
    345348
  • django/db/backends/oracle/base.py

    diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
    index c197422..6cfd608 100644
    a b class DatabaseFeatures(BaseDatabaseFeatures):  
    8383    has_bulk_insert = True
    8484    supports_tablespaces = True
    8585
     86    def _supports_regex(self):
     87        if self.connection.oracle_version > 9:
     88            return True
     89        else:
     90            return False
     91    supports_regex = property(_supports_regex)
     92    supports_regex_backreferencing = supports_regex
     93
    8694class DatabaseOperations(BaseDatabaseOperations):
    8795    compiler_module = "django.db.backends.oracle.compiler"
    8896
    WHEN (new.%(col_name)s IS NULL)  
    249257    def random_function_sql(self):
    250258        return "DBMS_RANDOM.RANDOM"
    251259
    252     def regex_lookup_9(self, lookup_type):
    253         raise NotImplementedError("Regexes are not supported in Oracle before version 10g.")
    254 
    255     def regex_lookup_10(self, lookup_type):
    256         if lookup_type == 'regex':
    257             match_option = "'c'"
    258         else:
    259             match_option = "'i'"
    260         return 'REGEXP_LIKE(%%s, %%s, %s)' % match_option
    261 
    262260    def regex_lookup(self, lookup_type):
    263         # If regex_lookup is called before it's been initialized, then create
    264         # a cursor to initialize it and recur.
    265         self.connection.cursor()
    266         return self.connection.ops.regex_lookup(lookup_type)
     261        if self.connection.oracle_version > 9:
     262            if lookup_type == 'regex':
     263                match_option = "'c'"
     264            else:
     265                match_option = "'i'"
     266            return 'REGEXP_LIKE(%%s, %%s, %s)' % match_option
     267        else:
     268            raise NotImplementedError("Regexes are not supported in Oracle before version 10g.")
    267269
    268270    def return_insert_id(self):
    269271        return "RETURNING %s INTO %%s", (InsertIdVar(),)
    class DatabaseWrapper(BaseDatabaseWrapper):  
    434436    def __init__(self, *args, **kwargs):
    435437        super(DatabaseWrapper, self).__init__(*args, **kwargs)
    436438
    437         self.oracle_version = None
     439        self._oracle_version = None
    438440        self.features = DatabaseFeatures(self)
    439441        use_returning_into = self.settings_dict["OPTIONS"].get('use_returning_into', True)
    440442        self.features.can_return_id_from_insert = use_returning_into
    class DatabaseWrapper(BaseDatabaseWrapper):  
    444446        self.introspection = DatabaseIntrospection(self)
    445447        self.validation = BaseDatabaseValidation(self)
    446448
     449    def _get_ora_version(self):
     450        if self._oracle_version is None:
     451            # To check the server version, we need a connection
     452            if self.connection is None:
     453                self._cursor().close()
     454            self._oracle_version = int(self.connection.version.split('.')[0])
     455        return self._oracle_version
     456    oracle_version = property(_get_ora_version)
     457
    447458    def check_constraints(self, table_names=None):
    448459        """
    449460        To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they
    class DatabaseWrapper(BaseDatabaseWrapper):  
    517528                    self.operators = self._likec_operators
    518529                else:
    519530                    self.operators = self._standard_operators
    520 
    521             try:
    522                 self.oracle_version = int(self.connection.version.split('.')[0])
    523                 # There's no way for the DatabaseOperations class to know the
    524                 # currently active Oracle version, so we do some setups here.
    525                 # TODO: Multi-db support will need a better solution (a way to
    526                 # communicate the current version).
    527                 if self.oracle_version <= 9:
    528                     self.ops.regex_lookup = self.ops.regex_lookup_9
    529                 else:
    530                     self.ops.regex_lookup = self.ops.regex_lookup_10
    531             except ValueError:
    532                 pass
    533531            try:
    534532                self.connection.stmtcachesize = 20
    535533            except:
    class FormatStylePlaceholderCursor(object):  
    650648        self.cursor.arraysize = 100
    651649
    652650    def _format_params(self, params):
    653         return tuple([OracleParam(p, self, True) for p in params])
     651        return tuple(OracleParam(p, self, True) for p in params)
    654652
    655653    def _guess_input_sizes(self, params_list):
    656654        sizes = [None] * len(params_list[0])
    class FormatStylePlaceholderCursor(object):  
    722720    def fetchmany(self, size=None):
    723721        if size is None:
    724722            size = self.arraysize
    725         return tuple([_rowfactory(r, self.cursor)
    726                       for r in self.cursor.fetchmany(size)])
     723        return tuple(_rowfactory(r, self.cursor)
     724                     for r in self.cursor.fetchmany(size))
    727725
    728726    def fetchall(self):
    729         return tuple([_rowfactory(r, self.cursor)
    730                       for r in self.cursor.fetchall()])
     727        return tuple(_rowfactory(r, self.cursor)
     728                     for r in self.cursor.fetchall())
    731729
    732730    def var(self, *args):
    733731        return VariableWrapper(self.cursor.var(*args))
  • tests/modeltests/lookup/tests.py

    diff --git a/tests/modeltests/lookup/tests.py b/tests/modeltests/lookup/tests.py
    index 9c2b0c6..068b5f7 100644
    a b class LookupTests(TestCase):  
    479479            self.assertEqual(str(ex), "Join on field 'headline' not permitted. "
    480480                             "Did you misspell 'starts' for the lookup type?")
    481481
     482    @skipUnlessDBFeature('supports_regex')
    482483    def test_regex(self):
    483484        # Create some articles with a bit more interesting headlines for testing field lookups:
    484485        for a in Article.objects.all():
Back to Top