This document describes the Krang upgrade system for developers. If you just want to upgrade Krang, see Upgrade.
Krang provides an upgrade system to allow existing Krang installations to use new code without losing data and configuration. When you make changes to Krang you may need to add commands to an upgrade module. This document will show you how.
The only thing that Krang does automatically is overwrite old source
files with new source files. For example, if you fix a bug in
lib/Krang/Story.pm and the fix doesn't require a database update
then your work is almost certainly done.
If you make a change to the DB schema, or the contents of the database
then you need to add code to affect that change during the upgrade.
For example, let's say I've added a new property for stories called
'foo_id'. That will naturally require a new column in the story
table, which I will add to story.sql:
foo_id INT UNSIGNED NOT NULL,
That's fine for new installations, which will use story.sql to
construct the story table, but for upgrades I need to make that
change to the live database. To do so I add a line to the
per_instance() subroutine in the upgrade module for this release,
upgrade/V0_022.pm:
sub per_instance {
my $self = shift;
my $dbh = dbh();
# add the foo_id column
$dbh->do("ALTER TABLE story ADD COLUMN foo_id INT UNSIGNED NOT NULL");
}
If an upgrade module for the current version doesn't exist yet just copy an older one and use it as a template. For more details, see Krang::Upgrade.
Krang does nothing with the data/ directory during upgrade unless
you write code to do it. If you make a change to how files are stored
under data/ then you'll need to add code to make the change.
For example, lets say I decided to rename the directory storing addon
details from addons/ to addon-db/. I would add code to the
per_installation() method in upgrade module:
sub per_installation {
my $self = shift;
# rename data/addons to data/addon-db
system("mv", catdir(KrangRoot, 'data', 'addons'),
catdir(KrangRoot, 'data', 'addon-db'));
}
This is done in per_installation() rather than per_instance()
because it should be done once during install, not once for each
instance.
Virtually any change you can write can be accomodated by the upgrade module. Just decide whether the change requires per-instance activity or per-installation and put your code in the proper method.
When Krang is running an upgrade it determines which upgrade modules to run by looking at the source and target versions. For example, to upgrade from v1.001 to v1.004 Krang would run, if available:
upgrade/V1_002.pm upgrade/V1_003.pm upgrade/V1_004.pm
While testing upgrade modules it helps to be able to run them by hand,
rather than as part of a full krang_upgrade run. Here's how it's
done, using V1_000.pm as an example:
KRANG_ROOT=`pwd` perl -Ilib -Iupgrade -MKrang::Script \ -MV1_000 -e 'V1_000->new()->upgrade()'