ESP function example

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, &paramnum);
        /*
        ** 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(&paramfmt, (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, &paramfmt) != 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, &paramfmt,(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(&paramfmt, (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, &paramfmt)
                                  != 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,
                                &paramfmt, (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;
}