Program examples for RRSAF

The Resource Recovery Services attachment facility (RRSAF) enables programs to communicate with Db2. You can use RRSAF as an alternative to CAF.

Example JCL for invoking RRSAF

The following sample JCL shows how to use RRSAF in a batch environment. The DSNRRSAF DD statement starts the RRSAF trace. Use that DD statement only if you are diagnosing a problem.

//jobname      JOB      z/OS_jobcard_information
//RRSJCL       EXEC     PGM=RRS_application_program
//STEPLIB      DD       DSN=application_load_library
//             DD       DSN=DB2_load_library
 
⋮
 
//SYSPRINT     DD       SYSOUT=*
//DSNRRSAF     DD       DUMMY
//SYSUDUMP     DD       SYSOUT=*

Example of loading and deleting the RRSAF language interface

The following code segment shows how an application loads entry points DSNRLI and DSNHLIR of the RRSAF language interface. Storing the entry points in variables LIRLI and LISQL ensures that the application loads the entry points only once. Delete the loaded modules when the application no longer needs to access Db2.

****************************** GET LANGUAGE INTERFACE ENTRY ADDRESSES
         LOAD  EP=DSNRLI          Load the RRSAF service request EP
         ST    R0,LIRLI           Save this for RRSAF service requests
         LOAD  EP=DSNHLIR         Load the RRSAF SQL call Entry Point
         ST    R0,LISQL           Save this for SQL calls
*        .
*        .     Insert connection service requests and SQL calls here
*        .
         DELETE EP=DSNRLI         Correctly maintain use count
         DELETE EP=DSNHLIR        Correctly maintain use count

Example of using dummy entry point DSNHLI for RRSAF

Each of the Db2 attachment facilities contains an entry point named DSNHLI. When you use RRSAF but do not specify the ATTACH(RRSAF) precompiler option, the precompiler generates BALR instructions to DSNHLI for SQL statements in your program. To find the correct DSNHLI entry point without including DSNRLI in your load module, code a subroutine, with entry point DSNHLI, that passes control to entry point DSNHLIR in the DSNRLI module. DSNHLIR is unique to DSNRLI and is at the same location as DSNHLI in DSNRLI. DSNRLI uses 31-bit addressing. If the application that calls this intermediate subroutine uses 24-bit addressing, the intermediate subroutine must account for the difference.

In the following example, LISQL is addressable because the calling CSECT used the same register 12 as CSECT DSNHLI. Your application must also establish addressability to LISQL.

***********************************************************************
* Subroutine DSNHLI intercepts calls to LI EP=DSNHLI
***********************************************************************
         DS    0D
DSNHLI   CSECT                    Begin CSECT
         STM   R14,R12,12(R13)    Prologue
         LA    R15,SAVEHLI        Get save area address
         ST    R13,4(,R15)        Chain the save areas
         ST    R15,8(,R13)        Chain the save areas
         LR    R13,R15            Put save area address in R13
         L     R15,LISQL          Get the address of real DSNHLI
         BASSM R14,R15            Branch to DSNRLI to do an SQL call
