⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex_alib.c

📁 sybase数据库ct library的开发,使用了所以有函数
💻 C
📖 第 1 页 / 共 2 页
字号:



/*
** Example async library built on top of CT-Lib
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctpublic.h>
#include "example.h"
#include "exasync.h"

#if !lint
static char Sccsid[] = {"%Z% %M% %I% %G%"};
#endif /* !lint */

/*****************************************************************************
** 
** defines used 
** 
*****************************************************************************/

/*
** Memory alignment boundary in bytes
*/
#ifndef MEM_BOUNDRY
#define MEM_BOUNDRY		(CS_INT)8
#endif

/*
** alignment macro for memory
*/
#ifndef MEM_SIZE_ALIGN
#define MEM_SIZE_ALIGN(S)	( (((S) + MEM_BOUNDRY - 1) \
					/ MEM_BOUNDRY) * MEM_BOUNDRY )
#endif

/*
** Internal state defines used
*/
#define EX_ASEND		(CS_INT)1
#define EX_ARESULTS		(CS_INT)2
#define EX_AFETCH		(CS_INT)3
#define EX_ACANCEL_CURRENT	(CS_INT)4
#define EX_ACANCEL_ALL		(CS_INT)5

#ifdef HAFAILOVER
extern CS_INT hafailoversucceed;
#endif  /* HAFAILOVER */

/*****************************************************************************
** 
** typedefs used 
** 
*****************************************************************************/

/*
** callback handle typedef
*/
typedef CS_RETCODE	(CS_INTERNAL * EX_CB_FUNC)PROTOTYPE((
						CS_CONNECTION *connection,
						CS_COMMAND *cmd,
						CS_INT function,
						CS_RETCODE status
						));

/*
** Define the internal async handle we use
*/
typedef struct _ex_async
{
	/*
	** Used defined input area
	*/
	EX_RESULTS	*results;	/* place to keep results */
	CS_BYTE		*mempool;	/* pointer to user pmemory pool */
	CS_INT		maxpool;	/* number of bytes available in pool */
	CS_BYTE		*memcurpool;	/* current pointer in mempool */
	CS_INT		poolsize;	/* current number of bytes available */
	CS_CONNECTION	*connection;	/* connection to use */
	/*
	** Internal info
	*/
	CS_INT		state;		/* what state our library is in */
	EX_CB_FUNC	completion_cb;	/* store user callback here */
	CS_BOOL		didfetch;	/* CS_TRUE if we have already fetched
					** rows from the server
					*/
	CS_INT		res_type;	/* passed to ct_results() */
	CS_COMMAND	*cmd;		/* command handle we allocate */

} ExAsync;

/*****************************************************************************
** 
** prototypes used 
** 
*****************************************************************************/

CS_STATIC CS_VOID CS_INTERNAL ex_apanic PROTOTYPE((
	char *msg
	));
CS_STATIC CS_RETCODE CS_INTERNAL ex_adone_comp PROTOTYPE((
	ExAsync *ex_async,
	CS_CONNECTION *connection,
	CS_COMMAND *cmd,
	CS_INT function,
	CS_RETCODE status
	));
CS_STATIC CS_RETCODE CS_INTERNAL ex_aerror PROTOTYPE((
	ExAsync *ex_async,
	CS_CONNECTION *connection,
	CS_COMMAND *cmd,
	CS_INT function,
	CS_RETCODE status
	));
CS_STATIC CS_VOID * CS_INTERNAL ex_amalloc PROTOTYPE((
	ExAsync *ex_async,
	CS_INT size
	));
CS_STATIC CS_RETCODE CS_INTERNAL ex_abind PROTOTYPE((
	ExAsync *ex_async,
	CS_COMMAND *cmd
	));
CS_STATIC CS_RETCODE CS_INTERNAL ex_asend_comp PROTOTYPE((
	ExAsync *ex_async,
	CS_CONNECTION *connection,
	CS_COMMAND *cmd,
	CS_INT function,
	CS_RETCODE status
	));
CS_STATIC CS_RETCODE CS_INTERNAL ex_aresults_comp PROTOTYPE((
	ExAsync *ex_async,
	CS_CONNECTION *connection,
	CS_COMMAND *cmd,
	CS_INT function,
	CS_RETCODE status
	));
CS_STATIC CS_RETCODE CS_INTERNAL ex_afetch_comp PROTOTYPE((
	ExAsync *ex_async,
	CS_CONNECTION *connection,
	CS_COMMAND *cmd,
	CS_INT function,
	CS_RETCODE status
	));
