Writing a specific upgrade procedure

Upgrade from an earlier version is performed using a job monitor that launches upgrade procedures in an automated way. Specific upgrade procedures can be added but you have to:

  1. Generate an upgrade processing.
  2. Reference this processing as an upgrade procedure in the Supervisor folder using the corresponding function (Usage > Upgrades > Upgrade process).
    This should be done before creating any upgrade plan and starting any folder revalidation.

This document describes the structure of such an upgrade processing. Refer to processing "UUMGTRTPUR01", if necessary. It is used to carry out the upgrade of the purchase requests.

Caution: Its source code is provided as an example. Do not modify it as it might make the upgrade procedure invalid.

Basic principles

During folder validation:

  1. Each transactions table is renamed. By default, the letter "U" is added before its name.
    Activity code "MIG" is assigned to each table to make it possible to identify them when the temporary tables are deleted after the upgrade validation.
  2. The content of these transactions tables is kept strictly identical to the original transactions tables.
  3. Their indices are deleted (except for the first index, and possibly an additional one that can speed up the upgrade processing).
  4. One or more empty transactions tables are created according to the dictionary of the new version (the specific fields or modifications to the standard fields made in the original table are included).
    The empty table usually has the same name as the original table, unless the table no longer exists in the new version.

The upgrade of specific tables can be managed using the same mechanism. This is described in MIGTAB entry point.

The following subprogram can determine the name of the table after it has been renamed:

 # FOLDER = code of folder# PTABLE = name of the movement table before the upgrade# PTABLE = name of the renamed movement table# If ERR>0: an error has been generated (the processing will be interrupted)Call MIGTABNAME(FOLDER,PTABLE, MTABLE, ERR) From TRTMIG
