Django

Code

Ticket #463: mysql_0.91.diff

File mysql_0.91.diff, 4.3 kB (added by edgars@way.lv, 3 years ago)

patch against release 0.91

  • 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) 
    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    def cursor(self): 
     104        from django.conf.settings import DEBUG 
     105        connection = self.__connect() 
     106        cursor = connection.cursor() 
     107        if connection.get_server_info() >= '4.1': 
    70108            cursor.execute("SET NAMES utf8") 
    71109        if DEBUG: 
    72110            return base.CursorDebugWrapper(MysqlDebugWrapper(cursor), self) 
    73111        return cursor 
    74112 
    75113    def commit(self): 
    76         self.connection.commit() 
     114        #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        #if self.connection: 
     125        #    try: 
     126        #        self.connection.rollback() 
     127        #    except Database.NotSupportedError: 
     128        #        pass 
     129        id = threading.currentThread() 
     130        self.__lock.reader_enters()  
     131        try:  
     132           if id in self.__connections:  
     133                try:  
     134                    self.__connections[id].rollback()  
     135                except Database.NotSupportedError:  
     136                    pass  
     137        finally:  
     138            self.__lock.reader_leaves()  
    84139 
    85140    def close(self): 
    86         if self.connection is not None: 
    87             self.connection.close() 
    88             self.connection = None 
    89  
     141        #if self.connection is not None: 
     142        #    self.connection.close() 
     143        #    self.connection = None 
     144        id = threading.currentThread()  
     145        self.__lock.writer_enters()  
     146        try:  
     147            if id in self.__connections:  
     148                self.__connections[id].close()  
     149                del self.__connections[id]  
     150        finally:  
     151            self.__lock.writer_leaves()  
    90152    def quote_name(self, name): 
    91153        if name.startswith("`") and name.endswith("`"): 
    92154            return name # Quoting once is enough.