openphoto/frontend — Issue #209: Handling version upgrades seamlessly and with user intervention
Author: jmathai
Created: 2011-10-11 05:23:21+00:00
State: open
Labels: Release 1.3

This issue tracks gracefully handling updates in the OpenPhoto software. There are three scenarios.

===The software requires no updates beyond the code itself.

Nothing required.

===The software requires updates which can be applied without user intervention.

The required updates can be applied without needing the user to provide any information. An example of this is to add a new SimpleDb domain or a MySql table. Since we already have the secrets to perform these tasks we should do it as seamlessly as possible.

===The software requires updates which require the user to accept new terms or provide information.

This requires the user to provide some sort of information. An example of this is if the user has to provide an alternate email address for some new feature that requires it. Sorry, best example I could think of.

=========================

To handle this I'm proposing we add a "version" with the code in `src/configs/defaults.ini`

[currentVersion]
version="1.0.0"

1. The first digit represents major upgrades that require user intervention to complete.
1. The second digit represents minor upgrades that can be seamlessly updated without user intervention.
1. The third digit represents upgrades that require no additional changes.

In the code we would check the `currentVersion` against `lastVersion` which is stored as part of the setup/upgrade process. The `lastVersion` is stored in `src/configs/{hostname}.ini` which gets created by the setup.

[lastVersion]
version="1.0.0"

With any upgrade, `currentVersion` will be higher than `lastVersion` and we can determine what type of "upgrade" needs to take place. When these values do not match we should display a page that requires the user to confirm the changes. If the code can be modified without the user's input then we should execute them accordingly. If the changes require user intervention then the user should be sent through the setup flow again.

This means that there needs to be a standard way that "upgrade" code gets executed. Sometimes this can be handled in the `initialize` methods but we shouldn't put "upgrade" code in there. I suggest moving that logic out into an `Upgrade` class that has a few methods that will pull in and execute files for each version upgrade.

For example, we might have an directory `src/libraries/upgrade` with files named according to the version number that they apply to.

Let's assume we are starting on version 1.0.0 and the user upgrades to 1.3.0. There maybe code to upgrade from 1.0.0 to 1.1.0, 1.1.0 to 1.2.0 and then 1.2.0 to 1.3.0.

The files may look like so:

upgrade
|- upgrade-1.1.0.php
|- upgrade-1.2.0.php
|- upgrade-1.3.0.php

We would identify there was an upgrade because `currentVersion` and `lastVersion` don't match. As a result the `Upgrade` class would get a list of upgrade files and execute them.

There are some implementation details but these upgrade files would contain SQL for table upgrades and updates to the config file. They'd be executed in order so that upgrades from any version to any version would work.