Often, while testing application programs, you need to run a program that uses logical files. But, to avoid the problem of inadvertently updating production (live) files, you need to play it safe: You must first make a copy of the physical file and its related logical files in another library. Then, you must place that library high in the library list so the system finds it before it finds the library with the original, production, files.
However, you are faced with the problem of finding which logical files are attached to the physical file and then running all the appropriate commands to make the duplicates. So, I created a utility that will copy a physical file and all of the logicals that go along with it. Thus, you have the Copy All Logical Files (CPYALLLF) command (see Figure 1).
CPYALLLF asks for the qualified name of the physical file and the name of the target library. It then does a little editing to make sure that you actually enter valid libraries, verifying that the "from" and "to" libraries are not the same and that the physical file actually exists in the original library (if it exists in the target library, it will ask you if you want to proceed).
Then, CPYALLLF performs a Display Database Relations (DSPDBR) command to find all the logical files attached to the physical file. After that, it calls a program to delete all the logical files, if any exist, and then the physical file in the target library. Once this is done, the program does a Copy File (CPYF) from the original library to the target library (see Figures 2 and 3). Then, it calls the same program used to delete the logical files but with a different parameter to add the logical (see Figure 4). Thats it; now, you have your physical file and all of its logicals where you need them!
CPYALLLF prints an exception report for any of the following reasons:
The file was not created because it is a join logical.
The file was not created because you do not have authority to that object in the library in which it resides.
The file was not created because it was not found in the original library.
The file was created in the target library.
You can modify this utility by cloning the part that deletes the logical files and then the physical file for a quick delete after you no longer need the files.
I have found the CPYALLLF command to be a useful and efficient utility. Currently, I am on a Y2K team, and the testing sometimes produces unpredictable results. Glad it was done in my library, which didnt affect the whole system.
/*===================================================================*/
/* To compile: */
/* */
/* CRTCMD CMD(XXX/CPYALLLF) PGM(XXX/ALL003CL) + */
/* SRCFILE(XXX/QCMDSRC) TEXT(Copy All + */
/* Logical Files) */
/* */
/*===================================================================*/
CMD PROMPT(Copy All Logical Files)
PARM KWD(PF) TYPE(Q1) MIN(1) PROMPT(Physical file)
Q1: QUAL TYPE(*NAME) LEN(10) MIN(1) EXPR(*YES)
QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) +
SPCVAL((*LIBL) (*CURLIB)) EXPR(*YES) +
PROMPT(Library)
PARM KWD(TGTLIB) TYPE(*NAME) LEN(10) MIN(1) +
EXPR(*YES) PROMPT(Target library)
PARM KWD(OVERWRITE) TYPE(*LGL) LEN(1) DFT(*NO) +
SPCVAL((*YES 1) (*NO 0)) +
PROMPT(Overwrite target library) /*===================================================================*/
/* To compile: */
/* */
/* CRTCLPGM PGM(XXX/ALL003CL) SRCFILE(XXX/QCLSRC) + */
/* TEXT(CPP for CPYALLLF command) */
/* */
/* Prerequisites: Utility command FWDPGMMSG (MC, January 1998) */
/*===================================================================*/
PGM PARM(&Q_PF &TGTLIB &OVERWRITE)
DCL VAR(&ADDED) TYPE(*LGL) LEN(1)
DCL VAR(&EXISTS) TYPE(*LGL) LEN(1)
DCL VAR(&FALSE) TYPE(*LGL) LEN(1) VALUE(0)
DCL VAR(&OBJATR) TYPE(*CHAR) LEN(10)
DCL VAR(&OVERWRITE) TYPE(*LGL) LEN(1)
DCL VAR(&PF) TYPE(*CHAR) LEN(10)
DCL VAR(&PFLIB) TYPE(*CHAR) LEN(10)
DCL VAR(&Q_PF) TYPE(*CHAR) LEN(20)
DCL VAR(&TGTLIB) TYPE(*CHAR) LEN(10)
DCL VAR(&TRUE) TYPE(*LGL) LEN(1) VALUE(1)
MONMSG MSGID(CPF0000 MCH0000) EXEC(GOTO CMDLBL(ERROR))
/* Break qualified name */
CHGVAR VAR(&PF) VALUE(%SST(&Q_PF 1 10))
CHGVAR VAR(&PFLIB) VALUE(%SST(&Q_PF 11 10))
/* Verify library names */
IF COND(&PFLIB *NE *LIBL *AND &PFLIB *NE +
*CURLIB) THEN(DO)
CHKOBJ OBJ(&PFLIB) OBJTYPE(*LIB)
MONMSG MSGID(CPF9801) EXEC(DO)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) +
MSGDTA(Library *BCAT &PFLIB *BCAT does +
not exist) MSGTYPE(*ESCAPE)
ENDDO
ENDDO
Figure 1: The CPYALLLF command
CHKOBJ OBJ(&TGTLIB) OBJTYPE(*LIB)
MONMSG MSGID(CPF9801) EXEC(DO)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) +
MSGDTA(Library *BCAT &TGTLIB *BCAT +
does not exist) MSGTYPE(*ESCAPE)
ENDDO
/* Verify existence of physical file */
CHKOBJ OBJ(&PFLIB/&PF) OBJTYPE(*FILE)
MONMSG MSGID(CPF9801) EXEC(DO)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) +
MSGDTA(Physical file *BCAT &PF *BCAT +
not found in *BCAT &PFLIB) MSGTYPE(*ESCAPE)
ENDDO
RTVOBJD OBJ(&PFLIB/&PF) OBJTYPE(*FILE) +
RTNLIB(&PFLIB) OBJATR(&OBJATR)
IF COND(&OBJATR *NE PF) THEN(DO)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(File +
*BCAT &PF *BCAT is not a physical file) +
MSGTYPE(*ESCAPE)
ENDDO
/* Make sure that libraries are not the same */
IF COND(&PFLIB *EQ &TGTLIB) THEN(DO)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(Source +
and target libraries cannot be the same) +
MSGTYPE(*ESCAPE)
ENDDO
/* Check for physical file in target library */
CHGVAR VAR(&EXISTS) VALUE(&TRUE)
CHKOBJ OBJ(&TGTLIB/&PF) OBJTYPE(*FILE)
MONMSG MSGID(CPF9801) EXEC(DO)
RCVMSG MSGTYPE(*EXCP) RMV(*YES)
CHGVAR VAR(&EXISTS) VALUE(&FALSE) ENDDO
IF COND(&EXISTS *AND *NOT &OVERWRITE) THEN(DO)
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(File +
*BCAT &PF *BCAT already exists in *BCAT +
&TGTLIB) MSGTYPE(*ESCAPE)
ENDDO
/* Add target library to *LIBL if necessary */
CHGVAR VAR(&ADDED) VALUE(&TRUE)
ADDLIBLE LIB(&TGTLIB)
MONMSG MSGID(CPF2103) EXEC(DO)
RCVMSG MSGTYPE(*EXCP) RMV(*YES)
CHGVAR VAR(&ADDED) VALUE(&FALSE) ENDDO
/* Create work file listing all logicals */
DSPDBR FILE(&PFLIB/&PF) OUTPUT(*OUTFILE) +
OUTFILE(QTEMP/QADSPDBR) OUTMBR(*FIRST +
*REPLACE)
/* Delete all logical files from target library */
OVRDBF FILE(QADSPDBR) TOFILE(QTEMP/QADSPDBR)
CALL PGM(ALL003RG) PARM(D &PFLIB &TGTLIB)
DLTOVR FILE(QADSPDBR)
/* Delete physical file from target library */
DLTF FILE(&TGTLIB/&PF)
MONMSG MSGID(CPF2105) EXEC(DO)
RCVMSG MSGTYPE(*EXCP) RMV(*YES)
ENDDO
/* Copy the physical file */
CPYF FROMFILE(&PFLIB/&PF) TOFILE(&TGTLIB/&PF) +
FROMMBR(*ALL) TOMBR(*FROMMBR) +
MBROPT(*ADD) CRTFILE(*YES)
/* Create all logical files */
OVRDBF FILE(QADSPDBR) TOFILE(QTEMP/QADSPDBR)
CALL PGM(ALL003RG) PARM(A &PFLIB &TGTLIB)
DLTOVR FILE(QADSPDBR)
/* Remove target library from *LIBL */
IF COND(&ADDED) THEN(DO)
RMVLIBLE LIB(&TGTLIB)
ENDDO
/* Report successful completion */
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) +
MSGDTA(CPYALLLF completed successfully) +
MSGTYPE(*COMP)
RETURN
ERROR:
IF COND(&ADDED) THEN(DO)
RMVLIBLE LIB(&TGTLIB)
MONMSG MSGID(CPF0000) ENDDO
FWDPGMMSG
MONMSG MSGID(CPF0000)
ENDPGM *=================================================================
* To compile:
*
* CRTRPGPGM PGM(XXX/ALL003RG) SRCFILE(XXX/QRPGSRC) +
* TEXT(Called from ALL003CL)
*
*=================================================================
FQADSPDBRIF E DISK
FQSYSPRT O F 132 OV PRINTER UC
*================================================================
C READ QADSPDBR 50
C * IN50 DOWEQ*OFF
*
C MODE IFEQ D
C EXSR PRODEL
C ELSE
*
C WHJREF IFGT 0
C EXSR CKOV
C EXCPT$NJOIN
C ELSE
C EXSR PROADD
C ENDIF
*
C ENDIF
*
C READ QADSPDBR 50
C ENDDO
*
C MODE IFNE D
C CLOSEQSYSPRT
C ENDIF
*
C MOVE *ON *INLR
*================================================================
* PROADD: This will add the logicals in the TO Lib
*================================================================
C PROADD BEGSR
*
* Create logical file
C MOVE A MODE
C MOVE *BLANKS MSGID
*
C CALL ALL004CLADDDEL
*
C EXSR CKOV
C MSGID IFNE *BLANKS
C EXSR ERROR
C ELSE
C EXCPT$GOOD
C ENDIF
*
C ENDSR
*================================================================
Figure 2: CL program ALL003CL
* PRODEL: This will delete the logicals in the TO Lib
*================================================================
C PRODEL BEGSR
*
* Delete logical file
C MOVE D MODE
C MOVE *BLANKS MSGID
*
C CALL ALL004CLADDDEL
*
C ENDSR
*================================================================
* CKOV: This will check for overflow in the print file
*================================================================
C CKOV BEGSR
*
C * INOV IFEQ *ON
C EXCPT$HEAD
C MOVE *OFF *INOV
C ENDIF
*
C ENDSR
*================================================================
* ERROR: This will print error messages
*================================================================
C ERROR BEGSR
*
C MSGID IFEQ CPF2189
C EXCPT$NOAUT
C ELSE
C EXCPT$NFND
C ENDIF
*
C ENDSR
*================================================================
* *INZSR:
*================================================================
C * INZSR BEGSR
*
C * ENTRY PLIST
C PARM MODE 1
C PARM FLIB 10
C PARM TLIB 10
*
C ADDDEL PLIST
C PARM MODE 1
C PARM WHREFI
C PARM FLIB
C PARM TLIB
C PARM MSGID 7
*
C MODE IFNE D
C OPEN QSYSPRT
C EXCPT$HEAD
C ENDIF
*
C ENDSR
*================================================================
OQSYSPRT E 01 $HEAD
O UDATE Y 10
O 80 Copy File Status Report
O 125 Page:
O PAGE Z 132
O E 2 $NJOIN
O WHREFI 10
O 34 was not created because
O 55 it is a join logical
O E 2 $NOAUT
O WHREFI 10
O 34 was not created because
O 56 you do have authority
O 74 to that object in
O FLIB 85
O E 2 $NFND
O WHREFI 10
O 34 was not created because
O 59 the object was not found
O 70 in library
O FLIB 81
O E 2 $GOOD
O WHREFI 10
O 33 was created in library
O TLIB 44 /*===================================================================*/
/* To compile: */
/* */
/* CRTCLPGM PGM(XXX/ALL004CL) SRCFILE(XXX/QCLSRC) + */
/* TEXT(Called from ALL003RG) */
/* */
/*===================================================================*/
PGM PARM(&MODE &LF &LFLIB &TGTLIB &MSGID)
DCL VAR(&LF) TYPE(*CHAR) LEN(10)
DCL VAR(&LFLIB) TYPE(*CHAR) LEN(10)
DCL VAR(&MODE) TYPE(*CHAR) LEN(1)
DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
DCL VAR(&TGTLIB) TYPE(*CHAR) LEN(10)
/* Delete the logical file */
IF COND(&MODE *EQ D) THEN(DO)
DLTF FILE(&TGTLIB/&LF)
MONMSG MSGID(CPF2105)
ENDDO
/* Create the logical file */
ELSE CMD(IF COND(&MODE *EQ A) THEN(DO))
CRTDUPOBJ OBJ(&LF) FROMLIB(&LFLIB) OBJTYPE(*FILE) +
TOLIB(&TGTLIB)
MONMSG MSGID(CPF2189 CPF2130) EXEC(DO)
RCVMSG MSGTYPE(*DIAG) MSGID(&MSGID)
ENDDO
ENDDO
ENDPGM
LATEST COMMENTS
MC Press Online