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

📄 ctlibadapter.cpp

📁 封装基于ctlib的sybase数据库的接口
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include "DbPool.h"
#include "CTLIBAdapter.h"

static CS_RETCODE CS_PUBLIC myctlib_server_msg_handler(CS_CONTEXT *ctx, CS_CONNECTION *conn, CS_SERVERMSG *srvr_msgtxt);
static CS_RETCODE CS_PUBLIC myctlib_client_msg_handler(CS_CONTEXT *ctx, CS_CONNECTION *conn, CS_CLIENTMSG *client_msgtxt);

/***********************************************************************/

CCTLIBAdapter::CCTLIBAdapter(CDbPool *pool)
:m_pPool(pool), m_pContext(NULL)
{

}

CCTLIBAdapter::~CCTLIBAdapter()
{
	release();
}

bool CCTLIBAdapter::init(DbInit_t *init)
{
#ifdef SYBASE
	void *func;
#endif
	if(m_pContext != NULL)
		return false;

	if(cs_ctx_alloc(CTLIB_VERSION, &m_pContext) != CS_SUCCEED)
	{
		m_pPool->PrintLog("allocate context failed.");
		goto error;
	}
	if(ct_init(m_pContext, CTLIB_VERSION) != CS_SUCCEED)
	{
		m_pPool->PrintLog("initialize database failed.");
		goto error;
	}
	if(init != NULL)
	{
#ifdef SYBASE
		func = init->ctlib_server_msg_handler==NULL ? myctlib_server_msg_handler : init->ctlib_server_msg_handler;
		if(ct_callback(m_pContext, NULL, CS_SET, CS_SERVERMSG_CB, func) != CS_SUCCEED)
		{
			m_pPool->PrintLog("register server message call back failed.");
			return false;
		}
		func = init->ctlib_client_msg_handler==NULL ? myctlib_client_msg_handler : init->ctlib_client_msg_handler;
		if(ct_callback(m_pContext, NULL, CS_SET, CS_CLIENTMSG_CB, func) != CS_SUCCEED)
		{
			m_pPool->PrintLog("register client message call back failed.");
			return false;
		}
#endif
	}
	return true;
error:
	release();
	return false;
}

void* CCTLIBAdapter::newConnect(DbInfo_t *info)
{
	void* stmt = NULL;
#ifdef SYBASE
	char sql[256];
#endif
	CTL_Connect_t *conn=NULL;
	int iLogin = CTLIB_LOGIN_TIMEOUT;

	if(info==NULL || m_pContext==NULL)
		return NULL;
	conn = (CTL_Connect_t*)calloc(1, sizeof(CTL_Connect_t));
	if(conn == NULL)
		return NULL;
	if(ct_con_alloc(m_pContext, &conn->conn) != CS_SUCCEED)
	{
		m_pPool->PrintLog("allocate context failed.");
		goto error;
	}
	if(ct_con_props(conn->conn, CS_SET, CS_USERNAME, info->user, CS_NULLTERM, NULL) != CS_SUCCEED)
	{
		m_pPool->PrintLog("set login user failed.");
		goto error;
	}
	if(ct_con_props(conn->conn, CS_SET, CS_PASSWORD, info->password, CS_NULLTERM, NULL) != CS_SUCCEED)
	{
		m_pPool->PrintLog("set login password failed.");
		goto error;
	}
	if(ct_config(m_pContext, CS_SET, CS_LOGIN_TIMEOUT, &iLogin, CS_UNUSED, NULL) != CS_SUCCEED)
	{
		m_pPool->PrintLog("set login timeout failed.");
		goto error;
	}
	if(ct_connect(conn->conn, info->server, CS_NULLTERM) != CS_SUCCEED)
	{
		m_pPool->PrintLog("connect database server failed.");
		goto error;
	}

#ifdef SYBASE	
	stmt = newStatement(conn);
	if(stmt == NULL)
	{
		m_pPool->PrintLog("new statement failed.");
		goto error;
	}
	sprintf(sql, "use %s", info->database);
	if(Execute(stmt, sql) < 0)
	{
		m_pPool->PrintLog("set database failed.");
		goto error;
	}
	closeStatement(stmt);
#endif
	return conn;
error:
	if(stmt != NULL)
	{
		closeStatement(stmt);
	}
	if(conn != NULL)
	{
		if(conn->conn != NULL)
		{
			ct_cancel(conn->conn, NULL, CS_CANCEL_ALL);
			ct_con_drop(conn->conn);
		}
		free(conn);
	}
	return NULL;
}

void CCTLIBAdapter::closeConnect(void *con)
{
	CTL_Connect_t *conn = (CTL_Connect_t*)con;
	if(con==NULL || m_pContext==NULL)
		return;
	if(conn->conn != NULL)
	{
		ct_cancel(conn->conn, NULL, CS_CANCEL_ALL);
		ct_close(conn->conn, CS_FORCE_CLOSE);
		ct_con_drop(conn->conn);
	}
	free(conn);
}

bool CCTLIBAdapter::testConnect(void *con, int timeout)
{
	void *stmt;
	bool ret = false;
	DbField_t record[1];
	DbDesc_t desc[1];
	int cols;
	CTL_Connect_t *conn = (CTL_Connect_t*)con;

	if(con==NULL || m_pContext==NULL)
		return false;
	ct_cancel(conn->conn, NULL, CS_CANCEL_ALL);
	stmt = newStatement(con);
	if(stmt == NULL)
		return false;
	if(Query(stmt, "select getdate()", record, desc, &cols, timeout) && cols==1)
		ret = true;	
	closeStatement(stmt);
	return ret;
}

