Ticket #463: mysql_rev2307.diff

File mysql_rev2307.diff, 4.1 KB (added by edgars.jekabsons@…, 9 years ago)

patch against trunk (rev. 2307)

  • 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
     17
    1418DatabaseError = Database.DatabaseError
    1519
    1620django_conversions = conversions.copy()
     
    4953
    5054class DatabaseWrapper:
    5155    def __init__(self):
    52         self.connection = None
     56        self.__connections = {}
     57        self.__threads = Set()
     58        self.__lock = RWLock()
    5359        self.queries = []
    54 
    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)
    68         cursor = self.connection.cursor()
    69         if self.connection.get_server_info() >= '4.1':
     97            connection = Database.connect(**kwargs)
     98            self.__connections[id] = connection
     99            self.__threads.add(id)
     100            return connection
     101        finally:
     102            self.__lock.writer_leaves()
     103
     104    def cursor(self):
     105        from django.conf.settings import DEBUG
     106        connection = self.__connect()
     107        cursor = connection.cursor()
     108        if connection.get_server_info() >= '4.1':
    70109            cursor.execute("SET NAMES utf8")
    71110        if DEBUG:
    72111            return base.CursorDebugWrapper(MysqlDebugWrapper(cursor), self)
    73112        return cursor
    74113
    75114    def commit(self):
    76         self.connection.commit()
     115        id = threading.currentThread()
     116        self.__lock.reader_enters()
     117        try:
     118            if id in self.__connections:
     119                self.__connections[id].commit()
     120        finally:
     121            self.__lock.reader_leaves()
    77122
    78123    def rollback(self):
    79         if self.connection:
    80             try:
    81                 self.connection.rollback()
    82             except Database.NotSupportedError:
    83                 pass
     124        id = threading.currentThread()
     125        self.__lock.reader_enters()
     126        try:
     127           if id in self.__connections:
     128                try:
     129                    self.__connections[id].rollback()
     130                except Database.NotSupportedError:
     131                    pass
     132        finally:
     133            self.__lock.reader_leaves()
    84134
    85135    def close(self):
    86         if self.connection is not None:
    87             self.connection.close()
    88             self.connection = None
     136        id = threading.currentThread()
     137        self.__lock.writer_enters()
     138        try:
     139            if id in self.__connections:
     140                self.__connections[id].close()
     141                del self.__connections[id]
     142        finally:
     143            self.__lock.writer_leaves()
    89144
    90145    def quote_name(self, name):
    91146        if name.startswith("`") and name.endswith("`"):
Back to Top