Just to give my point of view from my personnal experience, I totally agree with Krzysztof on this. A document versioning information is necessary when previous data has been saved in a wrong way, and on the upgrading point, this is also entirely true. The update procedure must be independant of the core code as it should be incremental and some "old" upgrades could be not always supported by the main structure.
const
SOFTWARE_VERSION = 4.3;
procedure Upgrade;
var
CurrentVersion
begin
CurrentVersion := GetCurrentVersionFromXmlFile;
if CurrentVersion > SOFTWARE_VERSION then
begin
//Warn user that it's software version seems too old to correctly open the file
return;
end;
if CurrentVersion <= 1.0 then
begin
//APPLY ?.? -> 1.0 Upgrades here
CurrentVersion := 1.0;
end;
if CurrentVersion <= 2.0 then
begin
//APPLY 1.0 -> 2.0 Upgrades here
CurrentVersion := 2.0;
end;
if CurrentVersion <= 3.0 then
begin
//APPLY 2.0 -> 3.0 Upgrades here
CurrentVersion := 3.0;
end;
// etc...
if CurrentVersion <= xx.yy then
begin
//APPLY 3.0 -> xx.yy Upgrades here
CurrentVersion := xx.yy ;
end;
if CurrentVersion <= SOFTWARE_VERSION then
begin
//APPLY xx.yy -> SOFTWARE_VERSION Upgrades here
CurrentVersion := SOFTWARE_VERSION;
//Warn user that it's file project has been updated (to a compliant application format) and changes will be kept after a save
end;
end;
Note that when I'm applying the version_A -> version_B upgrade, I'm not relying on the core code, all is managed internally by the upgrade procedure in order to avoid upgrade fails that could occured due to a progressive refactoring (deletion, renaming, etc.)