📄 exutils.c
字号:
/*
**
** Description
** -----------
** This example file contains utility routines which are used by all other
** sample programs. It demonstrates how an application can hide some of the
** implementation details of CT-Lib from higher level programs.
**
** Routines Used
** -------------
** cs_ctx_alloc
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctpublic.h>
#include "example.h"
#include "exutils.h"
#if !lint
static char Sccsid[] = {"%Z% %M% %I% %G%"};
#endif /* !lint */
/*****************************************************************************
**
** display functions
**
*****************************************************************************/
/*
** ex_display_dlen()
**
** Type of function:
** example program api
**
** Purpose:
**
** Returns:
** Nothing.
**
** Side Effects:
** None
**
** History:
** 11/12/92: Otto Lind : Created
*/
CS_INT CS_PUBLIC
ex_display_dlen(column)
CS_DATAFMT *column;
{
CS_INT len;
switch ((int) column->datatype)
{
case CS_CHAR_TYPE:
case CS_LONGCHAR_TYPE:
case CS_VARCHAR_TYPE:
case CS_TEXT_TYPE:
case CS_IMAGE_TYPE:
len = MIN(column->maxlength, MAX_CHAR_BUF);
break;
case CS_UNICHAR_TYPE:
len = MIN((column->maxlength / 2), MAX_CHAR_BUF);
break;
case CS_BINARY_TYPE:
case CS_VARBINARY_TYPE:
len = MIN((2 * column->maxlength) + 2, MAX_CHAR_BUF);
break;
case CS_BIT_TYPE:
case CS_TINYINT_TYPE:
len = 3;
break;
case CS_SMALLINT_TYPE:
len = 6;
break;
case CS_INT_TYPE:
len = 11;
break;
case CS_REAL_TYPE:
case CS_FLOAT_TYPE:
len = 20;
break;
case CS_MONEY_TYPE:
case CS_MONEY4_TYPE:
len = 24;
break;
case CS_DATETIME_TYPE:
case CS_DATETIME4_TYPE:
len = 30;
break;
case CS_NUMERIC_TYPE:
case CS_DECIMAL_TYPE:
len = (CS_MAX_PREC + 2);
break;
default:
len = 12;
break;
}
return MAX((CS_INT)(strlen(column->name) + 1), len);
}
/*
** ex_display_header()
**
** Type of function:
** example program api
**
** Purpose:
**
** Returns:
** Nothing.
**
** Side Effects:
** None
**
** History:
** 11/12/92: Otto Lind : Created
*/
CS_RETCODE CS_PUBLIC
ex_display_header(numcols, columns)
CS_INT numcols;
CS_DATAFMT columns[];
{
CS_INT i;
CS_INT l;
CS_INT j;
CS_INT disp_len;
fputc('\n', stdout);
for (i = 0; i < numcols; i++)
{
disp_len = ex_display_dlen(&columns[i]);
fprintf(stdout, "%s", columns[i].name);
fflush(stdout);
l = disp_len - strlen(columns[i].name);
for (j = 0; j < l; j++)
{
fputc(' ', stdout);
fflush(stdout);
}
}
fputc('\n', stdout);
fflush(stdout);
for (i = 0; i < numcols; i++)
{
disp_len = ex_display_dlen(&columns[i]);
l = disp_len - 1;
for (j = 0; j < l; j++)
{
fputc('-', stdout);
}
fputc(' ', stdout);
}
fputc('\n', stdout);
return CS_SUCCEED;
}
/*
** ex_display_column()
**
** Type of function:
** example program api
**
** Purpose:
**
** Returns:
** Nothing.
**
** Side Effects:
** None
**
** History:
** 11/12/92: Otto Lind : Created
*/
CS_RETCODE CS_PUBLIC
ex_display_column(context, colfmt, data, datalength, indicator)
CS_CONTEXT *context;
CS_DATAFMT *colfmt;
CS_VOID *data;
CS_INT datalength;
CS_INT indicator;
{
char *null = "NULL";
char *nc = "NO CONVERT";
char *cf = "CONVERT FAILED";
CS_DATAFMT srcfmt;
CS_DATAFMT destfmt;
CS_INT olen;
CS_CHAR wbuf[MAX_CHAR_BUF];
CS_BOOL res;
CS_INT i;
CS_INT disp_len;
CS_SMALLINT indi;
indi = (CS_SMALLINT)indicator;
if (indi == CS_NULLDATA)
{
olen = strlen(null);
strcpy(wbuf, null);
}
else
{
cs_will_convert(context, colfmt->datatype, CS_CHAR_TYPE, &res);
if (res != CS_TRUE)
{
olen = strlen(nc);
strcpy(wbuf, nc);
}
else
{
srcfmt.datatype = colfmt->datatype;
srcfmt.format = colfmt->format;
srcfmt.locale = colfmt->locale;
srcfmt.maxlength = datalength;
memset(&destfmt, 0, sizeof(destfmt));
memset(wbuf, 0, MAX_CHAR_BUF);
destfmt.maxlength = MAX_CHAR_BUF;
destfmt.datatype = CS_CHAR_TYPE;
destfmt.format = CS_FMT_NULLTERM;
destfmt.locale = NULL;
if (cs_convert(context, &srcfmt, data, &destfmt,
wbuf, &olen) != CS_SUCCEED)
{
olen = strlen(cf);
strcpy(wbuf, cf);
}
else
{
/*
** output length include null
** termination
*/
olen -= 1;
}
}
}
for (i = 0; i < olen; i++)
{
fprintf(stdout, "%c", wbuf[i]);
}
fflush(stdout);
disp_len = ex_display_dlen(colfmt);
for (i = 0; i < (disp_len - olen); i++)
{
fputc(' ', stdout);
}
fflush(stdout);
return CS_SUCCEED;
}
/*****************************************************************************
**
** error functions
**
*****************************************************************************/
/*
** ex_panic()
**
** Type of function:
** example program utility api
**
** Purpose:
** Reports a string message to EX_ERROR_OUT, and exits program.
**
** Returns:
** nothing
**
** Side Effects:
** Terminates program
*/
CS_VOID CS_PUBLIC
ex_panic(msg)
char *msg;
{
fprintf(EX_ERROR_OUT, "ex_panic: FATAL ERROR: %s\n", msg);
fflush(EX_ERROR_OUT);
exit(EX_EXIT_FAIL);
}
/*
** ex_error()
**
** Type of function:
** example program utility api
**
** Purpose:
** Reports a string message to EX_ERROR_OUT.
**
** Returns:
** nothing
**
** Side Effects:
** none.
*/
CS_VOID CS_PUBLIC
ex_error(msg)
char *msg;
{
fprintf(EX_ERROR_OUT, "ERROR: %s\n", msg);
fflush(EX_ERROR_OUT);
}
/*****************************************************************************
**
** callback functions
**
*****************************************************************************/
/*
** ex_clientmsg_cb()
**
** Type of function:
** example program client message handler
**
** Purpose:
** Installed as a callback into Open Client.
**
** Returns:
** CS_SUCCEED
**
** Side Effects:
** None
*/
CS_RETCODE CS_PUBLIC
ex_clientmsg_cb(context, connection, errmsg)
CS_CONTEXT *context;
CS_CONNECTION *connection;
CS_CLIENTMSG *errmsg;
{
fprintf(EX_ERROR_OUT, "\nOpen Client Message:\n");
fprintf(EX_ERROR_OUT, "Message number: LAYER = (%d) ORIGIN = (%d) ",
CS_LAYER(errmsg->msgnumber), CS_ORIGIN(errmsg->msgnumber));
fprintf(EX_ERROR_OUT, "SEVERITY = (%d) NUMBER = (%d)\n",
CS_SEVERITY(errmsg->msgnumber), CS_NUMBER(errmsg->msgnumber));
fprintf(EX_ERROR_OUT, "Message String: %s\n", errmsg->msgstring);
if (errmsg->osstringlen > 0)
{
fprintf(EX_ERROR_OUT, "Operating System Error: %s\n",
errmsg->osstring);
}
fflush(EX_ERROR_OUT);
return CS_SUCCEED;
}
/*
** ex_servermsg_cb()
**
** Type of function:
** example program server message handler
**
** Purpose:
** Installed as a callback into Open Client.
**
** Returns:
** CS_SUCCEED
**
** Side Effects:
** None
*/
CS_RETCODE CS_PUBLIC
ex_servermsg_cb(context, connection, srvmsg)
CS_CONTEXT *context;
CS_CONNECTION *connection;
CS_SERVERMSG *srvmsg;
{
fprintf(EX_ERROR_OUT, "\nServer message:\n");
fprintf(EX_ERROR_OUT, "Message number: %d, Severity %d, ",
srvmsg->msgnumber, srvmsg->severity);
fprintf(EX_ERROR_OUT, "State %d, Line %d\n",
srvmsg->state, srvmsg->line);
if (srvmsg->svrnlen > 0)
{
fprintf(EX_ERROR_OUT, "Server '%s'\n", srvmsg->svrname);
}
if (srvmsg->proclen > 0)
{
fprintf(EX_ERROR_OUT, " Procedure '%s'\n", srvmsg->proc);
}
fprintf(EX_ERROR_OUT, "Message String: %s\n", srvmsg->text);
fflush(EX_ERROR_OUT);
return CS_SUCCEED;
}
/*****************************************************************************
**
** utility functions
**
*****************************************************************************/
/*
** ex_init()
**
** Type of function:
** example program utility api
**
** Purpose:
** This function allocates the context structure, initializes
** Client-Library, and installs the default callbacks. If this function
** should fail, it will deallocated all memory allocations it has done.
**
** The callbacks are installed at the context level. Other applications
** may need to install callbacks at the connection level.
**
** Parameters:
** context - Pointer to A Pointer to CS_CONTEXT structure.
**
** Returns:
** Result of initialization functions from CT-Lib.
**
*/
CS_RETCODE CS_PUBLIC
ex_init(context)
CS_CONTEXT **context;
{
CS_RETCODE retcode;
CS_INT netio_type = CS_SYNC_IO;
/*
** Get a context handle to use.
*/
retcode = cs_ctx_alloc(EX_CTLIB_VERSION, context);
if (retcode != CS_SUCCEED)
{
ex_error("ex_init: cs_ctx_alloc() failed");
return retcode;
}
/*
** Initialize Open Client.
*/
retcode = ct_init(*context, EX_CTLIB_VERSION);
if (retcode != CS_SUCCEED)
{
ex_error("ex_init: ct_init() failed");
cs_ctx_drop(*context);
*context = NULL;
return retcode;
}
#ifdef EX_API_DEBUG
/*
** ct_debug stuff. Enable this function right before any call to
** OC-Lib that is returning failure.
*/
retcode = ct_debug(*context, NULL, CS_SET_FLAG, CS_DBG_API_STATES,
NULL, CS_UNUSED);
if (retcode != CS_SUCCEED)
{
ex_error("ex_init: ct_debug() failed");
}
#endif
/*
** Install client and server message handlers.
*/
if (retcode == CS_SUCCEED)
{
retcode = ct_callback(*context, NULL, CS_SET, CS_CLIENTMSG_CB,
(CS_VOID *)ex_clientmsg_cb);
if (retcode != CS_SUCCEED)
{
ex_error("ex_init: ct_callback(clientmsg) failed");
}
}
if (retcode == CS_SUCCEED)
{
retcode = ct_callback(*context, NULL, CS_SET, CS_SERVERMSG_CB,
(CS_VOID *)ex_servermsg_cb);
if (retcode != CS_SUCCEED)
{
ex_error("ex_init: ct_callback(servermsg) failed");
}
}
/*
** This is an synchronous example so set the input/output type
** to synchronous (This is the default setting, but show an
** example anyway).
*/
if (retcode == CS_SUCCEED)
{
retcode = ct_config(*context, CS_SET, CS_NETIO, &netio_type,
CS_UNUSED, NULL);
if (retcode != CS_SUCCEED)
{
ex_error("ex_init: ct_config(netio) failed");
}
}
if (retcode != CS_SUCCEED)
{
ct_exit(*context, CS_FORCE_EXIT);
cs_ctx_drop(*context);
*context = NULL;
}
return retcode;
}
/*
** ex_connect()
**
** Type of function:
** example program utility api
**
** Purpose:
** This routine establishes a connection to the server identified
** in example.h and sets the CS_USER, CS_PASSWORD, and
** CS_APPNAME properties for the connection.
**
** If a connection property is NULL, it is not set.
**
** If this function should fail, it will deallocated all memory
** allocations it has done.
**
** Parameters:
** context - Pointer to CS_CONTEXT structure.
** connection - Pointer to CS_CONNECTION pointer.
** appname - Name of application calling this routine.
** username - user name to use when connecting.
** password - password to use when connecting.
** server - server to connect to.
**
** Return:
** Result of function calls from CT-Lib.
*/
CS_RETCODE CS_PUBLIC
ex_connect(context, connection, appname, username, password, server)
CS_CONTEXT *context;
CS_CONNECTION **connection;
CS_CHAR *appname;
CS_CHAR *username;
CS_CHAR *password;
CS_CHAR *server;
{
CS_INT len;
CS_RETCODE retcode;
CS_BOOL hafailover = CS_TRUE;
/*
** Allocate a connection structure.
*/
retcode = ct_con_alloc(context, connection);
if (retcode != CS_SUCCEED)
{
ex_error("ct_con_alloc failed");
return retcode;
}
/*
** If a username is defined, set the CS_USERNAME property.
*/
if (retcode == CS_SUCCEED && username != NULL)
{
if ((retcode = ct_con_props(*connection, CS_SET, CS_USERNAME,
username, CS_NULLTERM, NULL)) != CS_SUCCEED)
{
ex_error("ct_con_props(username) failed");
}
}
/*
** If a password is defined, set the CS_PASSWORD property.
*/
if (retcode == CS_SUCCEED && password != NULL)
{
if ((retcode = ct_con_props(*connection, CS_SET, CS_PASSWORD,
password, CS_NULLTERM, NULL)) != CS_SUCCEED)
{
ex_error("ct_con_props(password) failed");
}
}
/*
** Set the CS_APPNAME property.
*/
if (retcode == CS_SUCCEED && appname != NULL)
{
if ((retcode = ct_con_props(*connection, CS_SET, CS_APPNAME,
appname, CS_NULLTERM, NULL)) != CS_SUCCEED)
{
ex_error("ct_con_props(appname) failed");
}
}
#ifdef HAFAILOVER
/*
** Set the CS_HAFAILOVER property.
*/
if (retcode == CS_SUCCEED )
{
if ((retcode = ct_con_props(*connection, CS_SET, CS_HAFAILOVER,
&hafailover, CS_UNUSED, NULL)) != CS_SUCCEED)
{
ex_error("ct_con_props(CS_HAFAILOVER) failed");
}
}
#endif /* HAFAILOVER */
/*
** Open a Server connection.
*/
if (retcode == CS_SUCCEED)
{
len = (server == NULL) ? 0 : CS_NULLTERM;
retcode = ct_connect(*connection, server, len);
if (retcode != CS_SUCCEED)
{
ex_error("ct_connect failed");
}
}
if (retcode != CS_SUCCEED)
{
ct_con_drop(*connection);
*connection = NULL;
}
return retcode;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -