Self foreign keys in activity backup/restore

Self foreign keys in activity backup/restore

by Markku Riekkinen -
Number of replies: 3

I am implementing an activity plugin and I have a problem in implementing the backup/restore feature. One of my plugin database tables has a foreign key referring to the table itself (field called parentid) and I do not know how to reliably restore this parentid field. Looking at the backup/restore tutorial in the moodle.org documentation, the normal way to implement backup only works in this case with the parentid field if the parent objects are stored before their children in the backup XML tree (the rows of this table become siblings in the tree since they all belong to the same DB table). However, I cannot sort all the DB rows in this way with just an SQL ORDER BY statement (which can be used in the backup set_source_table method) since the parent-child relations can have multiple levels, and there is no guarantee that parents have smaller database ID values than their children. I could sort the objects in PHP code but not with just SQL ORDER BY.

So, I was thinking that I should create some other XML tree besides the one for the activity, and the extra tree would provide some more parent-child mapping data. This data could be used after restoring the activity to go through all nodes and fix the parent pointers afterwards. But I do not know how I could implement this: creating another XML tree and using it after restoring other normal data so that I could loop through all database rows restored and fix their parent pointers. Any advice?

Average of ratings: -
In reply to Markku Riekkinen

Re: Self foreign keys in activity backup/restore

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Markku - I suggest you make use of the 'after_execute' function in your restore_PLUGINNAME_activty_structure_step class.

If you make a note of all the records you have created (maybe in a static variable, or flag the new records in some way), then once you have finished, you can loop through all the restored records and call $this->get_mapping() to convert the old ids to the new ids, then update the record (assuming you called $this->set_mapping() at the point where you created each of the records, during the restore).


In reply to Davo Smith

Re: Self foreign keys in activity backup/restore

by Markku Riekkinen -
Thanks Davo for an excellent suggestion! After implementing it, I think it works great. I used a normal instance variable in the class restore_PLUGINNAME_activity_structure_step to save the IDs that need to be fixed later in after_execute; is there any reason you suggested a static variable, presumably a private class static variable? Can I assume that there is only one instance of the class restore_PLUGINNAME_activity_structure_step that covers the restoration of a whole activity?
In reply to Markku Riekkinen

Re: Self foreign keys in activity backup/restore

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
I suggested a static variable only because I hadn't checked whether there was a single instance or not.