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

📄 exutils.c

📁 sybase数据库ct library的开发,使用了所以有函数
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
** 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;

	close_option = (status != CS_SUCCEED) ? CS_FORCE_CLOSE : CS_UNUSED;
	retcode = ct_close(connection, close_option);
	if (retcode != CS_SUCCEED)
	{
		ex_error("ex_con_cleanup: ct_close() failed");
		return retcode;
	}
	retcode = ct_con_drop(connection);
	if (retcode != CS_SUCCEED)
	{
		ex_error("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;

	exit_option = (status != CS_SUCCEED) ? CS_FORCE_EXIT : CS_UNUSED;
	retcode = ct_exit(context, exit_option);
	if (retcode != CS_SUCCEED)
	{
		ex_error("ex_ctx_cleanup: ct_exit() failed");
		return retcode;
	}
	retcode = cs_ctx_drop(context);
	if (retcode != CS_SUCCEED)
	{
		ex_error("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;

        /*
        ** 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("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("ex_execute_cmd: ct_command() failed");
                (void)ct_cmd_drop(cmd);
                return retcode;
        }

        if ((retcode = ct_send(cmd)) != CS_SUCCEED)
        {
                ex_error("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("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("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			row_count = 0;
	CS_INT			rows_read;
	CS_INT			disp_len;
	CS_DATAFMT		*datafmt;
	EX_COLUMN_DATA		*coldata;

	/*
	** Find out how many columns there are in this result set.
	*/
	retcode = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
	if (retcode != CS_SUCCEED)
	{
		ex_error("ex_fetch_data: ct_res_info() failed");
		return retcode;
	}

	/*
	** Make sure we have at least one column
	*/
	if (num_cols <= 0)
	{
		ex_error("ex_fetch_data: ct_res_info() returned zero columns");
		return CS_FAIL;
	}

	/*
	** Our program variable, called 'coldata', is an array of 
	** EX_COLUMN_DATA structures. Each array element represents
	** one column.  Each array element will re-used for each row.
	**
	** First, allocate memory for the data element to process.
	*/
	coldata = (EX_COLUMN_DATA *)malloc(num_cols * sizeof (EX_COLUMN_DATA));
	if (coldata == NULL)
	{
		ex_error("ex_fetch_data: malloc() failed");
		return CS_MEM_ERROR;
	}

	datafmt = (CS_DATAFMT *)malloc(num_cols * sizeof (CS_DATAFMT));
	if (datafmt == NULL)
	{
		ex_error("ex_fetch_data: malloc() failed");
		free(coldata);
		return CS_MEM_ERROR;
	}

	/*
	** Loop through the columns getting a description of each one
	** and binding each one to a program variable.
	**
	** We're going to bind each column to a character string; 
	** this will show how conversions from server native datatypes
	** to strings can occur via bind.
	**
	** We're going to use the same datafmt structure for both the describe
	** and the subsequent bind.
	**
	** If an error occurs within the for loop, a break is used to get out
	** of the loop and the data that was allocated is free'd before
	** returning.
	*/
	for (i = 0; i < num_cols; i++)
	{
		/*
		** Get the column description.  ct_describe() fills the
		** datafmt parameter with a description of the column.
		*/
		retcode = ct_describe(cmd, (i + 1), &datafmt[i]);
		if (retcode != CS_SUCCEED)
		{
			ex_error("ex_fetch_data: ct_describe() failed");
			break;
		}

		/*
		** update the datafmt structure to indicate that we want the
		** results in a null terminated character string.
		**
		** First, update datafmt.maxlength to contain the maximum
		** possible length of the column. To do this, call
		** ex_display_len() to determine the number of bytes needed
		** for the character string representation, given the
		** datatype described above.  Add one for the null
		** termination character.
		*/
		datafmt[i].maxlength = ex_display_dlen(&datafmt[i]) + 1;
		
		/*
		** Set datatype and format to tell bind we want things
		** converted to null terminated strings
		*/
		datafmt[i].datatype = CS_CHAR_TYPE;
		datafmt[i].format   = CS_FMT_NULLTERM;

		/*
		** Allocate memory for the column string
		*/
		coldata[i].value = (CS_CHAR *)malloc(datafmt[i].maxlength);
		if (coldata[i].value == NULL)
		{
			ex_error("ex_fetch_data: malloc() failed");
			retcode = CS_MEM_ERROR;
			break;
		}

		/*
		** Now bind.
		*/
		retcode = ct_bind(cmd, (i + 1), &datafmt[i],
				coldata[i].value, &coldata[i].valuelen,
				(CS_SMALLINT *)&coldata[i].indicator);
		if (retcode != CS_SUCCEED)
		{
			ex_error("ex_fetch_data: ct_bind() failed");
			break;
		}
	}
	if (retcode != CS_SUCCEED)
	{
		for (j = 0; j < i; j++)
		{
			free(coldata[j].value);
		}
		free(coldata);
		free(datafmt);
		return retcode;
	}

	/*
	** Display column header
	*/
	ex_display_header(num_cols, datafmt);

	/*
	** Fetch the rows.  Loop while ct_fetch() returns CS_SUCCEED or 
	** CS_ROW_FAIL
	*/
	while (((retcode = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
			&rows_read)) == CS_SUCCEED) || (retcode == CS_ROW_FAIL))
	{
		/*
		** Increment our row count by the number of rows just fetched.
		*/
		row_count = row_count + rows_read;

		/*
		** Check if we hit a recoverable error.
		*/
		if (retcode == CS_ROW_FAIL)
		{
			fprintf(stdout, "Error on row %d.\n", row_count);
			fflush(stdout);
		}

		/*
		** We have a row.  Loop through the columns displaying the
		** column values.
		*/
		for (i = 0; i < num_cols; i++)
		{	  
			/*
			** Display the column value
			*/
			fprintf(stdout, "%s", coldata[i].value);
			fflush(stdout);

			/*
			** If not last column, Print out spaces between this
			** column and next one. 
			*/
			if (i != num_cols - 1)
			{
				disp_len = ex_display_dlen(&datafmt[i]);
				disp_len -= coldata[i].valuelen - 1;
				for (j = 0; j < disp_len; j++)
				{
					fputc(' ', stdout);
				}
			}
		} 
		fprintf(stdout, "\n");
		fflush(stdout);
	}

	/*
	** Free allocated space.
	*/
	for (i = 0; i < num_cols; i++)
	{
		free(coldata[i].value);
	}
	free(coldata);
	free(datafmt);

	/*
	** We're done processing rows.  Let's check the final return
	** value of ct_fetch().
	*/
	switch ((int)retcode)
	{
		case CS_END_DATA:
			/*
			** Everything went fine.
			*/
			fprintf(stdout, "All done processing rows.\n");
			fflush(stdout);
			retcode = CS_SUCCEED;
			break;

		case CS_FAIL:
			/*
			** Something terrible happened.
			*/
			ex_error("ex_fetch_data: ct_fetch() failed");
			return retcode;
			/*NOTREACHED*/
			break;

		default:
			/*
			** We got an unexpected return value.
			*/
			ex_error("ex_fetch_data: ct_fetch() returned an expected retcode");
			return retcode;
			/*NOTREACHED*/
			break;

	}

	return retcode;
}

/*****************************************************************************
** 
** sql based functions 
** 
*****************************************************************************/

/*
** ex_create_db()
**
** Type of function:
**      example program utility api
**
** Purpose:
**      This routine creates a database and opens it. It first checks
**      that the database does not already exists. If it does exist
**      the database is dropped before creating a new one.
**
** Parameters:
**      connection      - Pointer to CS_CONNECTION structure.
**      dbname          - The name to be used for the created database.
**
** Return:
**      Result of functions called in CT-Lib.
**
*/

CS_RETCODE CS_PUBLIC
ex_create_db(connection, dbname)
CS_CONNECTION   *connection;
char            *dbname;
{
        CS_RETCODE      retcode;
        CS_CHAR         *cmdbuf;

        /*
        ** If the database already exists, drop it.
        */
        if ((retcode = ex_remove_db(connection, dbname)) != CS_SUCCEED)
        {
                ex_error("ex_create_db: ex_remove_db() failed");
        }

        /*
        ** Allocate the buffer for the command string.
        */
        cmdbuf = (CS_CHAR *) malloc(EX_BUFSIZE);
        if (cmdbuf == (CS_CHAR *)NULL)
        {
                ex_error("ex_create_db: malloc() failed");
                return CS_FAIL;
        }

        /*
        ** Set up and send the command to create the database.
        */
        sprintf(cmdbuf, "create database %s", dbname);
        if ((retcode = ex_execute_cmd(connection, cmdbuf)) != CS_SUCCEED)
        {
                ex_error("ex_create_db: ex_execute_cmd(create db) failed");
        }
	free(cmdbuf);
	return retcode;
}

/*
** ex_remove_db()
**
** Type of function:
**      example program utility api
**
** Purpose:
**      This routine removes a database. It first checks that
**      the database exists, and if so, removes it.
**
** Parameters:
**      connection      - Pointer to CS_CONNECTION structure.
**      dbname          - The name of the database to remove.
**
** Return:
**      Result of functions called in CT-Lib or CS_FAIL if a malloc failure
**      occurred.
*/

CS_RETCODE
ex_remove_db(connection, dbname)
CS_CONNECTION   *connection;
char            *dbname;
{
        CS_RETCODE      retcode;
        CS_CHAR         *cmdbuf;

        /*
        ** Connect to the master database in order to
        ** remove the specified database.
        */
        if ((retcode = ex_use_db(connection, "master")) != CS_SUCCEED)
        {
                ex_error("ex_remove_db: ex_use_db(master) failed");
                return retcode;
        }

        /*
        ** Allocate the buffer for the command string.
        */
        cmdbuf = (CS_CHAR *) malloc(EX_BUFSIZE);
        if (cmdbuf == (CS_CHAR *)NULL)
        {
                ex_error("ex_remove_db: malloc() failed");
                return CS_FAIL;
        }

        /*
        ** Set up and send the command to check for and drop the
        ** database if it exists.
        */
        sprintf(cmdbuf,
                "if exists (select name from sysdatabases where name = \"%s\") \
                drop database %s", dbname, dbname);
        if ((retcode = ex_execute_cmd(connection, cmdbuf)) != CS_SUCCEED)
        {
                ex_error("ex_remove_db: ex_execute_cmd(drop db) failed");
        }
        free(cmdbuf);
        return retcode;
}

/*
** ex_use_db()
**
** Type of function:
**      example program utility api
**
** Purpose:
**      This routine changes the current database to the named db passed in.
**
** Parameters:
**      connection      - Pointer to CS_CONNECTION structure.
**      dbname          - The name of the database to use.
**
** Return:
**      Result of functions called in CT-Lib or CS_FAIL if a malloc failure
**      occured.
*/

CS_RETCODE
ex_use_db(connection, dbname)
CS_CONNECTION   *connection;
char            *dbname;
{
        CS_RETCODE      retcode;
        CS_CHAR         *cmdbuf;

        /*
        ** Allocate the buffer for the command string.
        */
        cmdbuf = (CS_CHAR *) malloc(EX_BUFSIZE);
        if (cmdbuf == (CS_CHAR *)NULL)
        {
                ex_error("ex_use_db: malloc() failed");
                return CS_FAIL;
        }

        /*
        ** Set up and send the command to use the database
        */
	sprintf(cmdbuf, "use %s\n", dbname);
        if ((retcode = ex_execute_cmd(connection, cmdbuf)) != CS_SUCCEED)
        {
                ex_error("ex_use_db: ex_execute_cmd(use db) failed");
        }
        free(cmdbuf);
        return retcode;
}

⌨️ 快捷键说明

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