Ticket #463: mysql.diff

File mysql.diff, 4.0 KB (added by Nebojša Đorđević - nesh <nesh@…>, 9 years ago)

new patch

  • mysql.py

     
    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("`"):
Back to Top