Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

I think I've seen this ORM somewhere before...

Changeset 374

Show
Ignore:
Timestamp:
01/01/07 04:33:53
Author:
fumanchu
Message:

Folded the sqlite3 module back into storesqlite.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/doc/storage.html

    r373 r374  
    125125</ul> 
    126126 
    127 <h5>SQLite (pysqlite)</h5> 
     127<h5>SQLite (pysqlite/sqlite3)</h5> 
    128128<p>This class was developed against 
    129129    sqlite 3.0.8 (pysqlite-1.1.6.win32-py2.3), 
    130     and also tested on 
    131130    sqlite 3.3.3 (pysqlite-1.1.7.win32-py2.4), 
    132     sqlite 2.8.15-3 on Debian "sarge". 
     131    sqlite 2.8.15-3 on Debian "sarge", 
     132    and sqlite 3.3.4 (python 2.5 on win2k). 
     133    If you have Python 2.5 or later, the builtin _sqlite3 library 
     134    will be used; otherwise, you need to install pysqlite 1.x. 
    133135    Configuration entries:</p> 
    134136<ul> 
     
    139141</ul> 
    140142 
    141 <h5>SQLite 3 (built into Python 2.5+)</h5> 
    142 <p>This class was developed against sqlite 3.3.4 (python 2.5). 
    143     Configuration entries:</p> 
    144 <ul> 
    145     <li><b>Class:</b> "sqlite3" (<tt>dejavu.storage.storesqlite3.StorageManagerSQLite3</tt>)</li> 
    146     <li><b>Database:</b> Filename of the database. May be a relative path. 
    147         If the DB does not already exist, it will be created.</li> 
    148     <li><b>Mode:</b> Optional. DB file mode. Defaults to 0755.</li> 
    149 </ul> 
    150143 
    151144<h5>Firebird (kinterbasdb)</h5> 
     
    155148    Configuration entries:</p> 
    156149<ul> 
    157     <li><b>Class:</b> "sqlite" (<tt>dejavu.storage.storesqlite.StorageManagerSQLite</tt>)</li> 
     150    <li><b>Class:</b> "firebird" (<tt>dejavu.storage.storefirebird.StorageManagerFirebird</tt>)</li> 
    158151    <li><b>Name:</b> Filename of the database. Must be an absolute path.</li> 
    159152    <li><b>Host:</b> The TCP host name, usually "localhost".</li> 
  • trunk/storage/__init__.py

    r373 r374  
    472472    "shelve": "dejavu.storage.storeshelve.StorageManagerShelve", 
    473473    "sqlite": "dejavu.storage.storesqlite.StorageManagerSQLite", 
    474     "sqlite3": "dejavu.storage.storesqlite3.StorageManagerSQLite3", 
    475474    "sqlserver": "dejavu.storage.storeado.StorageManagerADO_SQLServer", 
    476475    } 
  • trunk/storage/storesqlite.py

    r373 r374  
    88from dejavu.storage import db 
    99 
    10 # Use _sqlite directly to avoid all of the DB-API overhead. 
    11 # This will import the "old API for SQLite 3.x", using e.g. pysqlite 1.1.7 
    12 import _sqlite 
    13  
    14 _version = storage.Version(_sqlite.sqlite_version()) 
     10try: 
     11    # Use _sqlite3 directly to avoid all of the DB-API overhead. 
     12    # This assumes the one built into Python 2.5+ 
     13    import _sqlite3 as _sqlite 
     14    _version = storage.Version(_sqlite.sqlite_version) 
     15    _cursor_required = True 
     16    _fetchall_required = True 
     17    _lastrowid_support = True 
     18except ImportError: 
     19    # Use _sqlite directly to avoid all of the DB-API overhead. 
     20    # This will import the "old API for SQLite 3.x", 
     21    # using e.g. pysqlite 1.1.7 
     22    import _sqlite 
     23    _version = storage.Version(_sqlite.sqlite_version()) 
     24    _cursor_required = False 
     25    _fetchall_required = False 
     26    _lastrowid_support = False 
     27 
    1528 
    1629# ESCAPE keyword was added Nov 2004, 1 month after 3.0.8 release. 
     
    442455     
    443456    def _get_columns(self, tablename, conn=None): 
    444 ##        # type, name, tbl_name, rootpage, sql 
    445 ##        data, _ = self.fetch("SELECT * FROM sqlite_master;", conn=conn) 
    446          
    447457        # cid, name, type, notnull, dflt_value, pk 
    448458        data, _ = self.fetch("PRAGMA table_info(%s);" % tablename, conn=conn) 
     
    605615        return "[" + name + "]" 
    606616     
    607     def _get_conn(self): 
    608         # SQLite should create the DB if missing. 
    609         return _sqlite.connect(self.name, self.mode) 
     617    if _cursor_required: 
     618        def _get_conn(self): 
     619            # SQLite should create the DB if missing. 
     620            conn = _sqlite.connect(self.name, self.mode, check_same_thread=False) 
     621            conn.isolation_level = None 
     622            conn.text_factory = str 
     623            return conn.cursor() 
     624    else: 
     625        def _get_conn(self): 
     626            return _sqlite.connect(self.name, self.mode) 
    610627     
    611628    create_database = _get_conn 
     
    652669                    try: 
    653670                        return conn.execute(query) 
    654                         #           ^^^^^^^ 
    655                     except _sqlite.OperationalError, x: 
    656                         if x.args[0] == 'database is locked': 
     671                    except (_sqlite.OperationalError, _sqlite.DatabaseError), x: 
     672                        msg = x.args[0] 
     673                        if msg == 'database is locked': 
    657674                            time.sleep(0.000001) 
    658675                            continue 
    659                     except _sqlite.DatabaseError, x: 
    660                         msg = x.args[0] 
    661                         if (msg.startswith("no such") or 
     676                        elif (msg.startswith("no such") or 
    662677                            msg == "database schema has changed"): 
    663678                            # Bah. Shut down all connections and get a new one, 
     
    674689        finally: 
    675690            self.release() 
     691     
     692    def fetch(self, query, conn=None): 
     693        """Return rowdata, columns (name, type) for the given query. 
     694         
     695        query should be a SQL query in string format 
     696        rowdata will be an iterable of iterables containing the result values. 
     697        columns will be an iterable of (column name, data type) pairs. 
     698        """ 
     699        if _fetchall_required: 
     700            res = self.execute(query, conn) 
     701            data = res.fetchall() 
     702            coldefs = [(c[0], c[1]) for c in res.description] 
     703            return data, coldefs 
     704        else: 
     705            res = self.execute(query, conn) 
     706            return res.row_list, res.col_defs 
    676707 
    677708 
     
    798829        values = ", ".join(values) 
    799830         
    800         # Use the same conn for INSERT and last_insert_rowid 
     831        # Use the same conn for INSERT and last row id 
    801832        conn = self.db.get_transaction() 
    802833        self.db.execute('INSERT INTO %s (%s) VALUES (%s);' % 
     
    804835         
    805836        # Grab the new ID. This is safe because db.reserve has a mutex. 
    806         new_id = conn.sqlite_last_insert_rowid() 
     837        if _lastrowid_support: 
     838            new_id = conn.lastrowid 
     839        else: 
     840            new_id = conn.sqlite_last_insert_rowid() 
    807841        setattr(unit, cls.identifiers[0], new_id) 
    808842     
  • trunk/test/test.py

    r373 r374  
    102102        'test_storeshelve', 
    103103        'test_storesqlite', 
    104         'test_storesqlite3', 
    105104        'test_storesqlserver', 
    106105    ] 
  • trunk/test/test_storesqlite.py

    r373 r374  
    11 
     2_sqlite = None 
    23try: 
    3     import _sqlite 
     4    # Use _sqlite3 directly to avoid all of the DB-API overhead. 
     5    # This assumes the one built into Python 2.5+ 
     6    import _sqlite3 as _sqlite 
    47except ImportError: 
    5     def run(): 
    6         import warnings 
    7         warnings.warn("The _sqlite module could not be imported. " 
    8                       "The SQLite test will not be run.") 
    9 else: 
     8    try: 
     9        # Use _sqlite directly to avoid all of the DB-API overhead. 
     10        # This will import the "old API for SQLite 3.x", 
     11        # using e.g. pysqlite 1.1.7 
     12        import _sqlite 
     13    except ImportError: 
     14        def run(): 
     15            import warnings 
     16            warnings.warn("The _sqlite module could not be imported. " 
     17                          "The SQLite test will not be run.") 
     18 
     19if _sqlite: 
    1020    SM_class = "sqlite" 
    1121    opts = {"Database": "sqlite_zoo_test"}