Beispiel #1
0
    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
Beispiel #2
0
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))