Visual Basic Interface
This chapter describes functions used by a Visual Basic interface with examples.
1. Overview
Unlike Power Builder, a Visual Basic interface does not exist as a separate module. It is an interface module that defines function prototypes so that a developer can directly call a client library.
Visual Basic interface modules are as follows.
| Module | Description |
|---|---|
atmi.bas |
File that defines a prototype for atmi functions. |
fdl. Bas |
File that defines a prototype for field key functions. |
comm.bas |
File that defines user macros. |
ilewinapi.bas |
File that defines functions provided by Windows. |
Developers can call the functions provided by a Tmax client library by installing the Visual Basic interface modules. However, be aware that the Visual Basic interfaces send values in a way that is different from other applications. In addition, the Visual Basic interfaces provide users with a Macro (comm.bas) to internally input and output data, instead of allowing them directly manipulate buffers.
Macro provides the following functions.
| Function | Description |
|---|---|
Displays fberrno in a MsgBox with the provided StrErr message. |
|
Configures the tpstart_t struct, a buffer that needs to be configured to connect to the Tmax system. |
|
Inserts a string into the CARRAY buffer. |
|
Saves image data in a position of a field specified by a field name and a field index in byte array. |
|
Retrieves a value in a position of the field buffer specified by a field name and by the nth position set by fbchg_tu(), a Tmax FDL function. The value is CHAR type. |
|
Saves double data in a position of the field buffer specified by a field index and field name in dData. |
|
Saves single data in a position of the field buffer specified by a field index and a field name in dData. |
|
Saves integer data in a position of a field specified by a field index and field name in iData . |
|
Saves long data of a field specified by a field index and a field name as iData. |
|
Saves the data of the string buffer in text. |
|
Retrieves string data in a position of the field buffer specified by a field index and a field name in order to save the data as text. |
|
Saves the string data in the CARRAY buffer as text. |
|
Saves byte array of image data in the field buffer according to the field index. |
|
Saves a value in a field specified by a field name and by the nth position set by fbchg_tu(), a Tmax FDL function. |
|
Inserts double data in a position of the field buffer specified by a field name and a field index. |
|
Inserts single data in a position of the field buffer specified by a field index. |
|
Inserts integer data in a position of a field buffer specified by a field index. |
|
Inserts long data in a position of a field buffer specified by a field index. |
|
Inserts data in a string buffer as text. |
|
Inserts string data in a position of the field buffer specified by a field index. |
|
Displays a string error that corresponds to tperrno as MsgBox, along with the given StrErr message. |
|
For more information about prototypes and features of atmi and field key functions, refer to Tmax Reference Guide and Tmax Application Development Guide. |
2. Functions
2.1. FdlErrorMsg
Displays fberrno in a MsgBox with the provided StrErr message.
-
Prototype
Sub FdlErrorMsg(StrErr As String)
-
Parameter
Parameter Description StrErr
Error message.
-
Return value
Displays a message box.
-
Example
lret = fbput(ByVal lsendbuf, ByVal lfid, ByVal txtInput.text, ByVal 0) If lret = -1 Then FdlErrorMsg("fbput") error processing … End If -
Related functions
TmaxError()
2.2. FilltpstartBuf
Configures the tpstart_t struct, a buffer that needs to be configured to connect to the Tmax system.
-
Prototype
Function FilltpstartBuf(sndbufp As Long, startinfop As tpstart_t) As Long
-
Parameter
Parameter Description sndbufp
Buffer to be allocated to the memory by the tpalloc function.
startinfop
Variable defined in the tpstart_t type.
-
Example
Dim lsndbuf As Integer Dim lret As Integer Dim cinfo As tpstart_t lsndbuf = tpalloc("TPSTART", "", 0) If lsndbuf = 0 Then error processing End If cinfo.cltname = "tmax" + Chr(0) cinfo.usrname = "tmax" + Chr(0) cinfo.dompwd = "xamt" + Chr(0) cinfo.usrpwd = "batman" + Chr(0) cinfo.flags = TPUNSOL_HND lret = FilltpstartBuf(lsndbuf, cinfo) If ret < 0 Then error processing End If ret = tpstart(lsndbuf) If ret < 0 Then error processing End If … -
Related functions
TmaxError()
2.3. GETCAR
Inserts a string into the CARRAY buffer.
-
Prototype
Function GETCAR(ByVal Carptr&, text As String, Datalen As Long) As Long
-
Parameter
Parameter Description Carptr
Pointer to the FDL.
text
Data.
Datalen
Length of the data.
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lrecvbuf As Long Dim text As String Dim lret As Long Dim lrbuflen As Long … lsendbuf = tpalloc("CARRAY", "", 1024) lrecvbuf = tpalloc("CARRAY", "", 1024) … lret = tpcall(ByVal "SVC1", ByVal lsendbuf, ByVal DataLen&, lrecvbuf, lrbuflen, ByVal 0) … 'Data length must be set in the CARRAY buffer. lret = GETCAR(lsendbuf, text, lrbuflen) … -
Related functions
GETINT(), GETLONG(), GETDOUBLE(), GETVAR(), GETSTR(), GETFLOAT(), GETSTR(), GETCHR()
2.4. GETCAR_BA
Saves image data in a position of a field specified by a field name and a field index in byte array.
-
Prototype
Function GETCAR_BA (ByVal Fdlptr&, Field As String, idx As Long, ByRef ByteArray() As Byte, datalen As Long) As Long -
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
ByteArray
Data.
datalen
Length of the byte array.
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim rbuffer(102400) As Byte Dim datalen As Long … lrecvbuf = tpalloc("FIELD", "", 102400) … lret = PUTCAR_BA(ByVal lsendbuf, "TP_BITMAP", 0, lbuffer, datalen) if lret < 0 then error processing … end if … lret = tpcall(ByVal "FILEUP", ByVal lsendbuf, ByVal datalen&, lrecvbuf, lrbuflen, ByVal 0) lblComment.Caption = lblComment.Caption & " -> tpcall : " & lret If lret = -1 Then error processing … end If … lret = GETCAR_BA(ByVal lrecvbuf, "TP_BITMAP", 0, rbuffer, datalen) if lret < 0 then error processing … end if … -
Related functions
GETINT(), GETLONG(), GETDOUBLE(), GETCAR(), GETVAR(), GETFLOAT(), GETSTR(), GETCHR()
2.5. GETCHR
Retrieves a value in a position of the field buffer specified by a field name and by the nth position set by fbchg_tu(), a Tmax FDL function. The value is CHAR type.
-
Prototype
Function GETCHR(ByVal Fdlptr&, ByVal Field As String, ByVal idx As Integer, ByRef data As String, ByVal datalen As Integer) As Integer -
Parameter
Parameter Description Fldptr
Pointer to the string buffer.
Field
Field name.
idx
Field index.
data
String data to be stored.
datalen
Length of the string data to be stored.
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim chr As String lsendbuf = fballoc(10, 100) Irecvbuf = fballoc(10, 100) … lret = tpcall(ByVal "SVC1", ByVal lsendbuf, ByVal DataLen&, lrecvbuf, lrbuflen, ByVal 0) … lret = GETSTR(lrecvbuf, "CHR", 0, chr, 1 ) … -
Related functions
GETINT(), GETLONG(), GETDOUBLE(), GETVAR(), GETSTR(), GETCAR(), GETFLOAT()
2.6. GETDOUBLE
Saves double data in a position of the field buffer specified by a field index and field name in dData.
-
Prototype
Function GETDOUBLE(ByVal Fdlptr&, Field As String, idx As Long, dData As Double) As Long
-
Parameter
Parameter Description Fldptr
Pointer to the string buffer.
Field
Field name.
idx
Field index.
data
String data to be stored.
datalen
Length of the string data to be stored.
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim doubledata As Double lsendbuf = tpalloc("FIELD ", "", 0) … lret = GETDOUBLE(ByVal lsendbuf, "DOUBLEDATA", 0, doubledata) … -
Related functions
GETINT(), GETLONG(), GETVAR(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()
2.7. GETFLOAT
Saves single data in a position of the field buffer specified by a field index and a field name in dData.
-
Prototype
Function GETFLOAT (ByVal Fdlptr&, Field As String, idx As Long, dData As Single) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
dData
Data.
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim doubledata As Single lsendbuf = tpalloc("FIELD ", "", 0) … lret = GETFLOAT (ByVal lsendbuf, "DOUBLEDATA", 0, doubledata) … -
Related functions
GETINT(), GETLONG(), GETVAR(), GETCAR(), GETSTR(), GETCHR(), GETDOUBLE()
2.8. GETINT
Saves integer data in a position of a field specified by a field index and field name in iData.
-
Prototype
Function GETINT(ByVal Fdlptr&, Field As String, idx As Long, iData As Integer) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
iData
Data.
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim intdata As Integer lsendbuf = tpalloc("FIELD ", "", 0) lret = GETINT(ByVal lsendbuf, "INTDATA", 0, intdata) … -
Related functions
GETLONG(), GETDOUBLE(), GETVAR(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()
2.9. GETLONG
Saves long data of a field specified by a field index and a field name as iData.
-
Prototype
Function GETLONG(ByVal Fdlptr&, Field As String, idx As Long, lData As Long) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
iData
Data.
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim longdata As Long lsendbuf = tpalloc("FIELD ", "", 0) … lret = GETLONG(ByVal lsendbuf, "LONGDATA", 0, longdata) … -
Related functions
GETINT(), GETDOUBLE(), GETVAR(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()
2.10. GETSTR
Saves the data of the string buffer in text.
-
Prototype
Function GETSTR(ByVal strptr&, text As String) As Long
-
Parameter
Parameter Description strptr
Pointer to the string buffer.
text
Data.
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim text As String lsendbuf = fballoc(10, 100) Irecvbuf = fballoc(10, 100) … lret = tpcall(ByVal "SVC1", ByVal lsendbuf, ByVal DataLen&, lrecvbuf, lrbuflen, ByVal 0) … lret = GETSTR(lrecvbuf, text) … -
Related functions
GETINT(), GETLONG(), GETDOUBLE(), GETVAR(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()
2.11. GETVAR
Retrieves string data in a position of the field buffer specified by a field index and a field name in order to save the data as text.
-
Prototype
Function GETVAR(ByVal Fdlptr&, Field As String, idx As Long, text As String) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
iData
Data
-
Return value
Return value Description 1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long lsendbuf = tpalloc("FIELD ", "", 0) … lret = GETVAR(ByVal lsendbuf, "INPUT", 0, txtOutput.text) … -
Related functions
GETINT(), GETLONG(), GETDOUBLE(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()
2.12. PUTCAR
Saves the string data in the CARRAY buffer as text.
-
Prototype
Function PUTCAR(ByVal Carptr&, text As String, Datalen As Long) As Long
-
Parameter
Parameter Description Carptr
Pointer to the FDL buffer.
text
Data.
Datalen
Length of the data.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim lret As Long Dim DataLen As Long lsendbuf = tpalloc("CARRAY", "", 1024) 'The length of the data must be entered in the CARRAY buffer. DataLen = LenB(txtInput.text) lret = PUTCAR(ByVal lsendbuf, txtInput.text, DataLen) …Data can be entered to the string buffer by using the lstrcpy function provided by the system.
Dim lsendbuf As Long Dim lret As Long lsendbuf = tpalloc("STRING", "", 1024) lret = lstrcpy(ByVal lsendbuf, ByVal txtInput.text) -
Related functions
PUTINT(), PUTLONG(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR()
2.13. PUTCAR_BA
Saves byte array of image data in the field buffer according to the field index.
-
Prototype
Function PUTCAR_BA(ByVal Fdlptr&, Field As String, idx As Long, ByteArray() As Byte, datalen As Long) As Long -
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
ByteArray
Data.
datalen
Length of the byte array.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim iSrc As Integer Dim lCopy As Long Dim lSize As Long Dim lbuffer() As Byte Dim datalen As Long … lsendbuf = tpalloc("FIELD", "", 102400) … iSrc = FreeFile Open ".\nmlogo.bmp" For Binary Access Read As iSrc lSize = LOF(iSrc) datalen = lSize Do If lSize > MAX_BUFFER Then lSize = lSize - MAX_BUFFER lCopy = MAX_BUFFER Else lCopy = lSize End If ReDim lbuffer(lCopy - 1) Get iSrc, , lbuffer Loop Until lCopy = lSize Close iSrc lret = PUTCAR_BA(ByVal lsendbuf, "TP_BITMAP", 0, lbuffer, datalen) if lret < 0 then error processing … end if … -
Related functions
PUTINT(), PUTLONG(), PUTDOUBLE(), PUTCAR(), PUTVAR(), PUTFLOAT(), PUTSTR(), PUTCHR()
2.14. PUTCHR
Saves a value in a field specified by a field name and by the nth position set by fbchg_tu(), a Tmax FDL function. The CHAR type is used to save the data. If data already exists in the nth field, the data will be changed to the given value. If data does not exist in the nth field, the given data will be automatically added to the field.
-
Prototype
Function PUTCHR(ByVal Fdlptr&, ByVal Field As String, ByVal idx As Integer, ByRef data As String, ByVal datalen As Integer) As Integer -
Parameter
Parameter Description Fldptr
Pointer to the string buffer.
Fieldt
Field name.
idx
Field index.
data
String data to be stored.
datalen
Length of the string data to be stored.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim chr As String lsendbuf = fballoc(10, 100) chr = "a" … lret = PUTSTR(lsendbuf, "CHR", 0, chr, 1 ) … Function PUTCHR(ByVal Fdlptr&, ByVal Field As String, ByVal idx As Integer, ByRef data As Char, ByVal datalen As Integer) -
Related functions
PUTINT(), PUTLONG(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR()
2.15. PUTDOUBLE
Inserts double data in a position of the field buffer specified by a field name and a field index.
-
Prototype
Function PUTDOUBLE(ByVal Fdlptr&, Field As String, idx As Long, dData As Double) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
dData
Data.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim doubledata As Double lsendbuf = tpalloc("FIELD ", "", 0) … lret = PUTDOUBLE(ByVal lsendbuf, "DOUBLEDATA", 0, doubledata) … -
Related functions
PUTINT(), PUTLONG(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR(), PUTCHR()
2.16. PUTFLOAT
Inserts single data in a position of the field buffer specified by a field index.
-
Prototype
Function PUTFLOAT(ByVal Fdlptr&, Field As String, idx As Long, dData As Single) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
dData
Data.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim doubledata As Single lsendbuf = tpalloc("FIELD ", "", 0) … lret = PUTFLOAT(ByVal lsendbuf, "DOUBLEDATA", 0, doubledata) … -
Related functions
PUTINT(), PUTLONG(), PUTVAR(), PUTCAR(), PUTDOUBLE(), PUTSTR(), PUTCHR()
2.17. PUTINT
Inserts integer data in a position of a field buffer specified by a field index.
-
Prototype
Function PUTINT(ByVal Fdlptr&, Field As String, idx As Long, iData As Integer) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
iData
Data.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim intdata As Integer lsendbuf = tpalloc("FIELD ", "", 0) … lret = PUTINT(ByVal lsendbuf, "INTDATA", 0, intdata) … -
Related functions
PUTLONG(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR(), PUTCHR()
2.18. PUTLONG
Inserts long data in a position of a field buffer specified by a field index.
-
Prototype
Function PUTLONG(ByVal Fdlptr&, Field As String, idx As Long, lData As Long) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
lData
Data.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim longdata As Long lsendbuf = tpalloc("FIELD ", "", 0) … lret = PUTLONG(ByVal lsendbuf, "LONGDATA", 0, longdata) … -
Related functions
PUTINT(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR(), PUTCHR()
2.19. PUTSTR
Inserts data in a string buffer as text.
-
Prototype
Function PUTSTR(ByVal strptr&, text As String) As Long
-
Parameter
Parameter Description strptr
Pointer to the string buffer.
text
Data.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long Dim text As String lsendbuf = tpalloc("STRING", "", 1024) … lret = PUTSTR(lsendbuf, text) … -
Related functions
PUTINT(), PUTLONG(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTCHR()
2.20. PUTVAR
Inserts string data in a position of the field buffer specified by a field index.
-
Prototype
Function PUTVAR(ByVal Fdlptr&, Field As String, idx As Long, text As String) As Long
-
Parameter
Parameter Description Fdlptr
Pointer to the FDL buffer.
Field
Field name.
idx
Field index.
text
Data.
-
Return value
Return value Description Value other than -1
Function call is successful.
-1
Function call failed.
-
Example
Dim lsendbuf As Long Dim lret As Long lsendbuf = tpalloc("FIELD ", "", 0) … lret = PUTVAR(ByVal lsendbuf, "INPUT", 0, txtInput.text) … -
Related functions
PUTINT(), PUTLONG(), PUTDOUBLE(), PUTCAR(), PUTFLOAT(), PUTSTR(), PUTCHR()
2.21. TmaxError
Displays a string error that corresponds to tperrno as MsgBox, along with the given StrErr message.
-
Prototype
Sub TmaxError(StrErr As String)
-
Parameter
Parameter Description StrErr
Error message.
-
Return value
Displays a message window.

-
Example
Dim lsendbuf As Long Dim lrecvbuf As Long Dim lret As Long Dim lrbuflen As Long lsendbuf = tpalloc("CARRAY", "", 1024) lrecvbuf = tpalloc("CARRAY", "", 1024) lret = tpcall(ByVal "SVC1", ByVal lsendbuf, ByVal 0, lrecvbuf, lrbuflen, ByVal 0) If lret = -1 Then TmaxError ("tpcall (SVC1)") End If -
Related functions
FdlErrorMsg()
3. Example Program
A client program sends a service request that was received by a user. A server inserts, updates, inquires, and deletes data from the employee information (EMP) table of the Oracle database as the client requested.
3.1. Program Configuration
Both server and client environments must have been configured to use a client program. TMAXDIR, port number, and server IP are assumed to have been already configured.
The following example files are added as a module in a project.
-
<atmi.bas>
-
<fdl.bas>
-
<comm.bas>
-
<winapi.bas>
Each program consists of the following files.
-
Common programs
Program File Description demo.f
File that defines a field key buffer.
tmax
Library file.
tmconfig.m
Tmax environment configuration file.
-
Client programs
Program File Description EmployeeGrid.frm
Program that shows inquiry results.
EmployeeGrid.frx
Program that shows inquiry results.
EmployeeMgr.frm
Main program that inquires, updates, deletes, and inserts.
MSSCCPRJ.SCC
Source code control file.
QA_4GL.vbg
Client program group project file.
QA_4GL_Sample.exe
Client program executable file.
QA_4GL_Sample.vbp
Client program project file.
QA_4GL_Sample.vbw
Client program workspace file.
Atmi.bas
File that defines a prototype for atmi functions.
comm.bas
User macro definition file
fdl.bas
File that defines a prototype for field key functions.
winapi.bas
Function definition file provided by Windows.
-
Server program
Program File Description emp_c.mk
Makefile.
emp_c.pc
Server program that provides service. AIX and Oracle 9i are used.
3.2. Program Features
The following describes the features of each program.
-
Client programs
Function Description Tmax connection
NULL argument is used.
Buffer type
An 'fdl' file needs to be created by compiling a FIELD KEY buffer and a struct file.
Communication mode
A send buffer and a receive buffer must be specified differently for tpcall().
Transaction option
TMS allocates AutoTransaction.
-
Server programs
Function Description Service
FDLSELECT, FDLINSERT, FDLDELETE, and FDLUPDATE need to be created.
Database
Oracle database. Database information is specified in SVRGROUP of a system configuration file.
Communication type
A send buffer and a receive buffer must be specified differently for tpcall().
Transaction option
TMS allocates AutoTransaction.
3.3. Common Programs
DataBase EMP Table
The following is an example of Tmax EMP database (Oracle) table.
EMPNO NUMBER NOT NULL P1 ENAME VARCHAR(16) JOB VARCHAR(16) MGR NUMBER HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER
Tmax EMP Field Table
The following is an example of Tmax EMP field table.
<demo.f>
#For tmax demo employee program EMPNO 7500 long - - ENAME 7501 string - - JOB 7502 string - - MGR 7503 long - - DATE 7504 string - - SAL 7505 float - - COMM 7506 float - - DEPTNO 7507 long - - E_TYPE 9009 long - - E_CODE 9010 long - - E_MSG 9011 string - - E_TMP 9012 long - -
Tmax Environment Configuration
The following shows an example of Tmax environment configuration file.
<tmconfig.m>
*DOMAIN
dom1 SHMKEY = 70000, MAXUSER = 200, MINCLH = 1, MAXCLH = 5,
TPORTNO = 8888, BLOCKTIME = 200, TXTIME = 200
*NODE
tmax1 TMAXDIR = "/home/tmax",
APPDIR = "/home/tmax/appbin",
PATHDIR = "/home/tmax/path",
TLOGDIR = "/home/tmax/log/tlog",
SLOGDIR = "/home/tmax/log/slog"
ULOGDIR = "/home/tmax/log/ulog"
*SVRGROUP
svg1 NODENAME = tmax1,
DBNAME = ORACLE,
OPENINFO = "ORACLE_XA+Acc=P/scott/tiger+SesTm=60",
TMSNAME = svg1_tms
*SERVER
emp_c SVGNAME = svg1, MIN = 1
*SERVICE
FDLSELECT VRNAME = emp_c
FDLUPDATE SVRNAME = emp_c
FDLDELETE SVRNAME = emp_c
FDLINSERT SVRNAME = emp_c
3.4. Client Programs
Main Screen Format Design
The following shows a main screen format.

The following table shows the components of a main screen format.
| Control name | Control type | Note |
|---|---|---|
EmployeeMgr |
Form |
Caption="Employee management program" |
LabelErr |
Label |
Caption="Error" |
BtnExit |
Command button |
Caption="Close" |
BtnIns |
Command button |
Caption="Insert" |
BtnDel |
Command button |
Caption="Update" |
BtnUdt |
Command button |
Caption="Query" |
BtnSel |
Command button |
|
EditName |
Text box |
|
EditEmpNo |
Text box |
|
EditDept |
Text box |
|
EditComm |
Text box |
|
EditSal |
Text box |
|
EditDate |
Text box |
|
EditMgr |
Text box |
|
EditJob |
Text box |
The following example executes a designed main screen format.
EmployeeMgr.frm Source
Option Explicit
Private Sub BtnDel_Click()
Dim Isendbuf As Long
Dim Irecvbuf As Long
Dim Irbuflen As Long
Dim Iret As Long
Dim text As String
Dim value As Long
Dim dvalue As Double
Dim svalue As Single
Dim tx_b As Integer
Dim txbool As Integer 'If a transaction begins, 1 is returned. Otherwise 0 is returned.'
' tpstart '
tmaxStart
'Initializes the option to begin a transaction'
txbool = 0
If EditEmpNo.text = "" Then
MsgBox "Enter the emloyee number."
tmaxEnd
Exit Sub
End If
value = Trim(EditEmpNo.text)
' Allocate a buffer to send data '
Isendbuf = fballoc(100, 1024)
If Isendbuf = Null Then
TmaxError ("fballoc")
Call fbfree(Isendbuf)
tmaxEnd
Exit Sub
End If
' Allocate a buffer to receive data '
Irecvbuf = fballoc(100, 1024)
If Irecvbuf = Null Then
TmaxError ("fballoc")
Call fbfree(Irecvbuf)
tmaxEnd
Exit Sub
End If
Iret = PUTLONG(ByVal Isendbuf, "EMPNO", 0, value)
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Initiate a transaction '
Iret = tx_begin
txbool = 1
If Iret < 0 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Request for an inquiry service '
Iret = tpcall(ByVal "FDLDELETE", ByVal Isendbuf, ByVal 0, Irecvbuf,
Irbuflen, ByVal 0)
LabelErr.Caption = "sbuf = " & Isendbuf & ", rbuf = " & Irecvbuf
If Iret = -1 Then
TmaxError ("tpcall(SVC1)")
ViewErr (Irecvbuf)
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Save a transaction '
Iret = tx_commit
If Iret < 0 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
Else
txbool = 1
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
End Sub
Private Sub BtnExit_Click()
End
End Sub
Private Sub BtnIns_Click()
Dim Isendbuf As Long
Dim Irecvbuf As Long
Dim Irbuflen As Long
Dim Iret As Long
Dim text As String
Dim value As Long
Dim dvalue As Double
Dim svalue As Single
Dim lenL As Long
Dim txbool As Integer ' If a transaction begins, 1 is returned. Otherwise 0 is returned '
' tpstart '
tmaxStart
' Initializes the option to begin a transaction '
txbool = 0
If EditEmpNo.text = "" Then
MsgBox "Enter the employee number."
tmaxEnd
Exit Sub
End If
' Allocate a buffer to send data. '
Isendbuf = fballoc(100, 1024)
If Isendbuf = Null Then
TmaxError ("fballoc")
Call fbfree(Isendbuf)
tmaxEnd
Exit Sub
End If
' Allocate a buffer to receive data. '
Irecvbuf = fballoc(100, 1024)
If Irecvbuf = Null Then
TmaxError ("fballoc")
Call fbfree(Irecvbuf)
tmaxEnd
Exit Sub
End If
Iret = PUTLONG(ByVal Isendbuf, "EMPNO", 0, Trim(EditEmpNo.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTVAR(ByVal Isendbuf, "ENAME", 0, Trim(EditName.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTVAR(ByVal Isendbuf, "JOB", 0, Trim(EditJob.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTLONG(ByVal Isendbuf, "MGR", 0, Trim(EditMgr.text))
If Iret = -1 Then ' Initiate a transaction '
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTVAR(ByVal Isendbuf, "DATE", 0, Trim(EditDate.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
svalue = Trim(EditSal.text)
' The definition of fbput and fbget_fldkey functions are specified in the comm.bas file. '
' The fbget_fldkey function converts a field name to a key value. '
Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("SAL"), svalue, ByVal lenL)
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' The below comment can function the same as its subsequent statement. '
'svalue = Trim(EditComm.text)
'Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("COMM"), svalue, ByVal lenL)
'If Iret = -1 Then
' FdlErrorMsg ("fbput")
' Exit Sub
'End If
' Functions the same as the above comment. '
Iret = PUTFLOAT(ByVal Isendbuf, "COMM", 0, Trim(EditComm.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTLONG(ByVal Isendbuf, "DEPTNO", 0, Trim(EditDept.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Initiate a transaction '
Iret = tx_begin
txbool = 1
If Iret < 0 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Request for the updated service '
Iret = tpcall(ByVal "FDLINSERT", ByVal Isendbuf, ByVal 0, Irecvbuf,
Irbuflen, ByVal 0)
LabelErr.Caption = "sbuf = " & Isendbuf & ", rbuf = " & Irecvbuf
If Iret = -1 Then
TmaxError ("tpcall(SVC1)")
ViewErr (Irecvbuf)
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Save a transaction '
Iret = tx_commit
If Iret < 0 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
Else
txbool = 1
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
End Sub
' Function that displays an error related to Oracle. '
' Event handler that appears when the search button is clicked. '
Private Sub BtnSel_Click()
Hide
' Shows the search result window. '
EmployeeGrid.Show
End Sub
' Event handler that appears when the Update button is clicked. '
Private Sub BtnUdt_Click()
Dim Isendbuf As Long
Dim Irecvbuf As Long
Dim Irbuflen As Long
Dim Iret As Long
Dim text As String
Dim value As Long
Dim dvalue As Double
Dim svalue As Single
Dim lenL As Long
Dim txbool As Integer ' If a transaction begins, 1 is returned. Otherwise 0 is returned. '
' tpstart '
tmaxStart
' Option to begin a transaction '
txbool = 0
If EditEmpNo.text = "" Then
MsgBox "Enter the password number."
tmaxEnd
Exit Sub
End If
' Allocate a buffer to send data. '
Isendbuf = fballoc(100, 1024)
If Isendbuf = Null Then
TmaxError ("fballoc")
Call fbfree(Isendbuf)
tmaxEnd
Exit Sub
End If
' Allocate a buffer to receive data. '
Irecvbuf = fballoc(100, 1024)
If Irecvbuf = Null Then
TmaxError ("fballoc")
Call fbfree(Irecvbuf)
tmaxEnd
Exit Sub
End If
Iret = PUTLONG(ByVal Isendbuf, "EMPNO", 0, Trim(EditEmpNo.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTVAR(ByVal Isendbuf, "ENAME", 0, Trim(EditName.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTVAR(ByVal Isendbuf, "JOB", 0, Trim(EditJob.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTLONG(ByVal Isendbuf, "MGR", 0, Trim(EditMgr.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTVAR(ByVal Isendbuf, "DATE", 0, Trim(EditDate.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
svalue = Trim(EditSal.text)
' Declare Function fbput Lib "TMAX4GL.DLL"
(ByVal pFBUF As Long, ByVal fieldid As Long, pbuffer As Any,
ByVal Fieldlen As Long) As Long
Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("SAL"), svalue, ByVal lenL)
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
svalue = Trim(EditComm.text)
Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("COMM"), svalue, ByVal lenL)
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
Iret = PUTLONG(ByVal Isendbuf, "DEPTNO", 0, Trim(EditDept.text))
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Begin a transaction '
Iret = tx_begin
txbool = 1
If Iret < 0 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Requst for the updated service '
Iret = tpcall(ByVal "FDLUPDATE", ByVal Isendbuf, ByVal 0, Irecvbuf, Irbuflen,
ByVal 0)
LabelErr.Caption = "sbuf = " & Isendbuf & ", rbuf = " & Irecvbuf
If Iret = -1 Then
TmaxError ("tpcall(SVC1)")
ViewErr (Irecvbuf)
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Save a transaction '
Iret = tx_commit
If Iret < 0 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
Else
txbool = 1
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
End Sub
Private Sub ExitSub(txbool As Integer, Isendbuf As Long, Irecvbuf As Long)
If txbool = 1 Then
tx_rollback
End If
' Release an allocated buffer '
Call fbfree(ByVal Isendbuf&)
Call fbfree(ByVal Irecvbuf&)
' Function to execute tpend '
tmaxEnd
Exit Sub
End Sub
' tpstart '
Private Sub tmaxStart()
Dim ret As Integer
' Retrieve the environment configuration file. '
' It is defined in the atmi.bas file. '
' Declare Function tmaxreadenv Lib "TMAX4GL.DLL" (ByVal envfile As String,
ByVal label As String)
As Long '
' For the detailed information, refer to "Tmax Reference Guide".'
ret = tmaxreadenv("C:\tmax.env", "aix5l389")
If ret < 0 Then
TmaxError ("tmaxreadenv")
Exit Sub
End If
ret = tpstart(ByVal 0&)
If ret = -1 Then
LabelErr.Caption = "tpstart error = " & gettperrno()
TmaxError ("tpstart")
Exit Sub
Else
LabelErr.Caption = "tpstart return value = " & ret & " tpstart success"
End If
End Sub
' tpend '
Private Sub tmaxEnd()
Dim ret As Integer
ret = tpend()
If ret = -1 Then
LabelErr.Caption = "tpend error = " & gettperrno()
TmaxError ("tpend")
Exit Sub
Else
LabelErr.Caption = "tpreturn return value = " & ret
End If
End Sub
Oracle Error Display
The following figure is an Oracle error message display screen.

The following example shows the environment configuration necessary to execute an Oracle error message display screen.
' Funtion that displays Oracle error messages '
Private Sub ViewErr(ByVal a As Long)
'E_TYPE 9009 long - -
'E_CODE 9010 long - -
'E_MSG 9011 string - -
'E_TMP 9012 long - -
Dim typeL, codeL, tmpL As Long
Dim msgS As String
Dim Iret As Integer
' Refer to Tmax FDL Reference Guide. '
' The funtions are defined in comm.bas. '
Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_TYPE"), 0, typeL, 0)
If Iret = -1 Then
FdlErrorMsg ("fbget_tu")
Exit Sub
End If
Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_CODE"), 0, codeL, 0)
If Iret = -1 Then
FdlErrorMsg ("fbget_tu")
Exit Sub
End If
Iret = GETVAR(ByVal a, "E_MSG", 0, msgS)
If Iret = -1 Then
TmaxError ("ViewErr, GETVAR, E_MSG")
Exit Sub
End If
Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_TMP"), 0, tmpL, 0)
If Iret = -1 Then
FdlErrorMsg ("fbget_tu")
Exit Sub
End If
' Show error messages in a messge box. '
MsgBox ("Error Type : " & typeL & " ,Code : " & codeL & " ,Message :
" & msgS & " ,Tmp : " & tmpL)
End Sub
Employee Inquiry Screen
The following figure shows an employee inquiry screen format.

The following table shows the components of an inquiry screen format.
| Control name | Control type | Property to update |
|---|---|---|
EmployeeGrid |
Form |
Caption="List of employee information" |
InfoText |
Text box |
MultiLine=True |
BtnReturn |
Command button |
Caption="Return" |
The following example executes a designed inquiry screen format.
EmployeeGrid.frm Source LabelErr
Option Explicit
' Close the inquiry window. '
Private Sub BtnReturn_Click()
Hide
EmployeeMgr.Show
End Sub
' Function that shows the inquiry results when the Inquire button is clicked. '
Private Sub Form_Activate()
Dim Isendbuf As Long
Dim Irecvbuf As Long
Dim Irbuflen As Long
Dim Iret As Integer
Dim text As String
Dim value As Long
Dim dvalue As Double
Dim svalue As Single
Dim lenL As Long
Dim initS, outputS As String
Dim empnoS, enameS, jobS, mgrS, dateS, salS, commS, deptnoS As String
Dim cntL As Long
Dim eNo As Long
Dim txbool As Integer ' If a transaction begins, 1 is returned. Otherwise 0 is returned. '
' tpstart '
tmaxStart
' Initialize an option to begin a transaction '
txbool = 0
initS = vbCrLf & vbTab & vbTab & vbTab & "***** Query Results *****"
& vbCrLf & vbTab & "==================================================="
& vbCrLf & vbTab & "Employee Number Name Position Manager Data Hired Salary COMM Dept."
& vbCrLf & vbTab & "==================================================="
& vbCrLf & vbCrLf
If EmployeeMgr.EditEmpNo.text = "" Then
MsgBox "Enter the employee number."
Hide
EmployeeMgr.Show
Exit Sub
End If
' Allocate a buffer to send data '
Isendbuf = fballoc(100, 1024)
If Isendbuf = Null Then
TmaxError ("fballoc")
Call fbfree(Isendbuf)
tmaxEnd
Exit Sub
End If
' Allocate a buffer to receive data '
Irecvbuf = fballoc(100, 1024)
If Irecvbuf = Null Then
TmaxError ("fballoc")
Call fbfree(Irecvbuf)
tmaxEnd
Exit Sub
End If
' Retreive an employee number from the employee management page. '
eNo = Trim(EmployeeMgr.EditEmpNo.text)
Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("EMPNO"), eNo, ByVal lenL)
If Iret = -1 Then
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
' Request for inquiry service '
Iret = tpcall(ByVal "FDLSELECT", ByVal Isendbuf, ByVal 0, Irecvbuf, Irbuflen,
ByVal 0)
If Iret = -1 Then
ViewErr (Irecvbuf)
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
cntL = fbkeyoccur(ByVal Irecvbuf, ByVal fbget_fldkey("EMPNO"))
Dim i As Long
For i = 0 To cntL - 1
Iret = GETLONG(ByVal Irecvbuf, "EMPNO", i, value)
If Iret = -1 Then
TmaxError ("GETLONG(EMPNO)")
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
empnoS = value
Iret = GETVAR(ByVal Irecvbuf, "ENAME", i, text)
If Iret = -1 Then
TmaxError ("GETVAR(ENAME)")
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
enameS = text
Iret = GETVAR(ByVal Irecvbuf, "JOB", i, text)
If Iret = -1 Then
TmaxError ("GETVAR(JOB)")
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
jobS = text
Iret = GETLONG(ByVal Irecvbuf, "MGR", i, value)
If Iret = -1 Then
TmaxError ("GETLONG(MGR)")
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
mgrS = value
Iret = GETVAR(ByVal Irecvbuf, "DATE", i, text)
If Iret = -1 Then
TmaxError ("GETVAR(DATE)")
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
dateS = text
' Retreive float data from SAL data field. '
' The function is defined in comm.bas. '
Iret = fbget_tu(ByVal Irecvbuf, ByVal fbget_fldkey("SAL"), i, svalue, 0)
If Iret = -1 Then
FdlErrorMsg ("fbget_tu")
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
salS = svalue
Iret = GETFLOAT(ByVal Irecvbuf, "COMM", i, svalue)
If Iret = -1 Then
TmaxError ("GETFLOAT(COMM)")
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
commS = svalue
Iret = GETLONG(ByVal Irecvbuf, "DEPTNO", i, value)
If Iret = -1 Then
TmaxError ("GETLONG(DEPTNO)")
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End If
deptnoS = value & vbCrLf
outputS = outputS & " " & empnoS & vbTab & enameS & vbTab & jobS
& vbTab & mgrS & vbTab & dateS & vbTab
& salS & vbTab & commS & vbTab & deptnoS
Next i
InfoText.text = initS & outputS
' Displays returned data in the text box '
LabelErr.Caption = "SAL = " & dvalue
Call ExitSub(txbool, Isendbuf, Irecvbuf)
End Sub
Private Sub ExitSub(txbool As Integer, Isendbuf As Long, Irecvbuf As Long)
If txbool = 1 Then
tx_rollback
End If
' Release the allocated buffer '
Call fbfree(ByVal Isendbuf&)
Call fbfree(ByVal Irecvbuf&)
' Function that executes tpend '
tmaxEnd
Exit Sub
End Sub
' tpstart '
Private Sub tmaxStart()
Dim ret As Integer
' Retreive the environment configuration file. '
' It is defined in the atmi.bas file. '
' Declare Function tmaxreadenv Lib "TMAX4GL.DLL"(ByVal envfile As String,
ByVal label As String) As Long '
' For the detailed information, refer to "Tmax Reference Guide". '
ret = tmaxreadenv("C:\tmax.env", "aix5l389")
If ret < 0 Then
TmaxError ("tmaxreadenv")
Exit Sub
End If
ret = tpstart(ByVal 0&)
If ret = -1 Then
LabelErr.Caption = "tpstart error = " & gettperrno()
TmaxError ("tpstart")
Exit Sub
Else
LabelErr.Caption = "tpstart return value = " & ret & " tpstart success"
End If
End Sub
' tpend '
Private Sub tmaxEnd()
Dim ret As Integer
ret = tpend()
If ret = -1 Then
LabelErr.Caption = "tpend error = " & gettperrno()
TmaxError ("tpend")
Exit Sub
Else
LabelErr.Caption = "tpreturn return value = " & ret
End If
End Sub
' Function that displays Oracle errors '
Private Sub ViewErr(ByVal a As Long)
'E_TYPE 9009 long - -
'E_CODE 9010 long - -
'E_MSG 9011 string - -
'E_TMP 9012 long - -
Dim typeL As Long
Dim codeL As Long
Dim msgS As String
Dim tmpL As Long
Dim Iret As Integer
Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_TYPE"), 0, typeL, 0)
If Iret = -1 Then
FdlErrorMsg ("fbget_tu")
Exit Sub
End If
Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_CODE"), 0, codeL, 0)
If Iret = -1 Then
FdlErrorMsg ("fbget_tu")
Exit Sub
End If
Iret = GETVAR(ByVal a, "E_MSG", 0, msgS)
Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_TMP"), 0, tmpL, 0)
If Iret = -1 Then
FdlErrorMsg ("fbget_tu")
Exit Sub
End If
MsgBox ("Error Type : " & typeL & " ,Code : " & codeL & " ,Message : "&msgS&",
Tmp : " & tmpL)
End Sub
3.5. Server Programs
Service Programs
The following is an example of service program.
<emp_c.pc>
#include <stdio.h>
#include <ctype.h>
#include <tuxinc/macro.h>
#include "../../fdl/demo_fdl.h"
EXEC SQL include sqlca.h;
EXEC SQL INCLUDE ORACA;
EXEC ORACLE OPTION (ORACA=YES);
EXEC ORACLE OPTION (RELEASE_CURSOR=YES);
#define INP 1
#define ORA 2
#define TMX 3
#define APP 4
EXEC SQL begin declare section;
int h_empno;
char h_ename[11];
char h_job[10];
int h_mgr;
char h_date[11];
float h_sal;
float h_comm;
int h_deptno;
EXEC SQL end declare section;
void svc_error(long type, long err_code, char *msg, long tmp);
FDLINSERT( TPSVCINFO *msg )
{
FBUF *rcvbuf;
int i, occurrence;
rcvbuf = (FBUF *)msg->data;
h_empno = h_mgr = h_sal = h_comm = h_deptno = 0;
memset(h_ename, 0x00, sizeof(h_ename));
memset(h_job, 0x00, sizeof(h_job));
memset(h_date, 0x00, sizeof(h_date));
occurrence = fbkeyoccur(rcvbuf, EMPNO);
for (i=0; i< occurrence; i++){
fbget_tu(rcvbuf, EMPNO, i, (char *)&h_empno, 0);
fbget_tu(rcvbuf, MGR, i, (char *)&h_mgr, 0);
fbget_tu(rcvbuf, SAL, i, (char *)&h_sal, 0);
fbget_tu(rcvbuf, COMM, i, (char *)&h_comm, 0);
fbget_tu(rcvbuf, DEPTNO,i, (char *)&h_deptno, 0);
fbget_tu(rcvbuf, ENAME, i, (char *)h_ename, 0);
fbget_tu(rcvbuf, JOB , i, (char *)h_job, 0);
fbget_tu(rcvbuf, DATE , i, (char *)h_date, 0);
EXEC SQL INSERT
INTO emp(empno, ename, job, mgr, hiredate, sal,comm, deptno)
VALUES (:h_empno, :h_ename, :h_job, :h_mgr,
to_date(:h_date,'yyyymmdd'), :h_sal, :h_comm, :h_deptno );
}
if(sqlca.sqlcode != 0)
goto LB_DBERROR;
EXEC SQL WHENEVER SQLERROR
goto LB_DBERROR;
tpreturn(TPSUCCESS, 0L, (char *)rcvbuf, 0L, 0L);
LB_DBERROR :
EXEC SQL WHENEVER SQLERROR CONTINUE;
svc_error(ORA, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, 0);
}
FDLDELETE( TPSVCINFO *msg )
{
FBUF *rcvbuf;
int i, occurrence;
rcvbuf = ( FBUF *)msg->data;
occurrence = fbkeyoccur(rcvbuf, EMPNO);
for (i=0; i< occurrence; i++){
fbget_tu (rcvbuf, EMPNO, i, (char *)&h_empno , 0);
EXEC SQL DELETE
FROM emp
WHERE empno = :h_empno;
}
if(sqlca.sqlcode != 0)
goto LB_DBERROR;
EXEC SQL WHENEVER SQLERROR
goto LB_DBERROR ;
EXEC SQL WHENEVER NOT FOUND
goto LB_DBERROR ;
tpreturn(TPSUCCESS, 0L, (char *)rcvbuf, 0L, 0L);
LB_DBERROR :
EXEC SQL WHENEVER SQLERROR CONTINUE;
svc_error(ORA, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, 0);
}
FDLSELECT( TPSVCINFO *msg )
{
FBUF *rcvbuf;
FLDLEN fldlen;
int i=0, ROWMEM=200, CHKROW=500;
rcvbuf = (FBUF *)msg->data;
if((rcvbuf=(FBUF *)tprealloc((char *)rcvbuf,ROWMEM*CHKROW))==NULL) {
rcvbuf=(FBUF *)msg->data;
goto LB_TMAXERROR ;
}
h_empno = h_mgr = h_sal = h_comm = h_deptno = 0;
memset( h_ename, 0x00, sizeof( h_ename ) );
memset( h_job, 0x00, sizeof( h_job ) );
memset( h_date, 0x00, sizeof( h_date ) );
fbget_tu( rcvbuf, EMPNO, 0, (char *)&h_empno, &fldlen);
EXEC SQL DECLARE DB_CUR CURSOR FOR
SELECT nvl(empno,0), nvl(ename,' '), nvl(job,' '),
nvl(to_char(hiredate,'yyyymmdd'),' '), nvl(mgr,0),
nvl(sal,0), nvl(comm,0), nvl(deptno,0)
FROM emp
WHERE empno >= :h_empno-50 AND empno <= :h_empno+50;
EXEC SQL OPEN DB_CUR;
if(sqlca.sqlcode != 0)
goto LB_DBERROR;
EXEC SQL WHENEVER SQLERROR
goto LB_DBERROR ;
EXEC SQL WHENEVER NOT FOUND
Do break ;
while(1) {
EXEC SQL FETCH DB_CUR
INTO :h_empno,
:h_ename,
:h_job,
:h_date,
:h_mgr,
:h_sal,
:h_comm,
:h_deptno;
fbchg_tu(rcvbuf, EMPNO, i,(char *)&h_empno, 0);
fbchg_tu(rcvbuf, MGR, i,(char *)&h_mgr, 0);
fbchg_tu(rcvbuf, SAL, i,(char *)&h_sal, 0);
fbchg_tu(rcvbuf, DEPTNO, i,(char *)&h_deptno, 0);
fbchg_tu(rcvbuf, COMM, i,(char *)&h_comm, 0);
fbchg_tu(rcvbuf, ENAME, i,(char *)h_ename, 0);
fbchg_tu(rcvbuf, JOB, i,(char *)h_job, 0);
fbchg_tu(rcvbuf, DATE, i,(char *)h_date, 0);
i++;
}
if (i < 1) goto LB_DBERROR;
EXEC SQL CLOSE DB_CUR;
tpreturn(TPSUCCESS, 0L, (char *)rcvbuf, 0L, 0L);
LB_DBERROR :
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL CLOSE DB_CUR ;
svc_error(ORA, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, 0L) ;
LB_TMAXERROR :
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL CLOSE DB_CUR;
svc_error(TMX, tperrno, "", 0L);
}
FDLUPDATE( TPSVCINFO *msg )
{
FBUF *rcvbuf ;
int i, occurrence;
rcvbuf = (FBUF *)msg->data;
h_empno = h_mgr = h_sal = h_comm = h_deptno = 0;
memset( h_ename, 0x00, sizeof( h_ename ) );
memset( h_job, 0x00, sizeof( h_job ) );
memset( h_date, 0x00, sizeof( h_date ) );
occurrence = fbkeyoccur(rcvbuf, EMPNO);
for (i=0; i< occurrence; i++){
fbget_tu ( rcvbuf, EMPNO, i, (char *)&h_empno, 0);
fbget_tu ( rcvbuf, ENAME, i, (char *)h_ename, 0);
fbget_tu ( rcvbuf, JOB, i, (char *)h_job, 0);
fbget_tu ( rcvbuf, MGR, i, (char *)&h_mgr, 0);
fbget_tu ( rcvbuf, SAL, i, (char *)&h_sal, 0);
fbget_tu ( rcvbuf, COMM, i, (char *)&h_comm,0);
fbget_tu ( rcvbuf, DEPTNO, i, (char *)&h_deptno,0);
fbget_tu ( rcvbuf, DATE, i, (char *)h_date, 0);
EXEC SQL UPDATE emp
SET ename = nvl(:h_ename, ename),
job = nvl(:h_job, job),
mgr = :h_mgr,
hiredate = nvl(to_date(:h_date,
'yyyymmdd'),hiredate),
sal = :h_sal,
comm = :h_comm,
deptno = :h_deptno
WHERE empno = :h_empno;
if(sqlca.sqlcode != 0)
goto LB_DBERROR;
EXEC SQL WHENEVER SQLERROR
goto LB_DBERROR;
EXEC SQL WHENEVER NOT FOUND
goto LB_DBERROR;
}
tpreturn(TPSUCCESS, 0L, (char *)rcvbuf, 0L, 0L);
LB_DBERROR :
EXEC SQL WHENEVER SQLERROR CONTINUE;
svc_error(ORA, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, 0L) ;
}
/*********************************************************************
* Error Processing: If an error occurs in a service routine, the error is entered to the buffer and sent to the client.
********************************************************************/
void svc_error(long type, long err_code, char *msg, long tmp) {
FBUF *transf;
char *svcname;
char err_msg[100];
char temp[100];
int i = 0;
printf("type ==>[%ld]\n", type);
printf("err_code ==>[%ld]\n", err_code);
printf("msg ==>[%s]\n", msg);
strcpy(err_msg, msg);
if ((transf = (FBFR *)tpalloc("FML", NULL, 0)) == NULL) {
printf("tpalloc failed! errno = %d\n", tperrno);
}
switch(type) {
case INP:
switch(err_code) {
case -1000:
strcpy(err_msg,"The user is not authorized.");
break;
default:
strcpy(err_msg,
"Input error message is not registered.");
}
break;
case ORA:
if (strlen(err_msg)== 0)
strcpy(err_msg, sqlca.sqlerrm.sqlerrmc);
break;
case TMX:
if (strlen(err_msg)== 0)
strcpy(err_msg, tpstrerror(tperrno));
break;
case APP:
if (strlen(err_msg)== 0) {
/* Sets an error message if * err_mssg="" is specified. ******/
switch(err_code) {
case -500: /* SYSTEM Error */
strcpy(err_msg,"File creation error.");
break;
case -502:
strcpy(err_msg,"Failed to call an internal service.");
break;
case -504:
strcpy(err_msg, "Socket communication error.");
break;
case -505: /* Displays 'processing error if the application is updated by another transaction.*/
/* "[%s] has been updated by another application after an inquiry is performed.
\n\nQuery again and process it.": Processed in a client*/
strcpy(err_msg, "does not exist.");
break;
case -5002:
strcpy(err_msg, "Contact to the computer center.");
break;
default:
strcpy(err_msg,
"Application Error Message is not registered.");
}
}
break;
}
/* ROLLBACK */
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL ROLLBACK;
fbchg_tu ( transf, E_TYPE, i, (char *)&type,0);
fbchg_tu ( transf, E_CODE, i, (char *)&err_code,0);
fbchg_tu ( transf, E_MSG, i, (char *)err_msg,0);
fbchg_tu ( transf, E_TMP, i, (char *)&tmp,0);
tpreturn(TPFAIL, 0, (char *)transf, 0L, 0L);
}
Makefile
The following example creates an emp_c.pc source as a Tmax application.
<emp_c.mk>
include $(ORACLE_HOME)/precomp/lib/env32.mk
ORALIBDIR = $(LIBHOME)
ORALIB = -L/home/oracle/OraHome/lib32/ -lclntsh -lld -lm `cat
/home/oracle/OraHome/lib32/sysliblist` -lm -lc_r -lpthreads
TARGET = emp_c
APOBJS = emp_c.o
NSDLOBJ = $(TMAXDIR)/lib/sdl.o
#CC
CC=cc
#Oracle
LIBS = -lsvr -loras
OBJS = $(APOBJS) $(SVCTOBJ)
SVCTOBJ = $(TARGET)_svctab.o
CFLAGS = -q32 -O -I$(TMAXDIR)
LDFLAGS = -brtl
APPDIR = $(TMAXDIR)/appbin
SVCTDIR = $(TMAXDIR)/svct
TMAXLIBDIR = $(TMAXDIR)/lib
#
.SUFFIXES : .c
.c.o:
$(CC) $(CFLAGS) $(LDFLAGS) -c $<
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -L$(TMAXLIBDIR) -o $(TARGET)
-L$(ORALIBDIR) $(ORALIB) $(OBJS) $(LIBS) $(NSDLOBJ)
mv $(TARGET) $(TMAXDIR)/appbin
$(APOBJS): $(TARGET).pc
proc iname=emp_c include=$(TMAXDIR)
define=__LINUX_ORACLE_PROC__
$(CC) $(CFLAGS) $(LDFLAGS) -c $(TARGET).c
$(SVCTOBJ):
touch $(SVCTDIR)/$(TARGET)_svctab.c
$(CC) $(CFLAGS) $(LDFLAGS) -c $(SVCTDIR)/$(TARGET)_svctab.c
#
clean:
-rm -f *.o core $(TARGET) $(TARGET).lis