comparison roundup/backends/rdbms_common.py @ 2417:fe722c32ce0c maint-0.7

merge from HEAD
author Richard Jones <richard@users.sourceforge.net>
date Wed, 09 Jun 2004 06:16:56 +0000
parents 1ccfcfeca61b
children e4f06fcbbc89
comparison
equal deleted inserted replaced
2408:e12a610eb7f3 2417:fe722c32ce0c
1 # $Id: rdbms_common.py,v 1.98.2.5 2004-05-29 02:09:13 richard Exp $ 1 # $Id: rdbms_common.py,v 1.98.2.6 2004-06-09 06:16:56 richard Exp $
2 ''' Relational database (SQL) backend common code. 2 ''' Relational database (SQL) backend common code.
3 3
4 Basics: 4 Basics:
5 5
6 - map roundup classes to relational tables 6 - map roundup classes to relational tables
141 if schema: 141 if schema:
142 self.database_schema = eval(schema[0]) 142 self.database_schema = eval(schema[0])
143 else: 143 else:
144 self.database_schema = {} 144 self.database_schema = {}
145 145
146 def save_dbschema(self, schema): 146 def save_dbschema(self):
147 ''' Save the schema definition that the database currently implements 147 ''' Save the schema definition that the database currently implements
148 ''' 148 '''
149 s = repr(self.database_schema) 149 s = repr(self.database_schema)
150 self.sql('delete from schema')
150 self.sql('insert into schema values (%s)', (s,)) 151 self.sql('insert into schema values (%s)', (s,))
151 152
152 def post_init(self): 153 def post_init(self):
153 ''' Called once the schema initialisation has finished. 154 ''' Called once the schema initialisation has finished.
154 155
176 del tables[classname] 177 del tables[classname]
177 save = 1 178 save = 1
178 179
179 # update the database version of the schema 180 # update the database version of the schema
180 if save: 181 if save:
181 self.sql('delete from schema') 182 self.save_dbschema()
182 self.save_dbschema(self.database_schema)
183 183
184 # reindex the db if necessary 184 # reindex the db if necessary
185 if self.indexer.should_reindex(): 185 if self.indexer.should_reindex():
186 self.reindex() 186 self.reindex()
187 187
188 # commit 188 # commit
189 self.sql_commit() 189 self.sql_commit()
190 190
191 # update this number when we need to make changes to the SQL structure 191 # update this number when we need to make changes to the SQL structure
192 # of the backen database 192 # of the backen database
193 current_db_version = 2 193 current_db_version = 3
194 def upgrade_db(self): 194 def upgrade_db(self):
195 ''' Update the SQL database to reflect changes in the backend code. 195 ''' Update the SQL database to reflect changes in the backend code.
196 196
197 Return boolean whether we need to save the schema. 197 Return boolean whether we need to save the schema.
198 ''' 198 '''
211 211
212 # version 1 doesn't have the OTK, session and indexing in the 212 # version 1 doesn't have the OTK, session and indexing in the
213 # database 213 # database
214 self.create_version_2_tables() 214 self.create_version_2_tables()
215 215
216 if version == 2:
217 self.fix_version_2_tables()
218
216 self.database_schema['version'] = self.current_db_version 219 self.database_schema['version'] = self.current_db_version
217 return 1 220 return 1
218 221
222 def fix_version_2_tables(self):
223 '''Default (used by sqlite): NOOP'''
224 pass
225
226 def _convert_journal_tables(self):
227 '''Get current journal table contents, drop the table and re-create'''
228 c = self.cursor
229 cols = ','.join('nodeid date tag action params'.split())
230 for klass in self.classes.values():
231 # slurp and drop
232 sql = 'select %s from %s__journal order by date'%(cols,
233 klass.classname)
234 c.execute(sql)
235 contents = c.fetchall()
236 self.drop_journal_table_indexes(klass.classname)
237 c.execute('drop table %s__journal'%klass.classname)
238
239 # re-create and re-populate
240 self.create_journal_table(klass)
241 a = self.arg
242 sql = 'insert into %s__journal (%s) values (%s,%s,%s,%s,%s)'%(
243 klass.classname, cols, a, a, a, a, a)
244 for row in contents:
245 # no data conversion needed
246 self.cursor.execute(sql, row)
247
248 def _convert_string_properties(self):
249 '''Get current Class tables that contain String properties, and
250 convert the VARCHAR columns to TEXT'''
251 c = self.cursor
252 for klass in self.classes.values():
253 # slurp and drop
254 cols, mls = self.determine_columns(klass.properties.items())
255 scols = ','.join([i[0] for i in cols])
256 sql = 'select id,%s from _%s'%(scols, klass.classname)
257 c.execute(sql)
258 contents = c.fetchall()
259 self.drop_class_table_indexes(klass.classname, klass.getkey())
260 c.execute('drop table _%s'%klass.classname)
261
262 # re-create and re-populate
263 self.create_class_table(klass, create_sequence=False)
264 a = ','.join([self.arg for i in range(len(cols)+1)])
265 sql = 'insert into _%s (id,%s) values (%s)'%(klass.classname,
266 scols, a)
267 for row in contents:
268 l = []
269 for entry in row:
270 # mysql will already be a string - psql needs "help"
271 if entry is not None and not isinstance(entry, type('')):
272 entry = str(entry)
273 l.append(entry)
274 self.cursor.execute(sql, l)
219 275
220 def refresh_database(self): 276 def refresh_database(self):
221 self.post_init() 277 self.post_init()
222 278
223 def reindex(self): 279 def reindex(self):
225 for nodeid in klass.list(): 281 for nodeid in klass.list():
226 klass.index(nodeid) 282 klass.index(nodeid)
227 self.indexer.save_index() 283 self.indexer.save_index()
228 284
229 hyperdb_to_sql_datatypes = { 285 hyperdb_to_sql_datatypes = {
230 hyperdb.String : 'VARCHAR(255)', 286 hyperdb.String : 'TEXT',
231 hyperdb.Date : 'TIMESTAMP', 287 hyperdb.Date : 'TIMESTAMP',
232 hyperdb.Link : 'INTEGER', 288 hyperdb.Link : 'INTEGER',
233 hyperdb.Interval : 'VARCHAR(255)', 289 hyperdb.Interval : 'VARCHAR(255)',
234 hyperdb.Password : 'VARCHAR(255)', 290 hyperdb.Password : 'VARCHAR(255)',
235 hyperdb.Boolean : 'BOOLEAN', 291 hyperdb.Boolean : 'BOOLEAN',
464 def create_multilink_table(self, spec, ml): 520 def create_multilink_table(self, spec, ml):
465 ''' Create a multilink table for the "ml" property of the class 521 ''' Create a multilink table for the "ml" property of the class
466 given by the spec 522 given by the spec
467 ''' 523 '''
468 # create the table 524 # create the table
469 sql = 'create table %s_%s (linkid varchar, nodeid varchar)'%( 525 sql = 'create table %s_%s (linkid varchar(255), nodeid varchar(255))'%(
470 spec.classname, ml) 526 spec.classname, ml)
471 if __debug__: 527 if __debug__:
472 print >>hyperdb.DEBUG, 'create_class', (self, sql) 528 print >>hyperdb.DEBUG, 'create_class', (self, sql)
473 self.cursor.execute(sql) 529 self.cursor.execute(sql)
474 self.create_multilink_table_indexes(spec, ml) 530 self.create_multilink_table_indexes(spec, ml)
1090 return self.cursor.fetchall() 1146 return self.cursor.fetchall()
1091 1147
1092 def pack(self, pack_before): 1148 def pack(self, pack_before):
1093 ''' Delete all journal entries except "create" before 'pack_before'. 1149 ''' Delete all journal entries except "create" before 'pack_before'.
1094 ''' 1150 '''
1095 # get a 'yyyymmddhhmmss' version of the date 1151 date_stamp = self.hyperdb_to_sql_value[Date](pack_before)
1096 date_stamp = pack_before.serialise()
1097 1152
1098 # do the delete 1153 # do the delete
1099 for classname in self.classes.keys(): 1154 for classname in self.classes.keys():
1100 sql = "delete from %s__journal where date<%s and "\ 1155 sql = "delete from %s__journal where date<%s and "\
1101 "action<>'create'"%(classname, self.arg) 1156 "action<>'create'"%(classname, self.arg)

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