Ticket #7732: oracle_pool.5.diff

File oracle_pool.5.diff, 7.4 KB (added by Matt Boersma, 15 years ago)

Modified patch against trunk [10832] that passes the Django test suite

  • django/db/backends/oracle/base.py

     
    273273        'iendswith': "LIKEC UPPER(%s) ESCAPE '\\'",
    274274    }
    275275    oracle_version = None
     276    _pool_defaults = {'SESSION_POOL_MIN': 1,
     277                      'SESSION_POOL_MAX': 3,
     278                      'SESSION_POOL_INCREMENT': 1,}
    276279
    277280    def __init__(self, *args, **kwargs):
    278281        super(DatabaseWrapper, self).__init__(*args, **kwargs)
     
    284287        self.introspection = DatabaseIntrospection(self)
    285288        self.validation = BaseDatabaseValidation()
    286289
     290        # Fetch connection pool settings
     291        opts = self.settings_dict['DATABASE_OPTIONS']
     292        if not isinstance(opts, dict):
     293            # Insurance against foolish users...
     294            opts = {}
     295        if opts.get('SESSION_POOL', False):
     296            self._use_pool = True
     297            self._pool_settings = dict(self._pool_defaults)
     298            self._pool_settings.update(opts)
     299        else:
     300            self._use_pool = False
     301
     302    def _get_pool (self):
     303        if not hasattr (self.__class__, '_pool'):
     304            settings_dict = self.settings_dict
     305            Database.OPT_Threading = 1
     306            if len(settings_dict['DATABASE_HOST'].strip()) == 0:
     307                settings_dict['DATABASE_HOST'] = 'localhost'
     308            if len(settings_dict['DATABASE_PORT'].strip()) != 0:
     309                dsn = Database.makedsn(settings_dict['DATABASE_HOST'],
     310                                       int(settings_dict['DATABASE_PORT']),
     311                                       settings_dict['DATABASE_NAME'])
     312                p = Database.SessionPool(settings_dict['DATABASE_USER'],
     313                                         settings_dict['DATABASE_PASSWORD'],
     314                                         dsn,
     315                                         self._pool_settings['SESSION_POOL_MIN'],
     316                                         self._pool_settings['SESSION_POOL_MAX'],
     317                                         self._pool_settings['SESSION_POOL_INCREMENT'],
     318                                         threaded = True)
     319            else:
     320                p = Database.SessionPool(settings_dict['DATABASE_USER'],
     321                                         settings_dict['DATABASE_PASSWORD'],
     322                                         settings_dict['DATABASE_NAME'],
     323                                         self._pool_settings['SESSION_POOL_MIN'],
     324                                         self._pool_settings['SESSION_POOL_MAX'],
     325                                         self._pool_settings['SESSION_POOL_INCREMENT'],
     326                                         threaded = True)
     327            setattr(self.__class__, '_pool', p)
     328            # TODO I think the init stuff only needs to happen once per pool,
     329            # but it may be once per connection...
     330            conn = p.acquire()
     331            self._init_oracle_settings(conn)
     332            p.release(conn)
     333        return getattr(self.__class__, '_pool')
     334
     335    pool = property (_get_pool)
     336
    287337    def _valid_connection(self):
    288338        return self.connection is not None
    289339
     
    300350        return "%s/%s@%s" % (settings_dict['DATABASE_USER'],
    301351                             settings_dict['DATABASE_PASSWORD'], dsn)
    302352
    303     def _cursor(self):
    304         cursor = None
    305         if not self._valid_connection():
    306             conn_string = self._connect_string()
    307             self.connection = Database.connect(conn_string, **self.settings_dict['DATABASE_OPTIONS'])
    308             cursor = FormatStylePlaceholderCursor(self.connection)
     353    def _init_oracle_settings(self, connection):
     354        cursor = FormatStylePlaceholderCursor(connection)
    309355            # Set oracle date to ansi date format.  This only needs to execute
    310356            # once when we create a new connection. We also set the Territory
    311357            # to 'AMERICA' which forces Sunday to evaluate to a '1' in TO_CHAR().
     
    313359                           "NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF' "
    314360                           "NLS_TERRITORY = 'AMERICA'")
    315361            try:
    316                 self.oracle_version = int(self.connection.version.split('.')[0])
     362            self.oracle_version = int(connection.version.split('.')[0])
    317363                # There's no way for the DatabaseOperations class to know the
    318364                # currently active Oracle version, so we do some setups here.
    319365                # TODO: Multi-db support will need a better solution (a way to
     
    324370                    self.ops.regex_lookup = self.ops.regex_lookup_10
    325371            except ValueError:
    326372                pass
     373        return cursor
     374
     375    def _cursor(self):
     376        cursor = None
     377        if not self._valid_connection():
     378            if self._use_pool and self.pool is not None:
     379                self.connection = self.pool.acquire()
     380            else:
     381                    self.connection = Database.connect(self._connect_string(),
     382                        **self.settings_dict['DATABASE_OPTIONS'])
     383                    cursor = self._init_oracle_settings(self.connection)
    327384            try:
    328385                self.connection.stmtcachesize = 20
    329386            except:
    330387                # Django docs specify cx_Oracle version 4.3.1 or higher, but
    331388                # stmtcachesize is available only in 4.3.2 and up.
    332389                pass
     390            # TODO Does pulling a connection from the pool count as "creation"?
    333391            connection_created.send(sender=self.__class__)
    334392        if not cursor:
    335393            cursor = FormatStylePlaceholderCursor(self.connection)
    336394        return cursor
    337395
     396    def close(self):
     397       from django.conf import settings
     398       if self._use_pool:
     399           if self.connection is not None:
     400               self.pool.release(self.connection)
     401               self.connection = None
     402       else:
     403           if self.connection is not None:
     404               self.connection.close()
     405               self.connection = None
     406
    338407    # Oracle doesn't support savepoint commits.  Ignore them.
    339408    def _savepoint_commit(self, sid):
    340409        pass
  • django/db/backends/oracle/creation.py

     
    111111        settings.TEST_DATABASE_USER = settings.DATABASE_USER = self.connection.settings_dict["DATABASE_USER"] = TEST_DATABASE_USER
    112112        settings.DATABASE_PASSWORD = self.connection.settings_dict["DATABASE_PASSWORD"] = TEST_DATABASE_PASSWD
    113113
     114        if hasattr(self.connection, '_pool'):
     115            self.connection.close()
     116            del self.connection.__class__._pool
     117
    114118        return settings.DATABASE_NAME
    115119
    116120    def _destroy_test_db(self, test_database_name, verbosity=1):
     
    118122        Destroy a test database, prompting the user for confirmation if the
    119123        database already exists. Returns the name of the test database created.
    120124        """
     125
     126        if hasattr(self.connection, '_pool'):
     127            self.connection.close()
     128            del self.connection.__class__._pool
     129
    121130        TEST_DATABASE_NAME = self._test_database_name(settings)
    122131        TEST_DATABASE_USER = self._test_database_user(settings)
    123132        TEST_DATABASE_PASSWD = self._test_database_passwd(settings)
Back to Top