void* CCTLIBAdapter::newStatement(void *con)
{
	CTL_Statement_t *stmt = NULL;
	CTL_Connect_t * conn = (CTL_Connect_t*)con;

	if(con==NULL || m_pContext==NULL)
		return NULL;
	stmt = (CTL_Statement_t*)calloc(1, sizeof(CTL_Statement_t));
	if(stmt == NULL)
		return NULL;
	stmt->indicator = conn->indicator;
	if(ct_cmd_alloc(conn->conn, &stmt->stmt) != CS_SUCCEED)
	{
		m_pPool->PrintLog("allocate statement failed.");
		goto error;
	}

	return stmt;
error:
	if(stmt != NULL)
	{
		if(stmt->stmt != NULL)
		{
			ct_cancel(NULL, stmt->stmt, CS_CANCEL_ALL);
			ct_cmd_drop(stmt->stmt);
		}
		free(stmt);
	}
	return NULL;
}

void CCTLIBAdapter::closeStatement(void *stmt)
{
	CTL_Statement_t *s = (CTL_Statement_t*)stmt;
	if(stmt==NULL || m_pContext==NULL)
		return;
	if(s->stmt != NULL)
	{
		ct_cancel(NULL, s->stmt, CS_CANCEL_ALL);
		ct_cmd_drop(s->stmt);
	}
	free(s);
}

bool CCTLIBAdapter::Query(void *stmt, char *sql, DbField_t *record, DbDesc_t *desc, int *cols, int timeout)
{
	CS_INT result;
	int i;
	CS_DATAFMT tformat;
	CS_DATAFMT format;
	CTL_Statement_t *s = (CTL_Statement_t*)stmt;

	if(stmt==NULL || sql==NULL || record==NULL || cols==NULL || timeout<0 || m_pContext==NULL)
		return false;
	ct_cancel(NULL, s->stmt, CS_CANCEL_ALL);
	if(ct_command(s->stmt, CS_LANG_CMD, sql, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED)
	{
		m_pPool->PrintLog("set query sql failed.");
		return false;
	}
	if(ct_send(s->stmt) != CS_SUCCEED)
	{
		m_pPool->PrintLog("send query failed.");
		return false;
	}
	if(timeout > 0)
	{
		if(ct_config(m_pContext, CS_SET, CS_TIMEOUT, &timeout, CS_UNUSED, NULL) != CS_SUCCEED)
			m_pPool->PrintLog("set query timeout failed.");
	}
	if(ct_results(s->stmt, &result) != CS_SUCCEED)
	{
		m_pPool->PrintLog("get query results failed.");
		return false;
	}
	if(result != CS_ROW_RESULT)
	{
		m_pPool->PrintLog("query result type is error.");
		return false;
	}
	if(ct_res_info(s->stmt, CS_NUMDATA, cols, CS_UNUSED, NULL) != CS_SUCCEED)
	{
		m_pPool->PrintLog("get result columns failed.");
		return false;
	}
	memset(&tformat, 0, sizeof(tformat));
	tformat.datatype = CS_CHAR_TYPE;
	tformat.maxlength = MAX_VALUE_LENGTH;
	tformat.count = 1;
	tformat.format = CS_FMT_NULLTERM;
	for(i=0; i<*cols; i++)
	{
		if(desc != NULL)
		{
			memset(&desc[i], 0, sizeof(desc[i]));
			if(ct_describe(s->stmt, i+1, &format) != CS_SUCCEED)
			{
				m_pPool->PrintLog("get query field information failed.");
				return false;
			}
			strncpy(desc[i].fieldname, format.name, MAX_FIELD_DESC);
			desc[i].type = DbType(format.datatype);
			desc[i].scale = format.scale;
			desc[i].precision = format.precision;
			//字符串长度
			if(desc[i].precision==0 && format.maxlength>0)
				desc[i].precision = format.maxlength;
		}
		if(ct_bind(s->stmt, i+1, &tformat, record[i].buf, NULL, &s->indicator[i]) != CS_SUCCEED)
		{
			m_pPool->PrintLog("bind query buffer failed.");
			return false;
		}
	}
	return true;
}

bool CCTLIBAdapter::Next(void *stmt, DbField_t *record, int cols)
{
	int i;
	CTL_Statement_t *s = (CTL_Statement_t*)stmt;
	if(stmt==NULL || record==NULL || cols<=0 || m_pContext==NULL)
		return false;
	
	if(ct_fetch(s->stmt, CS_UNUSED, CS_UNUSED, CS_UNUSED, NULL) != CS_SUCCEED)
		return false;
	for(i=0; i<cols; i++)
	{
		if(s->indicator[i] == -1)
			record[i].null = true;
		else
			record[i].null = false;
	}
	return true;
}

int CCTLIBAdapter::Execute(void *stmt, char *sql, int timeout, int row)
{
	int row_num;
	char rowsql[256];
	CTL_Statement_t *s = (CTL_Statement_t*)stmt;
	if(stmt==NULL || sql==NULL || timeout<0 || row<0 || m_pContext==NULL)
		return -1;

	if(row > 0)

⌨️ 快捷键说明

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