The following is an example of a C proxy program using Decimal Precision attribute. This code is hand-written not generated.
/*
* This sample's purpose is to provide a C programmer a starting
* point for coding a C proxy routine.
*
* This sample builds upon the CA (R) Gen sample model that is included
* with the CA Gen Toolset. The Gen server module used by this proxy
* example is packaged within the sample model as load module P900. This proxy
* example will only exercise a small amount of the sample models capabilities.
*
* This example application performs the following actions:
* - delDiv - deletes 4 division name records based on data specified in
* the import view. Implemented in the delete() function.
* - addDiv - adds four division name records based on data specified in the
* import view. Implemented in the add() function.
* - readDiv - retrieves division name records and moves them to the export
* repeating group view. Implemented in the read function.
* - check - the check function extracts data from the returned export
* view depending upon the delete/add/read operation just executed
*
* - The import view assignment statements are hard coded. In your
* application you will probably use a GUI interface to query for
* values.
*
* - The export views are displayed on the screen. In your application
* you will probably use a GUI interface to display these values.
*
* NOTE: Variable Name Case Sensitivity
*
* The C Proxy API uses case sensitivity to use the procedure step name
* as multiple variable names. If you use this sample C program as a basis
* for your program, take care to "match case" when replacing variable names.
*
* For example:
*
* - SERVER_DETAIL_DIVISION is used to represent the TranEntry data structure
* which contains all the information needed for a transaction (such as
* trancode and model name).
*
* - server_detail_division is used to represent the transaction specific
* view data structure which will be used to reference import and export
* views.
*
*
* This proxy example is designed to communicate with a server packaged
* within the CA Gen sample model which is included with the product
* distribution. The sample model's Cooperative Server load module P900
* must be generated and installed within the target environment to which
* this C proxy is to communicate, prior to attempting to execute this
* sample.
*/
/* Include the Gen C Proxy generated header file created from the
* sample model included with the product distribution
*/
#include "p900.h"
/* the following value is one of the returned exit state values. It's
* definition was obtained from server generated code. Additional exit state
* values could be obtained if desired.
*/
#define gui_return_from_link 219941543
/* Include other standard libraries as needed */
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef WIN32
/* for Windows */
#include <windows.h>
#define SLEEP(i) Sleep(i*1000)
#else
/* for UNIX */
#include <unistd.h>
#define SLEEP(i) sleep(i)
#endif
/* Contains communication information */
static ProxyParam* psParamBlock;
/* Used to store a communication configuration string */
char comcfg[256];
/* Error message length can be from 0-2048 this will determine
* how much of the error message will be returned by ProxyExecute.
* A shorter message may be returned depending on the error.
*/
#define errMsgLen 2048
char errMsg[errMsgLen];
/* Return code from routines {Failure, Success}
* ProxyExecuteReturnValues is defined in the proxyexe.h file supplied
* with the Gen installation.
*/
ProxyExecuteReturnValues ReturnVal;
/* Misc defines */
int nRC; /* Integer return code */
char ClientUserid[ProxyClientUseridLen+1]= "MYUSER";
char ClientPassword[ProxyClientPasswordLen+1]= "123";
char Dialect[ProxyDialectLen + 1] = "DEFAULT";
char NextLocation[ProxyNextLocationLen+1] = "TEST";
/* Command is one of A (add), D (delete), R (read) */
char Command[ProxyCommandLen+1] = " ";
long ExitStateNum;
MsgType ExitMsgType;
char ExitStateMsg[ProxyExitStateMsgLen+1];
char OutClientUserid[ProxyClientUseridLen+1];
char OutClientPassword[ProxyClientPasswordLen+1];
char OutDialect[ProxyDialectLen + 1];
char OutNextLocation[ProxyNextLocationLen+1];
char OutCommand[ProxyCommandLen+1];
long OutExitStateNum;
MsgType OutExitMsgType;
char OutExitStateMsg[ProxyExitStateMsgLen+1];
/* local function prototypes */
ProxyExecuteReturnValues addDiv();
ProxyExecuteReturnValues delDiv();
ProxyExecuteReturnValues readDiv();
void check();
int main (void)
{
printf ("Beginning of sample C proxy application \n\n");
/************************************************************************/
/* Setup */
/* ProxyStartTracing opens a file for debug/status information.
* ProxyStopTracing will be used to close the file.
* This function is optional, but must be called before ProxyTraceOut
* if used
* - The first parameter must be valid filename, the file will be
* created
* - The second parameter is the trace level.
* 0xFFFFFFFF requests the highest (verbose) level of messages.
* NULL indicates that the value of the CMIDEBUG environment
* variable should be used to determine the trace level
* Functions which return with a Failure status will generally write
* detailed information regarding the failure to the trace file.
*/
ProxyStartTracing((char *) "cproxy.out", (char*)"0xFFFFFFFF");
/* ProxyTraceOut writes a message to the trace file. These
* messages will be interspersed with standard debugging messages.
* This function call is optional.
*/
ProxyTraceOut(NULL, (char *) "CPROXY.C - ***** Beginning program");
/* ProxyAllocateParamBlock is used to create the parameter block
* (data structure) which contains information required for the
* transaction. A NULL return indicates an error in the creation
* of the parameter block.
* This function call is required.
*/
psParamBlock = ProxyAllocateParamBlock();
if (NULL == psParamBlock)
{
printf("Unsuccessful return from ProxyAllocateParamBlock\n");
return (Failure);
}
/* ProxySetClientUserid is used to set a userid in the parameter block.
* This function call is required if security on the server is used,
* otherwise it is optional.
*/
nRC = ProxySetClientUserid(psParamBlock, ClientUserid);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxySetClientUserid\n");
return (Failure);
}
/* ProxySetClientPassword is used to set a password in the parameter
* block.
* This function call is required if security on the server is used,
* otherwise it is optional.
*/
nRC = ProxySetClientPassword(psParamBlock, ClientPassword);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxySetClientPassword\n");
return (Failure);
}
/* ProxySetDialect is used to set the dialect in the parameter block.
* This function call is optional.
*/
nRC = ProxySetDialect(psParamBlock, Dialect);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxySetDialect\n");
return (Failure);
}
/* ProxySetNextLocation is used to set the next location in the parameter
* block.
* This function call is optional.
*/
nRC = ProxySetNextLocation(psParamBlock, NextLocation);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxySetNextLocation\n");
return (Failure);
}
/* ProxySetCommand is used to set the command in the parameter block.
* This function call is optional.
*/
nRC = ProxySetCommand(psParamBlock, Command);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxySetCommand\n");
return (Failure);
}
#ifndef TUXEDO
/* NOTE: ProxyConfigureComm() must not be called if targeting a Tuxedo Server
* environment. Tuxedo environment does not support retargeting the server.
*/
/* ProxyConfigureComm is used to set communication options.
* This function call is optional, communication options can be set in
* the following ways:
* - by specifying the options in the SERVER_DETAIL_DIVISION structure
* without a call to ProxyConfigureComm
* - by calling ProxyConfigureComm with a NULL third parameter to
* indicate that the file commcfg.ini should be used
* - by calling ProxyConfigureComm with a string containing the
* Comm Service Type, Host and Port as the third parameter
*/
/* This call to ProxyConfigureComm will use the file commcfg.ini
* NOTE: the commcfg.ini file must contain a valid override entry
* if this call is to succeed.
*/
nRC = ProxyConfigureComm(&SERVER_DETAIL_DIVISION, SERVER_DETAIL_DIVISION.service, NULL);
if (nRC == FALSE)
{
printf("Unsuccessful return from ProxyConfigureComm using File\n");
return (Failure);
}
/* This call to ProxyConfigureComm will use the string containing the
* Comm Service Type, Host and Port to set communication
* options. Be sure to include a space between each token.
*/
strcpy( comcfg, "TCP " ); /* Comm Service Type */
strcat( comcfg, "hostname " ); /* Host */
strcat( comcfg, "port#" ); /* Port */
nRC = ProxyConfigureComm(&SERVER_DETAIL_DIVISION, SERVER_DETAIL_DIVISION.service, comcfg);
if (nRC == FALSE)
{
printf("Unsuccessful return from ProxyConfigureComm using comcfg string \n");
return (Failure);
}
#endif /* ! TUXEDO */
/* The ProxyClear set of functions are used to clear the parameter block.
* Each part of the parameter block can be cleared individually, or the
* ProxyClearParamBlock function can be used to clear the entire
* parameter block.
* These function calls are optional.
* The ProxyClearParamBlock function would replace the other ProxyClear
* functions shown further below.
*/
nRC = ProxyClearParamBlock(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearParamBlock\n");
return (Failure);
}
/* Function specific to this proxy example
* Deletes the division name records which will be added by the addDiv
* Note: delete will call ProxyClearParamBlock
*/
delDiv();
SLEEP(2);
/* Function specific to this proxy example
* add several divisions
* Note: add will call ProxyClearParamBlock
*/
addDiv();
SLEEP(2);
/* Function specific to this proxy example
* read back the divisions just added
* Note: read will call ProxyClearParamBlock
*/
readDiv();
/* For sample purposes, the set of individual ProxyClear functions are shown
* below
*/
nRC = ProxyClearClientUserid(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearClientUserid\n");
return (Failure);
}
nRC = ProxyClearClientPassword(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearClientPassword\n");
return (Failure);
}
nRC = ProxyClearDialect(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearDialect\n");
return (Failure);
}
nRC = ProxyClearNextLocation(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearNextLocation\n");
return (Failure);
}
nRC = ProxyClearCommand(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearCommand\n");
return (Failure);
}
nRC = ProxyClearExitStateMsg(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearExitStateMsg\n");
return (Failure);
}
nRC = ProxyClearExitStateNum(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearExitStateNum\n");
return (Failure);
}
nRC = ProxyClearExitMsgType(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearExitMsgType\n");
return (Failure);
}
/* The ProxyDeleteParamBlock function is used to delete the psParamBlock
* structure.
* This function call is optional, but recommended.
*/
nRC = ProxyDeleteParamBlock(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyDeleteParamBlock\n");
return (Failure);
}
/* ProxyStopTracing is used to close the trace file opened by
* ProxyStartTracing.
* This function is optional, but is recommended if ProxyStartTracing is
* used.
*/
ProxyStopTracing();
printf ("\nEnding program cproxy \n");
return (TRUE);
}
/* addDiv()
* This function is specific to this proxy example.
* It attempts to add 4 division records
*/
ProxyExecuteReturnValues addDiv()
{
/* Add Divisions */
int count;
printf("Adding test divisions\n");
strcpy(Command,"A"); /* Add */
strcpy(server_detail_division.importRequest_command.value, Command);
/* add 4 Divisions */
for (count = 0; count <= 3; count++ )
{
/* use Numbers 90-93 */
server_detail_division.import_division.number = 90+count;
sprintf(server_detail_division.import_division.name, "Test Divison %d", count);
/* in case there are no employes in the database use 0*/
server_detail_division.import_employee.number = 0;
/* clear the parameter block */
nRC = ProxyClearParamBlock(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearParamBlock\n");
return (Failure);
}
/* Transaction processing
* ProxyExecute sends the transaction to the server and returns export
* data and messages. This function use the following parameters:
* - SERVER_DETAIL_DIVISION transaction structure which contains
* import and export views
* - psParamBlock parameter structure which contain communication
* information
* - errMsg will return any error message from the server
* - errMsgLen specifies the number of characters to write to errMsg
* This function call is required. The return value is Success or
* Failure
*/
if (ProxyExecute(&SERVER_DETAIL_DIVISION, psParamBlock, errMsg, errMsgLen) != Success)
{
printf("Unsuccessful return from ProxyExecute \n");
printf("errMsg = %s\n",errMsg);
ProxyTraceOut(NULL, errMsg);
return (Failure);
}
else /* check results */
check();
}
return (Success);
}
/* readDiv()
* This function is specific to this proxy example.
* read all divisions, returning division name and number
* The server returns the data in a repeating group view.
* If the previous add was successful there should be
* at least four divisions present. The check() function
* will extract the data read from the repeating group view.
*/
ProxyExecuteReturnValues readDiv()
{
printf("Reading test divisions\n");
#ifndef TUXEDO
/* NOTE: ProxyConfigureComm() must not be called if targeting a Tuxedo Server
* environment. Tuxedo environment does not support retargeting the server.
*/
/* setup to use SERVER_MAINTAIN_DIVISION
* This read uses a different procedure step than did delDiv/addDiv, so
* must call ProxyConfigureComm() to initialize for the desired
* procedure step
*/
nRC = ProxyConfigureComm(&SERVER_MAINTAIN_DIVISION,
SERVER_MAINTAIN_DIVISION.service, comcfg);
if (nRC == FALSE)
{
printf("Unsuccessful return from ProxyConfigureComm using comcfg string\n");
return (Failure);
}
#endif /* !TUXEDO */
strcpy(Command,"R");
/* non space implies server is to return sorted data */
strcpy(server_maintain_division.importSortWrk_sorting.sort_sequence, "S");
/* clear the paramater block */
nRC = ProxyClearParamBlock(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearParamBlock\n");
return (Failure);
}
/* Transaction processing
* ProxyExecute sends the transaction to the server and returns export
* data and messages. This function use the following parameters:
* - SERVER_MAINTAIN_DIVISION transaction structure which contains
* import and export views
* - psParamBlock parameter structure which contain communication
* information
* - errMsg will return any error message from the server
* - errMsgLen specifies the number of characters to write to errMsg
* This function call is required. The return value is Success or
* Failure
*/
if (ProxyExecute(&SERVER_MAINTAIN_DIVISION, psParamBlock,
errMsg, errMsgLen) != Success)
{
printf("Unsuccessful return from ProxyExecute \n");
printf("errMsg = %s\n",errMsg);
ProxyTraceOut(NULL, errMsg);
return (Failure);
}
check();
return (Success);
}
/* delDiv()
* This function is specific to this proxy example.
* Attempts to delete the four division records that addDiv() will then add.
* Hard coded to delete division 90-93, which may or may not exist.
*/
ProxyExecuteReturnValues delDiv()
{
int count;
printf("Deleting test divisions\n");
strcpy(Command,"D"); /* Delete */
strcpy(server_detail_division.importRequest_command.value, Command);
for (count = 0; count <=3; count ++)
{
server_detail_division.import_division.number = 90 + count;
printf(" Attempting to Delete Division %d\n",
server_detail_division.import_division.number);
nRC = ProxyClearParamBlock(psParamBlock);
if (nRC == Failure)
{
printf("Unsuccessful return from ProxyClearParamBlock\n");
return (Failure);
}
/* Transaction processing
* ProxyExecute sends the transaction to the server and returns export
* data and messages. This function use the following parameters:
* - SERVER_DETAIL_DIVISION transaction structure which contains
* import and export views
* - psParamBlock parameter structure which contain communication
* information
* - errMsg will return any error message from the server
* - errMsgLen specifies the number of characters to write to errMsg
* This function call is required. The return value is Success or
* Failure
*/
if (ProxyExecute(&SERVER_DETAIL_DIVISION, psParamBlock, errMsg, errMsgLen) != Success)
{
printf("Unsuccessful return from ProxyExecute \n");
printf("errMsg = %s\n",errMsg);
ProxyTraceOut(NULL, errMsg);
return (Failure);
}
}
printf("\n");
return (Success);
}
/* check()
* This function is specific to this proxy example.
* check the results of the ProxyExecute()
*/
void check()
{
int loop=0;
/* The ProxyGet set of functions are used to query the various data items
* within parameter block.
* These function calls are optional.
*/
strcpy(OutClientUserid,ProxyGetClientUserid(psParamBlock));
strcpy(OutClientPassword, ProxyGetClientPassword(psParamBlock));
strcpy(OutDialect, ProxyGetDialect(psParamBlock));
strcpy(OutNextLocation, ProxyGetNextLocation(psParamBlock));
strcpy(OutCommand, ProxyGetCommand(psParamBlock));
OutExitStateNum = ProxyGetExitStateNum(psParamBlock);
OutExitMsgType = ProxyGetExitMsgType(psParamBlock);
strcpy(OutExitStateMsg, ProxyGetExitStateMsg(psParamBlock));
/* processing a delete command */
if (strcmp(Command, "D") == 0)
{
/* did server set an exit state? If so, delete failed */
if (OutExitStateNum != 0)
{
printf("OutExitStateNum=%d\n", OutExitStateNum);
printf("OutExitStateMsg=%s\n", OutExitStateMsg);
}
else
printf("Delete successful\n");
return;
}
/* processing the add command */
if (strcmp(Command, "A") == 0)
{
if (OutExitStateNum == gui_return_from_link)
{
printf(" Division successfully added\n");
printf(" Exit State Number | Divsion: Number Name\n");
printf(" ----------------------------------------------------------\n");
printf(" %d", OutExitStateNum);
printf("\t\t\t %d", server_detail_division.export_division.number);
printf(" %s\n\n", server_detail_division.export_division.name);
}
else /* error */
{
printf("OutExitStateNum=%d\n", OutExitStateNum);
printf("OutExitStateMsg=%s\n", OutExitStateMsg);
return;
}
}
/* processing the read repeating group view */
if (strcmp(Command, "R") == 0)
{
printf(" List of Divisions\n");
if (server_maintain_division.allOutput.cardinality > 0)
{
printf(" Number Name\n");
printf(" ------------------------------\n");
for (loop = 0; loop < server_maintain_division.allOutput.cardinality; loop++ )
{
printf(" %d", server_maintain_division.allOutput.export_division.number[loop]);
printf(" %s\n", server_maintain_division.allOutput.export_division.name[loop]);
}
}
else
printf("\tNo Data Found\n");
}
}
|
Copyright © 2015 CA Technologies.
All rights reserved.
|
|