|
1 | | -# $Id: back_gadfly.py,v 1.31.2.1 2003-01-12 23:57:15 richard Exp $ |
| 1 | +# $Id: back_gadfly.py,v 1.31.2.2 2003-03-09 21:44:15 richard Exp $ |
2 | 2 | ''' Gadlfy relational database hypderb backend. |
3 | 3 |
|
4 | 4 | About Gadfly |
@@ -144,6 +144,95 @@ def load_journal(self, classname, cols, nodeid): |
144 | 144 | res.append((nodeid, date.Date(date_stamp), user, action, params)) |
145 | 145 | return res |
146 | 146 |
|
| 147 | + def update_class(self, spec, old_spec): |
| 148 | + ''' Determine the differences between the current spec and the |
| 149 | + database version of the spec, and update where necessary |
| 150 | +
|
| 151 | + GADFLY requires a commit after the table drop! |
| 152 | + ''' |
| 153 | + new_spec = spec |
| 154 | + new_has = new_spec.properties.has_key |
| 155 | + |
| 156 | + new_spec = new_spec.schema() |
| 157 | + if new_spec == old_spec: |
| 158 | + # no changes |
| 159 | + return 0 |
| 160 | + |
| 161 | + if __debug__: |
| 162 | + print >>hyperdb.DEBUG, 'update_class FIRING' |
| 163 | + |
| 164 | + # key property changed? |
| 165 | + if old_spec[0] != new_spec[0]: |
| 166 | + if __debug__: |
| 167 | + print >>hyperdb.DEBUG, 'update_class setting keyprop', `spec[0]` |
| 168 | + # XXX turn on indexing for the key property |
| 169 | + |
| 170 | + # detect multilinks that have been removed, and drop their table |
| 171 | + old_has = {} |
| 172 | + for name,prop in old_spec[1]: |
| 173 | + old_has[name] = 1 |
| 174 | + if not new_has(name) and isinstance(prop, Multilink): |
| 175 | + # it's a multilink, and it's been removed - drop the old |
| 176 | + # table |
| 177 | + sql = 'drop table %s_%s'%(spec.classname, prop) |
| 178 | + if __debug__: |
| 179 | + print >>hyperdb.DEBUG, 'update_class', (self, sql) |
| 180 | + self.cursor.execute(sql) |
| 181 | + continue |
| 182 | + old_has = old_has.has_key |
| 183 | + |
| 184 | + # now figure how we populate the new table |
| 185 | + fetch = ['_activity', '_creation', '_creator'] |
| 186 | + properties = spec.getprops() |
| 187 | + for propname,x in new_spec[1]: |
| 188 | + prop = properties[propname] |
| 189 | + if isinstance(prop, Multilink): |
| 190 | + if not old_has(propname): |
| 191 | + # we need to create the new table |
| 192 | + self.create_multilink_table(spec, propname) |
| 193 | + elif old_has(propname): |
| 194 | + # we copy this col over from the old table |
| 195 | + fetch.append('_'+propname) |
| 196 | + |
| 197 | + # select the data out of the old table |
| 198 | + fetch.append('id') |
| 199 | + fetch.append('__retired__') |
| 200 | + fetchcols = ','.join(fetch) |
| 201 | + cn = spec.classname |
| 202 | + sql = 'select %s from _%s'%(fetchcols, cn) |
| 203 | + if __debug__: |
| 204 | + print >>hyperdb.DEBUG, 'update_class', (self, sql) |
| 205 | + self.cursor.execute(sql) |
| 206 | + olddata = self.cursor.fetchall() |
| 207 | + |
| 208 | + # drop the old table |
| 209 | + self.cursor.execute('drop table _%s'%cn) |
| 210 | + |
| 211 | + # GADFLY requires a commit here, or the table spec screws up |
| 212 | + self.conn.commit() |
| 213 | + |
| 214 | + # create the new table |
| 215 | + cols, mls = self.create_class_table(spec) |
| 216 | + |
| 217 | + # figure the new columns |
| 218 | + extra = 0 |
| 219 | + for col in cols: |
| 220 | + if col not in fetch: |
| 221 | + fetch.append(col) |
| 222 | + extra += 1 |
| 223 | + |
| 224 | + if olddata: |
| 225 | + # do the insert |
| 226 | + fetchcols = ','.join(fetch) |
| 227 | + args = ','.join([self.arg for x in fetch]) |
| 228 | + sql = 'insert into _%s (%s) values (%s)'%(cn, fetchcols, args) |
| 229 | + if __debug__: |
| 230 | + print >>hyperdb.DEBUG, 'update_class', (self, sql, olddata[0]) |
| 231 | + for entry in olddata: |
| 232 | + self.cursor.execute(sql, tuple(entry) + (None,)*extra) |
| 233 | + |
| 234 | + return 1 |
| 235 | + |
147 | 236 | class GadflyClass: |
148 | 237 | def filter(self, search_matches, filterspec, sort=(None,None), |
149 | 238 | group=(None,None)): |
|
0 commit comments