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

📄 thrdutil.c

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

/*
**
** Description
** -----------
** 	This example file contains utility routines which are used by 
** 	multithreaded sample program. 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 "thrdutil.h"
#include "thrdfunc.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_VARCHAR_TYPE:
		case CS_TEXT_TYPE:
		case CS_IMAGE_TYPE:
			len = MIN(column->maxlength, 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(strlen(column->name) + 1, len);
}

/*
** ex_display_header()
**
** Type of function:
** example program api
**
** Purpose:
**	Displays header. Caller should protect this using global mutex
**	to avoid output from different threads being mixed up.
**
** Returns:
** Nothing.
**
** Side Effects:
** None
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_RETCODE CS_PUBLIC
ex_display_header(threadnum, numcols, columns)
CS_INT		threadnum;
CS_INT		numcols;
CS_DATAFMT	columns[];
{
	CS_INT		i;
	CS_INT		l;
	CS_INT		j;
	CS_INT		disp_len;

	fprintf(stdout, "\nThread_%d:", threadnum);
	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);
		}
	}
	fprintf(stdout, "\nThread_%d:", threadnum);
	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:
**	Displays a column. Caller should protect this using global mutex
**	to avoid output from different threads being mixed up.
**
** Returns:
** Nothing.
**
** Side Effects:
** None
**
** History:
** 11/12/92: Otto Lind : Created
*/

CS_RETCODE CS_PUBLIC
ex_display_column(threadnum, context, colfmt, data, datalength, indicator)
CS_INT		threadnum;
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;

	if (indicator == 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));

			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;
			}
		}
	}
	fprintf(stdout, "%s", wbuf);
	fflush(stdout);

	disp_len = ex_display_dlen(colfmt);
	for (i = 0; i < (disp_len - olen); i++)
	{
		fputc(' ', stdout);
	}
	fflush(stdout);
	
	return CS_SUCCEED;
}

/*
** ex_display_rows()
**
** Type of function:
** example program api
**
** Purpose:
**	Display a set of row data. It also displays the header first.
**
** Returns:
**	CS_SUCCEED always 
**
** Side Effects:
**	This acquires global mutex to display the rows as a single
**	undivided sequence.
**
*/
 
CS_RETCODE CS_PUBLIC
ex_display_rows(threadnum, numrows, numcols, colfmt, coldata)
CS_INT          threadnum;
CS_INT		numrows;
CS_INT		numcols;
CS_DATAFMT      *colfmt;
EX_COLUMN_DATA	*coldata;
{
	CS_INT row, col, j;
	CS_INT	disp_len;

	if (ex_take_global_mutex() != CS_SUCCEED)
	{
		fprintf(stdout, "Thread_%d:ex_take_global_mutex() failed.\n",
			threadnum);
		return CS_FAIL;
	}

	/* display header first */
	(void)ex_display_header(threadnum, numcols, colfmt);	

        for (row = 0; row < numrows; row++)
        {
                 /*
                 ** We have a row.  Loop through the columns
                 ** displaying the column values.
                 */
                 for (col = 0; col < numcols; col++)
                 {
                         /*
                         ** Display the column value
                         */
                         if (col == 0)
                         {
                                 fprintf(stdout, "Thread_%d:",
                                         threadnum);
                         }

                         fprintf(stdout, "%s", 
				EX_GET_COLUMN_VALUE(coldata, row, 
							col, colfmt));
                         fflush(stdout);

                         /*
                         ** If not last column, Print out spaces
                         ** between this column and next one.
                         */
                         if (col != numcols - 1)
                         {
                                 disp_len = ex_display_dlen(&colfmt[col]);
                                 disp_len -= coldata[col].valuelen[row] - 1;
                                 for (j = 0; j < disp_len; j++)
                                 {
                                         fputc(' ', stdout);
                                 }
                         }
                 }
                 fprintf(stdout, "\n");
                 fflush(stdout);
         }
	(void)ex_release_global_mutex();
	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(threadnum, msg)
CS_INT	threadnum;
char	*msg;
{
	EX_GLOBAL_PROTECT(fprintf(EX_ERROR_OUT,
			"Thread_%d:ex_panic: FATAL ERROR: %s\n",
	 		threadnum, 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(threadnum, msg)
CS_INT	threadnum;
char	*msg;
{
	EX_GLOBAL_PROTECT(fprintf(EX_ERROR_OUT, 
		"Thread_%d:ERROR: %s\n", threadnum, 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;
{
	CS_INT	threadnum = 0;

	/*                            
	** Get Connection specific data - get thread number from the   
	** user data stored in connection structure
	*/
	(void)ex_get_threadnum(context, connection, &threadnum); 

	/* take global lock to print error msg. undivided */
        if (ex_take_global_mutex() != CS_SUCCEED)
        {
                fprintf(stdout, "Thread_%d:ex_take_global_mutex() failed.\n",
                        threadnum);
                return CS_FAIL;
        }
	
	fprintf(EX_ERROR_OUT, "\nThread_%d:Open Client Message:\n", threadnum);
	fprintf(EX_ERROR_OUT, 
		"Thread_%d:Message number: LAYER = (%d) ORIGIN = (%d) ",
		threadnum,
		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, "Thread_%d:Message String: %s\n", threadnum, 
			errmsg->msgstring);
	if (errmsg->osstringlen > 0)
	{
		fprintf(EX_ERROR_OUT, "Thread_%d:Operating System Error: %s\n",
			threadnum, errmsg->osstring);
	}
	fflush(EX_ERROR_OUT);

	(void)ex_release_global_mutex();

	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;
{
        CS_INT  threadnum = 0;
 
        /*               
        ** Get Connection specific data - get thread number from the
        ** user data stored in connection structure
        */
        (void)ex_get_threadnum(context, connection, &threadnum); 
 
	/* take global lock to print error msg. undivided */
        if (ex_take_global_mutex() != CS_SUCCEED)
        {
                fprintf(stdout, "Thread_%d:ex_take_global_mutex() failed.\n",
                        threadnum);
                return CS_FAIL;
        }

	fprintf(EX_ERROR_OUT, "\nThread_%d:Server message:\n", threadnum);
	fprintf(EX_ERROR_OUT, "Thread_%d:Message number: %d, Severity %d, ",
		threadnum, 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, "Thread_%d:Server '%s'\n",
			threadnum, srvmsg->svrname);
	}
	
	if (srvmsg->proclen > 0)
	{
		fprintf(EX_ERROR_OUT, "Thread_%d: Procedure '%s'\n",
			threadnum, srvmsg->proc);
	}

	fprintf(EX_ERROR_OUT, "Thread_%d:Message String: %s\n",
			threadnum, srvmsg->text);
	fflush(EX_ERROR_OUT);

	(void)ex_release_global_mutex();

	return CS_SUCCEED;

⌨️ 快捷键说明

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