comparison roundup/backends/rdbms_common.py @ 1840:91a4619b1a14

hyperdb grows a refresh_database() method. There will be a future roundup-admin command to invoke this. XXXX Unit tests do _not_ cover large slabs of the hyperdb backend code, it seems. :-(
author Anthony Baxter <anthonybaxter@users.sourceforge.net>
date Tue, 07 Oct 2003 11:58:58 +0000
parents 532f51a2c741
children f63aa57386b0
comparison
equal deleted inserted replaced
1839:06f5b36b201b 1840:91a4619b1a14
1 # $Id: rdbms_common.py,v 1.64 2003-10-07 08:34:58 anthonybaxter Exp $ 1 # $Id: rdbms_common.py,v 1.65 2003-10-07 11:58:58 anthonybaxter 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
143 self.reindex() 143 self.reindex()
144 144
145 # commit 145 # commit
146 self.conn.commit() 146 self.conn.commit()
147 147
148 def refresh_database(self):
149 # now detect changes in the schema
150 for classname, spec in self.classes.items():
151 dbspec = self.database_schema[classname]
152 self.update_class(spec, dbspec, force=1)
153 self.database_schema[classname] = spec.schema()
154 # update the database version of the schema
155 self.sql('delete from schema')
156 self.save_dbschema(self.database_schema)
157 # reindex the db
158 self.reindex()
159 # commit
160 self.conn.commit()
161
162
148 def reindex(self): 163 def reindex(self):
149 for klass in self.classes.values(): 164 for klass in self.classes.values():
150 for nodeid in klass.list(): 165 for nodeid in klass.list():
151 klass.index(nodeid) 166 klass.index(nodeid)
152 self.indexer.save_index() 167 self.indexer.save_index()
168 else: 183 else:
169 cols.append('_'+col) 184 cols.append('_'+col)
170 cols.sort() 185 cols.sort()
171 return cols, mls 186 return cols, mls
172 187
173 def update_class(self, spec, old_spec): 188 def update_class(self, spec, old_spec, force=0):
174 ''' Determine the differences between the current spec and the 189 ''' Determine the differences between the current spec and the
175 database version of the spec, and update where necessary 190 database version of the spec, and update where necessary.
191 If 'force' is true, update the database anyway.
176 ''' 192 '''
177 new_spec = spec 193 new_spec = spec
178 new_has = new_spec.properties.has_key 194 new_has = new_spec.properties.has_key
179 195
180 new_spec = new_spec.schema() 196 new_spec = new_spec.schema()
181 new_spec[1].sort() 197 new_spec[1].sort()
182 old_spec[1].sort() 198 old_spec[1].sort()
183 if new_spec == old_spec: 199 if not force and new_spec == old_spec:
184 # no changes 200 # no changes
185 return 0 201 return 0
186 202
187 if __debug__: 203 if __debug__:
188 print >>hyperdb.DEBUG, 'update_class FIRING' 204 print >>hyperdb.DEBUG, 'update_class FIRING'
189 205
190 # key property changed? 206 # key property changed?
191 if old_spec[0] != new_spec[0]: 207 if force or old_spec[0] != new_spec[0]:
192 if __debug__: 208 if __debug__:
193 print >>hyperdb.DEBUG, 'update_class setting keyprop', `spec[0]` 209 print >>hyperdb.DEBUG, 'update_class setting keyprop', `spec[0]`
194 # XXX turn on indexing for the key property. 210 # XXX turn on indexing for the key property.
211 index_sql = 'drop index _%s_%s_idx'%(
212 spec.classname, old_spec[0])
213 if __debug__:
214 print >>hyperdb.DEBUG, 'drop_index', (self, index_sql)
215 try:
216 self.cursor.execute(index_sql1)
217 except:
218 # Hackage. Until we update the schema to include some
219 # backend-specific knowledge, assume that this might fail.
220 pass
221
222 index_sql = 'create index _%s_%s_idx on _%s(%s)'%(
223 spec.classname, new_spec[0],
224 spec.classname, new_spec[0])
225 if __debug__:
226 print >>hyperdb.DEBUG, 'create_index', (self, index_sql)
227 self.cursor.execute(index_sql1)
195 228
196 # detect multilinks that have been removed, and drop their table 229 # detect multilinks that have been removed, and drop their table
197 old_has = {} 230 old_has = {}
198 for name,prop in old_spec[1]: 231 for name,prop in old_spec[1]:
199 old_has[name] = 1 232 old_has[name] = 1
200 if not new_has(name) and isinstance(prop, Multilink): 233 if (force or not new_has(name)) and isinstance(prop, Multilink):
201 # it's a multilink, and it's been removed - drop the old 234 # it's a multilink, and it's been removed - drop the old
202 # table. First drop indexes. 235 # table. First drop indexes.
203 index_sqls = [ 'drop index %s_%s_l_idx'%(spec.classname, ml), 236 index_sqls = [ 'drop index %s_%s_l_idx'%(spec.classname, ml),
204 'drop index %s_%s_n_idx'%(spec.classname, ml) ] 237 'drop index %s_%s_n_idx'%(spec.classname, ml) ]
205 for index_sql in index_sqls: 238 for index_sql in index_sqls:
222 fetch = ['_activity', '_creation', '_creator'] 255 fetch = ['_activity', '_creation', '_creator']
223 properties = spec.getprops() 256 properties = spec.getprops()
224 for propname,x in new_spec[1]: 257 for propname,x in new_spec[1]:
225 prop = properties[propname] 258 prop = properties[propname]
226 if isinstance(prop, Multilink): 259 if isinstance(prop, Multilink):
227 if not old_has(propname): 260 if force or not old_has(propname):
228 # we need to create the new table 261 # we need to create the new table
229 self.create_multilink_table(spec, propname) 262 self.create_multilink_table(spec, propname)
230 elif old_has(propname): 263 elif old_has(propname):
231 # we copy this col over from the old table 264 # we copy this col over from the old table
232 fetch.append('_'+propname) 265 fetch.append('_'+propname)

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