Ticket #463: mysql_magic-removal_rev2360-1.diff

File mysql_magic-removal_rev2360-1.diff, 3.6 KB (added by greg@…, 10 years ago)

Patch for magic-removal 2360, using thread-local storage and python 2.3 support

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

     
    99from MySQLdb.converters import conversions
    1010from MySQLdb.constants import FIELD_TYPE
    1111import types
     12import threading
    1213
    1314DatabaseError = Database.DatabaseError
    1415
     
    4647        else:
    4748            return getattr(self.cursor, attr)
    4849
     50class ThreadLocal:
     51    def __getattr__(self, key):
     52        threadkey = 'ThreadLocal_%s' % (id(self),)
     53        thread = threading.currentThread()
     54        try:
     55            local = getattr(thread, threadkey)
     56            return local[key]
     57        except AttributeError:
     58            raise AttributeError(key)
     59        except KeyError:
     60            raise AttributeError(key)
     61
     62    def __setattr__(self, key, value):
     63        threadkey = 'ThreadLocal_%s' % (id(self),)
     64        thread = threading.currentThread()
     65        try:
     66            local = getattr(thread, threadkey)
     67        except AttributeError:
     68            local = {}
     69            setattr(thread, threadkey, local)
     70        local[key] = value
     71
     72    def __delattr__(self, key):
     73        threadkey = 'ThreadLocal_%s' % (id(self),)
     74        thread = threading.currentThread()
     75        try:
     76            local = getattr(thread, threadkey)
     77            del local[key]
     78        except AttributeError:
     79            raise AttributeError(key)
     80        except KeyError:
     81            raise AttributeError(key)
     82
    4983class DatabaseWrapper:
    5084    def __init__(self):
    51         self.connection = None
    5285        self.queries = []
     86        if hasattr(threading, 'local'):
     87            # threading.local is available in Python 2.4 and later
     88            self.threadlocal = threading.local()
     89        else:
     90            # workaround for Python 2.3 and earlier
     91            self.threadlocal = ThreadLocal()
    5392
    5493    def cursor(self):
    5594        from django.conf import settings
    56         if self.connection is None:
     95        conn = getattr(self.threadlocal, 'connection', None)
     96        if conn is None:
    5797            kwargs = {
    5898                'user': settings.DATABASE_USER,
    5999                'db': settings.DATABASE_NAME,
     
    63103            }
    64104            if settings.DATABASE_PORT:
    65105                kwargs['port'] = settings.DATABASE_PORT
    66             self.connection = Database.connect(**kwargs)
    67         cursor = self.connection.cursor()
    68         if self.connection.get_server_info() >= '4.1':
     106            conn = self.threadlocal.connection = Database.connect(**kwargs)
     107        else:
     108            conn.ping()
     109        cursor = conn.cursor()
     110        if conn.get_server_info() >= '4.1':
    69111            cursor.execute("SET NAMES utf8")
    70112        if settings.DEBUG:
    71113            return util.CursorDebugWrapper(MysqlDebugWrapper(cursor), self)
    72114        return cursor
    73115
    74116    def commit(self):
    75         self.connection.commit()
     117        conn = getattr(self.threadlocal, 'connection', None)
     118        if conn is not None:
     119            conn.commit()
    76120
    77121    def rollback(self):
    78         if self.connection:
     122        conn = getattr(self.threadlocal, 'connection', None)
     123        if conn is not None:
    79124            try:
    80                 self.connection.rollback()
     125                conn.rollback()
    81126            except Database.NotSupportedError:
    82127                pass
    83128
    84129    def close(self):
    85         if self.connection is not None:
    86             self.connection.close()
    87             self.connection = None
     130        conn = getattr(self.threadlocal, 'connection', None)
     131        if conn is not None:
     132            conn.close()
     133            self.threadlocal.connection = None
    88134
    89135supports_constraints = True
    90136
Back to Top