MULTIVALUE MIGRATION
Export your MultiValue data.
Choose your source system, review the configuration at the top of the program, and copy the complete exporter. Each version writes a portable Harbor Snapshot for RightMV.
01 / CHOOSE AND COPY
One format. Source-aware exporters.
The programs preserve item IDs and raw dynamic-array marks by encoding them as hexadecimal. Platform-specific account and file discovery stays in the exporter where it belongs.
Work on a consistent source. Use a quiesced system or supported snapshot, test with non-production data first, and protect the export as sensitive data.
* Program: ITERATE.ALL.EXPORT
* Description: Export all jBASE accounts, dictionaries, data files, and items
* as a RightMV Harbor Snapshot v1 file.
GOSUB INIT
GOSUB PROCESS.ACCOUNTS
GOSUB CLEANUP
STOP
*-------------------------------------------------------------------------------
INIT:
*-------------------------------------------------------------------------------
EXPORT.PATH = "c:\temp\my-export.mvoa"
OPENSEQ EXPORT.PATH OVERWRITE TO F.EXPORT ELSE
CREATE F.EXPORT ELSE
CRT "ERROR: Cannot create output file at " : EXPORT.PATH
STOP
END
END
OPEN "SYSTEM" TO F.SYSTEM ELSE
OPEN "SYSTEM.ACCOUNT" TO F.SYSTEM ELSE
CRT "ERROR: Cannot open SYSTEM or SYSTEM.ACCOUNT."
CLOSESEQ F.EXPORT
STOP
END
END
EXPORT.LINE = "MVOA 1"
GOSUB WRITE.EXPORT.LINE
EXPORT.LINE = "SOURCE-PRODUCT JBASE"
GOSUB WRITE.EXPORT.LINE
EXPORT.LINE = "SOURCE-CHARSET UNKNOWN"
GOSUB WRITE.EXPORT.LINE
EXPORT.LINE = "PAYLOAD-ENCODING HEX-BYTES"
GOSUB WRITE.EXPORT.LINE
RETURN
*-------------------------------------------------------------------------------
PROCESS.ACCOUNTS:
*-------------------------------------------------------------------------------
SELECT F.SYSTEM TO ACCOUNT.LIST
LOOP
READNEXT ACCOUNT.NAME FROM ACCOUNT.LIST ELSE EXIT
READ R.ACCOUNT FROM F.SYSTEM, ACCOUNT.NAME THEN
ACCOUNT.PATH = R.ACCOUNT<2>
IF ACCOUNT.PATH # "" THEN
VOC.PATH = ACCOUNT.PATH : "/VOC"
OPEN VOC.PATH TO F.VOC THEN
CRT "Processing Account: " : ACCOUNT.NAME
ACCOUNT.HEX = OCONV(ACCOUNT.NAME, "MX")
EXPORT.LINE = "ACCOUNT " : ACCOUNT.HEX
GOSUB WRITE.EXPORT.LINE
* Export the account VOC itself before following its file
* pointers. IMPORT-ALL uses this as ordinary DATA content.
FILE.NAME = "VOC"
FILE.NAME.HEX = OCONV(FILE.NAME, "MX")
EXPORT.LINE = "FILE DATA " : FILE.NAME.HEX
GOSUB WRITE.EXPORT.LINE
OPEN VOC.PATH TO F.HANDLE THEN
GOSUB PROCESS.ITEMS
CLOSE F.HANDLE
END
GOSUB PROCESS.FILES
CLOSE F.VOC
END ELSE
CRT "WARNING: Cannot open VOC for account " : ACCOUNT.NAME
END
END
END
REPEAT
RETURN
*-------------------------------------------------------------------------------
PROCESS.FILES:
*-------------------------------------------------------------------------------
SELECT F.VOC TO VOC.LIST
LOOP
READNEXT VOC.ID FROM VOC.LIST ELSE EXIT
READ R.VOC FROM F.VOC, VOC.ID THEN
VOC.TYPE = R.VOC<1>
* A ]D companion is exported through its owning file.
IS.DICT.POINTER = 0
IF LEN(VOC.ID) >= 2 THEN
IF VOC.ID[LEN(VOC.ID)-1, 2] = "]D" THEN IS.DICT.POINTER = 1
END
IF (VOC.TYPE = "F" OR VOC.TYPE = "F4") AND NOT(IS.DICT.POINTER) THEN
FILE.NAME = VOC.ID
FILE.NAME.HEX = OCONV(FILE.NAME, "MX")
PHYSICAL.FILE = R.VOC<2>
IF PHYSICAL.FILE = "" THEN PHYSICAL.FILE = FILE.NAME
* Resolve relative paths beneath the account directory while
* retaining Unix, UNC, and drive-letter absolute paths.
IS.ABSOLUTE = 0
IF PHYSICAL.FILE[1, 1] = "/" THEN IS.ABSOLUTE = 1
IF PHYSICAL.FILE[1, 1] = "\" THEN IS.ABSOLUTE = 1
IF LEN(PHYSICAL.FILE) >= 2 THEN
IF PHYSICAL.FILE[2, 1] = ":" THEN IS.ABSOLUTE = 1
END
IF NOT(IS.ABSOLUTE) THEN
PHYSICAL.FILE = ACCOUNT.PATH : "/" : PHYSICAL.FILE
END
OPEN "DICT", PHYSICAL.FILE TO F.HANDLE THEN
CRT " Exporting DICT " : FILE.NAME
EXPORT.LINE = "FILE DICT " : FILE.NAME.HEX
GOSUB WRITE.EXPORT.LINE
GOSUB PROCESS.ITEMS
CLOSE F.HANDLE
END
OPEN PHYSICAL.FILE TO F.HANDLE THEN
CRT " Exporting DATA " : FILE.NAME
EXPORT.LINE = "FILE DATA " : FILE.NAME.HEX
GOSUB WRITE.EXPORT.LINE
GOSUB PROCESS.ITEMS
CLOSE F.HANDLE
END ELSE
CRT "WARNING: Cannot open data file " : PHYSICAL.FILE
END
END
END
REPEAT
RETURN
*-------------------------------------------------------------------------------
PROCESS.ITEMS:
*-------------------------------------------------------------------------------
SELECT F.HANDLE TO ITEM.LIST
LOOP
READNEXT ITEM.ID FROM ITEM.LIST ELSE EXIT
READ R.ITEM FROM F.HANDLE, ITEM.ID THEN
ITEM.ID.HEX = OCONV(ITEM.ID, "MX")
ITEM.DATA.HEX = OCONV(R.ITEM, "MX")
ITEM.SIZE = LEN(R.ITEM)
* ITEM <hex-id> <decoded-byte-count> <hex-payload>
EXPORT.LINE = "ITEM " : ITEM.ID.HEX : " " : ITEM.SIZE
IF ITEM.SIZE > 0 THEN
EXPORT.LINE = EXPORT.LINE : " " : ITEM.DATA.HEX
END
GOSUB WRITE.EXPORT.LINE
END
REPEAT
RETURN
*-------------------------------------------------------------------------------
WRITE.EXPORT.LINE:
*-------------------------------------------------------------------------------
WRITESEQ EXPORT.LINE APPEND TO F.EXPORT ELSE
CRT "ERROR: Snapshot write failed. Output is incomplete."
CLOSESEQ F.EXPORT
STOP
END
RETURN
*-------------------------------------------------------------------------------
CLEANUP:
*-------------------------------------------------------------------------------
EXPORT.LINE = "END"
GOSUB WRITE.EXPORT.LINE
CLOSE F.SYSTEM
CLOSESEQ F.EXPORT
CRT "Export completed successfully to " : EXPORT.PATH
RETURN02 / IMPORT
Load the snapshot into RightMV.
Move the generated .mvoa file to the RightMV host, then run:
IMPORT-ALL /path/to/export.mvoaBEFORE PRODUCTION
Verify, reconcile, then migrate.
Compare account, file and item counts; sample empty and multivalued records; validate dictionaries and business totals; and keep the source system unchanged until acceptance is complete.
Download RightMV →