How to: Write Extension Upgrade Code
The process of upgrading an extension includes uninstalling the current version of the extension and then installing a new version. If the extension modifies the schema of an existing table, or adds new tables, upgrade code will be required to handle the data that was automatically archived from the tables during uninstall.
For more information about upgrading extensions, see Upgrading NAV Extensions.
To write upgrade code for an extension
Create new codeunit.
This must be a Normal type codeunit, not an Upgrade codeunit, as specified by the codeunit's SubType Property (Codeunit).
Add the following global functions to the codeunit:
If the extension contains non-company-specific tables, add the OnNavAppUpgradePerDatabase() function to upgrade these tables.
If the extension contains company-specific tables that pertain to a specific company, add the OnNavAppUpgradePerCompany() function to upgrade these tables.
Make sure that the Local Property of the functions is set to No.
Add the upgrade code to the appropriate function.
The upgrade code will depend on what you want to do with the archived data, plus additional factors such as the version of the archive data, whether the schema has changed, and whether the data can be modified by users. Determine which of the following upgrade methods is required for each new or modified table in your extension.
Restore table data
If the table has the same schema as the archive data and doesn’t require any special upgrade logic, then use the
NAV.APP.RESTOREARCHIVEDATA(TableNo)system function to copy the archived data to the table. The data that is copied may be for new tables added as part of the extension or for fields added to existing base NAV tables.
The following code restores the archived data for tables 50000 and 50001 on company basis.
PROCEDURE OnNavAppUpgradePerCompany@1(); BEGIN NAVAPP.RESTOREARCHIVEDATA(50000); NAVAPP.RESTOREARCHIVEDATA(50001); END;
Delete table data
If you do not want to restore the archived data to the table, then use the
NAVAPP.DELETEARCHIVEDATA(TableNo)system function to delete the archived data.
The following code deletes the archived data for tables 50002 on company basis.
PROCEDURE OnNavAppUpgradePerCompany@1(); BEGIN NAVAPP.DELETEARCHIVEDATA(50002); END;
Upgrade table data
If the archived data is from a previous version and requires special upgrade logic, then use custom code to upgrade the records retrieved from the archive tables. For this scenario, you will use the following system functions:
[Version :=] NAVAPP.GETARCHIVEVERSION(TableNo, RecordRef)
Returns the extension version of archived data.
[Ok :=] NAVAPP.GETARCHIVERECORDREF(TableNo, VAR RecordRef)
Returns a RecordRef for the identified table.
Restores the archived data to the database.
The following code upgrades records that are retrieves from the archived table for table 50003. The upgrade code that is run depends on the extension version number of the archived data.
VAR ArchiveRecRef@1000 : RecordRef; FldRef@1001 : FieldRef; DestRec@1002 : Record; Version@1003 : Text; PROCEDURE OnNavAppUpgradePerCompany@1(); BEGIN Version := NAVAPP.GETARCHIVEVERSION(); IF Version < '18.104.22.168' THEN BEGIN // The Version 1 to Version 2 upgrade code block. Copy over relevant old fields and initialize new fields using archive data. IF NAVAPP.GETARCHIVERECORDREF(50003, ArchiveRecRef) THEN BEGIN IF ArchiveRecRef.FINDSET(FALSE) THEN BEGIN DestRec.INIT; REPEAT FldRef := ArchiveRecRef.FIELD(50000); DestRec.Key := FldRef.VALUE; FldRef := ArchiveRecRef.FIELD(50001); DestRec.V1Field := FldRef.VALUE; DestRec.V2Field := 'NEW FIELD DEFAULT VALUE'; DestRec.INSERT; UNTIL ArchiveRecRef.NEXT = 0; END END END ELSE BEGIN // This is the reinstall (version 2 to version 2) block. // Because the schema is the same for all minor versions of the version 2 product, // you can copy the data in without changes. NAVAPP.RESTOREARCHIVEDATA(50003); END END;
The preceding sample code uses a strongly typed instance of the record for the destination. The other option is to use a RecordRef for both the source and destination. The sample code also assumes that any version 2 build of the extension uses the same table schema. If this is not true for your extension, you may have to use more specific version checks.
It is best practice to use the
IF NAVAPP.GETARCHIVERECORDREF(50003, ArchiveRecRef) THEN BEGINconstruct to catch any exception that is thrown, for example, if an invalid table was passed.