📄 ctlibadapter.cpp
字号:
#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 + -