Sometimes the solution to a problem is staring you right in the face. Sometimes you already know the answer but can't see it because the pieces are labeled in a way that is outside the scope of the solution. Sometimes you can just use an old tool to provide a piece of functionality you thought you needed to code a home grown solution for. Recently, such a time occurred for me.
I was in a meeting discussing the logistics of transferring multiple gigs of text data across the internet. The source computer was an iSeries, the target was something else. Much of the discussion centered on network latency and the time it was going to take to transfer that much data, and how processes were going to have to be pushed back a day because the window was too short. Well I said why don't we just zip up the file and send it that way. Data files tend to be highly compressible, up to 90%. "Can you do that on an iSeries." That was the infrastructure guy. Why not, I can run Java on it. I shouldn't be too hard to find something, even if I have to write a simple Java program. "Don't do anything we won't be able to understand." That was one of the RPG programmers. IMHO, the legacy tag belongs with those who use the technology, and the technologies they choose to use rather than with the hardware and operating system. For me it was a challenge.
A day later I had a working command using a tool that is bundled with every Java Development Kit. I knew this, but it took a slight memory jog from a college to remind me. A JAR file is a ZIP file with a different extension. IBM explicitly provides a tool to convert a database file to a CSV file, or a flat text file, but to compress that file into a ZIP file you need to use the JAR utility and give the file a .ZIP extension. Works like a champ. IBM even provides an alternate JAR utility that acts more like a command line compression utility to create zip files, but instead of calling it zip, or izip or something like that they call it ajar.
Well, a short CL later and I have a full featured program that takes a database file name, a zip file name and path (in the integrated file system or IFS), and a format selector (*DLM or *FIXED). It probably would have made more sense to name that format *CSV instead of *DLM, but IBM's conversion utility calls it *DLM. The output is a zip file with the name and path as specified in the input parameters.
And Here it is:
I was in a meeting discussing the logistics of transferring multiple gigs of text data across the internet. The source computer was an iSeries, the target was something else. Much of the discussion centered on network latency and the time it was going to take to transfer that much data, and how processes were going to have to be pushed back a day because the window was too short. Well I said why don't we just zip up the file and send it that way. Data files tend to be highly compressible, up to 90%. "Can you do that on an iSeries." That was the infrastructure guy. Why not, I can run Java on it. I shouldn't be too hard to find something, even if I have to write a simple Java program. "Don't do anything we won't be able to understand." That was one of the RPG programmers. IMHO, the legacy tag belongs with those who use the technology, and the technologies they choose to use rather than with the hardware and operating system. For me it was a challenge.
A day later I had a working command using a tool that is bundled with every Java Development Kit. I knew this, but it took a slight memory jog from a college to remind me. A JAR file is a ZIP file with a different extension. IBM explicitly provides a tool to convert a database file to a CSV file, or a flat text file, but to compress that file into a ZIP file you need to use the JAR utility and give the file a .ZIP extension. Works like a champ. IBM even provides an alternate JAR utility that acts more like a command line compression utility to create zip files, but instead of calling it zip, or izip or something like that they call it ajar.
Well, a short CL later and I have a full featured program that takes a database file name, a zip file name and path (in the integrated file system or IFS), and a format selector (*DLM or *FIXED). It probably would have made more sense to name that format *CSV instead of *DLM, but IBM's conversion utility calls it *DLM. The output is a zip file with the name and path as specified in the input parameters.
And Here it is:
PGM PARM(&DBF &ZIPFILE &FORMAT)
DCL VAR(&DBF) TYPE(*CHAR) LEN(32)
DCL VAR(&ZIPFILE) TYPE(*CHAR) LEN(255)
DCL VAR(&FORMAT) TYPE(*CHAR) LEN(6)
DCL VAR(&FILE) TYPE(*CHAR) LEN(10)
DCL VAR(&LIB) TYPE(*CHAR) LEN(10)
DCL VAR(&MBR) TYPE(*CHAR) LEN(10)
DCL VAR(&CMD) TYPE(*CHAR) LEN(255)
DCL VAR(&TEXTFILE) TYPE(*CHAR) LEN(15)
DCL VAR(&TEMPFILE) TYPE(*CHAR) LEN(40)
DCL VAR(&ERRLOOP) TYPE(*CHAR) LEN(1) VALUE(N)
DCL VAR(&INTER) TYPE(*CHAR) LEN(1)
MONMSG MSGID(CPF0000 QSH0000) EXEC(GOTO CMDLBL(ERROR))
RTVJOBA TYPE(&INTER)
CHGVAR VAR(&FILE) VALUE(%SST(&DBF 3 10))
CHGVAR VAR(&LIB) VALUE(%SST(&DBF 13 10))
CHGVAR VAR(&MBR) VALUE(%SST(&DBF 23 10))
/* Ensure ZIP directory exists for error logging */
MKDIR DIR('/zip')
MONMSG MSGID(CPFA0A0)
/* Delete &zipfile if it exists */
RMVLNK OBJLNK(&ZIPFILE)
MONMSG MSGID(CPFA0A9)
/* build text file name */
IF COND(&FORMAT *EQ *DLM) THEN(DO)
CHGVAR VAR(&TEXTFILE) VALUE(&FILE *TCAT '.csv')
ENDDO
ELSE CMD(DO)
CHGVAR VAR(&TEXTFILE) VALUE(&FILE *TCAT '.txt')
ENDDO
/* generate temporary file name */
RTVTMPIFSN NAME(&TEMPFILE)
IF COND(&TEMPFILE *EQ ' ') THEN(CHGVAR VAR(&TEMPFILE) +
VALUE('/tmp/$$__tempfile'))
/* export DBF to temporary file */
CPYTOIMPF FROMFILE(&LIB/&FILE &MBR) TOSTMF(&TEMPFILE) +
MBROPT(*REPLACE) STMFCODPAG(*STDASCII) +
RCDDLM(*CRLF) DTAFMT(&FORMAT) RMVBLANK(*TRAILING)
MONMSG MSGID(CPF2817) EXEC(DO)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Error +
converting Database File to Interface File') +
MSGTYPE(*DIAG)
GOTO CMDLBL(ERROR)
ENDDO
/* Send 'compressing' status message */
IF COND(&INTER *EQ '1') THEN(SNDPGMMSG MSGID(CPF9897) +
MSGF(QCPFMSG) MSGDTA('Compressing file ' *CAT +
&FILE) TOPGMQ(*EXT) MSGTYPE(*STATUS))
/*---------------------------------------------------------------*/
/* This command is using the unix environment to zip up the file */
/* extracted above. All errors are logged to a text file */
/* named error.txt. The 2>> operator redirects stderr to the */
/* file following it, and adds any messages to the end of the */
/* file. */
/* */
/* The following unix utilities are used here: */
/* ajar - create an archive */
/* */
/* The following environment variables are used here: */
/* QIBM_QSH_CMD_ESCAPE_MSG - Sends QSH0005 as an escape message */
/* if the exit status is not 0 (Qshell error condition) */
/*---------------------------------------------------------------*/
/* Send an escape message if the command fails */
ADDENVVAR ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG) VALUE(Y) +
REPLACE(*YES)
/* Create &zipfile from temporary file */
CHGVAR VAR(&CMD) VALUE('ajar -c -M' *BCAT &ZIPFILE *BCAT +
'''' *CAT &TEMPFILE *TCAT ''' :' *BCAT &TEXTFILE +
*BCAT '2>>' *BCAT '/zip/error.txt')
QSH CMD(&CMD)
MONMSG MSGID(QSH0005) EXEC(DO)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Error +
creating ZIP file') MSGTYPE(*DIAG)
GOTO CMDLBL(ERROR)
ENDDO
/* Delete temporaty file */
RMVLNK OBJLNK(&TEMPFILE)
MONMSG MSGID(CPFA0A9)
/* Exit Normally */
GOTO CMDLBL(OUT)
/* Process Errors */
ERROR: IF COND(&ERRLOOP *EQ Y) THEN(GOTO CMDLBL(OUT))
CHGVAR VAR(&ERRLOOP) VALUE(Y)
/* Delete temporaty file */
RMVLNK OBJLNK(&TEMPFILE)
MONMSG MSGID(CPFA0A9)
/* Send Escape message */
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Error +
Processing File') MSGTYPE(*ESCAPE)
OUT: ENDPGM
Check it out. Create a ZIP file using the Java Archive utility. A Rose by any other name would smell as sweet!
Comments for Teaching Old Dogs New Tricks