Django

Code

Ticket #463: mysql_magic-removal_rev2360-1.diff

File mysql_magic-removal_rev2360-1.diff, 3.6 kB (added by greg@abbas.no-spam.org, 3 years ago)

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

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

    old new  
    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