CS_RETCODE CS_PUBLIC ex_acompletion_cb PROTOTYPE((
	CS_CONNECTION *connection,
	CS_COMMAND *cmd,
	CS_INT function,
	CS_RETCODE status
	));

/*****************************************************************************
** 
** functions
** 
*****************************************************************************/

/*
** ex_apanic()
**
** Type of function:
** internal example async lib
**
** Purpose:
** Reports a string message to stderr, and exits program.
**
** Returns:
** nothing
**
** Side Effects:
** Terminates program
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_STATIC CS_VOID CS_INTERNAL  
ex_apanic(msg)
char	*msg;
{
	fprintf(stderr, "\n\nex_apanic: FATAL ERROR: %s\n", msg);
	fflush(stderr);
	exit(ERROR_EXIT);
}

/*
** ex_aerror()
**
** Type of function:
** internal example async lib
**
** Purpose:
** Error function which is called when ct_results or ct_fetch fails.
** It attempts to force a wakeup  of the user api callback.
** 
** Returns:
** Status passed in.
**
** Side Effects:
** None.
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_STATIC CS_RETCODE CS_INTERNAL
ex_aerror(ex_async, connection, cmd, function, status)
ExAsync		*ex_async;
CS_CONNECTION	*connection;
CS_COMMAND	*cmd;
CS_INT		function;
CS_RETCODE	status;
{
	if (status == CS_CANCELED)
	{
		fprintf(stderr, "\nex_aerror: client lib returned canceled\n");
	}
	else
	{
		fprintf(stderr, "\nex_aerror: client lib error encountered\n");
	}
	fprintf(stderr, "function %d, status = %d\n", function, status);
	fflush(stderr);

	/*
	** Try and force a wakeup
	*/
	(void)ex_adone_comp(ex_async, connection, cmd, function, status);

	return status;
}

/*
** ex_amalloc()
**
** Type of function:
** internal example async lib
**
** Purpose:
** returns a chunk of memory from the memory pool
**
** Returns:
** ptr to memory or NULL
** 
** History:
** 11/12/92: Otto Lind : Created
*/

CS_STATIC CS_VOID * CS_INTERNAL 
ex_amalloc(ex_async, size)
ExAsync		*ex_async;
CS_INT		size;
{
	CS_VOID		*buff;

	size = MEM_SIZE_ALIGN(size);
	if (size > ex_async->poolsize)
	{
		return NULL;
	}
	buff = (CS_VOID *)ex_async->memcurpool;
	ex_async->memcurpool += size;
	ex_async->poolsize   -= size;

	return buff;
}

/*
** ex_abind()
**
** Type of function:
** internal example async lib
**
** Purpose:
** Allocated row data from the user define memory pool and bind the
** memory via ct_bind(). It uses the array binding feature of ct_lib
** to cut down the number of async operations needed.
**
** Returns:
** CS_SUCCEED	If ok.
** CS_MEM_ERROR	If the memory pool is exhausted.
** 
** History:
** 11/12/92: Otto Lind : Created
*/