The basic renaming rule is to add the letter "U" before the name of the table. However, there are exceptions, for example if the name of the table exceeds 12 characters. Entry point "TABNAME" in processing "TRTMIG" is used to set entry point "MTABLE" by defining "PTABLE" with a rule that can be different.Each unitary procedure is defined using a program that upgrades one or several tables in the base. This processing must be called "UUMGSPExxxnn", with "xxx" being the root identifying the table to upgrade, and "nn" being two numbers (to enable the use of several processing routines). It functions as follows:In order to obtain the best performances possible:In order for the unit procedures to be easily interrupted and resumed:## Description of the upgraden processingThe upgrade processing contains the following elements:These subprograms are described in this document.In the given examples, processing "UUMGTRTZMY01" corresponds to the unit upgrade phase of a single table called "ZMYTABLE". After the preliminary folder revalidation phase:The upgrade procedure will populate table "ZMYTABLE" using the information in table "UZMYTABLE".## Preliminary linesThe preliminary lines directly start the processing from the editor using the Execution function:
# Definition of the current folder, and read of the folder tableLocal Char FOLDER(30): FOLDER = nomap# Name of the upgrade procedureLocal Char PROG(20): PROG="UUMGTRTZMY01"If !GSERVEURCall SAIDOS(FOLDER,"") From SAIDOSEndifIf FOLDER<> ""If clalev([F:ADS])=0: Local File ADOSSIER [ADS]: EndifRead [ADS] DOSSIER=[L]FOLDER: If fstat: Raz [F:ADS]: Endif# Opening of the log and display of a timing windowIf !GSERVEURCall TEMPON("O") From GESECRANCall OUVRE_TRACE(PROG) From LECFICEndif# Launching of the procedureCall MAJ_UUMGSPEZMA00(FOLDER)# Closing the logIf !GSERVEURCall TEMPOFF From GESECRANCall FERME_TRACE From LECFICCall LEC_TRACE From LECFICEndifEndifEnd
## Reset to zero subprogramThe subprogram declared by "Subprog RAZ_UUMGTRTZMY01(FOLDER)" allows you to revert to the initial situation, if necessary, in order to relaunch the procedure. It must at least include the following basic phases:## Update subprogramSubprogram "MAJ_UUMGTRTZMY01" is used to transcodify the content of table "UZMYTABLE" to populate table "ZMYTABLE". It performs the following tasks:
  1. Define the name of the upgrade procedure at the beginning:
    Local Char PROG(20): PROG="UUMGTRTZMY01"
  2. Update the status of the procedure using the following subprogram:
     # CURSTAT variable Integer managing the status (local menu 21)# The possible values are Pending, In progress, Completed... # If the procedure is launched, CURSTAT=2# If it is over, CURSTAT=3# In case of error, it will need to be set to 7# Variable PROG contains the name of the procedure# (for example, UUMGTRTZMY01)Call MIGSTKENDFLG (FOLDER,PROG,CURSTAT,ERR) From TRTMIG
    Note: If a preliminary condition makes the launch unnecessary, the status needs to be "Completed" for the procedure to be considered as running and for the next procedures to follow. Otherwise, the status is set to "In progress"
  3. Test the presence of the current and previous tables using subprogram "MIGTABNAME". In case of error, the status of the task has to be set to the correct value ("7") with subprogram "MIGSTKENDFLG".
  4. Open the tables necessary for the upgrade. The internal tables of the upgrade procedure are opened using:
     Call MIG_OUVRE From TRTMIG
  5. Keep logs to a minimum. Adding a log to each line can cause a lack of disk space, which can interrupt the upgrades. However, it is useful to create a log starting with "Start of the phase updating xxx", and a time stamp starting with "Process started at". These logs will use the following subprograms:
     # Log line if ERR=0, else, error lineCall ECR_TRACE("message",ERR) From GESECRAN# Time stamped log lineCall ECR_TIME("message") From DOSSUB
  6. Delete indices to improve the insertion time in tables. Only the first active index is kept at the beginning of the procedure. The indices are recreated at the end of the procedure, using the following subprograms:
     Call MIGTABINIT(FOLDER,"ZMYTABLE",ERR) From TRTMIG
    Caution: The procedure has to be the only operating procedure in the table when it is run. No other procedure must be read, modified, or inserted in the table while the procedure is run. If the table has to be accessed by several procedures, this subprogram must not be used.
  7. Find the first key to be processed in the processing loop using the following subprogram:
    # TBMKEY(1..NBMKEY) is a table containing the key values# where to resume the read. At a minimum, the components# of the last processed key value are included, but the following can be added# a segment to determine the break level reached# on a multiple key. TBMKEY must be empty before the call# If it is returned empty, it means that there was no current key value# (the procedure is then started at the beginning).# NBMKEY is used to define the number of expected values# NBL and NBUP count the number of lines read and updated so far.Call MIGGETKEY (FOLDER,PROG,NBMKEY,TBMKEY,NBL,NBUP,ERR)& From TRTMIG
    It is not empty when the upgrade resumes after an interruption.
  8. Enter the read loop of the original tables and the write loop of the destination tables. For performance reasons, it is recommended to avoid the use of isolated read orders on tables. It is also recommended to use link instructions instead, preferably with strict joins (syntax Where CLE~=... ). If a "smaller" table (containing less than 1,000 lines) must be read for initialization or control reasons, it is usually better to store the useful content of this table in variables before starting the loop.
  9. Avoid writing an overly large number of lines which can cause errors. To do this, the number of lines is counted and the loop is interrupted every N lines. For example, N can be set to 50,000, using global variable GMAXUPDTRS.
  10. Use the writeb instruction for performance reasons. This instruction groups the records and improves performances, especially for multi-tier architectures. It can only be used if the table is not re-read in the loop. It implies that a grouping factor is set using a variable named adxwrb ("10" is an appropriate value). It is then necessary to stack the values of the written keys to be able to retrieve all the keys currently being used in case of error (this error is generated with the flush instruction and not the writeb instruction). The following subprogram can be used:
     # Stacking of keys.# KEY_ARRAY is an alphanumerical array declared by# Local Char KEY_ARRAY(N)(adxwrb) at the beginning of the processing# (sizeN is dependent on the size of the key values)# NUMBER a variable Shortint that determines the number of stacked keys# KEY_VALUE encoded key value if the key is subdivided into several partsCall STK (KEY_ARRAY, NUMBER,KEY_VALUE) From TRTMIG
  11. Perform a flush on the table (if writeb is used) by managing a possible error if the loop is exited (after N loops, or because the processing is complete). If an error has been generated and adxwrb is larger than "1", the keys that caused the error can be found in the "KEY_ARRAY" array, in the first adxwrb indices. A rollback is then run before setting the procedure to "Completed with errors" and ending the processing.
  12. Update the number of lines read and updated using the following call:
     Call MIGSTKKEY (FOLDER,PROG,NBMKEY,TBMKEY,NBL,NBUP,ERR)& From TRTMIG
    A commit is then performed.
  13. Carry out an interruption request test, if necessary. In the absence of such a request, and if not all the lines have been processed, a loop is started again on N lines. The interruption test is carried out using the following subprogram:
     # The STOP variable is equal to 0 if an interruption request has been madeCall MIGSTKPROGRESS (FOLDER,PROG,STOP,ERR) From TRTMIG
  14. Conduct the following operations if an interruption request has been made (or if the processing is completed):
     # Indexing of the processed table(s)# (only if MIGTABINIT has been used)Call MIGTABEND(FOLDER,"ZMYTABLE",ERR) From TRTMIG# Alert the monitor of the processing endCall MIGTRTEND(FOLDER,PROG) From TRTMIGCall ECR_TIME(PROG+": Task completed") From DOSSUB
