comparison roundup/backends/back_sqlite.py @ 2514:091711fb2f8c

Initial logging integration: replace all debug prints with logging calls... ...clean up and replace some with info() logs.
author Richard Jones <richard@users.sourceforge.net>
date Fri, 02 Jul 2004 05:22:09 +0000
parents 31cb1014300c
children a9e1fff1e793
comparison
equal deleted inserted replaced
2512:f5542d92307a 2514:091711fb2f8c
1 # $Id: back_sqlite.py,v 1.29 2004-05-28 01:09:11 richard Exp $ 1 # $Id: back_sqlite.py,v 1.30 2004-07-02 05:22:09 richard Exp $
2 '''Implements a backend for SQLite. 2 '''Implements a backend for SQLite.
3 3
4 See https://pysqlite.sourceforge.net/ for pysqlite info 4 See https://pysqlite.sourceforge.net/ for pysqlite info
5 5
6 6
53 '''Open a standard, non-autocommitting connection. 53 '''Open a standard, non-autocommitting connection.
54 54
55 pysqlite will automatically BEGIN TRANSACTION for us. 55 pysqlite will automatically BEGIN TRANSACTION for us.
56 ''' 56 '''
57 db = os.path.join(self.config.DATABASE, 'db') 57 db = os.path.join(self.config.DATABASE, 'db')
58 self.config.logging.getLogger('hyperdb').info('open database %r'%db)
58 conn = sqlite.connect(db=db) 59 conn = sqlite.connect(db=db)
59 # set a 30 second timeout (extraordinarily generous) for handling 60 # set a 30 second timeout (extraordinarily generous) for handling
60 # locked database 61 # locked database
61 conn.db.sqlite_busy_timeout(30 * 1000) 62 conn.db.sqlite_busy_timeout(30 * 1000)
62 cursor = conn.cursor() 63 cursor = conn.cursor()
72 self.load_dbschema() 73 self.load_dbschema()
73 except sqlite.DatabaseError, error: 74 except sqlite.DatabaseError, error:
74 if str(error) != 'no such table: schema': 75 if str(error) != 'no such table: schema':
75 raise 76 raise
76 self.init_dbschema() 77 self.init_dbschema()
77 self.cursor.execute('create table schema (schema varchar)') 78 self.sql('create table schema (schema varchar)')
78 self.cursor.execute('create table ids (name varchar, num integer)') 79 self.sql('create table ids (name varchar, num integer)')
79 self.cursor.execute('create index ids_name_idx on ids(name)') 80 self.sql('create index ids_name_idx on ids(name)')
80 self.create_version_2_tables() 81 self.create_version_2_tables()
81 82
82 def create_version_2_tables(self): 83 def create_version_2_tables(self):
83 self.cursor.execute('create table otks (otk_key varchar, ' 84 self.sql('create table otks (otk_key varchar, '
84 'otk_value varchar, otk_time integer)') 85 'otk_value varchar, otk_time integer)')
85 self.cursor.execute('create index otks_key_idx on otks(otk_key)') 86 self.sql('create index otks_key_idx on otks(otk_key)')
86 self.cursor.execute('create table sessions (session_key varchar, ' 87 self.sql('create table sessions (session_key varchar, '
87 'session_time integer, session_value varchar)') 88 'session_time integer, session_value varchar)')
88 self.cursor.execute('create index sessions_key_idx on ' 89 self.sql('create index sessions_key_idx on '
89 'sessions(session_key)') 90 'sessions(session_key)')
90 91
91 # full-text indexing store 92 # full-text indexing store
92 self.cursor.execute('CREATE TABLE __textids (_class varchar, ' 93 self.sql('CREATE TABLE __textids (_class varchar, '
93 '_itemid varchar, _prop varchar, _textid integer primary key) ') 94 '_itemid varchar, _prop varchar, _textid integer primary key) ')
94 self.cursor.execute('CREATE TABLE __words (_word varchar, ' 95 self.sql('CREATE TABLE __words (_word varchar, '
95 '_textid integer)') 96 '_textid integer)')
96 self.cursor.execute('CREATE INDEX words_word_ids ON __words(_word)') 97 self.sql('CREATE INDEX words_word_ids ON __words(_word)')
97 sql = 'insert into ids (name, num) values (%s,%s)'%(self.arg, self.arg) 98 sql = 'insert into ids (name, num) values (%s,%s)'%(self.arg, self.arg)
98 self.cursor.execute(sql, ('__textids', 1)) 99 self.sql(sql, ('__textids', 1))
99 100
100 def add_new_columns_v2(self): 101 def add_new_columns_v2(self):
101 # update existing tables to have the new actor column 102 # update existing tables to have the new actor column
102 tables = self.database_schema['tables'] 103 tables = self.database_schema['tables']
103 for classname, spec in self.classes.items(): 104 for classname, spec in self.classes.items():
122 old_spec[1].sort() 123 old_spec[1].sort()
123 if not force and new_spec == old_spec: 124 if not force and new_spec == old_spec:
124 # no changes 125 # no changes
125 return 0 126 return 0
126 127
127 if __debug__: 128 self.config.logging.getLogger('hyperdb').info('update_class %s'%spec.classname)
128 print >>hyperdb.DEBUG, 'update_class FIRING for', spec.classname
129 129
130 # detect multilinks that have been removed, and drop their table 130 # detect multilinks that have been removed, and drop their table
131 old_has = {} 131 old_has = {}
132 for name, prop in old_spec[1]: 132 for name, prop in old_spec[1]:
133 old_has[name] = 1 133 old_has[name] = 1
135 continue 135 continue
136 # it's a multilink, and it's been removed - drop the old 136 # it's a multilink, and it's been removed - drop the old
137 # table. First drop indexes. 137 # table. First drop indexes.
138 self.drop_multilink_table_indexes(spec.classname, ml) 138 self.drop_multilink_table_indexes(spec.classname, ml)
139 sql = 'drop table %s_%s'%(spec.classname, prop) 139 sql = 'drop table %s_%s'%(spec.classname, prop)
140 if __debug__: 140 self.sql(sql)
141 print >>hyperdb.DEBUG, 'update_class', (self, sql)
142 self.cursor.execute(sql)
143 old_has = old_has.has_key 141 old_has = old_has.has_key
144 142
145 # now figure how we populate the new table 143 # now figure how we populate the new table
146 if adding_v2: 144 if adding_v2:
147 fetch = ['_activity', '_creation', '_creator'] 145 fetch = ['_activity', '_creation', '_creator']
156 self.create_multilink_table(spec, propname) 154 self.create_multilink_table(spec, propname)
157 elif force: 155 elif force:
158 tn = '%s_%s'%(spec.classname, propname) 156 tn = '%s_%s'%(spec.classname, propname)
159 # grabe the current values 157 # grabe the current values
160 sql = 'select linkid, nodeid from %s'%tn 158 sql = 'select linkid, nodeid from %s'%tn
161 if __debug__: 159 self.sql(sql)
162 print >>hyperdb.DEBUG, 'update_class', (self, sql)
163 self.cursor.execute(sql)
164 rows = self.cursor.fetchall() 160 rows = self.cursor.fetchall()
165 161
166 # drop the old table 162 # drop the old table
167 self.drop_multilink_table_indexes(spec.classname, propname) 163 self.drop_multilink_table_indexes(spec.classname, propname)
168 sql = 'drop table %s'%tn 164 sql = 'drop table %s'%tn
169 if __debug__: 165 self.sql(sql)
170 print >>hyperdb.DEBUG, 'migration', (self, sql)
171 self.cursor.execute(sql)
172 166
173 # re-create and populate the new table 167 # re-create and populate the new table
174 self.create_multilink_table(spec, propname) 168 self.create_multilink_table(spec, propname)
175 sql = '''insert into %s (linkid, nodeid) values 169 sql = '''insert into %s (linkid, nodeid) values
176 (%s, %s)'''%(tn, self.arg, self.arg) 170 (%s, %s)'''%(tn, self.arg, self.arg)
177 for linkid, nodeid in rows: 171 for linkid, nodeid in rows:
178 self.cursor.execute(sql, (int(linkid), int(nodeid))) 172 self.sql(sql, (int(linkid), int(nodeid)))
179 elif old_has(propname): 173 elif old_has(propname):
180 # we copy this col over from the old table 174 # we copy this col over from the old table
181 fetch.append('_'+propname) 175 fetch.append('_'+propname)
182 176
183 # select the data out of the old table 177 # select the data out of the old table
184 fetch.append('id') 178 fetch.append('id')
185 fetch.append('__retired__') 179 fetch.append('__retired__')
186 fetchcols = ','.join(fetch) 180 fetchcols = ','.join(fetch)
187 cn = spec.classname 181 cn = spec.classname
188 sql = 'select %s from _%s'%(fetchcols, cn) 182 sql = 'select %s from _%s'%(fetchcols, cn)
189 if __debug__: 183 self.sql(sql)
190 print >>hyperdb.DEBUG, 'update_class', (self, sql)
191 self.cursor.execute(sql)
192 olddata = self.cursor.fetchall() 184 olddata = self.cursor.fetchall()
193 185
194 # TODO: update all the other index dropping code 186 # TODO: update all the other index dropping code
195 self.drop_class_table_indexes(cn, old_spec[0]) 187 self.drop_class_table_indexes(cn, old_spec[0])
196 188
197 # drop the old table 189 # drop the old table
198 if __debug__: 190 self.sql('drop table _%s'%cn)
199 print >>hyperdb.DEBUG, 'update_class "drop table _%s"'%cn
200 self.cursor.execute('drop table _%s'%cn)
201 191
202 # create the new table 192 # create the new table
203 self.create_class_table(spec) 193 self.create_class_table(spec)
204 194
205 if olddata: 195 if olddata:
218 # do the insert of the old data - the new columns will have 208 # do the insert of the old data - the new columns will have
219 # NULL values 209 # NULL values
220 args = ','.join([self.arg for x in inscols]) 210 args = ','.join([self.arg for x in inscols])
221 cols = ','.join(inscols) 211 cols = ','.join(inscols)
222 sql = 'insert into _%s (%s) values (%s)'%(cn, cols, args) 212 sql = 'insert into _%s (%s) values (%s)'%(cn, cols, args)
223 if __debug__:
224 print >>hyperdb.DEBUG, 'update_class', (self, sql, olddata[0])
225 for entry in olddata: 213 for entry in olddata:
226 d = [] 214 d = []
227 for name in inscols: 215 for name in inscols:
228 # generate the new value for the Interval int column 216 # generate the new value for the Interval int column
229 if name.endswith('_int__'): 217 if name.endswith('_int__'):
235 elif entry.has_key(name): 223 elif entry.has_key(name):
236 v = entry[name] 224 v = entry[name]
237 else: 225 else:
238 v = None 226 v = None
239 d.append(v) 227 d.append(v)
240 self.cursor.execute(sql, tuple(d)) 228 self.sql(sql, tuple(d))
241 229
242 return 1 230 return 1
243 231
244 def sql_close(self): 232 def sql_close(self):
245 ''' Squash any error caused by us already having closed the 233 ''' Squash any error caused by us already having closed the
276 raise 264 raise
277 # open a new cursor for subsequent work 265 # open a new cursor for subsequent work
278 self.cursor = self.conn.cursor() 266 self.cursor = self.conn.cursor()
279 267
280 def sql_index_exists(self, table_name, index_name): 268 def sql_index_exists(self, table_name, index_name):
281 self.cursor.execute('pragma index_list(%s)'%table_name) 269 self.sql('pragma index_list(%s)'%table_name)
282 for entry in self.cursor.fetchall(): 270 for entry in self.cursor.fetchall():
283 if entry[1] == index_name: 271 if entry[1] == index_name:
284 return 1 272 return 1
285 return 0 273 return 0
286 274
288 def newid(self, classname): 276 def newid(self, classname):
289 ''' Generate a new id for the given class 277 ''' Generate a new id for the given class
290 ''' 278 '''
291 # get the next ID 279 # get the next ID
292 sql = 'select num from ids where name=%s'%self.arg 280 sql = 'select num from ids where name=%s'%self.arg
293 if __debug__: 281 self.sql(sql, (classname, ))
294 print >>hyperdb.DEBUG, 'newid', (self, sql, classname)
295 self.cursor.execute(sql, (classname, ))
296 newid = int(self.cursor.fetchone()[0]) 282 newid = int(self.cursor.fetchone()[0])
297 283
298 # update the counter 284 # update the counter
299 sql = 'update ids set num=%s where name=%s'%(self.arg, self.arg) 285 sql = 'update ids set num=%s where name=%s'%(self.arg, self.arg)
300 vals = (int(newid)+1, classname) 286 vals = (int(newid)+1, classname)
301 if __debug__: 287 self.sql(sql, vals)
302 print >>hyperdb.DEBUG, 'newid', (self, sql, vals)
303 self.cursor.execute(sql, vals)
304 288
305 # return as string 289 # return as string
306 return str(newid) 290 return str(newid)
307 291
308 def setid(self, classname, setid): 292 def setid(self, classname, setid):
310 294
311 We add one to make it behave like the seqeunces in postgres. 295 We add one to make it behave like the seqeunces in postgres.
312 ''' 296 '''
313 sql = 'update ids set num=%s where name=%s'%(self.arg, self.arg) 297 sql = 'update ids set num=%s where name=%s'%(self.arg, self.arg)
314 vals = (int(setid)+1, classname) 298 vals = (int(setid)+1, classname)
315 if __debug__: 299 self.sql(sql, vals)
316 print >>hyperdb.DEBUG, 'setid', (self, sql, vals)
317 self.cursor.execute(sql, vals)
318 300
319 def create_class(self, spec): 301 def create_class(self, spec):
320 rdbms_common.Database.create_class(self, spec) 302 rdbms_common.Database.create_class(self, spec)
321 sql = 'insert into ids (name, num) values (%s, %s)' 303 sql = 'insert into ids (name, num) values (%s, %s)'
322 vals = (spec.classname, 1) 304 vals = (spec.classname, 1)
323 if __debug__: 305 self.sql(sql, vals)
324 print >>hyperdb.DEBUG, 'create_class', (self, sql, vals)
325 self.cursor.execute(sql, vals)
326 306
327 class sqliteClass: 307 class sqliteClass:
328 def filter(self, search_matches, filterspec, sort=(None,None), 308 def filter(self, search_matches, filterspec, sort=(None,None),
329 group=(None,None)): 309 group=(None,None)):
330 ''' If there's NO matches to a fetch, sqlite returns NULL 310 ''' If there's NO matches to a fetch, sqlite returns NULL

Roundup Issue Tracker: http://roundup-tracker.org/