Django

Code

Ticket #463: mysql.diff

File mysql.diff, 4.0 kB (added by Nebojša Đorđević - nesh <nesh@studioquattro.co.yu>, 3 years ago)

new patch

  • mysql.py

    old new  
    1010from MySQLdb.converters import conversions 
    1111from MySQLdb.constants import FIELD_TYPE 
    1212import types 
     13import threading 
     14from sets import Set 
     15from django.utils.synch import RWLock 
    1316 
    1417DatabaseError = Database.DatabaseError 
    1518 
     
    4952 
    5053class DatabaseWrapper: 
    5154    def __init__(self): 
    52         self.connection = None 
     55        self.__connections = {} 
     56        self.__threads = Set() 
     57        self.__lock = RWLock() 
    5358        self.queries = [] 
    5459 
    55     def cursor(self): 
    56         from django.conf.settings import DATABASE_USER, DATABASE_NAME, DATABASE_HOST, DATABASE_PORT, DATABASE_PASSWORD, DEBUG 
    57         if self.connection is None: 
     60    def _valid_connection(self, con): 
     61        try: 
     62            con.ping() 
     63            return True 
     64        except DatabaseError: 
     65            con.close() # close connection 
     66            return False 
     67     
     68    def __connect(self): 
     69        id = threading.currentThread() 
     70        self.__lock.reader_enters() 
     71        try: 
     72            if (id in self.__connections) and (self._valid_connection(self.__connections[id])): 
     73                return self.__connections[id] 
     74        finally: 
     75            self.__lock.reader_leaves() 
     76             
     77        self.__lock.writer_enters() 
     78        try: 
     79            # remove deadwood 
     80            dead = self.__threads - Set(threading.enumerate()) 
     81            for name in dead: 
     82                self.__connections[name].close() 
     83                del self.__connections[name] 
     84            self.__threads -= dead 
     85         
     86            # create new connection 
     87            from django.conf.settings import DATABASE_USER, DATABASE_NAME, DATABASE_HOST, DATABASE_PORT, DATABASE_PASSWORD 
    5888            kwargs = { 
    5989                'user': DATABASE_USER, 
    6090                'db': DATABASE_NAME, 
     
    6494            } 
    6595            if DATABASE_PORT: 
    6696                kwargs['port'] = DATABASE_PORT 
    67             self.connection = Database.connect(**kwargs) 
     97 
     98            connection = Database.connect(**kwargs) 
     99            self.__connections[id] = connection 
     100            self.__threads.add(id) 
     101            return connection 
     102        finally: 
     103            self.__lock.writer_leaves() 
     104 
     105    def cursor(self): 
     106        from django.conf.settings import DEBUG 
     107        connection = self.__connect() 
     108         
    68109        if DEBUG: 
    69             return base.CursorDebugWrapper(MysqlDebugWrapper(self.connection.cursor()), self) 
    70         return self.connection.cursor() 
     110            return base.CursorDebugWrapper(MysqlDebugWrapper(connection.cursor()), self) 
     111        return connection.cursor() 
    71112 
    72113    def commit(self): 
    73         self.connection.commit() 
     114        id = threading.currentThread() 
     115        self.__lock.reader_enters() 
     116        try: 
     117            if id in self.__connections: 
     118                self.__connections[id].commit() 
     119        finally: 
     120            self.__lock.reader_leaves() 
    74121 
    75122    def rollback(self): 
    76         if self.connection: 
    77             try: 
    78                 self.connection.rollback() 
    79             except Database.NotSupportedError: 
    80                 pass 
     123        id = threading.currentThread() 
     124        self.__lock.reader_enters() 
     125        try: 
     126            if id in self.__connections: 
     127                try: 
     128                    self.__connections[id].rollback() 
     129                except Database.NotSupportedError: 
     130                    pass 
     131        finally: 
     132            self.__lock.reader_leaves() 
    81133 
    82134    def close(self): 
    83         if self.connection is not None: 
    84             self.connection.close() 
    85             self.connection = None 
     135        id = threading.currentThread() 
     136        self.__lock.writer_enters() 
     137        try: 
     138            if id in self.__connections: 
     139                self.__connections[id].close() 
     140                del self.__connections[id] 
     141        finally: 
     142            self.__lock.writer_leaves() 
    86143 
    87144    def quote_name(self, name): 
    88145        if name.startswith("`") and name.endswith("`"):