It is then possible to close the tables and free the resources, if any, then stop the subprogram using the end instruction.## PATCH subprogramThis subprogram is used to perform a launch by patch. The "ADOSSIER" table needs to be open. The record corresponding to the folder to be processed is read, and the upgrade procedure is launched. This subprogram can be organized as follows:
Subprog PATCH(FOLDER)Value Char FOLDER# No launch on the supervisor folderIf FOLDER=GDOSX3: End: Endif#Loading of class [F:ADS]If clalev([F:ADS])=0 Local File ADOSSIER [ADS]: EndifRead [ADS] DOSSIER=FOLDER: If fstat: Raz [F:ADS]: Endif#Launch of the procedureCall MAJ_UUMGTRTZMY01(FOLDER)End

Subprogram UTI_MOUL

This subprogram is used to launch folder validation. It is similar to the PATCH subprogram, except that table "ADOSSIER" does not need to be open, and the record corresponding to the folder to be processed does not need to be read. All this is ensured by the calling processing. Its sole purpose is to launch the corresponding procedure. This subprogram can be organized as follows:

Subprog UTIL_MOUL(FOLDER)Value Char FOLDER# No launch on the supervisor folderIf FOLDER=GDOSX3: End: Endif#Launch of the procedureCall MAJ_UUMGTRTZMY01(FOLDER)End

MIGTAB entry point

If specific transactions tables have to be managed in a similar way by the upgrade processing, the following phases are necessary:

If this entry point is not used, the specific tables (which are protected by a specific activity code) will not be impacted at all, and will remain in their original state. It usually corresponds to what must be done by default if the version change has no impact on the structure of the specific tables.

Similarly, any specific field present in a standard transactions table that has content that should be transferred as such does not need to follow any specific rule. The standard upgrade processing routines use class assignments to copy data.

The name of the processing where the "MIGTAB" entry point is located depends on the software based on SAFE X3. In the case of Sage X3, entry point "MIGTAB" can be found in processing "TRTMIGTABX3".

This processing will also contain lines such as:

 Call MIGTABTABADD(FOLDER,"ZMYTABLE","ZMY","index",& NBTAB,WTABLE,WTABLEJ,WABRJ,WTABIDX,ERR) From TRTMIG

With most of the variable names provided below being fixed:

Entry points of the standard upgrade processing routines

Each standard upgrade procedure contains entry points used to interact with the switching logic of the standard tables. These entry points are the following: