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

📄 ex_alib.c

📁 sybase数据库ct library的开发,使用了所以有函数
💻 C
📖 第 1 页 / 共 2 页
字号:
** None.
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_STATIC CS_RETCODE CS_INTERNAL
ex_aresults_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;

	/*
	** check status to see what happened in last ct_results(). If
	** completed, call ex_adone_comp() 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 */

	    case CS_END_RESULTS:
		return ex_adone_comp(ex_async, connection, cmd, function, CS_SUCCEED);

	    default:
	    	return ex_aerror(ex_async, connection, cmd, function, status);
	}

	switch ((int)ex_async->res_type)
	{
	    case CS_ROW_RESULT:
		if (ex_async->didfetch == CS_TRUE)
		{
			/*
			** We don't handle multiple result sets. Issue a
			** cancel_all. The cancel attention should not be
			** used here. Instead, it would be used in the main
			** line code to cancel this library's processing.  
			*/
			fprintf(stderr, "\nMultiple result sets not supported\n");
			fflush(stderr);
			ex_async->state = EX_ACANCEL_ALL;
			retstat = ct_cancel(NULL, cmd, CS_CANCEL_ALL);
		}
		else
		{
			/*
			** Now we are in a fetching state. If the bind fails
			** (most likely not enough memory was provided). We
			** still need to continue async processing, since
			** ex_abind() is not async. Since we can't process
			** the results, we just throw them away.
			*/
			retstat = ex_abind(ex_async, cmd);
			if (retstat == CS_SUCCEED)
			{
 				ex_async->state = EX_AFETCH;
 				retstat = ct_fetch(cmd, CS_UNUSED,
 						CS_UNUSED, CS_UNUSED,
 						&ex_async->results->numrows);
			}
 			else
 			{
 				fprintf(stderr, "\nError: ex_abind() failed\n");
				fflush(stderr);
 				ex_async->state = EX_ACANCEL_ALL;
 				retstat = ct_cancel(NULL, cmd, CS_CANCEL_ALL);
 			}
		}
		break;

	    case CS_CMD_SUCCEED:
	    case CS_CMD_DONE:
	    case CS_CMD_FAIL:
		/*
		** This means no rows were returned, remain in the result
		** state and call results again.
		*/
		retstat = ct_results(cmd, &ex_async->res_type);
		break;

	    case CS_STATUS_RESULT:
		/*
		** throw the status value away.
		*/
		ex_async->state = EX_ACANCEL_CURRENT;
		retstat = ct_cancel(NULL, cmd, CS_CANCEL_CURRENT);
		break;

	    case CS_PARAM_RESULT:
	    case CS_COMPUTE_RESULT:
	    default:
		fprintf(stderr, "\nUnexpected result type encountered\n");
		fflush(stderr);
		ex_async->state = EX_ACANCEL_ALL;
		retstat = ct_cancel(NULL, cmd, CS_CANCEL_ALL);
		break;
	}

	return retstat;
}

/*
** ex_afetch_comp()
**
** Type of function:
** internal example async lib
**
** Purpose:
** This function will determine if all the rows have been fetched. If so,
** the async state is switched backed to results, and a call to 
** ct_results() is made.
**
** Returns:
** return of ct_results() or
** return of ct_fetch()
**
** Side Effects:
** None.
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_STATIC CS_RETCODE CS_INTERNAL
ex_afetch_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;

	/*
	** check status to see what happened in last ct_fetch(). If
	** completed, call ct_results() to continue processing.
	*/
	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 */

	    case CS_END_DATA:
		ex_async->state    = EX_ARESULTS;
		ex_async->didfetch = CS_TRUE;
		return ct_results(cmd, &ex_async->res_type);

	    default:
	    	return ex_aerror(ex_async, connection, cmd, function, status);
	}

	/*
	** The fetch was supposed to be a one shot deal. Here we clear the
	** binds and call fetch again to return CS_END_DATA. Note that this
	** is not the best way to handle this. Multiple fetchs may cause
	** recursion on the process stack. The code was left the way it is to
	** demonstrate that multiple fetchs are possible.
	**
	** The best way to handle this would be to use:
	**
	** ex_async->state = EX_ACANCEL_CURRENT;
	** return ct_cancel(NULL, cmd, CS_CANCEL_CURRENT);
	*/
	retstat = ct_bind(cmd, CS_UNUSED, NULL, NULL, NULL, NULL);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}
	return ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, NULL);
}

/*
** ex_acompletion_cb()
**
** Type of function:
** internal example async lib
**
** Purpose:
** Installed as a callback into Open Client. It will dispatch to the
** appropriate completion processing routine based on async state.
** 
** Another approach to callback processing is to have each completion
** routine install the completion callback for the next step in
** processing. We use one dispatch point to aid in debugging the
** async processing (only need to set one breakpoint).
**
** Returns:
** return of completion processing routine.
**
** Side Effects:
** None
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_RETCODE CS_PUBLIC
ex_acompletion_cb(connection, cmd, function, status)
CS_CONNECTION	*connection;
CS_COMMAND	*cmd;
CS_INT		function;
CS_RETCODE	status;
{
	CS_RETCODE	retstat;
	ExAsync		*ex_async;
	CS_INT          hafail;

	fprintf(stdout, "\nex_acompletion_cb: function %d Completed",
				function);
	fflush(stdout);

#ifdef HAFAILOVER
	/*
	**  If HA failover has succeeded then it has to go back to the
	**  connected state. Need to send a query now
	*/
	ct_con_props(connection, CS_GET, CS_HAFAILOVER,
		&hafail, CS_UNUSED, NULL);

        if((hafail) && (status == CS_RET_HAFAILOVER))
        {
                hafailoversucceed = CS_TRUE;

                return(CS_HAFAILOVER);
        }
        if ((hafail) && (status == CS_SUCCEED) && function == CT_CLOSE)
        {
                return(CS_SUCCEED);

        }
#endif  /* HAFAILOVER */

	/*
	** Extract the user area out of the command handle.
	*/
	retstat = ct_cmd_props(cmd, CS_GET, CS_USERDATA, &ex_async,
					CS_SIZEOF(ex_async), NULL);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	/*
	** Based on async state, do the right thing
	*/
	switch ((int)ex_async->state)
	{
	    case EX_ASEND:
	    case EX_ACANCEL_CURRENT:
		retstat = ex_asend_comp(ex_async, connection, cmd,
				function, status);
		break;

	    case EX_ARESULTS:
		retstat = ex_aresults_comp(ex_async, connection, cmd,
				function, status);
		break;

	    case EX_AFETCH:
		retstat = ex_afetch_comp(ex_async, connection, cmd,
				function, status);
		break;

	    case EX_ACANCEL_ALL:
		retstat = ex_adone_comp(ex_async, connection, cmd,
				function, status);
		break;

	    default:
		ex_apanic("ex_acompletion_cb: unexpected async state");
		break;
	}

	return retstat;
}

/*
** ex_async_query()
**
** Type of function:
** example async lib api
**
** Purpose:
** This routine will asynchronously send a query to a server and
** retrieve any rows sent back.
**
** Returns:
** CS_PENDING
**
** Side Effects:
** Will install a different async completion callback.
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_RETCODE CS_PUBLIC
ex_async_query(ex_handle, query, querylen)
EX_ASYNC	*ex_handle;
CS_CHAR		*query;
CS_INT		querylen;
{
	ExAsync		*ex_async;
	CS_RETCODE	retstat;
	CS_BOOL		pollprop;

	/*
	** set up async handle for query
	*/
	ex_async = (ExAsync *)ex_handle;
	ex_async->poolsize   = ex_async->maxpool;
	ex_async->memcurpool = ex_async->mempool;
	ex_async->didfetch   = CS_FALSE;

	/*
	** clear results area
	*/
	ex_async->results->numrows   = 0;
	ex_async->results->numcols   = 0;
	ex_async->results->colfmts   = NULL;
	ex_async->results->data      = NULL;
	ex_async->results->datalen   = NULL;
	ex_async->results->indicator = NULL;

	/*
	** Extract the user completion callback for this connection
	*/
	retstat = ct_callback(NULL, ex_async->connection, CS_GET,
					CS_COMPLETION_CB,
					(CS_VOID *)&ex_async->completion_cb);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	/*
	** Install our completion callback for this connection. Since this
	** will overwrite the user installed callback, all subsequent error
	** processing should make sure to call ex_aerror() to recover from
	** the error.
	*/
	retstat = ct_callback(NULL, ex_async->connection, CS_SET,
					CS_COMPLETION_CB,
					(CS_VOID *)ex_acompletion_cb);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	/*
	** Disable polling. We do this to insure that the ct_poll() routine
	** will not report a completion for this connection until we call the
	** user installed callback.
	*/
	pollprop = CS_TRUE;
	retstat = ct_con_props(ex_async->connection, CS_SET, CS_DISABLE_POLL,
			  &pollprop, CS_UNUSED, NULL);
	if (retstat != CS_SUCCEED)
	{
	    	return ex_aerror(ex_async, ex_async->connection, ex_async->cmd,
				 EX_ASYNC_QUERY, retstat);
	}

	/*
	** Install the exhandle into the user area of the command handle.
	*/
	retstat = ct_cmd_props(ex_async->cmd, CS_SET, CS_USERDATA, &ex_async,
					CS_SIZEOF(ex_async), NULL);
	if (retstat != CS_SUCCEED)
	{
	    	return ex_aerror(ex_async, ex_async->connection, ex_async->cmd,
				 EX_ASYNC_QUERY, retstat);
	}

	/*
	** Tell Open Client about the query we want to send.
	*/
	retstat = ct_command(ex_async->cmd, CS_LANG_CMD, query,
					querylen, CS_UNUSED);
	if (retstat != CS_SUCCEED)
	{
	    	return ex_aerror(ex_async, ex_async->connection, ex_async->cmd,
				 EX_ASYNC_QUERY, retstat);
	}

	/*
	** The async manager can be debugged by the following api. This is
	** mostly useful for developers who are working with the internal async
	** routines.
	*/
#if EX_ASYNC_DEBUG
{
	CS_CONTEXT	*context;
	ct_con_props(ex_async->connection, CS_GET, CS_PARENT_HANDLE,
		&context, CS_UNUSED, NULL);
	ct_debug(context, NULL, CS_SET_FLAG, CS_DBG_ASYNC, NULL, CS_UNUSED);
}
#endif

	/*
	** Now send the query to the server.
	*/
	ex_async->state = EX_ASEND;
	retstat = ct_send(ex_async->cmd);
	if (retstat != CS_PENDING)
	{
	    	return ex_aerror(ex_async, ex_async->connection, ex_async->cmd,
				 EX_ASYNC_QUERY, retstat);
	}
	return retstat;
}

/*
** ex_async_alloc()
**
** Type of function:
** example async lib api
**
** Purpose:
** This routine will allocate and initialize a async handle
**
** Returns:
** CS_SUCCEED
**
** Side Effects:
** None.
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_RETCODE CS_PUBLIC
ex_async_alloc(connection, results, mempool, maxpool, ex_handle)
CS_CONNECTION	*connection;
EX_RESULTS	*results;
CS_VOID		*mempool;
CS_INT		maxpool;
EX_ASYNC	**ex_handle;
{
	ExAsync		*ex_async;
	CS_RETCODE	retstat;

	/*
	** allocate and initialize the async data area to store async
	** information.
	*/
	ex_async = (ExAsync *)malloc(sizeof (ExAsync));
	if (ex_async == NULL)
	{
		return CS_MEM_ERROR;
	}
	ex_async->results    = results;
	ex_async->mempool    = (CS_BYTE *)mempool;
	ex_async->maxpool    = maxpool;
	ex_async->connection = connection;

	/*
	** get a command handle.
	*/
	retstat = ct_cmd_alloc(connection, &ex_async->cmd);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	*ex_handle = (CS_VOID *)ex_async;

	return CS_SUCCEED;
}

/*
** ex_async_free()
**
** Type of function:
** example async lib api
**
** Purpose:
** Free the async handle passed in.
**
** Returns:
** CS_PENDING
**
** Side Effects:
** None.
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_RETCODE CS_PUBLIC
ex_async_free(ex_handle)
EX_ASYNC	*ex_handle;
{
	ExAsync		*ex_async;
	CS_RETCODE	retstat;

	/*
	** free allocate and initialize the async data area to store async
	** information.
	*/
	ex_async = (ExAsync *)ex_handle;

	/*
	** drop the command handle.
	*/
	retstat = ct_cmd_drop(ex_async->cmd);
	if (retstat != CS_SUCCEED)
	{
		return retstat;
	}

	/*
	** Free the async handle
	*/
	memset(ex_async, 0, sizeof (*ex_async));
	free(ex_async);

	return CS_SUCCEED;
}

⌨️ 快捷键说明

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