数据库连接作为一种资源,我们的应用必须对之进行行之有效的管理。我们在访问数据库的时候,一般传统上采用先建立连接,然后使用该连接访问数据库,在使用完毕后,关闭该连接。这是我们经常采用的方法。该方法的好处是使用简单,不用对连接进行任何管理。但随之带来的缺点也就出现了,在应用需要频繁访问数据库的时候,这种方法就会使程序的效率十分低下,甚至有时候是不能满足应用的需要的。随着数据库连接池技术出现了,我们的应用根据访问数据库的频率动态决定创建连接的数量,以及决定在适当的时刻可以关闭一些数据库连接,用以节省这种资源。笔者最近在参考了网上大量代码的同时,实现了如何利用Pro C++使用数据库连接池完成了多线程对oracle数据库的访问。本着来源于网络,共享与网络的精神,和大家共同探讨,其中笔者的大部分代码来源是黄剑锋先生的共享代码,在此深表感谢。实现的基本功能如下:
1:可以设定最小的数据库连接数。
2:可以设定最大的数据库连接数。
3:当数据库某个连接空闲时间多长时间后,该连接池会自动断开连接以节省数据库连接资源。
4:提供了每个连接被使用的次数接口,方便统计和分析各个连接的情况。
5:提供了每个连接从上次访问完毕,懂查看的时候为止,已经空闲的时长,以秒为单位。
6:可以动态访问数据库存储过程,即存储过程的名字可以动态变化的。
CConnection:
#pragma once
#include
#include
#include
#define RT_OK 0
#define RT_NG -1
#define DB_CORE 0
#define DB_CORE_1 DB_CORE
using namespace std;
/*数据库错误原因*/
#define RT_CONNECT_FAILED -2
#define RT_SOURCE_BUSY -3
#define RT_NO_DATA_FOUND -4 /*when fetch cursor over or cursor is empty*/
#define RT_DOUBLE_KEY -5 /*unique constraint violated*/
#define RT_OTHER_ERROR -99
/****************************************数据库单连接******************************************/
class CConnection
{
public:
CConnection();
CConnection(std::string db_string, std::string db_name);
virtual ~CConnection();
void settimerid(int timerid);
int gettimerid();
void addinvoke();
void set(std::string db_string, std::string db_name);
void set_db_string(std::string db_string);
void set_db_name(std::string db_name);
string get_db_string();
string get_db_name();
void output();
void setidletimepoint();
void* getctctx();
static int multi_thread();
int start();
int stop();
int connect();
int disconnect();
int reconnect();
bool is_connected();
/*示例*/
int DML_DEMO_1();
int DML_DEMO_2(int i);
int DML_DEMO_3(int i);
int DML_DEMO_4(char* inputparam, char* outputparam);
int DML_DEMO_5(char* spname, char* inputparam, char* outputparam);
private:
bool db_connected_;
int invoke_;
time_t idletimepoint_;
int timerid_;
/*数据库连接上下文*/
void * ctx_;
std::string db_string_; /*数据库连接串 user/pwd@sid*/
std::string db_name_; /*数据库连接别名*/
int SqlError(void *_sqlca, const char *_FunName);
};
/*==================================================================================================
* 项目名称: Proc++程序模板
* 功能: 实现Proc预编译程序设计模式
* 作者: huangjf
* 联系: [email protected]
* 最近修改: 2010-7-15
* 版本: v2.0.1
==================================================================================================*/
#include
#include
#include
#include
#include
#include
#include
#include "Logger.h"
#include "Connection.h"
CConnection::CConnection()
{
CLogger::createinstance()->logdebugmsg("(+)connection address=%08x\n", this);
db_connected_ = false;
ctx_ = NULL;
db_string_ = "NULL";
db_name_ = "NULL";
invoke_ = 0;
idletimepoint_ = time(NULL);
timerid_ = -1;
}
CConnection::CConnection(std::string db_string, std::string db_name)
{
CLogger::createinstance()->logdebugmsg("(+)connection address=%08x\n", this);
db_connected_ = false;
ctx_ = NULL;
db_string_ = db_string;
db_name_ = db_name;
invoke_ = 0;
idletimepoint_ = time(NULL);
timerid_ = -1;
}
CConnection::~CConnection()
{
CLogger::createinstance()->logdebugmsg("(-)connection address=%08x\n", this);
db_connected_ = false;
}
void CConnection::settimerid(int timerid)
{
timerid_ = timerid;
}
int CConnection::gettimerid()
{
return timerid_;
}
void CConnection::addinvoke()
{
invoke_++;
}
void CConnection::set(std::string db_string, std::string db_name)
{
db_string_ = db_string;
db_name_ = db_name;
}
void CConnection::set_db_string(std::string db_string)
{
db_string_ = db_string;
}
void CConnection::set_db_name(std::string db_name)
{
db_name_ = db_name;
}
string CConnection::get_db_string()
{
return db_string_;
}
void CConnection::setidletimepoint()
{
time(&idletimepoint_);
}
void CConnection::output()
{
CLogger::createinstance()->logdebugmsg("connection=%08x invoke=%d idletime=%d\n", this, invoke_, time(NULL) - idletimepoint_);
}
void* CConnection::getctctx()
{
return ctx_;
}
string CConnection::get_db_name()
{
return db_name_;
}
int CConnection::multi_thread()
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
EXEC SQL ENABLE THREADS;
CLogger::createinstance()->logdebugmsg("start database muti thread mode:success\n");
return RT_OK;
sqlerr:
CLogger::createinstance()->logdebugmsg("start database muti thread mode:failure\n");
return RT_NG;
}
int CConnection::start()
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
EXEC SQL BEGIN DECLARE SECTION;
sql_context ctx = NULL;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONTEXT ALLOCATE :ctx;
this->ctx_ = ctx;
if (this->ctx_ != NULL)
{
CLogger::createinstance()->logdebugmsg("create database context:success\n");
return RT_OK;
}
else
{
CLogger::createinstance()->logdebugmsg("create database context:failure\n");
return RT_NG;
}
sqlerr:
return (SqlError(&sqlca, "start()"));
}
int CConnection::stop()
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
EXEC SQL BEGIN DECLARE SECTION;
sql_context ctx = NULL;
EXEC SQL END DECLARE SECTION;
ctx = this->ctx_;
EXEC SQL CONTEXT FREE :ctx;
CLogger::createinstance()->logdebugmsg("destroy database context:success\n");
return RT_OK;
sqlerr:
CLogger::createinstance()->logdebugmsg("destroy database context:failure\n");
return (SqlError(&sqlca, "stop()"));
}
int CConnection::connect()
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
if (this->ctx_ == NULL) return RT_NG;
if (this->db_connected_ == true) return RT_OK;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR vcConnStr[512]; /*数据库连接串 user/pwd@sid*/
VARCHAR vcLinkName[64]; /*数据库连接别名*/
sql_context ctx = NULL; /*数据库连接上下文*/
EXEC SQL END DECLARE SECTION;
ACE_OS::memset(&vcConnStr, 0x00, sizeof(vcConnStr));
ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));
ACE_OS::strncpy((char *)vcConnStr.arr, this->db_string_.c_str(), this->db_string_.length());
vcConnStr.len = ACE_OS::strlen((char *)vcConnStr.arr);
ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());
vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);
ctx = this->ctx_;
EXEC SQL CONTEXT USE :ctx;
EXEC SQL CONNECT :vcConnStr AT :vcLinkName;
this->db_connected_ = true;
CLogger::createinstance()->logdebugmsg("connect to database [%s]:success\n", this->db_name_.c_str());
return RT_OK;
sqlerr:
this->db_connected_ = false;
CLogger::createinstance()->logdebugmsg("connect to database [%s]:failure\n", this->db_name_.c_str());
return (SqlError(&sqlca, "connect()"));
}
int CConnection::disconnect()
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
if (this->ctx_ == NULL) return RT_NG;
if (this->db_connected_ == false) return RT_OK;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR vcLinkName[64]; /*数据库连接别名*/
sql_context ctx = NULL; /*数据库连接上下文*/
EXEC SQL END DECLARE SECTION;
ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));
ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());
vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);
ctx = this->ctx_;
EXEC SQL CONTEXT USE :ctx;
/*EXEC SQL AT :vcLinkName ROLLBACK WORK RELEASE;*/
EXEC SQL AT :vcLinkName COMMIT WORK RELEASE;
this->db_connected_ = false;
CLogger::createinstance()->logdebugmsg("disconnect to database [%s]:success\n", this->db_name_.c_str());
return RT_OK;
sqlerr:
this->db_connected_ = false;
CLogger::createinstance()->logdebugmsg("disconnect to database [%s]:failure\n", this->db_name_.c_str());
return (SqlError(&sqlca, "disconnect()"));
}
int CConnection::reconnect()
{
this->disconnect();
this->connect();
return this->db_connected_==true ? RT_OK : RT_NG;
}
bool CConnection::is_connected()
{
return this->db_connected_;
}
int CConnection::SqlError(void *_sqlca, const char *_FunName)
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
if (this->ctx_ == NULL) return RT_NG;
if (this->db_connected_ == false) return RT_NG;
int iRet;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR vcLinkName[64]; /*数据库连接别名*/
sql_context ctx = NULL; /*数据库连接上下文*/
struct sqlca *sql_ca;
EXEC SQL END DECLARE SECTION;
memset(&vcLinkName, 0x00, sizeof(vcLinkName));
ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());
vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);
ctx = this->ctx_;
EXEC SQL CONTEXT USE :ctx;
sql_ca = (struct sqlca *)_sqlca;
if (sql_ca->sqlcode == 0)
{
return RT_OK;
}
if (sql_ca->sqlcode == -1)
{
iRet = RT_DOUBLE_KEY;
}
else if (((sql_ca->sqlcode == -1012)||(sql_ca->sqlcode == -1041)||(sql_ca->sqlcode == -3114)||(sql_ca->sqlcode == -1003)||(sql_ca->sqlcode == 1455))||((sql_ca->sqlcode <= -12150)&&(sql_ca->sqlcode >= -12285))||((sql_ca->sqlcode >= -12699)&&(sql_ca->sqlcode <= -12500)))
{
iRet = RT_CONNECT_FAILED;
this->db_connected_ = false;
}
else if (sql_ca->sqlcode == 1403 ) /*no data found*/
{
iRet = RT_NO_DATA_FOUND;
}
else if (sql_ca->sqlcode == -54)
{
iRet = RT_SOURCE_BUSY;
}
else if (sql_ca->sqlcode == -1)
{
iRet = RT_DOUBLE_KEY; /*unique constraint violated*/
}
else
{
iRet = RT_OTHER_ERROR;
}
CLogger::createinstance()->logdebugmsg("database [%s] happen error:\nfunction :[%s]\nresult :[%d]\nerrorcode:[%d]\nerrorinfo:[%s]\n",
this->db_name_.c_str(),
_FunName,
iRet,
sql_ca->sqlcode,
sql_ca->sqlerrm.sqlerrmc);
/*ORA-01033: ORACLE initialization or shutdown in progress*/
/*ORA-24324: service handle not initialized*/
/*ORA-03114: not connected to ORACLE*/
/*ORA-01089: immediate shutdown in progress - no operations are permitte */
/*ORA-24909: call in progress. Current operation cancelled*/
/*ORA-01012: not logged on*/
/*ORA-01438: value larger than specified precision allows for this colum*/
/*ORA-00001: 违反唯一约束条件*/
/*ORA-01400: 无法将 NULL 插入*/
EXEC SQL AT :vcLinkName ROLLBACK WORK;
sqlerr:
return iRet;
}
/********************************************************代码演示区**********************************************************/
/*********************************************************************************************
*功 能:SELECT示例
*输 入:NONE
*
*输 出:NONE
*
*返 回:RT_OK:成功,RT_NG:失败
*修 改 记 录:NONE
*********************************************************************************************/
int CConnection::DML_DEMO_1()
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
if (this->ctx_ == NULL) return RT_NG;
if (this->db_connected_ == false) return RT_NG;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR vcLinkName[64]; /*数据库连接别名*/
sql_context ctx = NULL; /*数据库连接上下文*/
VARCHAR v_sysdate[32];
EXEC SQL END DECLARE SECTION;
ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));
ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());
vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);
ctx = this->ctx_;
EXEC SQL CONTEXT USE :ctx;
/*TODO 自有变量赋值*/
ACE_OS::memset(&v_sysdate, 0x00, sizeof(v_sysdate));
EXEC SQL AT :vcLinkName
SELECT to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') INTO :v_sysdate
FROM DUAL;
CLogger::createinstance()->logdebugmsg("[%s]\n", (char *)v_sysdate.arr);
return RT_OK;
/*
notfound:
CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_1() ERROR:No record exist\n", this->db_name_.c_str());
return RT_NG;
*/
sqlerr:
return (SqlError(&sqlca, "DML_DEMO_1()"));
}
/*********************************************************************************************
*功 能:INSERT INTO示例
*输 入:NONE
*
*输 出:NONE
*
*返 回:RT_OK:成功,RT_NG:失败
*修 改 记 录:NONE
*********************************************************************************************/
int CConnection::DML_DEMO_2(int i)
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
EXEC SQL WHENEVER NOT FOUND GOTO notfound;
if (this->ctx_ == NULL) return RT_NG;
if (this->db_connected_ == false) return RT_NG;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR vcLinkName[64]; /*数据库连接别名*/
sql_context ctx = NULL; /*数据库连接上下文*/
VARCHAR dyn_stmt[1024];
EXEC SQL END DECLARE SECTION;
ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));
ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());
vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);
ctx = this->ctx_;
EXEC SQL CONTEXT USE :ctx;
ACE_OS::memset(&dyn_stmt, 0x00, sizeof(dyn_stmt));
/*TODO 自有变量赋值*/
dyn_stmt.len = ACE_OS::snprintf((char *)dyn_stmt.arr, sizeof(dyn_stmt.arr), "insert into TB1(COL1, COL2) values(%d, sysdate)", i);
CLogger::createinstance()->logdebugmsg("SQL:[%s]\n", dyn_stmt.arr);
EXEC SQL AT :vcLinkName EXECUTE IMMEDIATE :dyn_stmt;
if (sqlca.sqlcode == 0)
{
CLogger::createinstance()->logdebugmsg("insert into TB1 table success\n");
}
else
{
CLogger::createinstance()->logdebugmsg("insert into TB1 table failure\n");
}
EXEC SQL AT :vcLinkName COMMIT WORK;
return RT_OK;
notfound:
CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_2() ERROR:No record exist\n", this->db_name_.c_str());
return RT_NG;
sqlerr:
return (SqlError(&sqlca, "DML_DEMO_2()"));
}
/*********************************************************************************************
*功 能:PREPARE SELECT示例
*输 入:NONE
*
*输 出:NONE
*
*返 回:RT_OK:成功,RT_NG:失败
*修 改 记 录:NONE
*********************************************************************************************/
int CConnection::DML_DEMO_3(int i)
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
/*EXEC SQL WHENEVER NOT FOUND GOTO notfound;*/
if (this->ctx_ == NULL) return RT_NG;
if (this->db_connected_ == false) return RT_NG;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR vcLinkName[64]; /*数据库连接别名*/
sql_context ctx = NULL; /*数据库连接上下文*/
int v_col1;
VARCHAR v_col2[24];
VARCHAR dyn_stmt[1024];
EXEC SQL END DECLARE SECTION;
ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));
ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());
vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);
ctx = this->ctx_;
EXEC SQL CONTEXT USE :ctx;
/*TODO 自有变量赋值*/
ACE_OS::memset(&dyn_stmt, 0x00, sizeof(dyn_stmt));
dyn_stmt.len = ACE_OS::snprintf((char *)dyn_stmt.arr, sizeof(dyn_stmt.arr), "SELECT COL1, to_char(COL2, 'YYYY-MM-DD HH24:MI:SS') FROM TB1 WHERE COL1=%d", i);
CLogger::createinstance()->logdebugmsg("SQL:[%s]\n", dyn_stmt.arr);
EXEC SQL AT :vcLinkName DECLARE S STATEMENT;
EXEC SQL AT :vcLinkName PREPARE S FROM :dyn_stmt;
EXEC SQL AT :vcLinkName DECLARE C_TB1_1 CURSOR FOR S;
EXEC SQL AT :vcLinkName OPEN C_TB1_1;
for (;;)
{
v_col1 = 0;
ACE_OS::memset(&v_col2, 0x00, sizeof(v_col2));
EXEC SQL WHENEVER NOT FOUND DO BREAK;
EXEC SQL FETCH C_TB1_1 INTO :v_col1, :v_col2;
if (sqlca.sqlcode != 0) break;
CLogger::createinstance()->logdebugmsg("(%d):COL2=[%s]\n",
v_col1,
v_col2.arr);
}
EXEC SQL AT :vcLinkName CLOSE C_TB1_1;
EXEC SQL AT :vcLinkName COMMIT WORK;
return RT_OK;
/*
notfound:
CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_3() ERROR:No record exist\n", this->db_name_.c_str());
return RT_NG;
*/
sqlerr:
return (SqlError(&sqlca, "DML_DEMO_3()"));
}
/*********************************************************************************************
*功 能:EXECUTE PROCEDURE示例
*输 入:存储过程名, 存储过程入参
*
*输 出:存储过程返回值
*
*返 回:RT_OK:成功,RT_NG:失败
*修 改 记 录:NONE
*********************************************************************************************/
int CConnection::DML_DEMO_4(char* inputparam, char* outputparam)
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
EXEC SQL WHENEVER NOT FOUND GOTO notfound;
if (this->ctx_ == NULL) return RT_NG;
if (this->db_connected_ == false) return RT_NG;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR vcLinkName[64]; /*数据库连接别名*/
sql_context ctx = NULL; /*数据库连接上下文*/
VARCHAR v_input[512];
VARCHAR v_output[512];
EXEC SQL END DECLARE SECTION;
ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));
ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());
vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);
ctx = this->ctx_;
EXEC SQL CONTEXT USE :ctx;
/*TODO 自有变量赋值*/
v_input.len = ACE_OS::snprintf((char *)v_input.arr, sizeof(v_input.arr),"%s",inputparam);
ACE_OS::memset(&v_output, 0x00, sizeof(v_output));
/*执行PL/SQL块*/
EXEC SQL AT :vcLinkName EXECUTE
BEGIN
sp_test(:v_input, :v_output);
END;
END-EXEC;
if (sqlca.sqlcode == 0)
{
ACE_OS::snprintf((char *)outputparam, v_output.len, "%s", v_output.arr);
outputparam[ v_output.len + 1] = '\0';
CLogger::createinstance()->logdebugmsg("storage procedure (sp_test) success, result=%s\n", outputparam);
}
else
{
CLogger::createinstance()->logdebugmsg("storage procedure (sp_test) failure\n");
}
EXEC SQL AT :vcLinkName COMMIT WORK;
return RT_OK;
notfound:
CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_4() ERROR:No record exist\n", this->db_name_.c_str());
return RT_NG;
sqlerr:
return (SqlError(&sqlca, "DML_DEMO_4()"));
}
/*********************************************************************************************
*功 能:PREPARE PL/SQL块示例
*输 入:NONE
*
*输 出:NONE
*
*返 回:RT_OK:成功,RT_NG:失败
*修 改 记 录:NONE
*********************************************************************************************/
int CConnection::DML_DEMO_5(char* spname, char* inputparam, char* outputparam)
{
#undef SQLCA
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
EXEC SQL WHENEVER NOT FOUND GOTO notfound;
if (this->ctx_ == NULL) return RT_NG;
if (this->db_connected_ == false) return RT_NG;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR vcLinkName[64]; /*数据库连接别名*/
sql_context ctx = NULL; /*数据库连接上下文*/
VARCHAR v_input[512];
VARCHAR v_output[512];
VARCHAR dyn_stmt[1024];
EXEC SQL END DECLARE SECTION;
ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));
ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());
vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);
ctx = this->ctx_;
EXEC SQL CONTEXT USE :ctx;
/*TODO 自有变量赋值*/
ACE_OS::memset(&dyn_stmt, 0x00, sizeof(dyn_stmt));
dyn_stmt.len = ACE_OS::snprintf((char *)dyn_stmt.arr, sizeof(dyn_stmt.arr), "BEGIN %s(:v_input,:v_output); END;", spname);
v_input.len = ACE_OS::snprintf((char *)v_input.arr, sizeof(v_input), "%s", inputparam);
ACE_OS::memset(&v_output, 0x00, sizeof(v_output));
//CLogger::createinstance()->logdebugmsg("SQL: [%s]\n", dyn_stmt.arr);
EXEC SQL AT :vcLinkName DECLARE SS STATEMENT;
EXEC SQL AT :vcLinkName PREPARE SS FROM :dyn_stmt;
EXEC SQL AT :vcLinkName EXECUTE SS USING :v_input, :v_output;
if (sqlca.sqlcode == 0)
{
ACE_OS::snprintf((char *)outputparam, v_output.len, "%s", v_output.arr);
outputparam[ v_output.len + 1] = '\0';
CLogger::createinstance()->logdebugmsg("storage procedure (%s) success and result=%s\n", spname, outputparam);
}
else
{
CLogger::createinstance()->logdebugmsg("storage procedure (%s) failure\n", spname);
}
EXEC SQL AT :vcLinkName COMMIT WORK;
return RT_OK;
notfound:
CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_5() ERROR:No record exist\n", this->db_name_.c_str());
return RT_NG;
sqlerr:
return (SqlError(&sqlca, "DML_DEMO_5()"));
}
cconnectionpool:
#pragma once
#include "Connection.h"
#include "ace/Synch.h"
#include
using namespace std;
typedef list CONNECTIONLIST;
class CConnectionpool : ACE_Event_Handler
{
public:
CConnectionpool(string dbstring, string dbname);
CConnectionpool(string dbstring, string dbname,int maxconn, int minconn, int m_keepalive);
~CConnectionpool(void);
private:
CONNECTIONLIST m_idlelist;
CONNECTIONLIST m_busylist;
string m_dbstring;
string m_dbname;
int m_maxconn;
int m_minconn;
int m_keepalive;
ACE_Thread_Mutex m_mutex;
ACE_Condition *m_pcondition;
bool active_;
private:
CConnection* applyfor();
bool payback(CConnection* pconn);
bool removefromidlelist(CConnection* pconn);
int addtimer(CConnection *pconn);
int removetimer(CConnection *pconn);
virtual int handle_timeout(const ACE_Time_Value &tv, const void *arg);
int getconnectionsize();
public:
bool start();
bool stop();
int executesp(char* spname, char* inputparam, char* outparam);
void output();
bool getactive();
};
#include "Connectionpool.h"
#include "ace/Reactor.h"
#include "Logger.h"
CConnectionpool::CConnectionpool(string dbstring, string dbname)
{
m_dbstring = dbstring;
m_dbname = dbname;
m_minconn = 2;
m_maxconn = 4;
m_keepalive = 10;
m_pcondition = new ACE_Condition(m_mutex);
}
CConnectionpool::CConnectionpool(string dbstring, string dbname, int minconn, int maxconn, int keepalive)
{
m_dbstring = dbstring;
m_dbname = dbname;
m_minconn = minconn;
m_maxconn = maxconn;
m_keepalive = keepalive;
m_pcondition = new ACE_Condition(m_mutex);
}
CConnectionpool::~CConnectionpool(void)
{
delete m_pcondition;
}
bool CConnectionpool::start()
{
bool result = false;
if (CConnection::multi_thread() == RT_OK)
{
active_ = true;
result = true;
}
return result;
}
bool CConnectionpool::stop()
{
active_ = false;
while(m_busylist.size() != 0)
{
ACE_OS::sleep(1);
}
printf("all connections are idle, we can destroy them\n");
typedef CONNECTIONLIST::iterator ITERATOR;
ITERATOR LI;
for(LI = m_idlelist.begin(); LI != m_idlelist.end();)
{
removetimer(*LI);
(*LI)->disconnect();
(*LI)->stop();
delete (*LI);
LI = m_idlelist.erase(LI);
}
return true;
}
CConnection* CConnectionpool::applyfor()
{
m_mutex.acquire();
CConnection *pconn = NULL;
if (m_idlelist.size() > 0)
{
pconn = m_idlelist.front();
m_idlelist.pop_front();
m_busylist.push_back(pconn);
//删除定时器
removetimer(pconn);
}
else
{
int idle = m_idlelist.size();
int busy = m_busylist.size();
int all = idle + busy;
if (all < m_maxconn)
{
pconn = new CConnection(m_dbstring, m_dbname);
pconn->start();
pconn->reconnect();
m_busylist.push_back(pconn);
}
else
{
while(m_idlelist.size() == 0)
{
m_pcondition->signal();
m_pcondition->wait();
}
pconn = m_idlelist.front();
m_idlelist.pop_front();
m_busylist.push_back(pconn);
//删除定时器
removetimer(pconn);
}
}
m_mutex.release();
return pconn;
}
bool CConnectionpool::payback(CConnection* pconn)
{
m_mutex.acquire();
typedef CONNECTIONLIST::iterator ITERATOR;
ITERATOR LI;
bool find = false;
for(LI = m_busylist.begin(); LI != m_busylist.end();)
{
if (*LI == pconn)
{
LI = m_busylist.erase(LI);
find = true;
}
else
{
LI++;
}
}
if (find)
{
m_idlelist.push_back(pconn);
pconn->setidletimepoint();
//启动定时器
addtimer(pconn);
m_pcondition->signal();
}
m_mutex.release();
return find;
}
int CConnectionpool::getconnectionsize()
{
m_mutex.acquire();
int idle = m_idlelist.size();
int busy = m_busylist.size();
int all = idle + busy;
m_mutex.release();
return all;
}
bool CConnectionpool::removefromidlelist(CConnection* pconn)
{
m_mutex.acquire();
typedef CONNECTIONLIST::iterator ITERATOR;
ITERATOR LI;
bool find = false;
CConnection *ptemp = NULL;
for(LI = m_idlelist.begin(); LI != m_idlelist.end();)
{
if (*LI == pconn)
{
pconn->disconnect();
pconn->stop();
delete pconn;
m_idlelist.erase(LI);
find = true;
break;
}
}
m_mutex.release();
return find;
}
int CConnectionpool::executesp(char* spname, char* inputparam, char* outparam)
{
int ret = -1;
if (!active_) return ret;
CConnection *pconn = NULL;
pconn = applyfor();
if (pconn != NULL)
{
pconn->addinvoke();
ret = pconn->DML_DEMO_5(spname, inputparam, outparam);
}
payback(pconn);
return ret;
}
void CConnectionpool::output()
{
m_mutex.acquire();
typedef CONNECTIONLIST::iterator ITERATOR;
ITERATOR LI;
int idle = m_idlelist.size();
int busy = m_busylist.size();
int all = idle + busy;
printf("total=%d\n", all);
printf("idle=%d\n", idle);
printf("busy=%d\n", busy);
printf("........idle list........\n");
for(LI = m_idlelist.begin(); LI != m_idlelist.end(); LI++)
{
(*LI)->output();
}
printf("........busy list........\n");
for(LI = m_busylist.begin(); LI != m_busylist.end(); LI++)
{
(*LI)->output();
}
m_mutex.release();
}
int CConnectionpool::addtimer(CConnection *pconn)
{
ACE_Time_Value tv(this->m_keepalive, 0);
int timerid = ACE_Reactor::instance()->schedule_timer(this, (void*)pconn, tv);
pconn->settimerid(timerid);
return timerid;
}
int CConnectionpool::removetimer(CConnection *pconn)
{
return ACE_Reactor::instance()->cancel_timer(pconn->gettimerid());
}
int CConnectionpool::handle_timeout(const ACE_Time_Value &tv, const void *arg)
{
CConnection *pconn = (CConnection*)arg;
CLogger::createinstance()->logdebugmsg("handle_timeout current=%d connection=%08x timerid=%d ok\n", getconnectionsize(), pconn, pconn->gettimerid());
if (getconnectionsize() > m_minconn)
{
removefromidlelist(pconn);
}
return 0;
}
bool CConnectionpool::getactive()
{
return active_;
}
cclienttask
#pragma once
#include "ace/Task.h"
#include "ace/Synch.h"
#include "Connectionpool.h"
class CClienttask : public ACE_Task
{
public:
CClienttask(void);
CClienttask(CConnectionpool* connpool, int execount);
~CClienttask(void);
public:
virtual int open();
virtual int svc();
virtual int close();
private:
ACE_thread_t threads[0x04];
CConnectionpool* m_pconnpool;
int m_execount;
};
#include "Clienttask.h"
#include "Logger.h"
CClienttask::CClienttask(void)
{
}
CClienttask::CClienttask(CConnectionpool* connpool, int execount)
{
m_pconnpool = connpool;
m_execount = execount;
}
CClienttask::~CClienttask(void)
{
}
int CClienttask::open()
{
return activate(THR_NEW_LWP, 4, 0, ACE_DEFAULT_THREAD_PRIORITY, -1, this, 0, 0, 0, threads);
}
int CClienttask::svc()
{
if (ACE_Thread::self() == threads[0])
{
CLogger::createinstance()->logdebugmsg("watch thread started, threadid=%d\n", threads[0]);
while(true)
{
int command = 0;
scanf_s("%d", &command);
if(command == 1)
{
m_pconnpool->output();
}
else if(command == 2)
{
m_pconnpool->stop();
}
}
}
else if (ACE_Thread::self() == threads[1])
{
CLogger::createinstance()->logdebugmsg("client task started, threadid=%d\n", threads[1]);
int i = 0;
while(i < m_execount && m_pconnpool->getactive())
{
char input[100];
sprintf_s(input, 100, "%05dwangxu%05d", threads[1], i);
char output[100];
m_pconnpool->executesp("sp_test", input, output);
i++;
}
}
else if (ACE_Thread::self() == threads[2])
{
CLogger::createinstance()->logdebugmsg("client task started, threadid=%d\n", threads[2]);
int i = 0;
while(i < m_execount && m_pconnpool->getactive())
{
char input[100];
sprintf_s(input, 100, "%05dwangxu%05d", threads[2], i);
char output[100];
m_pconnpool->executesp("sp_test", input, output);
i++;
}
}
else if (ACE_Thread::self() == threads[3])
{
CLogger::createinstance()->logdebugmsg("client task started, threadid=%d\n", threads[3]);
int i = 0;
while(i < m_execount && m_pconnpool->getactive())
{
char input[100];
sprintf_s(input, 100, "%05dwangxu%05d", threads[3], i);
char output[100];
m_pconnpool->executesp("sp_test", input, output);
i++;
}
}
return 0;
}
int CClienttask::close()
{
return 0;
}
CLogger
#pragma once
#include "ace/Activation_Queue.h"
#include "ace/Method_Request.h"
#include "ace/Task.h"
#include "ace/Future.h"
#include "ace/Auto_Ptr.h"
#include
#include
#include
#include
#include
using namespace std;
class CLogger : public ACE_Task
{
public:
/*log level*/
enum LEVEL
{
DEBUG = 0x00,
INFO = 0x01,
WARN = 0x02,
FAULT = 0x03
};
/*output direct*/
enum DIRECTOR
{
SCREENOUT = 0x00,
FILEOUT = 0x01,
BOTH = 0x02
};
/*log mode*/
enum MODE
{
TEST = 0x00,
RUN = 0x01
};
/*whether the log will be split*/
enum SPLIT
{
ONE = 0x00,
FOUR = 0x01
};
/*delete log automatic or manual*/
enum MANAGER
{
AUTODEL = 0x00,
MANUALDEL = 0x01
};
public:
CLogger(void);
CLogger(LEVEL level, DIRECTOR director, MODE mode, SPLIT split, MANAGER manager);
~CLogger(void);
int logdebugmsg_i(const char* fmt, ...);
int loginfomsg_i(const char* fmt, ...);
int logwarnmsg_i(const char* fmt, ...);
int logfaultmsg_i(const char* fmt, ...);
ACE_Future logdebugmsg(const char* fmt, ...);
ACE_Future loginfomsg(const char* fmt, ...);
ACE_Future logwarnmsg(const char* fmt, ...);
ACE_Future logfaultmsg(const char* fmt, ...);
void setparam(LEVEL level, DIRECTOR director, MODE mode, SPLIT split, MANAGER manager);
virtual int open();
virtual int close();
virtual int svc();
static CLogger* createinstance();
private:
static CLogger* _instance;
ACE_thread_t threads[0x01];
ACE_Activation_Queue m_activation_queue;
private:
LEVEL m_level;
DIRECTOR m_director;
MODE m_mode;
SPLIT m_split;
MANAGER m_manager;
string m_directory;
void createlogdirectory();
string getdatetime();
string getdate();
void closefilehandle();
FILE* getonefilehandle();
FILE* getdebugfilehandle();
FILE* getinfofilehandle();
FILE* getwarnfilehandle();
FILE* getfaultfilehandle();
FILE* m_fpfourdebug;
string m_filenamedebug;
FILE* m_fpfourinfo;
string m_filenameinfo;
FILE* m_fpfourwarn;
string m_filenamewarn;
FILE* m_fpfourfault;
string m_filenamefault;
FILE* m_fponelog;
string m_filenamelog;
public:
void setlevel(LEVEL level);
LEVEL getlevel();
void setdirector(DIRECTOR director);
DIRECTOR getdirector();
void setmode(MODE mode);
MODE getmode();
void setsplit(SPLIT split);
SPLIT getsplit();
void setmanager(MANAGER manager);
MANAGER getmanager();
};
#include
#include "Logger.h"
#include "Logdebugmsg_MO.h"
#include "Loginfomsg_MO.h"
#include "Logwarnmsg_MO.h"
#include "Logfaultmsg_MO.h"
CLogger* CLogger::_instance = 0;
CLogger* CLogger::createinstance()
{
if (_instance == 0)
{
_instance = new CLogger;
}
return _instance;
}
CLogger::CLogger(void)
{
m_level = CLogger::DEBUG;
m_director = CLogger::BOTH;
m_mode = CLogger::TEST;
m_split = CLogger::FOUR;
m_manager = CLogger::AUTODEL;
m_fpfourdebug = NULL;
m_fpfourinfo = NULL;
m_fpfourwarn = NULL;
m_fpfourfault = NULL;
m_fponelog = NULL;
m_filenamedebug = "null";
m_filenameinfo = "null";
m_filenamewarn = "null";
m_filenamefault = "null";
m_filenamelog = "null";
createlogdirectory();
}
CLogger::CLogger(LEVEL level, DIRECTOR director, MODE mode, SPLIT split, MANAGER manager)
{
m_level = level;
m_director = director;
m_mode = mode;
m_split = split;
m_manager = manager;
m_fpfourdebug = NULL;
m_fpfourinfo = NULL;
m_fpfourwarn = NULL;
m_fpfourfault = NULL;
m_fponelog = NULL;
m_filenamedebug = "null";
m_filenameinfo = "null";
m_filenamewarn = "null";
m_filenamefault = "null";
m_filenamelog = "null";
createlogdirectory();
}
void CLogger::closefilehandle()
{
if (m_fpfourdebug != NULL)
{
fclose(m_fpfourdebug);
m_fpfourdebug = NULL;
m_filenamedebug = "null";
}
if (m_fpfourinfo != NULL)
{
fclose(m_fpfourinfo);
m_fpfourinfo = NULL;
m_filenameinfo = "null";
}
if (m_fpfourwarn != NULL)
{
fclose(m_fpfourwarn);
m_fpfourwarn = NULL;
m_filenamewarn = "null";
}
if (m_fpfourfault != NULL)
{
fclose(m_fpfourfault);
m_fpfourfault = NULL;
m_filenamefault = "null";
}
if (m_fponelog != NULL)
{
fclose(m_fponelog);
m_fponelog = NULL;
m_filenamelog = "null";
}
}
CLogger::~CLogger(void)
{
closefilehandle();
}
void CLogger::setlevel(LEVEL level)
{
closefilehandle();
m_level = level;
}
CLogger::LEVEL CLogger::getlevel()
{
return m_level;
}
void CLogger::setdirector(DIRECTOR director)
{
closefilehandle();
m_director = director;
}
CLogger::DIRECTOR CLogger::getdirector()
{
return m_director;
}
void CLogger::setmode(MODE mode)
{
closefilehandle();
m_mode = mode;
}
CLogger::MODE CLogger::getmode()
{
return m_mode;
}
void CLogger::setsplit(SPLIT split)
{
closefilehandle();
m_split = split;
}
CLogger::SPLIT CLogger::getsplit()
{
return m_split;
}
void CLogger::setmanager(MANAGER manager)
{
m_manager = manager;
}
CLogger::MANAGER CLogger::getmanager()
{
return m_manager;
}
string CLogger::getdatetime()
{
time_t current;
current = time(NULL);
struct tm pdatetime;
int error = localtime_s(&pdatetime, ¤t) ;
char datetime[100];
memset(datetime, 0x00, 100);
sprintf_s(datetime, 100, "%04d-%02d-%02d %02d:%02d %02d",
pdatetime.tm_year + 1900,
pdatetime.tm_mon + 1,
pdatetime.tm_mday,
pdatetime.tm_hour,
pdatetime.tm_min,
pdatetime.tm_sec);
return string(datetime);
}
string CLogger::getdate()
{
time_t current;
struct tm pdatetime;
time(¤t);
int error = localtime_s(&pdatetime, ¤t) ;
char date[100];
memset(date, 0x00, 100);
sprintf_s(date, 100, "%04d-%02d-%02d",
pdatetime.tm_year + 1900,
pdatetime.tm_mon + 1,
pdatetime.tm_mday);
return string(date);
}
int CLogger::logdebugmsg_i(const char* fmt, ...)
{
if (getlevel() > CLogger::DEBUG) return 0;
va_list ap;
va_start(ap, fmt);
if (getdirector() == CLogger::SCREENOUT)
{
vfprintf(stdout, fmt, ap);
}
else
{
if (getsplit() == CLogger::ONE)
{
m_fponelog = getonefilehandle();
vfprintf(m_fponelog, fmt, ap);
if (getmode() == CLogger::TEST)
{
fclose(m_fponelog);
m_fponelog = NULL;
}
}
else
{
m_fpfourdebug = getdebugfilehandle();
vfprintf(m_fpfourdebug, fmt, ap);
if (getmode() == CLogger::TEST)
{
fclose(m_fpfourdebug);
m_fpfourdebug = NULL;
}
}
if (getdirector() == CLogger::BOTH)
{
vfprintf(stdout, fmt, ap);
}
}
va_end(ap);
return 0;
}
int CLogger::loginfomsg_i(const char* fmt, ...)
{
if (getlevel() > CLogger::INFO) return 0;
va_list ap;
va_start(ap, fmt);
if (getdirector() == CLogger::SCREENOUT)
{
vfprintf(stdout, fmt, ap);
}
else
{
if (getsplit() == CLogger::ONE)
{
m_fponelog = getonefilehandle();
vfprintf(m_fponelog, fmt, ap);
if (getmode() == CLogger::TEST)
{
fclose(m_fponelog);
m_fponelog = NULL;
}
}
else
{
m_fpfourinfo = getinfofilehandle();
vfprintf(m_fpfourinfo, fmt, ap);
if (getmode() == CLogger::TEST)
{
fclose(m_fpfourinfo);
m_fpfourinfo = NULL;
}
}
if (getdirector() == CLogger::BOTH)
{
vfprintf(stdout, fmt, ap);
}
}
va_end(ap);
return 0;
}
int CLogger::logwarnmsg_i(const char* fmt, ...)
{
if (getlevel() > CLogger::WARN) return 0;
va_list ap;
va_start(ap, fmt);
if (getdirector() == CLogger::SCREENOUT)
{
vfprintf(stdout, fmt, ap);
}
else
{
if (getsplit() == CLogger::ONE)
{
m_fponelog = getonefilehandle();
vfprintf(m_fponelog, fmt, ap);
if (getmode() == CLogger::TEST)
{
fclose(m_fponelog);
m_fponelog = NULL;
}
}
else
{
m_fpfourwarn = getwarnfilehandle();
vfprintf(m_fpfourwarn, fmt, ap);
if (getmode() == CLogger::TEST)
{
fclose(m_fpfourwarn);
m_fpfourwarn = NULL;
}
}
if (getdirector() == CLogger::BOTH)
{
vfprintf(stdout, fmt, ap);
}
}
va_end(ap);
return 0;
}
int CLogger::logfaultmsg_i(const char* fmt, ...)
{
if (getlevel() > CLogger::FAULT) return 0;
va_list ap;
va_start(ap, fmt);
if (getdirector() == CLogger::SCREENOUT)
{
vfprintf(stdout, fmt, ap);
}
else
{
if (getsplit() == CLogger::ONE)
{
m_fponelog = getonefilehandle();
vfprintf(m_fponelog, fmt, ap);
if (getmode() == CLogger::TEST)
{
fclose(m_fponelog);
m_fponelog = NULL;
}
}
else
{
m_fpfourfault = getfaultfilehandle();
vfprintf(m_fpfourfault, fmt, ap);
if (getmode() == CLogger::TEST)
{
fclose(m_fpfourfault);
m_fpfourfault = NULL;
}
}
if (getdirector() == CLogger::BOTH)
{
vfprintf(stdout, fmt, ap);
}
}
va_end(ap);
return 0;
}
void CLogger::createlogdirectory()
{
if (m_director == CLogger::SCREENOUT) return;
string fulldir = "..\\log";
if (_access(fulldir.c_str(), 0) == -1)
{
printf("create %s\n", fulldir.c_str());
_mkdir(fulldir.c_str());
}
fulldir = "..\\log\\debug";
if (_access(fulldir.c_str(), 0) == -1)
{
printf("create %s\n", fulldir.c_str());
_mkdir(fulldir.c_str());
}
fulldir = "..\\log\\info";
if (_access(fulldir.c_str(), 0) == -1)
{
printf("create %s\n", fulldir.c_str());
_mkdir(fulldir.c_str());
}
fulldir = "..\\log\\warn";
if (_access(fulldir.c_str(), 0) == -1)
{
printf("create %s\n", fulldir.c_str());
_mkdir(fulldir.c_str());
}
fulldir = "..\\log\\fault";
if (_access(fulldir.c_str(), 0) == -1)
{
printf("create %s\n", fulldir.c_str());
_mkdir(fulldir.c_str());
}
}
FILE* CLogger::getonefilehandle()
{
string filename = "..\\log\\" + getdate() + ".log";
if ((filename.compare(m_filenamelog) == 0) && (m_fponelog != NULL))
{
}
else if((filename.compare(m_filenamelog) == 0) && (m_fponelog == NULL))
{
fopen_s(&m_fponelog, filename.c_str(), "a+");
}
else if((filename.compare(m_filenamelog) != 0) && (m_fponelog != NULL))
{
fclose(m_fponelog);
m_fponelog = NULL;
fopen_s(&m_fponelog, filename.c_str(), "a+");
m_filenamelog = filename;
}
else if((filename.compare(m_filenamelog) != 0) && (m_fponelog == NULL))
{
fopen_s(&m_fponelog, filename.c_str(), "a+");
m_filenamelog = filename;
}
return m_fponelog;
}
FILE* CLogger::getdebugfilehandle()
{
string filename = "..\\log\\debug\\" + getdate() + ".dlog";
if ((filename.compare(m_filenamedebug) == 0) && (m_fpfourdebug != NULL))
{
}
else if((filename.compare(m_filenamedebug) == 0) && (m_fpfourdebug == NULL))
{
fopen_s(&m_fpfourdebug, filename.c_str(), "a+");
}
else if((filename.compare(m_filenamedebug) != 0) && (m_fpfourdebug != NULL))
{
fclose(m_fpfourdebug);
m_fpfourdebug = NULL;
fopen_s(&m_fpfourdebug, filename.c_str(), "a+");
m_filenamedebug = filename;
}
else if((filename.compare(m_filenamedebug) != 0) && (m_fpfourdebug == NULL))
{
fopen_s(&m_fpfourdebug, filename.c_str(), "a+");
m_filenamedebug = filename;
}
return m_fpfourdebug;
}
FILE* CLogger::getinfofilehandle()
{
string filename = "..\\log\\info\\" + getdate() + ".ilog";
if ((filename.compare(m_filenameinfo) == 0) && (m_fpfourinfo != NULL))
{
}
else if((filename.compare(m_filenameinfo) == 0) && (m_fpfourinfo == NULL))
{
fopen_s(&m_fpfourinfo, filename.c_str(), "a+");
}
else if((filename.compare(m_filenameinfo) != 0) && (m_fpfourinfo != NULL))
{
fclose(m_fpfourinfo);
m_fpfourinfo = NULL;
fopen_s(&m_fpfourinfo, filename.c_str(), "a+");
m_filenameinfo = filename;
}
else if((filename.compare(m_filenameinfo) != 0) && (m_fpfourinfo == NULL))
{
fopen_s(&m_fpfourinfo, filename.c_str(), "a+");
m_filenameinfo = filename;
}
return m_fpfourinfo;
}
FILE* CLogger::getwarnfilehandle()
{
string filename = "..\\log\\warn\\" + getdate() + ".wlog";
if ((filename.compare(m_filenamewarn) == 0) && (m_fpfourwarn != NULL))
{
}
else if((filename.compare(m_filenamewarn) == 0) && (m_fpfourwarn == NULL))
{
fopen_s(&m_fpfourwarn, filename.c_str(), "a+");
}
else if((filename.compare(m_filenamewarn) != 0) && (m_fpfourwarn != NULL))
{
fclose(m_fpfourwarn);
m_fpfourwarn = NULL;
fopen_s(&m_fpfourwarn, filename.c_str(), "a+");
m_filenamewarn = filename;
}
else if((filename.compare(m_filenamewarn) != 0) && (m_fpfourwarn == NULL))
{
fopen_s(&m_fpfourwarn, filename.c_str(), "a+");
m_filenamewarn = filename;
}
return m_fpfourwarn;
}
FILE* CLogger::getfaultfilehandle()
{
string filename = "..\\log\\fault\\" + getdate() + ".flog";
if ((filename.compare(m_filenamefault) == 0) && (m_fpfourfault != NULL))
{
}
else if((filename.compare(m_filenamefault) == 0) && (m_fpfourfault == NULL))
{
fopen_s(&m_fpfourfault, filename.c_str(), "a+");
}
else if((filename.compare(m_filenamefault) != 0) && (m_fpfourfault != NULL))
{
fclose(m_fpfourfault);
m_fpfourfault = NULL;
fopen_s(&m_fpfourfault, filename.c_str(), "a+");
m_filenamefault = filename;
}
else if((filename.compare(m_filenamefault) != 0) && (m_fpfourfault == NULL))
{
fopen_s(&m_fpfourfault, filename.c_str(), "a+");
m_filenamefault = filename;
}
return m_fpfourfault;
}
int CLogger::open()
{
return activate(THR_NEW_LWP, 1, 0, ACE_DEFAULT_THREAD_PRIORITY, -1, this, 0, 0, 0, threads);
}
int CLogger::close()
{
return 0;
}
int CLogger::svc()
{
while(true)
{
auto_ptr mo(m_activation_queue.dequeue());
if (mo->call() == -1)
break;
}
return 0;
}
ACE_Future CLogger::logdebugmsg(const char* fmt, ...)
{
char logmsg1[1024];
memset(logmsg1, 0x00, 1024);
va_list ap;
va_start(ap, fmt);
_vsnprintf_s(logmsg1, 1024, fmt, ap);
va_end(ap);
char logmsg2[1024];
memset(logmsg2, 0x00, 1024);
sprintf_s(logmsg2, 1024, "[%s] %s", getdatetime().c_str(), logmsg1);
ACE_Future resultant_future;
CLogdebugmsg_MO *pmo = new CLogdebugmsg_MO(this, logmsg2, resultant_future);
m_activation_queue.enqueue(pmo);
return resultant_future;
}
ACE_Future CLogger::loginfomsg(const char* fmt, ...)
{
char logmsg1[1024];
memset(logmsg1, 0x00, 1024);
va_list ap;
va_start(ap, fmt);
_vsnprintf_s(logmsg1, 1024, fmt, ap);
va_end(ap);
char logmsg2[1024];
memset(logmsg2, 0x00, 1024);
sprintf_s(logmsg2, 1024, "[%s] %s", getdatetime().c_str(), logmsg1);
ACE_Future resultant_future;
m_activation_queue.enqueue(new CLoginfomsg_MO(this, logmsg2, resultant_future));
return resultant_future;
}
ACE_Future CLogger::logwarnmsg(const char* fmt, ...)
{
char logmsg1[1024];
memset(logmsg1, 0x00, 1024);
va_list ap;
va_start(ap, fmt);
_vsnprintf_s(logmsg1, 1024, fmt, ap);
va_end(ap);
char logmsg2[1024];
memset(logmsg2, 0x00, 1024);
sprintf_s(logmsg2, 1024, "[%s] %s", getdatetime().c_str(), logmsg1);
ACE_Future resultant_future;
m_activation_queue.enqueue(new CLogwarnmsg_MO(this, logmsg2, resultant_future));
return resultant_future;
}
ACE_Future CLogger::logfaultmsg(const char* fmt, ...)
{
char logmsg1[1024];
memset(logmsg1, 0x00, 1024);
va_list ap;
va_start(ap, fmt);
_vsnprintf_s(logmsg1, 1024, fmt, ap);
va_end(ap);
char logmsg2[1024];
memset(logmsg2, 0x00, 1024);
sprintf_s(logmsg2, 1024, "[%s] %s", getdatetime().c_str(), logmsg1);
ACE_Future resultant_future;
m_activation_queue.enqueue(new CLogfaultmsg_MO(this, logmsg2, resultant_future));
return resultant_future;
}
CLogdebugmsg_MO
#pragma once
#include "ace\method_request.h"
#include "Logger.h"
class CLogdebugmsg_MO : public ACE_Method_Request
{
public:
CLogdebugmsg_MO(CLogger* logger, const char* fmt, ACE_Future &future_result);
~CLogdebugmsg_MO(void);
private:
CLogger * m_plogger;
char* m_fmt;
ACE_Future m_future_result;
public:
int call();
};
#include "Logdebugmsg_MO.h"
CLogdebugmsg_MO::CLogdebugmsg_MO(CLogger* logger, const char* fmt, ACE_Future &future_result)
{
int length = strlen(fmt) + 1;
m_fmt = new char[length];
memcpy_s(m_fmt, length, fmt, length);
m_plogger = logger;
m_future_result = future_result;
}
CLogdebugmsg_MO::~CLogdebugmsg_MO(void)
{
delete []m_fmt;
}
int CLogdebugmsg_MO::call()
{
return m_future_result.set(m_plogger->logdebugmsg_i(m_fmt));
}
CLoginfomsg_MO
#pragma once
#include "ace\method_request.h"
#include "Logger.h"
class CLoginfomsg_MO : public ACE_Method_Request
{
public:
CLoginfomsg_MO(CLogger* logger, const char* fmt, ACE_Future &future_result);
~CLoginfomsg_MO(void);
private:
CLogger * m_plogger;
char* m_fmt;
ACE_Future m_future_result;
public:
int call();
};
#include "Loginfomsg_MO.h"
CLoginfomsg_MO::CLoginfomsg_MO(CLogger* logger, const char* fmt, ACE_Future &future_result)
{
int length = strlen(fmt) + 1;
m_fmt = new char[length];
memcpy_s(m_fmt, length, fmt, length);
m_plogger = logger;
m_future_result = future_result;
}
CLoginfomsg_MO::~CLoginfomsg_MO(void)
{
delete []m_fmt;
}
int CLoginfomsg_MO::call()
{
return m_future_result.set(m_plogger->loginfomsg_i(m_fmt));
}
CLogwarnmsg_MO
#pragma once
#include "ace\method_request.h"
#include "Logger.h"
class CLogwarnmsg_MO : public ACE_Method_Request
{
public:
CLogwarnmsg_MO(CLogger* logger, const char* fmt, ACE_Future &future_result);
~CLogwarnmsg_MO(void);
private:
CLogger * m_plogger;
char* m_fmt;
ACE_Future m_future_result;
public:
int call();
};
#include "Logwarnmsg_MO.h"
CLogwarnmsg_MO::CLogwarnmsg_MO(CLogger* logger, const char* fmt, ACE_Future &future_result)
{
int length = strlen(fmt) + 1;
m_fmt = new char[length];
memcpy_s(m_fmt, length, fmt, length);
m_plogger = logger;
m_future_result = future_result;
}
CLogwarnmsg_MO::~CLogwarnmsg_MO(void)
{
delete []m_fmt;
}
int CLogwarnmsg_MO::call()
{
return m_future_result.set(m_plogger->logwarnmsg_i(m_fmt));
}
CLogwarnmsg_MO
#pragma once
#include "ace\method_request.h"
#include "Logger.h"
class CLogfaultmsg_MO : public ACE_Method_Request
{
public:
CLogfaultmsg_MO(CLogger* logger, const char* fmt, ACE_Future &future_result);
~CLogfaultmsg_MO(void);
private:
CLogger * m_plogger;
char* m_fmt;
ACE_Future m_future_result;
public:
int call();
};
#include "Logfaultmsg_MO.h"
CLogfaultmsg_MO::CLogfaultmsg_MO(CLogger* logger, const char* fmt, ACE_Future &future_result)
{
int length = strlen(fmt) + 1;
m_fmt = new char[length];
memcpy_s(m_fmt, length, fmt, length);
m_plogger = logger;
m_future_result = future_result;
}
CLogfaultmsg_MO::~CLogfaultmsg_MO(void)
{
delete []m_fmt;
}
int CLogfaultmsg_MO::call()
{
return m_future_result.set(m_plogger->logfaultmsg_i(m_fmt));
}
Proc
// Proc.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include "Connectionpool.h"
#include "ace/Reactor.h"
#include "Clienttask.h"
#include "Logger.h"
int main(int argc, char* argv[])
{
ACE_Reactor::instance();
ACE_OS::sleep(2);
CLogger::createinstance()->open();
CConnectionpool connpool("ucs/ucs@ucs", "ucs", 5, 10, 10);
connpool.start();
ACE_OS::sleep(2);
CClienttask clienttask(&connpool, 1);
clienttask.open();
while(1)
{
ACE_Reactor::instance()->handle_events();
}
return 0;
}