Contact: fumanchu@aminus.org

Log in as guest/geniusql to create tickets

Changeset 75

Show
Ignore:
Timestamp:
04/12/07 21:59:41
Author:
fumanchu
Message:

New conns.ConnectionPerThread? class (and new SQLiteDatabase.threadsafe attribute).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/geniusql/conns.py

    r74 r75  
    119119 
    120120 
     121class ConnectionPerThread(object): 
     122    """A database connection factory which uses one connection per thread. 
     123     
     124    This is useful for SQLite; from http://www.sqlite.org/c_interface.html: 
     125         
     126        "If SQLite is compiled with the THREADSAFE preprocessor macro set 
     127        to 1, then it is safe to use SQLite from two or more threads of 
     128        the same process at the same time. But each thread should have 
     129        its own sqlite* pointer returned from sqlite_open. It is never safe 
     130        for two or more threads to access the same sqlite* pointer at the 
     131        same time. 
     132         
     133        In precompiled SQLite libraries available on the website, the Unix 
     134        versions are compiled with THREADSAFE turned off but the windows 
     135        versions are compiled with THREADSAFE turned on. If you need 
     136        something different that this you will have to recompile." 
     137     
     138    See also http://www.sqlite.org/faq.html#q8 
     139    """ 
     140     
     141    def __init__(self, open, close, retry=5): 
     142        self.open = open 
     143        self.close = close 
     144        self.retry = retry 
     145        self.conns = {} 
     146     
     147    def __call__(self): 
     148        """Return the connection for the current thread.""" 
     149        threadid = threading._get_ident() 
     150        try: 
     151            return self.conns[threadid] 
     152        except KeyError: 
     153            for i in xrange(self.retry): 
     154                try: 
     155                    conn = self.open() 
     156                    self.conns[threadid] = conn 
     157                    return conn 
     158                except errors.OutOfConnectionsError: 
     159                    conn = None 
     160                    time.sleep(i + 1) 
     161            raise errors.OutOfConnectionsError() 
     162     
     163    def shutdown(self): 
     164        """Release all database connections.""" 
     165        # Empty the conn map. 
     166        while self.conns: 
     167            threadid, conn = self.conns.popitem() 
     168            self.close(conn) 
     169 
     170 
    121171class SingleConnection(object): 
    122172    """A single database connection for all consumers. 
  • trunk/geniusql/providers/sqlite.py

    r74 r75  
    11import datetime 
    22import os 
     3import sys 
    34import time 
    45 
     
    564565            # So we need to give :memory: databases a SingleConnection. 
    565566            self._factory = conns.SingleConnection(self._get_conn, self._del_conn) 
    566         else: 
     567        elif not self.db.threadsafe: 
     568            self._factory = conns.ConnectionPerThread(self._get_conn, self._del_conn) 
     569        else: 
     570            # Use the default behavior (pool) 
    567571            conns.ConnectionManager._set_factory(self) 
    568572     
     
    835839     
    836840    pks_must_be_indexed = False 
     841     
     842    # Based on SQLite FAQ: http://www.sqlite.org/faq.html#q8 
     843    # Override as needed. 
     844    threadsafe = ("win" in sys.platform) 
    837845     
    838846    def __init__(self, **kwargs):