📄 thrdutil.c
字号:
}
/*****************************************************************************
**
** 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(threadnum, context)
CS_INT threadnum;
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(threadnum, "ex_init: cs_ctx_alloc() failed");
return retcode;
}
/*
** Put this thread number in context user data for later use.
*/
retcode = cs_config(*context, CS_SET, CS_USERDATA, &threadnum,
CS_SIZEOF(CS_INT), NULL);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum, "cs_config(CS_SET CS_USERDATA) failed");
return retcode;
}
/*
** Initialize Open Client.
*/
retcode = ct_init(*context, EX_CTLIB_VERSION);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum, "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(threadnum, "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(threadnum,
"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(threadnum,
"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(threadnum,
"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:
** threadnum - Id of the thread that invokes this call
** 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(threadnum, context, connection, appname, username, password, server)
CS_INT threadnum;
CS_CONTEXT *context;
CS_CONNECTION **connection;
CS_CHAR *appname;
CS_CHAR *username;
CS_CHAR *password;
CS_CHAR *server;
{
CS_INT len;
CS_RETCODE retcode;
/*
** Allocate a connection structure.
*/
retcode = ct_con_alloc(context, connection);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum, "ct_con_alloc failed");
return retcode;
}
/*
** Put this thread number in connection user data for later use.
*/
retcode = ct_con_props(*connection, CS_SET, CS_USERDATA, &threadnum,
CS_SIZEOF(CS_INT), NULL);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum, "ct_con_props(CS_SET CS_USERDATA) 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(threadnum, "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(threadnum, "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(threadnum, "ct_con_props(appname) failed");
}
}
/*
** 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(threadnum, "ct_connect failed");
}
}
if (retcode != CS_SUCCEED)
{
ct_con_drop(*connection);
*connection = NULL;
}
return retcode;
}
/*
** ex_con_cleanup()
**
** Type of function:
** example program utility api
**
** Purpose:
** The routine closes a connection and deallocates the
** CS_CONNECTION structure.
**
** Parameters:
** connection - Pointer to connection structure.
** status - status of last interaction with this Client-Library
** If not ok, this routine will perform a force close.
**
** Returns:
** Result of function calls from CT-Lib.
*/
CS_RETCODE CS_PUBLIC
ex_con_cleanup(connection, status)
CS_CONNECTION *connection;
CS_RETCODE status;
{
CS_RETCODE retcode;
CS_INT close_option;
CS_INT threadnum = 0;
/*
** Get Connection specific data - get thread number from the
** user data stored in connection structure
*/
(void)ex_get_threadnum(NULL, connection, &threadnum);
close_option = (status != CS_SUCCEED) ? CS_FORCE_CLOSE : CS_UNUSED;
retcode = ct_close(connection, close_option);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum, "ex_con_cleanup: ct_close() failed");
return retcode;
}
retcode = ct_con_drop(connection);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum, "ex_con_cleanup: ct_con_drop() failed");
return retcode;
}
return retcode;
}
/*
** ex_ctx_cleanup()
**
** Type of function:
** example program utility api
**
** Purpose:
** The routine exits Client-Library deallocates the
** CS_CONTEXT structure.
**
** Parameters:
** context - Pointer to context structure.
** status - status of last interaction with Client-Library.
** If not ok, this routine will perform a force exit.
**
** Returns:
** Result of function calls from CT-Lib.
*/
CS_RETCODE CS_PUBLIC
ex_ctx_cleanup(context, status)
CS_CONTEXT *context;
CS_RETCODE status;
{
CS_RETCODE retcode;
CS_INT exit_option;
CS_INT threadnum = 0;
/*
** Get Connection specific data - get thread number from the
** user data stored in connection structure
*/
(void)ex_get_threadnum(context, NULL, &threadnum);
exit_option = (status != CS_SUCCEED) ? CS_FORCE_EXIT : CS_UNUSED;
retcode = ct_exit(context, exit_option);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum, "ex_ctx_cleanup: ct_exit() failed");
return retcode;
}
retcode = cs_ctx_drop(context);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum, "ex_ctx_cleanup: cs_ctx_drop() failed");
return retcode;
}
return retcode;
}
/*
** ex_execute_cmd()
**
** Type of function:
** example program utility api
**
** Purpose:
** This routine sends a language command to the server. It expects no
** rows or parameters to be returned from the server.
**
** Parameters:
** connection - Pointer to CS_COMMAND structure.
** cmdbuf - The buffer containing the command.
**
** Return:
** Result of functions called in CT-Lib
*/
CS_RETCODE CS_PUBLIC
ex_execute_cmd(connection, cmdbuf)
CS_CONNECTION *connection;
CS_CHAR *cmdbuf;
{
CS_RETCODE retcode;
CS_INT restype;
CS_COMMAND *cmd;
CS_RETCODE query_code;
CS_INT threadnum = 0;
/*
** Get Connection specific data - get thread number from the
** user data stored in connection structure
*/
(void)ex_get_threadnum(NULL, connection, &threadnum);
/*
** Get a command handle, store the command string in it, and
** send it to the server.
*/
if ((retcode = ct_cmd_alloc(connection, &cmd)) != CS_SUCCEED)
{
ex_error(threadnum, "ex_execute_cmd: ct_cmd_alloc() failed");
return retcode;
}
if ((retcode = ct_command(cmd, CS_LANG_CMD, cmdbuf, CS_NULLTERM,
CS_UNUSED)) != CS_SUCCEED)
{
ex_error(threadnum, "ex_execute_cmd: ct_command() failed");
(void)ct_cmd_drop(cmd);
return retcode;
}
if ((retcode = ct_send(cmd)) != CS_SUCCEED)
{
ex_error(threadnum, "ex_execute_cmd: ct_send() failed");
(void)ct_cmd_drop(cmd);
return retcode;
}
/*
** Examine the results coming back. If any errors are seen, the query
** result code (which we will return from this function) will be
** set to FAIL.
*/
query_code = CS_SUCCEED;
while ((retcode = ct_results(cmd, &restype)) == CS_SUCCEED)
{
switch((int)restype)
{
case CS_CMD_SUCCEED:
case CS_CMD_DONE:
break;
case CS_CMD_FAIL:
query_code = CS_FAIL;
break;
case CS_STATUS_RESULT:
retcode = ct_cancel(NULL, cmd, CS_CANCEL_CURRENT);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum,
"ex_execute_cmd: ct_cancel() failed");
query_code = CS_FAIL;
}
break;
default:
/*
** Unexpected result type.
*/
query_code = CS_FAIL;
break;
}
if (query_code == CS_FAIL)
{
/*
** Terminate results processing and break out of
** the results loop
*/
retcode = ct_cancel(NULL, cmd, CS_CANCEL_ALL);
if (retcode != CS_SUCCEED)
{
ex_error(threadnum,
"ex_execute_cmd: ct_cancel() failed");
}
break;
}
}
/*
** Clean up the command handle used
*/
if (retcode == CS_END_RESULTS)
{
retcode = ct_cmd_drop(cmd);
if (retcode != CS_SUCCEED)
{
query_code = CS_FAIL;
}
}
else
{
(void)ct_cmd_drop(cmd);
query_code = CS_FAIL;
}
return query_code;
}
/*
** ex_fetch_data()
**
** Type of function:
** example program utility api
**
** Purpose:
** This function processes fetchable results sets. The results include:
**
** CS_ROW_RESULT
** CS_CURSOR_RESULT
** CS_PARAM_RESULT
** CS_STATUS_RESULT
** CS_COMPUTE_RESULT
**
** Since the Client-Library result model has been unified, the same
** apis are used for each of the above result types.
**
** One caveat is the processing of CS_COMPUTE_RESULTs. The name field
** sent from the server is typically zero length. To display a meaningful
** header, the aggregate compute operator name should be found for the
** column, and that name used instead. The compute example program has
** code which demonstrates this.
**
** Parameters:
** cmd - Pointer to command structure
**
** Return:
** CS_MEM_ERROR If an memory allocation failed.
** CS_SUCCEED If the data was displayed.
** CS_FAIL If no columns were present.
** <retcode> Result of the Client-Library function if a failure was
** returned.
**
*/
CS_RETCODE CS_PUBLIC
ex_fetch_data(cmd)
CS_COMMAND *cmd;
{
CS_RETCODE retcode;
CS_INT num_cols;
CS_INT i;
CS_INT j;
CS_INT rows_read;
CS_DATAFMT *datafmt;
EX_COLUMN_DATA *coldata;
CS_INT threadnum;
CS_CONNECTION *connection;
CS_INT rowsize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -