source: trunk/src/allmydata/util/dbutil.py

Last change on this file was 1cfe843d, checked in by Alexandre Detiste <alexandre.detiste@…>, at 2024-02-22T23:40:25Z

more python2 removal

  • Property mode set to 100644
File size: 2.0 KB
Line 
1"""
2SQLite3 utilities.
3
4Test coverage currently provided by test_backupdb.py.
5
6Ported to Python 3.
7"""
8
9import os, sys
10
11import sqlite3
12
13
14class DBError(Exception):
15    pass
16
17
18def get_db(dbfile, stderr=sys.stderr,
19           create_version=(None, None), updaters=None, just_create=False, dbname="db",
20           ):
21    """Open or create the given db file. The parent directory must exist.
22    create_version=(SCHEMA, VERNUM), and SCHEMA must have a 'version' table.
23    Updaters is a {newver: commands} mapping, where e.g. updaters[2] is used
24    to get from ver=1 to ver=2. Returns a (sqlite3,db) tuple, or raises
25    DBError.
26    """
27    if updaters is None:
28        updaters = {}
29    must_create = not os.path.exists(dbfile)
30    try:
31        db = sqlite3.connect(dbfile)
32    except (EnvironmentError, sqlite3.OperationalError) as e:
33        raise DBError("Unable to create/open %s file %s: %s" % (dbname, dbfile, e))
34
35    schema, target_version = create_version
36    c = db.cursor()
37
38    # Enabling foreign keys allows stricter integrity checking.
39    # The default is unspecified according to <http://www.sqlite.org/foreignkeys.html#fk_enable>.
40    c.execute("PRAGMA foreign_keys = ON;")
41
42    if must_create:
43        c.executescript(schema)
44        c.execute("INSERT INTO version (version) VALUES (?)", (target_version,))
45        db.commit()
46
47    try:
48        c.execute("SELECT version FROM version")
49        version = c.fetchone()[0]
50    except sqlite3.DatabaseError as e:
51        # this indicates that the file is not a compatible database format.
52        # Perhaps it was created with an old version, or it might be junk.
53        raise DBError("%s file is unusable: %s" % (dbname, e))
54
55    if just_create: # for tests
56        return (sqlite3, db)
57
58    while version < target_version and version+1 in updaters:
59        c.executescript(updaters[version+1])
60        db.commit()
61        version = version+1
62    if version != target_version:
63        raise DBError("Unable to handle %s version %s" % (dbname, version))
64
65    return (sqlite3, db)
66
67
Note: See TracBrowser for help on using the repository browser.