1 # $Id: back_sqlite.py,v 1.12 2003-11-12 01:00:58 richard Exp $
2 __doc__ = '''
3 See https://pysqlite.sourceforge.net/ for pysqlite info
4 '''
5 import os, base64, marshal
7 from roundup import hyperdb
8 from roundup.backends import rdbms_common
9 from roundup.backends import locking
10 import sqlite
12 class Database(rdbms_common.Database):
13 # char to use for positional arguments
14 arg = '%s'
16 def sql_open_connection(self):
17 # ensure files are group readable and writable
18 os.umask(0002)
19 db = os.path.join(self.config.DATABASE, 'db')
21 # lock it
22 lockfilenm = db[:-3] + 'lck'
23 self.lockfile = locking.acquire_lock(lockfilenm)
24 self.lockfile.write(str(os.getpid()))
25 self.lockfile.flush()
27 self.conn = sqlite.connect(db=db)
28 self.cursor = self.conn.cursor()
29 try:
30 self.database_schema = self.load_dbschema()
31 except sqlite.DatabaseError, error:
32 if str(error) != 'no such table: schema':
33 raise
34 self.database_schema = {}
35 self.cursor.execute('create table schema (schema varchar)')
36 self.cursor.execute('create table ids (name varchar, num integer)')
37 self.cursor.execute('create index ids_name_idx on ids(name)')
39 def sql_close(self):
40 ''' Squash any error caused by us already having closed the
41 connection.
42 '''
43 try:
44 self.conn.close()
45 except sqlite.ProgrammingError, value:
46 if str(value) != 'close failed - Connection is closed.':
47 raise
49 def sql_rollback(self):
50 ''' Squash any error caused by us having closed the connection (and
51 therefore not having anything to roll back)
52 '''
53 try:
54 self.conn.rollback()
55 except sqlite.ProgrammingError, value:
56 if str(value) != 'rollback failed - Connection is closed.':
57 raise
59 def __repr__(self):
60 return '<roundlite 0x%x>'%id(self)
62 def sql_commit(self):
63 ''' Actually commit to the database.
65 Ignore errors if there's nothing to commit.
66 '''
67 try:
68 self.conn.commit()
69 except sqlite.DatabaseError, error:
70 if str(error) != 'cannot commit - no transaction is active':
71 raise
73 def sql_index_exists(self, table_name, index_name):
74 self.cursor.execute('pragma index_list(%s)'%table_name)
75 for entry in self.cursor.fetchall():
76 if entry[1] == index_name:
77 return 1
78 return 0
80 class sqliteClass:
81 def filter(self, search_matches, filterspec, sort=(None,None),
82 group=(None,None)):
83 ''' If there's NO matches to a fetch, sqlite returns NULL
84 instead of nothing
85 '''
86 return filter(None, rdbms_common.Class.filter(self, search_matches,
87 filterspec, sort=sort, group=group))
89 class Class(sqliteClass, rdbms_common.Class):
90 pass
92 class IssueClass(sqliteClass, rdbms_common.IssueClass):
93 pass
95 class FileClass(sqliteClass, rdbms_common.FileClass):
96 pass