def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures() autocommit = self.settings_dict['DATABASE_OPTIONS'].get('autocommit', False) self.features.uses_autocommit = autocommit self.isolation_level = int(not autocommit) self.features.can_return_id_from_insert = autocommit self.ops = DatabaseOperations() self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation() self.mapper = DatabaseMapper(self) self.connections = {} self._tables = None self._query = None self._needs_master = False
class DatabaseWrapper(BaseDatabaseWrapper): operators = { 'exact': '= %s', 'iexact': "= LOWER(%s)", 'contains': 'LIKE %s', 'icontains': 'LIKE LOWER(%s)', 'regex': '~ %s', 'iregex': '~* %s', 'gt': '> %s', 'gte': '>= %s', 'lt': '< %s', 'lte': '<= %s', 'startswith': 'LIKE %s', 'endswith': 'LIKE %s', 'istartswith': 'LIKE LOWER(%s)', 'iendswith': 'LIKE LOWER(%s)', } def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) self.features = DatabaseFeatures() autocommit = self.settings_dict['DATABASE_OPTIONS'].get('autocommit', False) self.features.uses_autocommit = autocommit self.isolation_level = int(not autocommit) self.features.can_return_id_from_insert = autocommit self.ops = DatabaseOperations() self.client = DatabaseClient(self) self.creation = DatabaseCreation(self) self.introspection = DatabaseIntrospection(self) self.validation = BaseDatabaseValidation() self.mapper = DatabaseMapper(self) self.connections = {} self._tables = None self._query = None self._needs_master = False def connect(self, params): """Get a connection to a database as specified by params""" if str(params) in self.connections: return self.connections[str(params)] else: try: connection = Database.connect(**params) self.connections[str(params)] = connection connection.set_client_encoding('UTF8') connection.set_isolation_level(self.isolation_level) connection_created.send(sender=self.__class__) cursor = connection.cursor() cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE]) cursor.close() except: logger.exception("Error connecting to %s" % params['database']) raise return connection def _get_default_params(self): """Get a dict of default values suitable for use with Database.connect""" settings_dict = self.settings_dict if settings_dict['DATABASE_NAME'] == '': from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.") conn_params = DatabaseSettings(database=settings_dict['DATABASE_NAME']) conn_params.update(settings_dict['DATABASE_OPTIONS']) if 'autocommit' in conn_params: del conn_params['autocommit'] if settings_dict['DATABASE_USER']: conn_params['user'] = settings_dict['DATABASE_USER'] if settings_dict['DATABASE_PASSWORD']: conn_params['password'] = settings_dict['DATABASE_PASSWORD'] if settings_dict['DATABASE_HOST']: conn_params['host'] = settings_dict['DATABASE_HOST'] if settings_dict['DATABASE_PORT']: conn_params['port'] = settings_dict['DATABASE_PORT'] return conn_params def _get_params_for_query(self): """Get the db params for the current query""" from django.db.models.sql import (InsertQuery, UpdateQuery, DeleteQuery) tables = self._tables needs_master = self._needs_master \ or isinstance(self._query, InsertQuery) \ or isinstance(self._query, UpdateQuery) \ or isinstance(self._query, DeleteQuery) return self.mapper.get_connection_description( tables, needs_master) def _cursor(self, *args, **kwargs): """Return a cursor. We return a ProxyCursor so that we can still perform database direction for future queries against that cursor. If we are forced to return a cursor for the default database (because the query is not from the ORM and therefore we don't have enough information yet) then the query can still be redirected when execute is called. """ params = self._get_default_params() if self._query is not None: self._tables = _get_tables(self._query) if self._tables is not None: params.update(self._get_params_for_query()) connection = self.connect(params) cursor = connection.cursor(*args, **kwargs) cursor.tzinfo_factory = None return ProxyCursor(cursor, params, self, *args, **kwargs) def connection_apply(self, method, *args, **kwargs): """Map a method call to all the current connections""" for connection in self.connections.values(): if callable(method): method(connection, *args, **kwargs) else: try: getattr(connection, method)(*args, **kwargs) except Database.OperationalError, e: raise Database.OperationalError("%s - %s" % (str(e), connection))