xp_echo.c has an ESP that accepts a user-supplied input parameter and echoes it to the ESP client, which is the process invoking the ESP. This example includes the xp_message function, which sends messages and status, and the xp_echo function which processes the input parameter and performs the echoing. You can use this example as a template for building your own ESP functions. The source is in $SYBASE/$SYBASE_ASE/sample/esp.
/* ** xp_echo.c ** ** Description: ** The following sample program is generic in ** nature. It echoes an input string which is ** passed as the first parameter to the xp_echo ** ESP. This string is retrieved into a buffer ** and then sent back (echoed) to the ESP client. */
#include <string.h> #include <stdlib.h> #include <malloc.h>
/* Required Open Server include files.*/ #include <ospublic.h> #include <oserror.h>
/* ** Constant defining the length of the buffer that receives the ** input string. All of the Adaptive Server parameters related ** to ESP may not exceed 255 char long. */
#define ECHO_BUF_LEN 255
/* ** Function: ** xp_message ** Purpose: Sends information, status and completion of the ** command to the server. ** Input: ** SRV_PROC * ** char * a message string. ** Output: ** void */
void xp_message ( SRV_PROC *srvproc, /* Pointer to Open Server thread control structure */ char *message_string /* Input message string */ )
{ /* ** Declare a variable that will contain information ** about the message being sent to the SQL client. */ CS_SERVERMSG *errmsgp;
/* ** Allocate memory for this variable. */ errmsgp = (CS_SERVERMSG *) malloc((CS_INT sizeof(CS_SERVERMSG)); if (errmsgp == NULL) return;
/* ** clean the structure */ */ memset(errmsgp,(CS_INT)0,(CS_INT) sizeof(CS_SERVERMSG));
/* ** Put you rnumber in as the message number. */ errmsgp->msgnumber = 25000;
errmsgp->state = 0;
/* **The message is fatal. */ errmsgp->severity = SRV_FATAL_SERVER;
/* ** Let’s copy the string over. */ errmsgp->textlen = strlen(message_string); if (errmsgp->textlen >= CS_MAX_MSG ) return; strncpy(errmsgp->text, message_string, errmsgp->textlen); errmsgp->status = (CS_FIRST_CHUNK | CS_LAST_CHUNK);
srv_sendinfo(srvproc, errmsgp, CS_TRAN_UNDEFINED);
/* Send the status to the client. */ srv_sendstatus(srvproc, 1);
/* ** A SRV_DONE_MORE instead of a SRV_DONE_FINAL must ** complete the result set of an Extended Stored ** Procedure. */ srv_senddone(srvproc, SRV_DONE_MORE, 0, 0);
free(errmsgp);
}
/* ** Function: xp_echo ** Purpose: ** Given an input string, this string is echoed as an output ** string to the corresponding SQL (ESP) client. ** Input: ** SRV_PROC * ** Output ** SUCCESS or FAILURE */
CS_RETCODE xp_echo ( SRV_PROC *srvproc ) { CS_INT paramnum; /* number of parameters */ CS_CHAR echo_str_buf[ECHO_BUF_LEN + 1]; /* buffer to hold input string */ CS_RETCODE result = CS_SUCCEED; CS_DATAFMT paramfmt; /* input/output param format */ CS_INT len; /* Length of input param */ CS_SMALLINT outlen;
/* ** Get number of input parameters.*/ */ srv_numparams(srvproc, ¶mnum);
/* ** Only one parameter is expected.*/ */ if (paramnum != 1) { /* ** Send a usage error message.*/ */ xp_message(srvproc, "Invalid number of parameters"); result = CS_FAIL; }
else { /* ** Perform initializations. */ outlen = CS_GOODDATA; memset(¶mfmt, (CS_INT)0, (CS_INT)sizeof(CS_DATAFMT));
/* ** We are receiving data through an ESP as the ** first parameter. So describe this expected ** parameter. */ if ((result == CS_SUCCEED) && srv_descfmt(srvproc, CS_GET SRV_RPCDATA, 1, ¶mfmt) != CS_SUCCEED) { result = CS_FAIL; }
/* ** Describe and bind the buffer to receive the ** parameter. */ if ((result == CS_SUCCEED) && (srv_bind(srvproc, CS_GET, SRV_RPCDATA, 1, ¶mfmt,(CS_BYTE *) echo_str_buf, &len, &outlen) != CS_SUCCEED)) { result = CS_FAIL; }
/* Receive the expected data.*/ if ((result == CS_SUCCEED) && srv_xferdata(srvproc,CS_GET,SRV_RPCDATA) != CS_SUCCEED) { result = CS_FAIL; }
/* ** Now we have the input info and are ready to ** send the output info. */ if (result == CS_SUCCEED) { /* ** Perform initialization. */ if (len == 0) outlen = CS_NULLDATA; else outlen = CS_GOODDATA;
memset(¶mfmt, (CS_INT)0, (CS_INT)sizeof(CS_DATAFMT));
strcpy(paramfmt.name, "xp_echo"); paramfmt.namelen = CS_NULLTERM; paramfmt.datatype = CS_CHAR_TYPE; paramfmt.format = CS_FMT_NULLTERM; paramfmt.maxlength = ECHO_BUF_LEN; paramfmt.locale = (CS_LOCALE *) NULL; paramfmt.status |= CS_CANBENULL;
/* ** Describe the data being sent. */ if ((result == CS_SUCCEED) && srv_descfmt(srvproc, CS_SET, SRV_ROWDATA, 1, ¶mfmt) != CS_SUCCEED) { result = CS_FAIL; }
/* ** Describe and bind the buffer that ** contains the data to be sent. */ if ((result == CS_SUCCEED) && (srv_bind(srvproc, CS_SET, SRV_ROWDATA, 1, ¶mfmt, (CS_BYTE *) echo_str_buf, &len, &outlen) != CS_SUCCEED)) { result = CS_FAIL; }
/* ** Send the actual data. */ if ((result == CS_SUCCEED) && srv_xferdata(srvproc, CS_SET, SRV_ROWDATA)!= CS_SUCCEED) { result = CS_FAIL; } }
/* ** Indicate to the ESP client how the ** transaction was performed. */ if (result == CS_FAIL) srv_sendstatus(srvproc, 1); else srv_sendstatus(srvproc, 0);
/* ** Send a count of the number of rows sent to ** the client. */ srv_senddone(srvproc,(SRV_DONE_COUNT | SRV_DONE_MORE), 0, 1);
}
return result;
}