*                                 DSNRLI is in 31-bit mode, so use
*                                 BASSM to assure that the addressing
*                                 mode is preserved.
         L     R13,4(,R13)        Restore R13 (caller's save area addr)
         L     R14,12(,R13)       Restore R14 (return address)
         RETURN (1,12)            Restore R1-12, NOT R0 and R15 (codes)

Example of connecting to Db2 with RRSAF

This example uses the variables that are declared in the following code.

****************** VARIABLES SET BY APPLICATION ***********************
LIRLI    DS    F                  DSNRLI entry point address
LISQL    DS    F                  DSNHLIR entry point address
SSNM     DS    CL4                DB2 subsystem name for IDENTIFY
CORRID   DS    CL12               Correlation ID for SIGNON
ACCTTKN  DS    CL22               Accounting token for SIGNON
ACCTINT  DS    CL6                Accounting interval for SIGNON
PLAN     DS    CL8                DB2 plan name for CREATE THREAD
COLLID   DS    CL18               Collection ID for CREATE THREAD.  If
*                                 PLAN contains a plan name, not used.
REUSE    DS    CL8                Controls SIGNON after CREATE THREAD
CONTROL  DS    CL8                Action that application takes based
*                                  on return code from RRSAF
****************** VARIABLES SET BY DB2 *******************************
STARTECB DS    F                  DB2 startup ECB
TERMECB  DS    F                  DB2 termination ECB
EIBPTR   DS    F                  Address of environment info block
RIBPTR   DS    F                  Address of release info block
****************************** CONSTANTS ******************************
CONTINUE DC    CL8'CONTINUE'      CONTROL value: Everything OK
IDFYFN   DC    CL18'IDENTIFY          ' Name of RRSAF service
SGNONFN  DC    CL18'SIGNON            ' Name of RRSAF service
CRTHRDFN DC    CL18'CREATE THREAD     ' Name of RRSAF service
TRMTHDFN DC    CL18'TERMINATE THREAD  ' Name of RRSAF service
TMIDFYFN DC    CL18'TERMINATE IDENTIFY' Name of RRSAF service
****************************** SQLCA and RIB **************************
    EXEC SQL INCLUDE SQLCA
         DSNDRIB                  Map the DB2 Release Information Block
******************* Parameter list for RRSAF calls ********************
RRSAFCLL CALL  ,(*,*,*,*,*,*,*,*),VL,MF=L

The following example code shows how to issue requests for the RRSAF functions IDENTIFY, SIGNON, CREATE THREAD, TERMINATE THREAD, and TERMINATE IDENTIFY. This example does not show a task that waits on the Db2 termination ECB. You can code such a task and use the z/OS® WAIT macro to monitor the ECB. The task that waits on the termination ECB should detach the sample code if the termination ECB is posted. That task can also wait on the Db2 startup ECB. This example waits on the startup ECB at its own task level.

***************************** IDENTIFY ********************************
         L     R15,LIRLI          Get the Language Interface address
         CALL  (15),(IDFYFN,SSNM,RIBPTR,EIBPTR,TERMECB,STARTECB),VL,MF=X
               (E,RRSAFCLL)
         BAL   R14,CHEKCODE       Call a routine (not shown) to check
*                                  return and reason codes
         CLC   CONTROL,CONTINUE   Is everything still OK
         BNE   EXIT               If CONTROL not 'CONTINUE', stop loop
         USING R8,RIB             Prepare to access the RIB
         L     R8,RIBPTR          Access RIB to get DB2 release level
         CLC   RIBREL,RIBR999     DB2 V10 or later?
         BE    USERELX            If RIBREL = '999', use RIBRELX
         WRITE 'The current DB2 release level is' RIBREL
         B     SIGNON             Continue with signon  USERELX  
         WRITE 'The current DB2 release level is' RIBRELX
***************************** SIGNON **********************************
SIGNON   L     R15,LIRLI          Get the Language Interface address
         CALL  (15),(SGNONFN,CORRID,ACCTTKN,ACCTINT),VL,MF=(E,RRSAFCLL)
         BAL   R14,CHEKCODE       Check the return and reason codes
*************************** CREATE THREAD *****************************
         L     R15,LIRLI          Get the Language Interface address
         CALL  (15),(CRTHRDFN,PLAN,COLLID,REUSE),VL,MF=(E,RRSAFCLL)
         BAL   R14,CHEKCODE       Check the return and reason codes
****************************** SQL ************************************
*              Insert your SQL calls here.  The DB2 Precompiler
*              generates calls to entry point DSNHLI.  You should
*              code a dummy entry point of that name to intercept
*              all SQL calls.  A dummy DSNHLI is shown in the following 
*              section.                                                 
************************ TERMINATE THREAD *****************************
         CLC   CONTROL,CONTINUE   Is everything still OK?
         BNE   EXIT               If CONTROL not 'CONTINUE', shut down
         L     R15,LIRLI          Get the Language Interface address
         CALL  (15),(TRMTHDFN),VL,MF=(E,RRSAFCLL)
         BAL   R14,CHEKCODE       Check the return and reason codes
************************ TERMINATE IDENTIFY ***************************
         CLC   CONTROL,CONTINUE   Is everything still OK
         BNE   EXIT               If CONTROL not 'CONTINUE', stop loop
         L     R15,LIRLI          Get the Language Interface address
         CALL  (15),(TMIDFYFN),VL,MF=(E,RRSAFCLL)
         BAL   R14,CHEKCODE       Check the return and reason codes