CS_STATIC CS_RETCODE CS_INTERNAL
ex_abind(ex_async, cmd)
ExAsync		*ex_async;
CS_COMMAND	*cmd;
{
	EX_RESULTS	*results = ex_async->results;
	CS_RETCODE	retstat;
	CS_INT		size;
	CS_INT		i;
	CS_INT		maxrows;	/* number of rows to fetch */

	/*
	** Determine the number of columns.
	*/
	retstat = ct_res_info(cmd, CS_NUMDATA, &results->numcols, CS_UNUSED, NULL);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	/*
	** Allocate column description and data pointers from memory pool
	*/
	size = sizeof (CS_DATAFMT) * results->numcols;
	results->colfmts = (CS_DATAFMT *)ex_amalloc(ex_async, size);
	if (results->colfmts == NULL)
	{
		return CS_MEM_ERROR;
	}
	size = sizeof (CS_BYTE *) * results->numcols;
	results->data = (CS_BYTE **)ex_amalloc(ex_async, size);
	if (results->data == NULL)
	{
		return CS_MEM_ERROR;
	}
	size = sizeof (CS_INT *) * results->numcols;
	results->datalen = (CS_INT **)ex_amalloc(ex_async, size);
	if (results->datalen == NULL)
	{
		return CS_MEM_ERROR;
	}
	size = sizeof (CS_INT *) * results->numcols;
	results->indicator = (CS_INT **)ex_amalloc(ex_async, size);
	if (results->indicator == NULL)
	{
		return CS_MEM_ERROR;
	}

	/*
	** For each column, get the description, and calculation the total
	** size needed for a row. Note that the MEM_SIZE_ALIGN() is needed,
	** but does represent a worst case scenario for memory usage.
	*/
	size = 0;
	for (i = 0; i < results->numcols; i++)
	{
		/*
		** Get the column description 
		*/
		retstat = ct_describe(cmd, i + 1, &results->colfmts[i]);
		if (retstat != CS_SUCCEED)
		{
			return retstat;
		}

		size += MEM_SIZE_ALIGN(results->colfmts[i].maxlength);
		size += MEM_SIZE_ALIGN(sizeof (CS_INT));
		size += MEM_SIZE_ALIGN(sizeof (CS_SMALLINT));
	}

	/*
	** size now represents the maximum number of bytes needed to
	** process a row. Here we set maxrows to best optimize the
	** space left in the memory pool.
	*/
	maxrows = ex_async->poolsize / size;

	/*
	** Allocate space for the column data.
	*/
	for (i = 0; i < results->numcols; i++)
	{
		results->colfmts[i].count = maxrows;

		results->data[i] = (CS_BYTE *)ex_amalloc(ex_async,
					results->colfmts[i].maxlength *
					maxrows);
		if (results->data[i] == NULL)
		{
			return CS_MEM_ERROR;
		}
		results->datalen[i] = (CS_INT *)ex_amalloc(ex_async,
					sizeof (CS_INT) * maxrows);
		if (results->datalen[i] == NULL)
		{
			return CS_MEM_ERROR;
		}
		results->indicator[i] = (CS_INT *)ex_amalloc(ex_async,
					sizeof (CS_INT) * maxrows);
		if (results->indicator[i] == NULL)
		{
			return CS_MEM_ERROR;
		}

		/*
		** Bind the results to the variable.
		*/
		retstat = ct_bind(cmd, i + 1, &results->colfmts[i],
					results->data[i],
					results->datalen[i],
					(CS_SMALLINT *)results->indicator[i]);
		if (retstat != CS_SUCCEED)
		{
			return retstat;
		}
	}
	return CS_SUCCEED;
}

/*
** ex_adone_comp()
**
** Type of function:
** internal example async lib
**
** Purpose:
** Re-installs the user complete callback and calls wakeup to invoke
** the callback.
**
** Returns:
** CS_SUCCEED
**
** Side Effects:
** None.
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_STATIC CS_RETCODE CS_INTERNAL
ex_adone_comp(ex_async, connection, cmd, function, status)
ExAsync		*ex_async;
CS_CONNECTION	*connection;
CS_COMMAND	*cmd;
CS_INT		function;
CS_RETCODE	status;
{
	CS_RETCODE	retstat;
	CS_BOOL		pollprop;

	/*
	** Re-install user completion routine
	*/
	retstat = ct_callback(NULL, connection, CS_SET, CS_COMPLETION_CB,
					(CS_VOID *)ex_async->completion_cb);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	/*
	** Enable polling
	*/
	pollprop = CS_FALSE;
	retstat = ct_con_props(connection, CS_SET, CS_DISABLE_POLL,
			  &pollprop, CS_UNUSED, NULL);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	/*
	** Force a wakeup on the connection handle
	*/
	retstat = ct_wakeup(connection, NULL, EX_ASYNC_QUERY, status);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	return CS_SUCCEED;
}

/*
** ex_asend_comp()
**
** Type of function:
** internal example async lib
**
** Purpose:
** This function will change the async state to results, and issue a
** ct_results()
**
** Returns:
** return of ct_results()
**
** Side Effects:
** None.
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_STATIC CS_RETCODE CS_INTERNAL
ex_asend_comp(ex_async, connection, cmd, function, status)
ExAsync		*ex_async;
CS_CONNECTION	*connection;
CS_COMMAND	*cmd;
CS_INT		function;
CS_RETCODE	status;
{
	/*
	** check status to see what happened in last command. If
	** an error occurred, call ex_aerror() to clean up.
	*/
	switch ((int)status)
	{
	    case CS_SUCCEED:
		break;

#ifdef HAFAILOVER
	    case CS_RET_HAFAILOVER:
		return ex_adone_comp(ex_async, connection, cmd, function, CS_SUCCEED);
#endif  /* HAFAILOVER */

	    default:
	    	return ex_aerror(ex_async, connection, cmd, function, status);
	}
	ex_async->state = EX_ARESULTS;
	return ct_results(cmd, &ex_async->res_type);
}

/*
** ex_aresults_comp()
**
** Type of function:
** internal example async lib
**
** Purpose:
** This function will process the result type from a ct_results(). If
** rows are to be fetched, the async state is updated and a ct_fetch()
** is done.
**
** Returns:
** return of ct_results()
**
** Side Effects:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -