Example Programs
This chapter provides and describes program examples.
1. Service Program
The following are the steps for writing a service program.
1.1. Example Program
The following is an example of a service program.
Since the service described in the example program uses the Tmax AUTOTRAN function in a server included in an XA server group, AUTOTRAN must be set to Y for the service in the Tmax configuration file. |
<$TMAXDIR/sample/cobserver/carrayauto.pco>
****************************************************** * XA service that uses a CARRAY buffer * ****************************************************** IDENTIFICATION DIVISION. PROGRAM-ID. CARRAYAUTO. AUTHOR. TMAX DEVELOPMENT. ENVIRONMENT DIVISION. CONFIGURATION SECTION. DATA DIVISION. FILE SECTION. WORKING-STORAGE SECTION. ****************************************************** * Definitions for Tmax ATMI functions ****************************************************** 01 TPSVCRET-REC. COPY TPSVCRET. * 01 TPTYPE-REC. COPY TPTYPE. * 01 TPSTATUS-REC. COPY TPSTATUS. * 01 TPSVCDEF-REC. COPY TPSVCDEF. * 01 TX-RETURN-STATUS. COPY TXSTATUS. ****************************************************** * Log message definitions ****************************************************** 01 LOGMSG. 05 LOGMSG-SVC PIC X(16). 05 FILLE PIC X(3) VALUES " : ". 05 LOGMSG-TEXT PIC X(80). 01 LOGMSG-LEN PIC S9(9) COMP-5. ****************************************************** * User defined data records ****************************************************** 01 RECV-STRING PIC X(100). 01 SEND-STRING PIC X(100). ****************************************************** * Declarations for user-defined Oracle host variables ****************************************************** EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 S-SRC. 05 S-TEMP PIC X(10) VARYING. EXEC SQL END DECLARE SECTION END-EXEC. EXEC SQL INCLUDE SQLCA END-EXEC. LINKAGE SECTION. * PROCEDURE DIVISION. * 000-MAIN. PERFORM 100-SVCSTART THRU 100-EXIT. PERFORM 200-DBINSERT THRU 200-EXIT. PERFORM 900-TPRETURNSCS THRU 900-TPRETURNSCS-X. 000-EXIT. ****************************************************** * Receiving data from a client ****************************************************** 100-SVCSTART. MOVE LENGTH OF RECV-STRING TO LEN. CALL "TPSVCSTART" USING TPSVCDEF-REC TPTYPE-REC RECV-STRING TPSTATUS-REC. IF NOT TPOK MOVE "TPSVCSTART Fail" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. IF TPTRUNCATE MOVE "Received data was truncated" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. DISPLAY "------------------------------------------------". MOVE SERVICE-NAME TO LOGMSG-SVC. MOVE "Starting the service " TO LOGMSG-TEXT. PERFORM 800-USERLOG. 100-EXIT. 200-DBINSERT. MOVE RECV-STRING(1:LEN) TO S-TEMP-ARR. MOVE LENGTH OF S-TEMP-ARR TO S-TEMP-LEN. * Handling DB INSERT EXEC SQL INSERT INTO TEMP (NAME,SAL) VALUES (RTRIM(:S-TEMP),150) END-EXEC. IF SQLCODE NOT = 0 PERFORM 800-SQLERROR PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. STRING "Inserted data : " S-TEMP-ARR DELIMITED BY SIZE INTO LOGMSG-TEXT. PERFORM 800-USERLOG. MOVE "Successful" TO SEND-STRING. 200-EXIT. 800-SQLERROR. * Writing log messages STRING "800-SQLERROR : " SQLERRMC DELIMITED BY SIZE INTO LOGMSG-TEXT. MOVE SQLCODE TO APPL-CODE. ****************************************************** * Write out a log err messages ****************************************************** 800-USERLOG. DISPLAY LOGMSG. ****************************************************** * The service completed successfully. ****************************************************** 900-TPRETURNSCS. MOVE "The service executed successfully." TO LOGMSG-TEXT. PERFORM 800-USERLOG. SET TPSUCCESS TO TRUE. MOVE LENGTH OF SEND-STRING TO LEN. COPY TPRETURN REPLACING DATA-REC BY SEND-STRING. 900-TPRETURNSCS-X. ****************************************************** * The service terminated abnormally. ****************************************************** 900-TPRETURNFAIL. MOVE "The service terminated abnormally." TO LOGMSG-TEXT. PERFORM 800-USERLOG. SET TPFAIL TO TRUE. MOVE "Cannot process " TO SEND-STRING. MOVE LENGTH OF SEND-STRING TO LEN. COPY TPRETURN REPLACING DATA-REC BY SEND-STRING. 900-TPRETURNFAIL-X.
The following describes each step in detail.
-
Set the service name. The service name to be used by a service caller in TPCALL is defined in PROGRAM-ID.
PROGRAM-ID. CARRAYAUTO.
-
Define buffers to be used to send and receive data to and from a client and a service caller.
****************************************************** * User defined data records ****************************************************** 01 RECV-STRING PIC X(100). 01 SEND-STRING PIC X(100).
-
Start the service. Data from a service caller is saved in the defined buffer.
In the example, data from a service caller to RECV-STRING is saved. If an error occurs, it is checked in "IF NOT TPOK". If the size of the buffer RECV-STRING is smaller than data from the service caller, the TPTRUNCATE error occurs.
MOVE LENGTH OF RECV-STRING TO LEN. CALL "TPSVCSTART" USING TPSVCDEF-REC TPTYPE-REC RECV-STRING TPSTATUS-REC. IF NOT TPOK MOVE "TPSVCSTART Fail" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. IF TPTRUNCATE MOVE "Received data was truncated" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF.
-
The service completed successfully.
SET TPSUCCESS TO TRUE. MOVE LENGTH OF SEND-STRING TO LEN. COPY TPRETURN REPLACING DATA-REC BY SEND-STRING.
-
An error is returned due to a logic error.
TPRETURN is used to send a response to the service caller after the business logic is complete. If the service fails to execute, TPFAIL is used. If TPRETURN is called using TPFAIL, the service caller receives tperrno=11(TPESVCFAIL) in the C language or TP-STATUS=11(TPESVCFAIL) in the COBOL language as an error code.
SET TPFAIL TO TRUE. MOVE "Cannot process " TO SEND-STRING. MOVE LENGTH OF SEND-STRING TO LEN. COPY TPRETURN REPLACING DATA-REC BY SEND-STRING.
1.2. Makefile
An executable file is created by linking a user service program with libraries provided by Tmax and the DB. The following are the steps for creating an executable file.
-
*.pco → *.cob
Precompile a ProCOBOL program.
-
*.cob → *.o
Create an object file by compiling a COBOL program.
-
*.o + *.a → executable file :
Create an executable file by linking the object file with libraries provided by Tmax and the DB.
If there is a single COBOL service and only one service exists in a server, the above 3 steps are handled in a single Makefile. However, in general, multiple services exist in a server. The first two steps must be processed for each service, while the third step is executed only once.
The first two steps are handled in a shell program, while the third step is handled in a Makefile.
$ cat carray_xa.sh
echo "-------------> carrayauto.pco"
procob18 sqlcheck=full userid=scott/tiger mode=ansi release_cursor=no
hold_cursor=yes maxliteral=160 ireclen=132 iname=carrayauto.pco
cob -C IBMCOMP -C NESTCALL -cx carrayauto.cob
echo "-------------> carraynauto.pco"
procob18 sqlcheck=full userid=scott/tiger mode=ansi release_cursor=no
hold_cursor=yes maxliteral=160 ireclen=132 iname=carraynauto.pco
cob -C IBMCOMP -C NESTCALL -cx carraynauto.cob
The following describes each step.
-
Create a COBOL object file with a shell.
sh carray_xa.sh -------------> carrayauto.pco Pro*COBOL: Release 1.8.76.0.0 - Production on Wed May 7 23:43:42 2003 (c) Copyright 2001 Oracle Corporation. All rights reserved. System default option values taken from: /database/ora9/precomp/admin/pcccob.cfg Precompiling carrayauto.pco -------------> carraynauto.pco Pro*COBOL: Release 1.8.76.0.0 - Production on Wed May 7 23:43:42 2003 (c) Copyright 2001 Oracle Corporation. All rights reserved. System default option values taken from: /database/ora9/precomp/admin/pcccob.cfg Precompiling carraynauto.pco
-
Compilation options for procob18 and cob depend on the operating system. For more information about options for procob18, refer to $ORACLE_HOME/precomp/demo/procob/demo_procob.mk.
-
Since carry_xa.sh precompiles and compiles carrayauto.pco and carraynauto.pco, both .pco files are required in the above example.
-
-
Create the Makefile to create an executable file.
#Makefile TARGET = carray_xa -----(1) TMAXCBLSTUB = cblstub -----(2) TMAXCBLSTUBOBJ = $(TMAXCBLSTUB).o COBOBJS = carrayauto.o carraynauto.o -----(3) OBJS = $(TMAXCBLSTUBOBJ) $(SDLOBJ) $(SVCTOBJ) SVCTOBJ = $(TARGET)_svctab.o SDLOBJ = $(TMAXDIR)/lib/sdl.o CFLAGS = -O -q32 -g -D_CBL_MODULE -I$(TMAXDIR) -I$(TMAXDIR)/usrinc LDFLAGS = -brtl COBFLAGS= -C IBMCOMP -C NESTCALL APPDIR = $(TMAXDIR)/appbin SVCTDIR = $(TMAXDIR)/svct LIBDIR = $(TMAXDIR)/lib LIBS = -loras -lcbls -----(4) ORALIBD = $(ORACLE_HOME)/lib32 ORALIBS = $(ORACLE_HOME)/precomp/lib32/cobsqlintf.o -lclntsh -lld -lm `cat $(ORACLE_HOME)/lib32/sysliblist` -lm -lc_r -lpthreads # .SUFFIXES : .c .c.o: $(CC) $(CFLAGS) -c $< # server compile # $(TARGET): $(OBJS) cob -Q "-brtl" $(COBFLAGS) -g -o $(TARGET) -L$(LIBDIR) -L$(ORALIBD) $(OBJS) $(COBOBJS) $(LIBS) $(ORALIBS) mv -f $(TARGET) $(APPDIR)/. rm -f $(TARGET).o $(SVCTOBJ) $(TMAXCBLSTUBOBJ) $(COBOBJS) $(TMAXCBLSTUBOBJ): cc $(CFLAGS) $(LDFLAGS) -c $(TMAXDIR)/cobinc/$(TMAXCBLSTUB).c $(SVCTOBJ):$(SVCTDIR)/$(TARGET)_svctab.c cc $(CFLAGS) -c $(SVCTDIR)/$(TARGET)_svctab.c ################################################ clean: -rm -f $(OBJS) core $(TARGET) $(TARGET).lis $(TARGET).cob
Item Description (1) TARGET
Specifies a server (executable file) name.
(2) TMAXCBLSTUB
Specifies a Tmax stub file name.
(3) COBOBJS
Specifies the name of an object file of a service written in COBOL.
(4) LIBS
Specifies a Tmax library name.
2. Program Using the FDL Buffer
Since a COBOL service program cannot directly use an FDL buffer, the buffer structure must be converted. To use an FDL buffer and view file, pre-tasks must be completed.
Extract cobolsanple.tar. viewdemo.v in the ucblinc directory as an example view file. fdldemo.f is an example FDL file.
Fdl : $TMAXDIR/ucblinc/fdldemo.f View : $TMAXDIR/ucblinc/viewdemo.v
2.1. Creating FDL
Create field information to be used in a client or server.
< fdldemo.f >
# name number type flags comments # string type FDL_S1 1001 string - - FDL_S2 1002 string - - # integer type FDL_I1 2001 int - - FDL_I2 2002 int - - # long type FDL_L1 3001 long - - FDL_L2 3002 long - - # float type FDL_F1 4001 float - - FDL_F2 4002 float - -
Locate the created tmax.fdl file in the directory set in $FDLFILE specified by an environment variable.
If cobolsample.tar is used, fdldemo.f is created in the $TMAXDIR/ucblinc directory. Execute fdlc in the directory to specify $TMAXDIR/ucblinc in $FDLFILE.
$fdlc –c –i fdldemo.f –o tmax.fdl
For more information about how to use a field buffer, refer to Tmax FDL Reference Guide. |
2.2. Creating a View File
Since a field buffer cannot be used in COBOL, create a view (structure/struct) and convert the data using a specific function to use field buffer data received from (or to be sent to) a requester.
< viewdemo.v >
VIEW viewdemo #type cname Fldkey count flag size null string sdata1 FDL_S1 1 - 20 "@@" string sdata2 FDL_S2 5 - 20 "@@" int idata1 FDL_I1 1 - - 0 int idata2 FDL_I2 5 - - 0 long ldata1 FDL_L1 1 - - 0 long ldata2 FDL_L2 5 - - 0 float fdata1 FDL_F1 1 - - 0 float fdata2 FDL_F2 5 - - 0 double ddata1 FDL_D1 1 - - 0 double ddata2 FDL_D2 5 - - 0 END
Locate the created tmax.sdl file in the directory set in $SDLFILE specified by an environment variable.
If cobolsample.tar is used, viewdemo.v is created in the $TMAXDIR/ucblinc directory. Execute sdlc in the directory to specify $TMAXDIR/ucblinc in $SDLFILE.
$cd $TMAXDIR/ucblinc
$ sdlc -c -v viewdemo.v -o tmax.sdl
$ ls -l
-rw-r-xr-- 1 tmax dba 382 Apr 28 17:27 viewdemo.v*
-rw-r--r-- 1 tmax dba 976 May 7 18:17 tmax.sdl
2.3. Creating a View File for COBOL
Create a view file for COBOL.
$ sdlc -C -v viewdemo.v
$ls -l total 48
total 48
drwxr-xr-x 2 tmax dba 512 Apr 30 14:48./
drwxr-xr-x 7 tmax dba 512 Apr 14 11:50 ../
-rw-r--r-- 1 tmax dba 671 Apr 30 14:48 VIEWDEMO.cbl
-rw-r-xr-- 1 tmax dba 382 Apr 28 17:27 viewdemo.v*
< VIEWDEMO.cbl >
* VIEWNAME: "viewdemo" 05 SDATA1 PIC X(20). 05 SDATA2 OCCURS 5 TIMES PIC X(20). 05 IDATA1 PIC S9(9) USAGE IS COMP-5. 05 IDATA2 OCCURS 5 TIMES PIC S9(9) USAGE IS COMP-5. 05 LDATA1 PIC S9(9) USAGE IS COMP-5. 05 LDATA2 OCCURS 5 TIMES PIC S9(9) USAGE IS COMP-5. 05 FDATA1 USAGE IS COMP-1. 05 FDATA2 OCCURS 5 TIMES USAGE IS COMP-1. 05 DDATA1 USAGE IS COMP-2. 05 DDATA2 OCCURS 5 TIMES USAGE IS COMP-2.
Since the created file must be used through the COPY command in the COBOL source code, locate the file in the directory specified in $COBCPY. If cobolsample.tar is used, the file is located in the $TMAXIDIR/ucblinc directory.
To efficiently manage the view file, it is recommended to save the file in a separate directory from the directory that contains the COBOL header files provided by Tmax. |
Set "export COBCPY=$TMAXDIR/cobinc:$TMAXDIR/ucblinc" and save user-created view files in $TMAXDIR/ucblinc.
The following files are saved in $TMAXDIR/ucblinc.
$ ls -l
-rw-r--r-- 1 tmax dba 671 May 7 18:17 VIEWDEMO.cbl
-rwxr-xr-- 1 tmax dba 381 Apr 30 15:10 fdldemo.f*
-rw-r--r-- 1 tmax dba 755 May 6 23:59 fdldemo_fdl.h
-rw-r--r-- 1 tmax dba 3852 May 6 23:59 tmax.fdl
-rw-r--r-- 1 tmax dba 976 May 7 20:13 tmax.sdl
-rw-r--r-- 1 tmax dba 996 May 7 00:56 viewdemo.sdl
-rw-r-xr-- 1 tmax dba 385 May 7 18:17 viewdemo.v*
-rw-r--r-- 1 tmax dba 574 May 7 20:13 viewdemo_sdl.h
-rw-r--r-- 1 tmax dba 571 Apr 30 14:53 viewdemo_sdl.h
2.4. Example Program
The following is an example of a service program that uses field buffers.
<$TMAXDIR/sample/cobserver/fdlins.pco>
****************************************************** * Service that uses an FDL buffer ****************************************************** IDENTIFICATION DIVISION. PROGRAM-ID. FDLINS. AUTHOR. TMAX DEVELOPMENT. ENVIRONMENT DIVISION. CONFIGURATION SECTION. DATA DIVISION. FILE SECTION. WORKING-STORAGE SECTION. ****************************************************** * Definitions for Tmax ATMI functions ****************************************************** 01 TPSVCRET-REC. COPY TPSVCRET. * 01 TPTYPE-REC. COPY TPTYPE. * 01 TPSTATUS-REC. COPY TPSTATUS. * 01 TPSVCDEF-REC. COPY TPSVCDEF. * 01 FML-REC. COPY FMLINFO. ****************************************************** * Log message definitions ****************************************************** 01 LOGMSG. 05 LOGMSG-SVC PIC X(16). 05 FILLER PIC X(3) VALUES " : ". 05 LOGMSG-TEXT PIC X(50). 01 LOGMSG-LEN PIC S9(9) COMP-5. ****************************************************** * User defined data records ****************************************************** 01 RECV-BUFFER. 03 RECV-ALIGN pic S9(9) COMP-5. 03 RECV-DATA pic x(1000). 01 SEND-BUFFER. 03 SEND-ALIGN pic S9(9) COMP-5. 03 SEND-DATA pic x(1000). 01 VIEWDEMO. COPY VIEWDEMO. LINKAGE SECTION. * PROCEDURE DIVISION. * 000-MAIN. PERFORM 100-SVCSTART THRU 100-EXIT. PERFORM 200-FDL2VIEW THRU 200-EXIT. PERFORM 300-VIEW2FDL THRU 300-EXIT. PERFORM 900-TPRETURNSCS THRU 900-TPRETURNSCS-X. 000-EXIT. ****************************************************** * Receiving data from a client ****************************************************** 100-SVCSTART. MOVE LENGTH OF RECV-BUFFER TO LEN. CALL "TPSVCSTART" USING TPSVCDEF-REC TPTYPE-REC RECV-BUFFER TPSTATUS-REC. IF NOT TPOK MOVE "TPSVCSTART Fail" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. IF TPTRUNCATE MOVE "Received data was truncated" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. DISPLAY "------------------------------------------------". MOVE SERVICE-NAME TO LOGMSG-SVC. MOVE "Starting the service " TO LOGMSG-TEXT. PERFORM 800-USERLOG. 100-EXIT. ****************************************************** * Moving FIELD buffer data to a struct ****************************************************** 200-FDL2VIEW. * VIEWNAME and FML-LENGTH must be specified. MOVE "viewdemo" TO VIEWNAME. MOVE LEN TO FML-LENGTH. * Moving field buffer data to a COBOL structure CALL "FVFTOS" USING RECV-BUFFER VIEWDEMO FML-REC. IF NOT FOK MOVE "FVFTOS FAILED " TO LOGMSG-TEXT DISPLAY "FML-STATUS : " FML-STATUS PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. 200-EXIT. ****************************************************** * Moving structure data to a field buffer ****************************************************** 300-VIEW2FDL. * FML-LENGTH must be used. MOVE LENGTH OF SEND-BUFFER TO FML-LENGTH. CALL "FINIT" USING SEND-BUFFER FML-REC. IF NOT FOK MOVE "FINIT FAILED " TO LOGMSG-TEXT DISPLAY "FML-STATUS : " FML-STATUS PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. MOVE "TEST STRING" TO SDATA1. MOVE "TEST STRING1" TO SDATA2(1). MOVE "TEST STRING2" TO SDATA2(2). MOVE "TEST STRING3" TO SDATA2(3). compute idata1 = idata1 + 10. compute idata2(1) = idata2(1) + 10. compute idata2(2) = idata2(2) + 10. compute idata2(3) = idata2(3) + 10. compute idata2(4) = idata2(4) + 10. compute ldata1 = ldata1 + 10. compute ldata2(1) = ldata2(1) + 10. compute ldata2(2) = ldata2(2) + 10. compute ldata2(3) = ldata2(3) + 10. compute ldata2(4) = ldata2(4) + 10. compute fdata1 = fdata1 + 10. compute fdata2(1) = fdata2(1) + 10. compute fdata2(2) = fdata2(2) + 10. compute fdata2(3) = fdata2(3) + 10. compute fdata2(4) = fdata2(4) + 10. compute ddata1 = ddata1 + 10. compute ddata2(1) = ddata2(1) + 10. compute ddata2(2) = ddata2(2) + 10. compute ddata2(3) = ddata2(3) + 10. compute ddata2(4) = ddata2(4) + 10. * Move COBOL structure data to a FDL buffer MOVE "viewdemo" TO VIEWNAME. SET FUPDATE TO TRUE. CALL "FVSTOF" USING SEND-BUFFER VIEWDEMO FML-REC. IF NOT FOK MOVE "FVSTOF FAILED " TO LOGMSG-TEXT DISPLAY "FML-STATUS : " FML-STATUS PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. 300-EXIT. ****************************************************** * Writing out a log error message ****************************************************** 800-USERLOG. DISPLAY LOGMSG. ****************************************************** * The service completed successfully. ****************************************************** 900-TPRETURNSCS. MOVE "The service executed successfully." TO LOGMSG-TEXT. PERFORM 800-USERLOG. SET TPSUCCESS TO TRUE. MOVE LENGTH OF SEND-BUFFER TO LEN. COPY TPRETURN REPLACING DATA-REC BY SEND-BUFFER. 900-TPRETURNSCS-X. ****************************************************** * The service terminated abnormally. ****************************************************** 900-TPRETURNFAIL. MOVE "The service terminated abnormally." TO LOGMSG-TEXT. PERFORM 800-USERLOG. SET TPFAIL TO TRUE. MOVE "Cannot process " TO SDATA1. MOVE LENGTH OF SEND-BUFFER TO LEN. COPY TPRETURN REPLACING DATA-REC BY SEND-BUFFER. 900-TPRETURNFAIL-X.
The following describes each step in detail.
-
Declare a field.
RECV-BUFFER/SEND-BUFFER is a buffer used to send or receive data from a service caller. VIEWDEMO is a structure used to convert a field buffer into a view and vice versa.
01 FML-REC. COPY FMLINFO. ****************************************************** * User defined data records ****************************************************** 01 RECV-BUFFER. 03 RECV-ALIGN pic S9(9) COMP-5. 03 RECV-DATA pic x(1000). 01 SEND-BUFFER. 03 SEND-ALIGN pic S9(9) COMP-5. 03 SEND-DATA pic x(1000). 01 VIEWDEMO. COPY VIEWDEMO. * VIEWFILE: "viewdemo.v" * VIEWNAME: "viewdemo" * * 05 SDATA1 PIC X(20). * 05 SDATA2 OCCURS 5 TIMES PIC X(20) * 05 IDATA1 PIC S9(9) USAGE IS COMP-5. * 05 IDATA2 OCCURS 10 TIMES PIC S9(9) USAGE IS COMP-5. * 05 LDATA1 PIC S9(9) USAGE IS COMP-5. * 05 LDATA2 OCCURS 5 TIMES PIC S9(9) USAGE IS COMP-5. * 05 FDATA1 USAGE IS COMP-1. * 05 FDATA2 OCCURS 10 TIMES USAGE IS COMP-1. * 05 DDATA1 USAGE IS COMP-2. * 05 DDATA2 OCCURS 10 TIMES USAGE IS COMP-2.
-
Receive a field buffer from a client.
To receive data from a service caller, TPSVCSTART must be executed first when the service starts.
****************************************************** * Receiving data from a client ****************************************************** 100-SVCSTART. MOVE LENGTH OF RECV-BUFFER TO LEN. CALL "TPSVCSTART" USING TPSVCDEF-REC TPTYPE-REC RECV-BUFFER TPSTATUS-REC. IF NOT TPOK MOVE "TPSVCSTART Fail" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. IF TPTRUNCATE MOVE "Received data was truncated" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. DISPLAY "------------------------------------------------". MOVE SERVICE-NAME TO LOGMSG-SVC. MOVE "Starting a service " TO LOGMSG-TEXT. PERFORM 800-USERLOG. 100-EXIT.
-
Convert the field buffer to a structure.
Field buffer data from the service caller is saved in a COBOL structure converted from the buffer. When an array is used, if the data is smaller than the array size, the unfilled portions of the array is filled in with the default value defined in the view file.
****************************************************** * Moving field buffer data to a structure ****************************************************** 200-FDL2VIEW. * VIEWNAME and FML-LENGTH must be specified. MOVE "viewdemo" TO VIEWNAME. MOVE LEN TO FML-LENGTH. * Moving field buffer data to a COBOL structure CALL "FVFTOS" USING RECV-BUFFER VIEWDEMO FML-REC. IF NOT FOK MOVE "FVFTOS FAILED " TO LOGMSG-TEXT DISPLAY "FML-STATUS : " FML-STATUS PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. 200-EXIT.
-
Handle data to perform business logic in the COBOL source code.
MOVE "TEST STRING" TO SDATA1. MOVE "TEST STRING1" TO SDATA2(1). MOVE "TEST STRING2" TO SDATA2(2). MOVE "TEST STRING3" TO SDATA2(3). …… compute ddata1 = ddata1 + 10. compute ddata2(1) = ddata2(1) + 10. compute ddata2(2) = ddata2(2) + 10. compute ddata2(3) = ddata2(3) + 10. compute ddata2(4) = ddata2(4) + 10.
-
Create a field buffer used to send data.
For the field buffer, the received buffer as well as a newly created buffer can be used. To create a new buffer, use FINIT.
****************************************************** * Moving structure data to a field buffer ****************************************************** 300-VIEW2FDL. * FML-LENGTH must be used. MOVE LENGTH OF SEND-BUFFER TO FML-LENGTH. CALL "FINIT" USING SEND-BUFFER FML-REC. IF NOT FOK MOVE "FINIT FAILED " TO LOGMSG-TEXT DISPLAY "FML-STATUS : " FML-STATUS PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF.
-
Convert the structure to a field buffer.
To send data to a service caller, convert structure data used in COBOL to field type data.
MOVE "viewdemo" TO VIEWNAME. SET FUPDATE TO TRUE. CALL "FVSTOF" USING SEND-BUFFER VIEWDEMO FML-REC. IF NOT FOK MOVE "FVSTOF FAILED " TO LOGMSG-TEXT DISPLAY "FML-STATUS : " FML-STATUS PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. 300-EXIT.
-
Send data to a client.
If the service executes successfully, TPSUCCESS must be used while executing TPRETURN.
****************************************************** * The service completed successfully. ****************************************************** 900-TPRETURNSCS. MOVE "The service executed successfully." TO LOGMSG-TEXT. PERFORM 800-USERLOG. SET TPSUCCESS TO TRUE. MOVE LENGTH OF SEND-BUFFER TO LEN. COPY TPRETURN REPLACING DATA-REC BY SEND-BUFFER. 900-TPRETURNSCS-X.
If the service fails to execute, TPFAIL must be used while executing TPRETURN.
****************************************************** * The service terminated abnormally. ****************************************************** 900-TPRETURNFAIL. MOVE "The service terminated abnormally." TO LOGMSG-TEXT. PERFORM 800-USERLOG. SET TPFAIL TO TRUE. MOVE "Cannot process " TO SDATA1. MOVE LENGTH OF SEND-BUFFER TO LEN. COPY TPRETURN REPLACING DATA-REC BY SEND-BUFFER. 900-TPRETURNFAIL-X.
2.5. Testing a Service Call
Call a service using the tmd utility without writing a client program.
$ cd TMAXDIR/sample/cobclient
$ tmd -i tmd_FDLINS
fkey = 469763049, fname = FDL_S1, type = string, value = TEST STRING
fkey = 469763050, fname = FDL_S2, type = string, value = TEST STRING1
fkey = 469763050, fname = FDL_S2, type = string, value = TEST STRING2
fkey = 469763050, fname = FDL_S2, type = string, value = TEST STRING3
fkey = 201328593, fname = FDL_I1, type = int, value = 20
fkey = 201328594, fname = FDL_I2, type = int, value = 30
fkey = 201328594, fname = FDL_I2, type = int, value = 10
fkey = 201328594, fname = FDL_I2, type = int, value = 10
fkey = 201328594, fname = FDL_I2, type = int, value = 10
fkey = 268438457, fname = FDL_L1, type = long, value = 10010
fkey = 268438458, fname = FDL_L2, type = long, value = 100010
fkey = 268438458, fname = FDL_L2, type = long, value = 200010
fkey = 268438458, fname = FDL_L2, type = long, value = 300010
fkey = 268438458, fname = FDL_L2, type = long, value = 10
fkey = 335548321, fname = FDL_F1, type = float, value = 20.123451
fkey = 335548322, fname = FDL_F2, type = float, value = 30.123449
fkey = 335548322, fname = FDL_F2, type = float, value = 10.000000
fkey = 335548322, fname = FDL_F2, type = float, value = 10.000000
fkey = 335548322, fname = FDL_F2, type = float, value = 10.000000
fkey = 402658185, fname = FDL_D1, type = double, value = 100010.123450
fkey = 402658186, fname = FDL_D2, type = double, value = 200010.123450
fkey = 402658186, fname = FDL_D2, type = double, value = 10.000000
fkey = 402658186, fname = FDL_D2, type = double, value = 10.000000
fkey = 402658186, fname = FDL_D2, type = double, value = 10.000000
Since the Tmax configuration file is not read, check TMAX_HOST_PORT, TMAX_HOST_ADDR, and FDLFILE, which are set in the user profile. |
3. Global Transaction Program
3.1. Example Program
The following is an example of a service program that uses global transactions.
<$TMAXDIR/sample/cobserver/carraynauto.pco>
****************************************************** * XA service that uses a CARRAY buffer * ****************************************************** IDENTIFICATION DIVISION. PROGRAM-ID. CARRAYNAUTO. …… WORKING-STORAGE SECTION. ****************************************************** * Definitions for Tmax ATMI functions ****************************************************** 01 TPSVCRET-REC. COPY TPSVCRET. * 01 TPTYPE-REC. COPY TPTYPE. * 01 TPSTATUS-REC. COPY TPSTATUS. * 01 TPSVCDEF-REC. COPY TPSVCDEF. * 01 TX-RETURN-STATUS. COPY TXSTATUS. …… PROCEDURE DIVISION. 000-MAIN. PERFORM 100-SVCSTART THRU 100-EXIT. PERFORM 200-DBINSERT THRU 200-EXIT. PERFORM 900-TPRETURNSCS THRU 900-TPRETURNSCS-X. 000-EXIT. 200-DBINSERT. MOVE RECV-STRING(1:LEN) TO S-TEMP-ARR. MOVE LENGTH OF S-TEMP-ARR TO S-TEMP-LEN. CALL "TXBEGIN" USING TX-RETURN-STATUS. IF NOT TPOK MOVE "FAIL TO TXBEGIN" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. * Handling DB INSERT EXEC SQL INSERT INTO TEMP (NAME,SAL) VALUES (RTRIM(:S-TEMP),150) END-EXEC. IF SQLCODE NOT = 0 PERFORM 800-SQLERROR PERFORM 800-USERLOG CALL "TXROLLBACK" USING TX-RETURN-STATUS IF NOT TPOK MOVE "txrollback ERROR " TO LOGMSG-TEXT PERFORM 800-USERLOG END-IF PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. CALL "TXCOMMIT" USING TX-RETURN-STATUS. IF NOT TPOK MOVE "TXCOMMIT ERROR" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. STRING "Inserted data : " S-TEMP-ARR DELIMITED BY SIZE INTO LOGMSG-TEXT. PERFORM 800-USERLOG. MOVE "Sunccessful " TO SEND-STRING. 200-EXIT.
The following describes each step in detail.
-
Start a global transaction.
CALL "TXBEGIN" USING TX-RETURN-STATUS. IF NOT TPOK MOVE "FAIL TO TXBEGIN" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF.
-
Commit a global transaction.
CALL "TXCOMMIT" USING TX-RETURN-STATUS. IF NOT TPOK MOVE "TXCOMMIT ERROR" TO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF.
-
Cancel a global transaction.
CALL "TXROLLBACK" USING TX-RETURN-STATUS IF NOT TPOK MOVE "txrollback ERROR " TO LOGMSG-TEXT PERFORM 800-USERLOG END-IF.
For a service that explicitly starts a transaction, "AUTOTRAN=N" (default value) must be set in the Tmax configuration file for Tmax 3.8.9 and later. If "AUTOTRAN=Y" is set, a global transaction automatically starts when a service starts. When the service explicitly uses TXBEGIN, it receives a TPEPROTO error.
Although "AUTOTRAN=N" is set, if both a client and a service explicitly start a transaction, TXBEGIN executed by the service returns the TPEPROTO error. |
4. Using TPSVRINIT and TPSVRDONE
4.1. TPSVRINIT
TPSVRINIT initializes a Tmax server. It executes only once when a Tmax server starts. In general, it performs a logic that links servers in a non-xa server group with a database. It is included in cobolsample.tar as tpsvrinit.pco and compiled (.o file is created) and linked with a server program object.
<$TMAXDIR/sample/cobserver/tpsvrinit.pco>
****************************************************** * To link non-XA server with DB (resource manager) ****************************************************** IDENTIFICATION DIVISION. PROGRAM-ID. TPSVRINIT. AUTHOR. TMAX DEVELOPMENT. ENVIRONMENT DIVISION. CONFIGURATION SECTION. DATA DIVISION. FILE SECTION. WORKING-STORAGE SECTION. EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 USERNAME PIC X(10) VARYING. 01 PASSWD PIC X(10) VARYING. EXEC SQL END DECLARE SECTION END-EXEC. EXEC SQL INCLUDE SQLCA END-EXEC. LINKAGE SECTION. 01 CMD-LINE. 05 ARGC PIC 9(4) COMP-5. 05 ARGV. 10 ARGS PIC X OCCURS 0 TO 9999 DEPENDING ON ARGC. 01 SERVER-INIT-STATUS. COPY TPSTATUS. * PROCEDURE DIVISION USING CMD-LINE SERVER-INIT-STATUS. * 000-TPSVRINIT-START. ****************************************************** * DB error check ****************************************************** EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC. DISPLAY "ARGC : " ARGC, " ARGV: " ARGV. ****************************************************** * DB connect ****************************************************** MOVE "SCOTT" TO USERNAME-ARR. MOVE 5 TO USERNAME-LEN. MOVE "TIGER" TO PASSWD-ARR. MOVE 5 TO PASSWD-LEN. EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWD END-EXEC. DISPLAY "CONNECTED TO ORACLE as User : " USERNAME-ARR. SET TPOK IN SERVER-INIT-STATUS TO TRUE. EXIT PROGRAM. SQL-ERROR. EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC. DISPLAY " ". DISPLAY "ORACLE ERROR DETECTED:". DISPLAY SQLERRMC. EXEC SQL ROLLBACK WORK RELEASE END-EXEC. SET TPEINVAL IN SERVER-INIT-STATUS TO TRUE. EXIT PROGRAM.
4.2. TPSVRDONE
TPSVRDONE terminates a Tmax server. It executes only once when a Tmax server terminates. In general, it performs a logic that unlinks servers in a non-xa server group with a database. It is included in cobolsample.tar as tpsvrdone.pco and compiled (.o file is created) and linked with a server program object.
<$TMAXDIR/sample/cobserver/tpsvrdone.pco>
****************************************************** * To unlink non-XA server with DB (resource manager) ****************************************************** IDENTIFICATION DIVISION. PROGRAM-ID. TPSVRDONE. AUTHOR. TMAX DEVELOPMENT. ENVIRONMENT DIVISION. CONFIGURATION SECTION. DATA DIVISION. FILE SECTION. WORKING-STORAGE SECTION. 01 SERVER-DONE-STATUS. COPY TPSTATUS. EXEC SQL INCLUDE SQLCA END-EXEC. * PROCEDURE DIVISION . * 000-TPSVRDONE-START. ****************************************************** * DB error check ****************************************************** EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC. ****************************************************** * DB disconnect ****************************************************** EXEC SQL COMMIT WORK RELEASE END-EXEC. DISPLAY " ". DISPLAY "DISCONNECTED TO ORACLE ". SET TPOK IN SERVER-DONE-STATUS TO TRUE. EXIT PROGRAM. SQL-ERROR. EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC. DISPLAY " ". DISPLAY "ORACLE ERROR DETECTED :". DISPLAY " ". DISPLAY SQLERRMC. EXEC SQL ROLLBACK WORK RELEASE END-EXEC. SET TPEINVAL IN SERVER-DONE-STATUS TO TRUE. EXIT PROGRAM.
4.3. Compiling and Starting a Service
Compile a service.
$ sh carray_nxa.sh
$ make -f carray_nxa.mk
Start the carray_nxa server.
$ tmboot -s carray_nxa
The server status can be checked using the $TMAXDIR/log/ulog/carray_nxa.out userlog file.
ARGC : 00023 ARGV: carray_nxa scott tiger CONNECTED TO ORACLE as User : SCOTT
5. Program Calling a Service from a Service
5.1. Example Program
The following is an example of a program that calls a service from a service.
< $TMAXDIR/sample/cobserver/svctpcall.pco >
****************************************************** * Service that uses a CARRAY buffer, not a DB * ****************************************************** IDENTIFICATION DIVISION. PROGRAM-ID. SVCTPCALL. AUTHOR. TMAX DEVELOPMENT. ENVIRONMENT DIVISION. CONFIGURATION SECTION. DATA DIVISION. FILE SECTION. WORKING-STORAGE SECTION. ****************************************************** * Definitions for Tmax ATMI functions ****************************************************** 01 TPSVCRET-REC. COPY TPSVCRET. * 01 TPTYPE-REC. COPY TPTYPE. * 01 TPSTATUS-REC. COPY TPSTATUS. * 01 TPSVCDEF-REC. COPY TPSVCDEF. ****************************************************** * Log message definitions ****************************************************** 01 LOGMSG. 05 LOGMSG-SVC PIC X(16). 05 FILLER PIC X(3) VALUES " : ". 05 LOGMSG-TEXT PIC X(50). 01 LOGMSG-LEN PIC S9(9) COMP-5. ****************************************************** * User defined data records ****************************************************** 01 RECV-STRING PIC X(100). 01 SEND-STRING PIC X(100). 77 NUM-TPSTATUS PIC 99. PROCEDURE DIVISION. * 000-MAIN. PERFORM 100-SVCSTART THRU 100-EXIT. PERFORM 200-TPCALL THRU 200-EXIT. PERFORM 900-TPRETURNSCS THRU 900-TPRETURNSCS-X. ****************************************************** * Receiving data from a client ****************************************************** 100-SVCSTART. …… 100-EXIT. ********************************************************** * tpcall in service ********************************************************** 200-TPCALL. MOVE "CARRAYNXA" TO SERVICE-NAME. MOVE LENGTH OF SEND-STRING TO LEN IN TPTYPE-REC. CALL "TPCALL" USING TPSVCDEF-REC TPTYPE-REC RECV-STRING TPTYPE-REC SEND-STRING TPSTATUS-REC . IF NOT TPOK MOVE "Service failed" TO LOGMSG-TEXT MOVE TP-STATUS TO NUM-TPSTATUS STRING "TPCALL call failed : " NUM-TPSTATUS DELIMITED BY SIZE INTO LOGMSG-TEXT PERFORM 800-USERLOG PERFORM 900-TPRETURNFAIL THRU 900-TPRETURNFAIL-X END-IF. 200-EXIT. ****************************************************** * Writing out a log error message ****************************************************** 800-USERLOG. DISPLAY LOGMSG. ****************************************************** * The service completed successfully. ****************************************************** 900-TPRETURNSCS. …… 900-TPRETURNSCS-X. ****************************************************** * service terminated abnormally. ****************************************************** 900-TPRETURNFAIL. …… 900-TPRETURNFAIL-X.
A service caller can be a Tmax client or service, which means that a Tmax service can be called from another Tmax service.
To call a service from another service, like the previous example, a buffer used in TPCALL must be used.
MOVE "CARRAYNXA" TO SERVICE-NAME. MOVE LENGTH OF SEND-STRING TO LEN IN TPTYPE-REC. CALL "TPCALL" USING TPSVCDEF-REC TPTYPE-REC RECV-STRING TPTYPE-REC SEND-STRING TPSTATUS-REC