@@ -191,83 +191,142 @@ def create_version_2_tables(self):
191191 self .cursor .execute (sql , ('__textids' , 1 ))
192192
193193 def add_actor_column (self ):
194- ''' While we're adding the actor column, we need to update the
194+ '''While we're adding the actor column, we need to update the
195195 tables to have the correct datatypes.'''
196- assert 0 , 'FINISH ME!'
197-
198- for spec in self .classes .values ():
199- new_has = spec .properties .has_key
200- new_spec = spec .schema ()
201- new_spec [1 ].sort ()
202- old_spec [1 ].sort ()
203- if not force and new_spec == old_spec :
204- # no changes
205- return 0
206-
207- if __debug__ :
208- print >> hyperdb .DEBUG , 'update_class FIRING'
209-
210- # detect multilinks that have been removed, and drop their table
211- old_has = {}
212- for name ,prop in old_spec [1 ]:
213- old_has [name ] = 1
214- if new_has (name ) or not isinstance (prop , hyperdb .Multilink ):
196+ for klass in self .classes .values ():
197+ cn = klass .classname
198+ properties = klass .getprops ()
199+ old_spec = self .database_schema ['tables' ][cn ]
200+
201+ execute = self .cursor .execute
202+
203+ # figure the non-Multilink properties to copy over
204+ propnames = ['activity' , 'creation' , 'creator' ]
205+
206+ # figure actions based on data type
207+ for name , s_prop in old_spec [1 ]:
208+ # s_prop is a repr() string of a hyperdb type object
209+ if s_prop .find ('Multilink' ) == - 1 :
210+ if properties .has_key (name ):
211+ propnames .append (name )
215212 continue
216- # it's a multilink, and it's been removed - drop the old
217- # table. First drop indexes.
218- self .drop_multilink_table_indexes (spec .classname , ml )
219- sql = 'drop table %s_%s' % (spec .classname , prop )
213+ tn = '%s_%s' % (cn , name )
214+
215+ if properties .has_key (name ):
216+ # grabe the current values
217+ sql = 'select linkid, nodeid from %s' % tn
218+ if __debug__ :
219+ print >> hyperdb .DEBUG , 'migration' , (self , sql )
220+ execute (sql )
221+ rows = self .cursor .fetchall ()
222+
223+ # drop the old table
224+ self .drop_multilink_table_indexes (cn , name )
225+ sql = 'drop table %s' % tn
220226 if __debug__ :
221- print >> hyperdb .DEBUG , 'update_class' , (self , sql )
222- self .cursor .execute (sql )
223- old_has = old_has .has_key
227+ print >> hyperdb .DEBUG , 'migration' , (self , sql )
228+ execute (sql )
224229
225- # now figure how we populate the new table
226- if adding_actor :
227- fetch = ['_activity' , '_creation' , '_creator' ]
228- else :
229- fetch = ['_actor' , '_activity' , '_creation' , '_creator' ]
230- properties = spec .getprops ()
231- for propname ,x in new_spec [1 ]:
232- prop = properties [propname ]
233- if isinstance (prop , hyperdb .Multilink ):
234- if force or not old_has (propname ):
235- # we need to create the new table
236- self .create_multilink_table (spec , propname )
237- elif old_has (propname ):
238- # we copy this col over from the old table
239- fetch .append ('_' + propname )
230+ if properties .has_key (name ):
231+ # re-create and populate the new table
232+ self .create_multilink_table (klass , name )
233+ sql = '''insert into %s (linkid, nodeid) values
234+ (%s, %s)''' % (tn , self .arg , self .arg )
235+ for linkid , nodeid in rows :
236+ execute (sql , (int (linkid ), int (nodeid )))
237+
238+ # figure the column names to fetch
239+ fetch = ['_%s' % name for name in propnames ]
240240
241241 # select the data out of the old table
242242 fetch .append ('id' )
243243 fetch .append ('__retired__' )
244244 fetchcols = ',' .join (fetch )
245- cn = spec .classname
246245 sql = 'select %s from _%s' % (fetchcols , cn )
247246 if __debug__ :
248- print >> hyperdb .DEBUG , 'update_class ' , (self , sql )
247+ print >> hyperdb .DEBUG , 'migration ' , (self , sql )
249248 self .cursor .execute (sql )
250- olddata = self .cursor .fetchall ()
251249
252- # TODO: update all the other index dropping code
250+ # unserialise the old data
251+ olddata = []
252+ propnames = propnames + ['id' , '__retired__' ]
253+ for entry in self .cursor .fetchall ():
254+ l = []
255+ olddata .append (l )
256+ for i in range (len (propnames )):
257+ name = propnames [i ]
258+ v = entry [i ]
259+
260+ if name in ('id' , '__retired__' ):
261+ l .append (int (v ))
262+ continue
263+ prop = properties [name ]
264+ if isinstance (prop , Date ) and v is not None :
265+ v = date .Date (v )
266+ elif isinstance (prop , Interval ) and v is not None :
267+ v = date .Interval (v )
268+ elif isinstance (prop , Password ) and v is not None :
269+ v = password .Password (encrypted = v )
270+ elif (isinstance (prop , Boolean ) or
271+ isinstance (prop , Number )) and v is not None :
272+ v = float (v )
273+
274+ # convert to new MySQL data type
275+ prop = properties [name ]
276+ if v is not None :
277+ v = self .hyperdb_to_sql_value [prop .__class__ ](v )
278+ l .append (v )
279+
253280 self .drop_class_table_indexes (cn , old_spec [0 ])
254281
255282 # drop the old table
256- self . cursor . execute ('drop table _%s' % cn )
283+ execute ('drop table _%s' % cn )
257284
258285 # create the new table
259- self .create_class_table (spec )
286+ self .create_class_table (klass )
260287
261- # do the insert of the old data - the new columns will have
262- # NULL values
288+ # do the insert of the old data
263289 args = ',' .join ([self .arg for x in fetch ])
264290 sql = 'insert into _%s (%s) values (%s)' % (cn , fetchcols , args )
265291 if __debug__ :
266- print >> hyperdb .DEBUG , 'update_class ' , (self , sql , olddata [ 0 ] )
292+ print >> hyperdb .DEBUG , 'migration ' , (self , sql )
267293 for entry in olddata :
268- self .cursor .execute (sql , tuple (entry ))
294+ if __debug__ :
295+ print >> hyperdb .DEBUG , '... data' , entry
296+ execute (sql , tuple (entry ))
269297
270- return 1
298+ # now load up the old journal data
299+ cols = ',' .join ('nodeid date tag action params' .split ())
300+ sql = 'select %s from %s__journal' % (cols , cn )
301+ if __debug__ :
302+ print >> hyperdb .DEBUG , 'migration' , (self , sql )
303+ execute (sql )
304+
305+ olddata = []
306+ for nodeid , journaldate , journaltag , action , params in \
307+ self .cursor .fetchall ():
308+ nodeid = int (nodeid )
309+ journaldate = date .Date (journaldate )
310+ params = eval (params )
311+ olddata .append ((nodeid , journaldate , journaltag , action ,
312+ params ))
313+
314+ # drop journal table and indexes
315+ self .drop_journal_table_indexes (cn )
316+ sql = 'drop table %s__journal' % cn
317+ if __debug__ :
318+ print >> hyperdb .DEBUG , 'migration' , (self , sql )
319+ execute (sql )
320+
321+ # re-create journal table
322+ self .create_journal_table (klass )
323+ for nodeid , journaldate , journaltag , action , params in olddata :
324+ self .save_journal (cn , cols , nodeid , journaldate ,
325+ journaltag , action , params )
326+
327+ # make sure the normal schema update code doesn't try to
328+ # change things
329+ self .database_schema ['tables' ][cn ] = klass .schema ()
271330
272331 def __repr__ (self ):
273332 return '<myroundsql 0x%x>' % id (self )
0 commit comments