Ticket #17291: ora_version.2.diff

File ora_version.2.diff, 6.2 KB (added by akaariai, 4 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..2223e6c 100644
    a b import datetime 
    99import decimal
    1010import sys
    1111
     12from django.utils.functional import cached_property
     13
    1214
    1315def _setup_environment(environ):
    1416    import platform
    class DatabaseFeatures(BaseDatabaseFeatures): 
    8385    has_bulk_insert = True
    8486    supports_tablespaces = True
    8587
     88    def _supports_regex(self):
     89        if self.connection.oracle_version > 9:
     90            return True
     91        else:
     92            return False
     93    supports_regex = property(_supports_regex)
     94    supports_regex_backreferencing = supports_regex
     95
    8696class DatabaseOperations(BaseDatabaseOperations):
    8797    compiler_module = "django.db.backends.oracle.compiler"
    8898
    WHEN (new.%(col_name)s IS NULL) 
    249259    def random_function_sql(self):
    250260        return "DBMS_RANDOM.RANDOM"
    251261
    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 
    262262    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)
     263        if self.connection.oracle_version > 9:
     264            if lookup_type == 'regex':
     265                match_option = "'c'"
     266            else:
     267                match_option = "'i'"
     268            return 'REGEXP_LIKE(%%s, %%s, %s)' % match_option
     269        else:
     270            raise NotImplementedError("Regexes are not supported in Oracle before version 10g.")
    267271
    268272    def return_insert_id(self):
    269273        return "RETURNING %s INTO %%s", (InsertIdVar(),)
    class DatabaseWrapper(BaseDatabaseWrapper): 
    434438    def __init__(self, *args, **kwargs):
    435439        super(DatabaseWrapper, self).__init__(*args, **kwargs)
    436440
    437         self.oracle_version = None
    438441        self.features = DatabaseFeatures(self)
    439442        use_returning_into = self.settings_dict["OPTIONS"].get('use_returning_into', True)
    440443        self.features.can_return_id_from_insert = use_returning_into
    class DatabaseWrapper(BaseDatabaseWrapper): 
    444447        self.introspection = DatabaseIntrospection(self)
    445448        self.validation = BaseDatabaseValidation(self)
    446449
     450    @cached_property
     451    def oracle_version(self):
     452        if self.connection is None:
     453            # To check the server version, we need a connection - open and
     454            # immediately close a cursor to ensure an open connection.
     455            self.cursor().close()
     456        return int(self.connection.version.split('.')[0])
     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