Browse Source

ä¿增加数据库部分函数

lht 6 years ago
parent
commit
77e57197f2
11 changed files with 665 additions and 590 deletions
  1. 13 13
      db/Makefile
  2. 2 2
      db/Makefile.am
  3. 2 2
      db/Makefile.in
  4. 19 19
      db/autom4te.cache/requests
  5. 12 10
      db/db_api/CDBCommon.h
  6. 374 372
      db/db_api/CDBConnPool.cpp
  7. 205 171
      db/db_api/CDBConnPool.h
  8. 18 0
      db/db_api/CDBConnect.cpp
  9. 19 0
      db/db_api/CDBConnect.h
  10. 1 1
      db/db_tool.cpp
  11. BIN
      db/libyadb.a

+ 13 - 13
db/Makefile

@@ -108,11 +108,11 @@ distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
   | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
 distcleancheck_listfiles = find . -type f -print
-ACLOCAL = ${SHELL} /home/lemon/resource/ya-serv/missing --run aclocal-1.12
+ACLOCAL = ${SHELL} /root/serv/missing --run aclocal-1.12
 AMTAR = $${TAR-tar}
-AUTOCONF = ${SHELL} /home/lemon/resource/ya-serv/missing --run autoconf
-AUTOHEADER = ${SHELL} /home/lemon/resource/ya-serv/missing --run autoheader
-AUTOMAKE = ${SHELL} /home/lemon/resource/ya-serv/missing --run automake-1.12
+AUTOCONF = ${SHELL} /root/serv/missing --run autoconf
+AUTOHEADER = ${SHELL} /root/serv/missing --run autoheader
+AUTOMAKE = ${SHELL} /root/serv/missing --run automake-1.12
 AWK = gawk
 CC = gcc
 CCDEPMODE = depmode=gcc3
@@ -120,7 +120,7 @@ CFLAGS = -g -O2
 CPPFLAGS = 
 CXX = g++
 CXXDEPMODE = depmode=gcc3
-CXXFLAGS = -g
+CXXFLAGS = -shared -fPIC -Wall -g
 CYGPATH_W = echo
 DEFS = 
 DEPDIR = .deps
@@ -137,7 +137,7 @@ LDFLAGS =
 LIBOBJS = 
 LIBS = 
 LTLIBOBJS = 
-MAKEINFO = ${SHELL} /home/lemon/resource/ya-serv/missing --run makeinfo
+MAKEINFO = ${SHELL} /root/serv/missing --run makeinfo
 MKDIR_P = /bin/mkdir -p
 OBJEXT = o
 PACKAGE = libyadb-a
@@ -153,10 +153,10 @@ SET_MAKE =
 SHELL = /bin/sh
 STRIP = 
 VERSION = 1.0
-abs_builddir = /home/lemon/resource/ya-serv/db
-abs_srcdir = /home/lemon/resource/ya-serv/db
-abs_top_builddir = /home/lemon/resource/ya-serv/db
-abs_top_srcdir = /home/lemon/resource/ya-serv/db
+abs_builddir = /root/serv/db
+abs_srcdir = /root/serv/db
+abs_top_builddir = /root/serv/db
+abs_top_srcdir = /root/serv/db
 ac_ct_CC = gcc
 ac_ct_CXX = g++
 am__include = include
@@ -176,7 +176,7 @@ host_alias =
 htmldir = ${docdir}
 includedir = ${prefix}/include
 infodir = ${datarootdir}/info
-install_sh = ${SHELL} /home/lemon/resource/ya-serv/install-sh
+install_sh = ${SHELL} /root/serv/install-sh
 libdir = ${exec_prefix}/lib
 libexecdir = ${exec_prefix}/libexec
 localedir = ${datarootdir}/locale
@@ -185,7 +185,7 @@ mandir = ${datarootdir}/man
 mkdir_p = $(MKDIR_P)
 oldincludedir = /usr/include
 pdfdir = ${docdir}
-prefix = /home/lemon/resource/ya-serv/db/../..
+prefix = /usr/local
 program_transform_name = s,x,x,
 psdir = ${docdir}
 sbindir = ${exec_prefix}/sbin
@@ -198,7 +198,7 @@ top_builddir = .
 top_srcdir = .
 AUTOMAKE_OPTIONS = foreign
 noinst_LIBRARIES = libyadb.a
-AM_CPPFLAGS = -Wall -pthread -m64 -std=c++11  -I${prefix}/include -I/usr/local/mysql/include -I. -I..
+AM_CPPFLAGS = -Wall -pthread -m64 -std=c++11  -I${prefix}/include -I/usr/local/mysql/include -I. -I.. -I../websocket/sio
 AM_LDFLAGS = -Wall -pthread -m64 -std=c++11  -L${prefix}/lib  -L/usr/local/mysql/lib
 libyadb_a_SOURCES = db_card.cpp db_api/CDBResultSet.cpp db_api/CDBConnect.cpp \
 		db_api/CDBHelper.cpp db_api/CDBConnPool.cpp db_tool.cpp db_area.cpp db_history.cpp

+ 2 - 2
db/Makefile.am

@@ -3,8 +3,8 @@ AUTOMAKE_OPTIONS=foreign
 noinst_LIBRARIES=libyadb.a
 
 
-CXXFLAGS=-g
-AM_CPPFLAGS=-Wall -pthread -m64 -std=c++11  -I${prefix}/include -I/usr/local/mysql/include -I. -I..
+CXXFLAGS=-shared -fPIC -Wall -g
+AM_CPPFLAGS=-Wall -pthread -m64 -std=c++11  -I${prefix}/include -I/usr/local/mysql/include -I. -I.. -I../websocket/sio
 AM_LDFLAGS =-Wall -pthread -m64 -std=c++11  -L${prefix}/lib  -L/usr/local/mysql/lib
 
 libyadb_a_SOURCES= db_card.cpp db_api/CDBResultSet.cpp db_api/CDBConnect.cpp \

+ 2 - 2
db/Makefile.in

@@ -120,7 +120,7 @@ CFLAGS = @CFLAGS@
 CPPFLAGS = @CPPFLAGS@
 CXX = @CXX@
 CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = -g
+CXXFLAGS = -shared -fPIC -Wall -g
 CYGPATH_W = @CYGPATH_W@
 DEFS = 
 DEPDIR = @DEPDIR@
@@ -198,7 +198,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AUTOMAKE_OPTIONS = foreign
 noinst_LIBRARIES = libyadb.a
-AM_CPPFLAGS = -Wall -pthread -m64 -std=c++11  -I${prefix}/include -I/usr/local/mysql/include -I. -I..
+AM_CPPFLAGS = -Wall -pthread -m64 -std=c++11  -I${prefix}/include -I/usr/local/mysql/include -I. -I.. -I../websocket/sio
 AM_LDFLAGS = -Wall -pthread -m64 -std=c++11  -L${prefix}/lib  -L/usr/local/mysql/lib
 libyadb_a_SOURCES = db_card.cpp db_api/CDBResultSet.cpp db_api/CDBConnect.cpp \
 		db_api/CDBHelper.cpp db_api/CDBConnPool.cpp db_tool.cpp db_area.cpp db_history.cpp

+ 19 - 19
db/autom4te.cache/requests

@@ -15,58 +15,58 @@
                         'configure.ac'
                       ],
                       {
-                        '_LT_AC_TAGCONFIG' => 1,
                         'AM_PROG_F77_C_O' => 1,
-                        'AC_INIT' => 1,
+                        '_LT_AC_TAGCONFIG' => 1,
                         'm4_pattern_forbid' => 1,
-                        'AC_CANONICAL_TARGET' => 1,
+                        'AC_INIT' => 1,
                         '_AM_COND_IF' => 1,
-                        'AC_CONFIG_LIBOBJ_DIR' => 1,
+                        'AC_CANONICAL_TARGET' => 1,
                         'AC_SUBST' => 1,
-                        'AC_CANONICAL_HOST' => 1,
+                        'AC_CONFIG_LIBOBJ_DIR' => 1,
                         'AC_FC_SRCEXT' => 1,
+                        'AC_CANONICAL_HOST' => 1,
                         'AC_PROG_LIBTOOL' => 1,
                         'AM_PROG_MKDIR_P' => 1,
                         'AM_INIT_AUTOMAKE' => 1,
-                        'AC_CONFIG_SUBDIRS' => 1,
                         'AM_PATH_GUILE' => 1,
+                        'AC_CONFIG_SUBDIRS' => 1,
                         'AM_AUTOMAKE_VERSION' => 1,
                         'LT_CONFIG_LTDL_DIR' => 1,
-                        'AC_REQUIRE_AUX_FILE' => 1,
                         'AC_CONFIG_LINKS' => 1,
-                        'LT_SUPPORTED_TAG' => 1,
+                        'AC_REQUIRE_AUX_FILE' => 1,
                         'm4_sinclude' => 1,
+                        'LT_SUPPORTED_TAG' => 1,
                         'AM_MAINTAINER_MODE' => 1,
                         'AM_NLS' => 1,
                         'AC_FC_PP_DEFINE' => 1,
                         'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
-                        '_m4_warn' => 1,
                         'AM_MAKEFILE_INCLUDE' => 1,
+                        '_m4_warn' => 1,
                         'AM_PROG_CXX_C_O' => 1,
-                        '_AM_COND_ENDIF' => 1,
                         '_AM_MAKEFILE_INCLUDE' => 1,
+                        '_AM_COND_ENDIF' => 1,
                         'AM_ENABLE_MULTILIB' => 1,
                         'AM_PROG_MOC' => 1,
                         'AM_SILENT_RULES' => 1,
                         'AC_CONFIG_FILES' => 1,
-                        'include' => 1,
                         'LT_INIT' => 1,
-                        'AM_PROG_AR' => 1,
+                        'include' => 1,
                         'AM_GNU_GETTEXT' => 1,
+                        'AM_PROG_AR' => 1,
                         'AC_LIBSOURCE' => 1,
-                        'AC_CANONICAL_BUILD' => 1,
                         'AM_PROG_FC_C_O' => 1,
+                        'AC_CANONICAL_BUILD' => 1,
                         'AC_FC_FREEFORM' => 1,
-                        'AC_FC_PP_SRCEXT' => 1,
                         'AH_OUTPUT' => 1,
-                        '_AM_SUBST_NOTMAKE' => 1,
+                        'AC_FC_PP_SRCEXT' => 1,
                         'AC_CONFIG_AUX_DIR' => 1,
-                        'AM_PROG_CC_C_O' => 1,
-                        'sinclude' => 1,
+                        '_AM_SUBST_NOTMAKE' => 1,
                         'm4_pattern_allow' => 1,
-                        'AM_CONDITIONAL' => 1,
-                        'AC_CANONICAL_SYSTEM' => 1,
+                        'sinclude' => 1,
+                        'AM_PROG_CC_C_O' => 1,
                         'AM_XGETTEXT_OPTION' => 1,
+                        'AC_CANONICAL_SYSTEM' => 1,
+                        'AM_CONDITIONAL' => 1,
                         'AC_CONFIG_HEADERS' => 1,
                         'AC_DEFINE_TRACE_LITERAL' => 1,
                         'AM_POT_TOOLS' => 1,

+ 12 - 10
db/db_api/CDBCommon.h

@@ -57,16 +57,18 @@ namespace YADB
 	*/
     struct _DB_CONN_SETTING_
 	{
-		std::string Host;//数据库主机地址
-		std::string User;//用户名
-		std::string PWD;//密码
-		std::string DBName;//数据库名
-		std::string CharSet;//字符集
-		std::string stmtSQL;//预处理SQL
-		int TimeOut;//连接数据库超时(单位:秒)
-		_DB_CONN_SETTING_()
-		{
-			TimeOut = 0;
+		unsigned int Port;//端口
+		int TimeOut;//连接数据库超时(单位:秒)
+		std::string Host;//数据库主机地址
+		std::string User;//用户名
+		std::string PWD;//密码
+		std::string DBName;//数据库名
+		std::string CharSet;//字符集
+		std::string stmtSQL;//预处理SQL
+		_DB_CONN_SETTING_()
+		{
+			Port    = 3306;
+			TimeOut = 0;
 		}
 	};
 

+ 374 - 372
db/db_api/CDBConnPool.cpp

@@ -1,372 +1,374 @@
-#include "CDBConnPool.h"
-#include <boost/bind.hpp>
-
-namespace YADB
-{
-    boost::lockfree::queue<_ASYNC_SQL_*, boost::lockfree::capacity<MAX_ASYNC_QUEQUE_CAPACITY>> __AsyncQueue;//异步执行无锁队列
-
-	CDBConnPool::CDBConnPool()
-	{
-		__pAsyncDBConn = 0;
-	}
-
-	CDBConnPool::~CDBConnPool()
-	{
-		Close();
-	}
-
-	CDBConnect * CDBConnPool::__CreateIdleConn( std::string& ConnErr, bool IsTemp )
-	{
-		//std::string ConnErr;
-
-		_DB_CONN_SETTING_ ConnSetting = static_cast< _DB_CONN_SETTING_ >(__Setting);
-		CDBConnect* pConn = new CDBConnect( IsTemp );
-		if ( !pConn->Connect( ConnSetting, ConnErr ) )
-		{
-			delete pConn;
-			pConn = 0;
-			return 0;
-		}
-
-		//如果设置了预处理SQL要准备预处理
-		if ( !ConnSetting.stmtSQL.empty() )
-		{
-			if ( !pConn->Preparestmt( ConnSetting.stmtSQL.c_str(), ConnErr ) )
-			{
-				delete pConn;
-				pConn = 0;
-				return 0;
-			}
-		}
-
-		__IdleConnList.push_back( pConn );
-		return pConn;
-	}
-
-	bool CDBConnPool::Create( const _DB_POOL_SETTING_& Setting, std::string& szError )
-	{
-		return Create(Setting,true,szError);
-	}
-
-	bool CDBConnPool::Create( const _DB_POOL_SETTING_& Setting,bool bAsync, std::string& szError )
-	{
-		std::unique_lock<std::mutex> lock( __mtx );
-
-		if ( Setting.PoolSize < DCC_MIN_COUNT )
-		{
-			szError = "PoolSize is too small!";
-			return false;
-		}
-
-		if ( Setting.PoolSize > DCC_MAX_COUNT )
-		{
-			szError = "PoolSize is too big!";
-			return false;
-		}
-
-		__Setting = Setting;
-		//检查连接池中是否已有连接数量
-		if ((int)__IdleConnList.size() < __Setting.PoolSize)
-		{
-			for ( int i = 0; i < __Setting.PoolSize; i++ )
-			{
-				CDBConnect* pConn = __CreateIdleConn( szError );
-				if ( !pConn )
-				{
-					return false;
-				}
-			}	
-		}
-		// 是否已创建异步线程
-		if (bAsync || !__Running)
-		{
-			//创建异步执行线程
-			__CreateAsyncThrdConn();
-
-			//启动异步执行线程
-			__StartAsyncThrd();
-		}
-		return true;
-	}
-
-	void CDBConnPool::Close()
-	{
-		std::unique_lock<std::mutex> lock( __mtx );
-
-		//停止异步执行线程
-		__StopAsyncThrd();
-
-		//刪除异步执行线程连接
-		__DestroyAsyncThrdConn();
-
-		//把所有列表中的连接对象都关闭删除并清除列表
-		CDBConnect* pConn = 0;
-		std::list<CDBConnect*>::iterator lit_conn;
-		for ( lit_conn = __BusyConnList.begin(); lit_conn != __BusyConnList.end(); lit_conn++ )
-		{
-			pConn = *lit_conn;
-			pConn->Close();
-			delete pConn;
-			pConn = 0;
-		}
-		__BusyConnList.clear();
-
-		for ( lit_conn = __IdleConnList.begin(); lit_conn != __IdleConnList.end(); lit_conn++ )
-		{
-			pConn = *lit_conn;
-			pConn->Close();
-			delete pConn;
-			pConn = 0;
-		}
-		__IdleConnList.clear();
-	}
-
-	CDBConnect * CDBConnPool::GetDBConnect( std::string& Error )
-	{
-		std::unique_lock<std::mutex> lock( __mtx );
-
-		CDBConnect* pConn = 0;
-
-		if ( __IdleConnList.size() > 0 )
-		{
-			pConn = *(__IdleConnList.begin());
-			__IdleConnList.pop_front();
-			__BusyConnList.push_back( pConn );
-		}
-		else
-		{
-			//如果已经没有空闲连接,只要当前连接池数量没有超过最大连接数就创建一个临时连接
-			// 这个判断没有意义(进入这个 __IdleConnList.size() <= 0 )
-			if ( __IdleConnList.size() < DCC_MAX_COUNT )
-			{
-				pConn = __CreateIdleConn( Error, true );
-				if ( !pConn )
-				{
-					Error = "Error,failed connect to database!";
-					return 0;
-				}
-
-				__IdleConnList.pop_front();
-				__BusyConnList.push_back( pConn );
-			}
-			else
-			{
-				Error = "Error,db connect count beyond the max connect count!";
-				return 0;
-			}
-		}
-
-		//验证看数据库连接是否还有效
-		if ( pConn )
-		{
-			if ( pConn->ConnctionTest( Error ) != 0 )
-			{
-				//重连一次
-				_DB_CONN_SETTING_ ConnSetting = static_cast< _DB_CONN_SETTING_ >(__Setting);
-				pConn->Close();
-				int nRet = pConn->Connect( ConnSetting, Error );
-				if ( nRet < 0 )
-				{
-					GiveBack( pConn );
-					Error = "Error,failed connect to database!";
-					return 0;
-				}
-			}
-		}
-
-		return pConn;
-	}
-
-	void CDBConnPool::GiveBack( CDBConnect * pConn )
-	{
-		std::unique_lock<std::mutex> lock( __mtx );
-
-		if ( 0 == pConn )
-		{
-			return;
-		}
-
-		__BusyConnList.remove( pConn );
-
-		//如果是临时连接,直接删除不再放入到空闲连接列表中
-		if ( pConn->IsTemp() )
-		{
-			delete pConn;
-			pConn = 0;
-		}
-		else
-		{
-			__IdleConnList.push_back( pConn );
-		}
-	}
-
-    void CDBConnPool::_AsyncThreadFunc( CDBConnPool* pOwner )
-    {
-    	std::string Error;
-    	while( pOwner->__Running )
-	    {
-    		_ASYNC_SQL_* pData = 0;
-		
-    		while ( __AsyncQueue.pop( pData ) )
-			{
-				if ( pData )
-				{
-					if ( __pAsyncDBConn )
-					{
-						my_ulonglong llRes = 0;
-						llRes = __pAsyncDBConn->ExecuteRealSql( pData->SQL.c_str(), Error ); 
-						if ( (my_ulonglong)-1 == llRes )
-						{
-							//Execute failed, write log...
-							printf( "Error,调用ExcuteRealSql失败,Err=%s \n sql=%s \n", Error.c_str(),  pData->SQL.c_str());
-							//如果失败了看是不是数据库断开连接了,尝试重新连接一次
-							if ( __pAsyncDBConn->ConnctionTest( Error ) != 0 )
-							{
-								_DB_CONN_SETTING_ ConnSetting = static_cast< _DB_CONN_SETTING_ >(__Setting);
-								__pAsyncDBConn->Close();
-								int nRet = __pAsyncDBConn->Connect( ConnSetting, Error );
-								if ( nRet < 0 )
-								{
-									Error = "Error,failed connect to database!";
-									//Connect failed, write log...
-									printf( "Error,failed connect to database,Err=%s\n", Error.c_str() );
-									//如果连接失败了休息一下
-									boost::this_thread::sleep( boost::posix_time::milliseconds( 100 ) );
-								}
-							}
-
-							//如果执行失败,失败次数加一,失败次数小于最大失败次数放到队尾下次再执行
-							pData->FailedCount++;
-							if ( pData->FailedCount < MAX_ASYNC_EXEC_FAILED_COUNT )
-							{
-								_ASYNC_SQL_* pNewData = new _ASYNC_SQL_();
-								pNewData->FailedCount = pData->FailedCount;
-								pNewData->SQL         = pData->SQL;
-								__AsyncQueue.push( pNewData );
-							}
-						}
-					}
-
-					delete pData;
-					pData = 0;
-				}
-			}
-
-    		boost::this_thread::sleep( boost::posix_time::microseconds( 10 ) );
-	    }
-
-    	//线程退出
-    	__IsExited = true;
-    }
-
-    void CDBConnPool::__StopAsyncThrd()
-    {
-    	if ( !__Running )
-    	{
-            return;
-    	}
-
-    	//等待异步执行线程退出
-	    __Running = false;
-
-	    while ( !__IsExited )
-	    {
-		    boost::this_thread::sleep(boost::posix_time::millisec(1));
-	    }
-
-	    //把异步执行无锁队列中每个元素释放
-	    _ASYNC_SQL_* pData = 0;
-		while ( __AsyncQueue.pop( pData ) )
-		{
-			if (pData)
-			{
-				delete pData;
-				pData = 0;
-			}
-		}
-    }
-
-	void CDBConnPool::__StartAsyncThrd()
-	{
-		__Running = true;
-		boost::thread thrd( boost::bind( &CDBConnPool::_AsyncThreadFunc, this, this ) );
-		thrd.detach();
-	}
-
-	void CDBConnPool::__CreateAsyncThrdConn()
-	{
-		std::string ConnErr;
-		//先断开之前的连接
-		this->__DestroyAsyncThrdConn();
-
-		_DB_CONN_SETTING_ ConnSetting = static_cast< _DB_CONN_SETTING_ >(__Setting);
-		CDBConnect* pConn = new CDBConnect();
-		if ( !pConn->Connect( ConnSetting, ConnErr ) )
-		{
-			delete pConn;
-			pConn = 0;
-			return;
-		}
-
-		__pAsyncDBConn = pConn;
-	}
-
-	void CDBConnPool::__DestroyAsyncThrdConn()
-	{
-        if ( __pAsyncDBConn )
-        {
-        	__pAsyncDBConn->Close();
-        	delete __pAsyncDBConn;
-        	__pAsyncDBConn = 0;
-        }
-	}
-
-    bool CDBConnPool::PushAsync( const std::string& strSQL )
-    {
-    	_ASYNC_SQL_* pData = new _ASYNC_SQL_;
-    	if ( !pData )
-    	{
-            return false;
-    	}
-
-    	pData->SQL = strSQL;
-    	return __AsyncQueue.push( pData );
-    }
-
-    bool CDBConnPool::Query( const char *szSql, CDBResultSet& DBRes,std::string& Error )
-    {
-		CDBConnect *pConn = GetDBConnect( Error );
-		if ( 0 == pConn )
-		{
-			return false;
-		}
-
-		MYSQL_RES* pRes = pConn->Query( szSql, Error );
-	GiveBack( pConn );
-        return DBRes.Bind( pRes, Error );
-    }
-    
-    MYSQL_RES* CDBConnPool::Query( const char *szSql, std::string& Error)
-    {
-        CDBConnect *pConn = GetDBConnect(Error);
-        if( 0 == pConn){
-            return nullptr;
-        }
-
-        MYSQL_RES* pRes = pConn->Query(szSql,Error);
-        GiveBack(pConn);
-        return pRes;
-    }
-    my_ulonglong CDBConnPool::ExecuteSql( const char *szSql, std::string& Error )
-    {
-    	CDBConnect *pConn = GetDBConnect( Error );
-		if ( 0 == pConn )
-		{
-			return -1;
-		}
-	my_ulonglong nRet = pConn->ExecuteSql( szSql, Error );
-		GiveBack( pConn );
-		return nRet;
-		//return pConn->ExecuteSql( szSql, Error );
-    }
-}
+#include "CDBConnPool.h"
+#include <boost/bind.hpp>
+#include <boost/lockfree/queue.hpp>
+
+namespace YADB
+{
+	boost::lockfree::queue<_ASYNC_SQL_*, boost::lockfree::capacity<MAX_ASYNC_QUEQUE_CAPACITY>> __AsyncQueue;//异步执行无锁队列
+
+	CDBConnPool::CDBConnPool()
+	{
+		__pAsyncDBConn = 0;
+	}
+
+	CDBConnPool::~CDBConnPool()
+	{
+		Close();
+	}
+
+	CDBConnect * CDBConnPool::__CreateIdleConn( std::string& Error, bool IsTemp )
+	{
+		std::string ConnErr;
+
+		_DB_CONN_SETTING_ ConnSetting = static_cast< _DB_CONN_SETTING_ >(__Setting);
+		CDBConnect* pConn = new CDBConnect( IsTemp );
+		if ( !pConn->Connect( ConnSetting, ConnErr ) )
+		{
+			delete pConn;
+			pConn = 0;
+			return 0;
+		}
+
+		//如果设置了预处理SQL要准备预处理
+		if ( !ConnSetting.stmtSQL.empty() )
+		{
+			if ( !pConn->Preparestmt( ConnSetting.stmtSQL.c_str(), Error ) )
+			{
+				delete pConn;
+				pConn = 0;
+				return 0;
+			}
+		}
+
+		__IdleConnList.push_back( pConn );
+		return pConn;
+	}
+
+	bool CDBConnPool::Create( const _DB_POOL_SETTING_& Setting, std::string& Error )
+	{
+		std::unique_lock<std::mutex> lock( __mtx );
+
+		if ( Setting.PoolSize < DCC_MIN_COUNT )
+		{
+			Error = "PoolSize is too small!";
+			return false;
+		}
+
+		if ( Setting.PoolSize > DCC_MAX_COUNT )
+		{
+			Error = "PoolSize is too big!";
+			return false;
+		}
+
+		__Setting = Setting;
+		std::string ConnErr;
+		for ( int i = 0; i < __Setting.PoolSize; i++ )
+		{
+			CDBConnect* pConn = __CreateIdleConn( Error );
+			if ( !pConn )
+			{
+				return false;
+			}
+		}
+
+		//创建异步执行线程
+		__CreateAsyncThrdConn();
+
+		//启动异步执行线程
+		__StartAsyncThrd();
+
+		return true;
+	}
+
+	void CDBConnPool::Close()
+	{
+		std::unique_lock<std::mutex> lock( __mtx );
+
+		//停止异步执行线程
+		__StopAsyncThrd();
+
+		//刪除异步执行线程连接
+		__DestroyAsyncThrdConn();
+
+		//把所有列表中的连接对象都关闭删除并清除列表
+		CDBConnect* pConn = 0;
+		std::list<CDBConnect*>::iterator lit_conn;
+		for ( lit_conn = __BusyConnList.begin(); lit_conn != __BusyConnList.end(); lit_conn++ )
+		{
+			pConn = *lit_conn;
+			pConn->Close();
+			delete pConn;
+			pConn = 0;
+		}
+		__BusyConnList.clear();
+
+		for ( lit_conn = __IdleConnList.begin(); lit_conn != __IdleConnList.end(); lit_conn++ )
+		{
+			pConn = *lit_conn;
+			pConn->Close();
+			delete pConn;
+			pConn = 0;
+		}
+		__IdleConnList.clear();
+	}
+
+	CDBConnect * CDBConnPool::GetDBConnect( std::string& Error )
+	{
+		std::unique_lock<std::mutex> lock( __mtx );
+
+		CDBConnect* pConn = 0;
+
+		if ( __IdleConnList.size() > 0 )
+		{
+			pConn = *(__IdleConnList.begin());
+			__IdleConnList.pop_front();
+			__BusyConnList.push_back( pConn );
+		}
+		else
+		{
+			//如果已经没有空闲连接,只要当前连接池数量没有超过最大连接数就创建一个临时连接
+			if ( __IdleConnList.size() < DCC_MAX_COUNT )
+			{
+				pConn = __CreateIdleConn( Error, true );
+				if ( !pConn )
+				{
+					Error = "Error,failed connect to database!";
+					return 0;
+				}
+
+				__IdleConnList.pop_front();
+				__BusyConnList.push_back( pConn );
+			}
+			else
+			{
+				Error = "Error,db connect count beyond the max connect count!";
+				return 0;
+			}
+		}
+
+		//验证看数据库连接是否还有效
+		if ( pConn )
+		{
+			if ( pConn->ConnctionTest( Error ) != 0 )
+			{
+				//重连一次
+				_DB_CONN_SETTING_ ConnSetting = static_cast< _DB_CONN_SETTING_ >(__Setting);
+				pConn->Close();
+				int nRet = pConn->Connect( ConnSetting, Error );
+				if ( nRet < 0 )
+				{
+					GiveBack( pConn );
+					Error = "Error,failed connect to database!";
+					return 0;
+				}
+			}
+		}
+
+		return pConn;
+	}
+
+	void CDBConnPool::GiveBack( CDBConnect * pConn )
+	{
+		std::unique_lock<std::mutex> lock( __mtx );
+
+		if ( 0 == pConn )
+		{
+			return;
+		}
+
+		__BusyConnList.remove( pConn );
+
+		//如果是临时连接,直接删除不再放入到空闲连接列表中
+		if ( pConn->IsTemp() )
+		{
+			delete pConn;
+			pConn = 0;
+		}
+		else
+		{
+			__IdleConnList.push_back( pConn );
+		}
+	}
+
+	void CDBConnPool::_AsyncThreadFunc( CDBConnPool* pOwner )
+	{
+		std::string Error;
+		while( pOwner->__Running )
+		{
+			_ASYNC_SQL_* pData = 0;
+			while ( __AsyncQueue.pop( pData ) )
+			{
+				if ( pData )
+				{
+					if ( __pAsyncDBConn )
+					{
+						my_ulonglong llRes = 0;
+						llRes = __pAsyncDBConn->ExecuteRealSql( pData->SQL.c_str(), Error );
+						if ( -1 == llRes )
+						{
+							//Execute failed, write log...
+							printf( "Error,调用ExcuteRealSql失败,Err=%s\n", Error.c_str() );
+							//如果失败了看是不是数据库断开连接了,尝试重新连接一次
+							if ( __pAsyncDBConn->ConnctionTest( Error ) != 0 )
+							{
+								_DB_CONN_SETTING_ ConnSetting = static_cast< _DB_CONN_SETTING_ >(__Setting);
+								__pAsyncDBConn->Close();
+								int nRet = __pAsyncDBConn->Connect( ConnSetting, Error );
+								if ( nRet < 0 )
+								{
+									Error = "Error,failed connect to database!";
+									//Connect failed, write log...
+									printf( "Error,failed connect to database,Err=%s\n", Error.c_str() );
+									//如果连接失败了休息一下
+									boost::this_thread::sleep( boost::posix_time::milliseconds( 100 ) );
+								}
+							}
+
+							//如果执行失败,失败次数加一,失败次数小于最大失败次数放到队尾下次再执行
+							pData->FailedCount++;
+							if ( pData->FailedCount < MAX_ASYNC_EXEC_FAILED_COUNT )
+							{
+								_ASYNC_SQL_* pNewData = new _ASYNC_SQL_();
+								pNewData->FailedCount = pData->FailedCount;
+								pNewData->SQL         = pData->SQL;
+								__AsyncQueue.push( pNewData );
+							}
+						}
+					}
+
+					delete pData;
+					pData = 0;
+				}
+			}
+
+			boost::this_thread::sleep_for( boost::chrono::milliseconds( 1 ) );
+		}
+
+		//线程退出
+		__IsExited = true;
+	}
+
+	void CDBConnPool::__StopAsyncThrd()
+	{
+		if ( !__Running )
+		{
+			return;
+		}
+
+		//等待异步执行线程退出
+		__Running = false;
+
+		while ( !__IsExited )
+		{
+			boost::this_thread::sleep_for( boost::chrono::milliseconds( 1 ) );
+		}
+
+		//把异步执行无锁队列中每个元素释放
+		_ASYNC_SQL_* pData = 0;
+		while ( __AsyncQueue.pop( pData ) )
+		{
+			if (pData)
+			{
+				delete pData;
+				pData = 0;
+			}
+		}
+	}
+
+	void CDBConnPool::__StartAsyncThrd()
+	{
+		boost::thread thrd( boost::bind( &CDBConnPool::_AsyncThreadFunc, this, this ) );
+		thrd.detach();
+	}
+
+	void CDBConnPool::__CreateAsyncThrdConn()
+	{
+		std::string ConnErr;
+
+		_DB_CONN_SETTING_ ConnSetting = static_cast< _DB_CONN_SETTING_ >(__Setting);
+		CDBConnect* pConn = new CDBConnect();
+		if ( !pConn->Connect( ConnSetting, ConnErr ) )
+		{
+			delete pConn;
+			pConn = 0;
+			return;
+		}
+
+		__pAsyncDBConn = pConn;
+	}
+
+	void CDBConnPool::__DestroyAsyncThrdConn()
+	{
+		if ( __pAsyncDBConn )
+		{
+			__pAsyncDBConn->Close();
+			delete __pAsyncDBConn;
+			__pAsyncDBConn = 0;
+		}
+	}
+
+	bool CDBConnPool::PushAsync( const std::string& strSQL )
+	{
+		_ASYNC_SQL_* pData = new _ASYNC_SQL_;
+		if ( !pData )
+		{
+			return false;
+		}
+
+		pData->SQL = strSQL;
+		return __AsyncQueue.push( pData );
+	}
+
+	bool CDBConnPool::Query( const char *szSql, CDBResultSet& DBRes, std::string& Error )
+	{
+		CDBConnect *pConn = GetDBConnect( Error );
+		if ( 0 == pConn )
+		{
+			return false;
+		}
+
+		MYSQL_RES* pRes = pConn->Query( szSql, Error );
+		GiveBack( pConn );
+		return DBRes.Bind( pRes, Error );
+	}
+
+	MYSQL_RES* CDBConnPool::Query( const char *szSql, std::string& Error )
+	{
+		CDBConnect *pConn = GetDBConnect( Error );
+		if ( 0 == pConn )
+		{
+			return false;
+		}
+
+		MYSQL_RES* pRes = pConn->Query( szSql, Error );
+		GiveBack( pConn );
+		return pRes;
+	}
+
+	my_ulonglong CDBConnPool::ExecuteSql( const char *szSql, std::string& Error )
+	{
+		CDBConnect *pConn = GetDBConnect( Error );
+		if ( 0 == pConn )
+		{
+			return -1;
+		}
+
+		my_ulonglong nRet = pConn->ExecuteSql( szSql, Error );
+		GiveBack( pConn );
+		return nRet;
+	}
+
+	my_ulonglong CDBConnPool::ExecuteSqlID( const char * szSql, std::string & Error )
+	{
+		CDBConnect *pConn = GetDBConnect( Error );
+		if ( 0 == pConn )
+		{
+			return -1;
+		}
+
+		my_ulonglong nRet = pConn->ExecuteSqlID( szSql, Error );
+
+		GiveBack( pConn );
+		return nRet;
+	}
+}

+ 205 - 171
db/db_api/CDBConnPool.h

@@ -1,111 +1,127 @@
+#ifndef CDBConnPool_h__
+#define CDBConnPool_h__
+
+
 /**
 * @brief
-鏁版嵁搴撹繛鎺ユ睜绫�
+数据库连接池类
 
 * @version
 V 1.0.0
 
 * @author
-鐜嬬泭淇�
+王益俊
 
 * @date
-鍒涘缓鏃堕棿:  2018-04-17\n
+创建时间:  2018-04-17\n
 
 * @note
-2018-04-17  鍒涘缓绫汇€俓n
+2018-04-17  创建类。\n
 
 * @warning
 
 * @bug
 
 */
-
-//#pragma once
-#ifndef YADB_CONNECT_POOL_H
-#define YADB_CONNECT_POOL_H
-
-#include <boost/atomic.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/lockfree/queue.hpp>
-
-#include <list>
-#include <string>
-#include <mutex>
-
-#include "CDBCommon.h"
-#include "CDBConnect.h"
-
-namespace YADB
-{
-	class CDBConnPool
-	{
-	private:
-		std::list<CDBConnect*> __BusyConnList;//姝e湪浣跨敤鐨勬暟鎹�簱杩炴帴鍒楄〃
-		std::list<CDBConnect*> __IdleConnList;//娌℃湁浣跨敤鐨勬暟鎹�簱杩炴帴鍒楄〃
-		_DB_POOL_SETTING_ __Setting;//鏁版嵁搴撹繛鎺ユ睜璁剧疆
-		std::mutex __mtx;//浜掓枼閲�
-		boost::atomic<bool> __Running{ false };//绾跨▼鏄�惁杩愯�鐨勬爣璇� 榛樿�鏈�紑鍚�,绛夊垱寤虹嚎绋嬪悗寮€鍚�
-		boost::atomic<bool> __IsExited{ false };//绾跨▼鏄�惁宸查€€鍑虹殑鏍囪瘑
-		CDBConnect* __pAsyncDBConn;//寮傛�鎵ц�绾跨▼鐢ㄧ殑鏁版嵁搴撹繛鎺�
-	private:
+
+#pragma once
+
+#include <boost/atomic.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/serialization/singleton.hpp>
+
+#include <list>
+#include <string>
+#include <mutex>
+
+#include "CDBCommon.h"
+#include "CDBConnect.h"
+
+namespace YADB
+{
+	class CDBConnPool
+	{
+	private:
+		std::list<CDBConnect*> __BusyConnList;//正在使用的数据库连接列表
+		std::list<CDBConnect*> __IdleConnList;//没有使用的数据库连接列表
+		_DB_POOL_SETTING_ __Setting;//数据库连接池设置
+		std::mutex __mtx;//互斥量
+		boost::atomic<bool> __Running{ true };//线程是否运行的标识		
+		boost::atomic<bool> __IsExited{ false };//线程是否已退出的标识
+		CDBConnect* __pAsyncDBConn;//异步执行线程用的数据库连接
+	private:
 		/**
-	    * @brief
-	    鍒涘缓涓€涓�┖闂茶繛鎺ュ嚱鏁般€�
 
-        * @param  [out] std::string& Error  閿欒�淇℃伅\n
-	    * @param  [in] bool IsTemp  鍒涘缓鐨勮繛鎺ユ槸鍚︽槸涓存椂鐨刓n
+		* @brief
+		创建一个空闲连接函数。
+		* @param  [out] std::string& Error  错误信息\n
+		* @param  [in] bool IsTemp  创建的连接是否是临时的\n
+
+		* @return 返回创建的连接
+		* @return  >0   成功\n
+		* @return  ==0  失败\n
+
+		* @note
+
+		* @warning
+		* @bug
 
-	    * @return 杩斿洖鍒涘缓鐨勮繛鎺�
-	    * @return  >0   鎴愬姛\n
-	    * @return  ==0  澶辫触\n
+		*/
+		CDBConnect* __CreateIdleConn( std::string& Error, bool IsTemp = false );
+		/**
+		* @brief
+		创建异步执行线程所用连接函数。
 
-	    * @note
+		* @param  无\n
 
-	    * @warning
+		* @return 无\n
 
-	    * @bug
+		* @note
 
-	    */
-		CDBConnect* __CreateIdleConn( std::string& Error, bool IsTemp = false );
+		* @warning
+
+		* @bug
+		*/
+		void __CreateAsyncThrdConn();
 		/**
-	    * @brief
-	    鍒涘缓寮傛�鎵ц�绾跨▼鎵€鐢ㄨ繛鎺ュ嚱鏁般€�
+		* @brief
+		??????创建异步执行线程所用连接函数。
 
-	    * @param  鏃燶n
+		* @param  无\n
 
-	    * @return 鏃燶n
+		* @return 无\n
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-		void __CreateAsyncThrdConn();
+		*/
+		void __DestroyAsyncThrdConn();
 		/**
-	    * @brief
-	    鍒�櫎鍒涘缓寮傛�鎵ц�绾跨▼鎵€鐢ㄨ繛鎺ュ嚱鏁般€�
+		* @brief
+		启动异步执行线程函数。
 
-	    * @param  鏃燶n
+		* @param  无\n
 
-	    * @return 鏃燶n
+		* @return 无
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-		void __DestroyAsyncThrdConn();
+		*/
+		void __StartAsyncThrd();
 		/**
 		* @brief
-		鍚�姩寮傛�鎵ц�绾跨▼鍑芥暟銆�
+		停止异步执行线程函数。
 
-		* @param  鏃燶n
+		* @param  无\n
 
-		* @return 鏃�
+		* @return 
 
 		* @note
 
@@ -114,165 +130,161 @@ namespace YADB
 		* @bug
 
 		*/
-		void __StartAsyncThrd();
-	    /**
-	    * @brief
-	    鍋滄�寮傛�鎵ц�绾跨▼鍑芥暟銆�
+		void __StopAsyncThrd();
+	protected:
+		/**
+		* @brief
+		异步执行线程函数。
 
-	    * @param  鏃燶n
+		* @param  [in] CDBConnPool* pOwner  线程所属对象\n
 
-	    * @return 鏃�
+		* @return 无\n
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-		void __StopAsyncThrd();
-	protected:
-	    /**
-	    * @brief
-	    寮傛�鎵ц�绾跨▼鍑芥暟銆�
+		*/
+		void _AsyncThreadFunc( CDBConnPool* pOwner );//线程函数
+	public:
+		CDBConnPool();
+		~CDBConnPool();
+		/**
+		* @brief
+		创建数据库连接池函数。
 
-	    * @param  [in] CDBConnPool* pOwner  绾跨▼鎵€灞炲�璞�n
+		* @param  [in] const _DB_POOL_SETTING_& Setting  数据库连接池设置\n
+		* @param  [out] std::string& Error  错误信息\n
 
-	    * @return 鏃燶n
+		* @return 返回创建数据库连接池是否成功
+		* @return  true   成功
+		* @return  false  失败
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-		void _AsyncThreadFunc( CDBConnPool* pOwner );//绾跨▼鍑芥暟
-	public:
-		CDBConnPool();
-		~CDBConnPool();
+		*/
+		bool Create( const _DB_POOL_SETTING_& Setting, std::string& Error );
 		/**
-	    * @brief
-	    鍒涘缓鏁版嵁搴撹繛鎺ユ睜鍑芥暟銆�
+		* @brief
+		关闭线程池函数。
 
-	    * @param  [in] const _DB_POOL_SETTING_& Setting  鏁版嵁搴撹繛鎺ユ睜璁剧疆\n
-		* @param  [in] bool bAsync  鏄�惁鍒涘缓寮傛�闃熷垪鍙婂�鐞嗙嚎绋媆n
-	    * @param  [out] std::string& szError  閿欒�淇℃伅\n
+		* @param  无\n
 
-	    * @return 杩斿洖鍒涘缓鏁版嵁搴撹繛鎺ユ睜鏄�惁鎴愬姛
-	    * @return  true   鎴愬姛
-	    * @return  false  澶辫触
+		* @return  无\n
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-	   	bool Create( const _DB_POOL_SETTING_& Setting, std::string& szError );
-		bool Create( const _DB_POOL_SETTING_& Setting,bool bAsync, std::string& szError );
+		*/
+		void Close();
 		/**
-	    * @brief
-	    鍏抽棴绾跨▼姹犲嚱鏁般€�
+		* @brief
+		从连接池中获得一个数据库连接函数。
 
-	    * @param  鏃燶n
+		* @param  [out] std::string& Error  错误信息\n
 
-	    * @return  鏃燶n
+		* @return 返回获得一个数据库连接是否成功
+		* @return  0 失败\n
+		* @return  !=0 获得的数据库连接\n
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-		void Close();
+		*/
+		CDBConnect* GetDBConnect( std::string& Error );
 		/**
-	    * @brief
-	    浠庤繛鎺ユ睜涓�幏寰椾竴涓�暟鎹�簱杩炴帴鍑芥暟銆�
+		* @brief
+		归还一个数据库连接到连接池中函数。
 
-	    * @param  [out] std::string& Error  閿欒�淇℃伅\n
+		* @param  [in] CDBConnect* pConn  数据库连接\n
 
-	    * @return 杩斿洖鑾峰緱涓€涓�暟鎹�簱杩炴帴鏄�惁鎴愬姛
-	    * @return  0 澶辫触\n
-	    * @return  !=0 鑾峰緱鐨勬暟鎹�簱杩炴帴\n
+		* @return  无\n
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-		CDBConnect* GetDBConnect( std::string& Error );
+		*/
+		void GiveBack( CDBConnect* pConn );
 		/**
-	    * @brief
-	    褰掕繕涓€涓�暟鎹�簱杩炴帴鍒拌繛鎺ユ睜涓�嚱鏁般€�
+		* @brief
+		把SQL语句加入异步执行队列函数。
 
-	    * @param  [in] CDBConnect* pConn  鏁版嵁搴撹繛鎺�n
+		* @param  [in] const std::string& strSQL  要执行的SQL语句\n
 
-	    * @return  鏃燶n
+		* @return  加入异步执行队列是否成功\n
+		* @return  true成功\n
+		* @return  false失败\n
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-		void GiveBack( CDBConnect* pConn );
-	    /**
-	    * @brief
-	    鎶奡QL璇�彞鍔犲叆寮傛�鎵ц�闃熷垪鍑芥暟銆�
+		*/
+		bool PushAsync( const std::string& strSQL );
+		/**
+		* @brief
+		执行SQL语句返回结果集函数。
 
-	    * @param  [in] const std::string& strSQL  瑕佹墽琛岀殑SQL璇�彞\n
+		* @param [in] const char *szSql  SQL语句\n
+		* @param [out] CDBResultSet& DBRes  结果集\n
+		* @param [out] std::string& Error  错误信息\n
 
-	    * @return  鍔犲叆寮傛�鎵ц�闃熷垪鏄�惁鎴愬姛\n
-	    * @return  true鎴愬姛\n
-	    * @return  false澶辫触\n
+		* @return 返回查询是否成功
+		* @return  true  成功\n
+		* @return  false  失败\n
 
-	    * @note
+		* @note
 
-	    * @warning
+		* @warning
 
-	    * @bug
+		* @bug
 
-	    */
-		bool PushAsync( const std::string& strSQL );
+		*/
+		bool Query( const char *szSql, CDBResultSet& DBRes, std::string& Error );
 		/**
-		 * @brief
-		 鎵ц�SQL璇�彞杩斿洖缁撴灉闆嗗嚱鏁般€�
+		* @brief
+		执行SQL语句返回原生结果集函数。
 
-		 * @param [in] const char *szSql  SQL璇�彞\n
-		 * @param [out] CDBResultSet& DBRes  缁撴灉闆哱n
-		 * @param [out] std::string& Error  閿欒�淇℃伅\n
+		* @param [in] const char *szSql  SQL语句\n
+		* @param [out] std::string& Error  错误信息\n
 
-		 * @return 杩斿洖鏌ヨ�鏄�惁鎴愬姛
-		 * @return  true  鎴愬姛\n
-		 * @return  false  澶辫触\n
+		* @return 返回查询的结果集
 
-		 * @note
+		* @note
 
-		 * @warning
+		* @warning
 
-		 * @bug
+		* @bug
 
 		*/
-		bool Query( const char *szSql, CDBResultSet& DBRes,std::string& Error );
-        MYSQL_RES* Query( const char *szSql, std::string& Error);      
-        
-        
+		MYSQL_RES* Query( const char *szSql, std::string& Error );
 		/**
 		* @brief
-		鎵ц�SQL璇�彞鍑芥暟銆�
+		执行SQL语句函数。
 
-		* @param [in] const char *szSql  SQL璇�彞\n
-		* @param [out] std::string& Error  閿欒�淇℃伅\n
+		* @param [in] const char *szSql  SQL语句\n
+		* @param [out] std::string& Error  错误信息\n
 
-		* @return 杩斿洖褰卞搷鍒扮殑璁板綍鏁伴噺
-		* @return  -1  澶辫触\n
-		* @return  >=0  鎴愬姛\n
+		* @return 返回影响到的记录数量
+		* @return  -1  失败\n
+		* @return  >=0  成功\n
 
 		* @note
 
@@ -281,9 +293,31 @@ namespace YADB
 		* @bug
 
 		*/
-		my_ulonglong ExecuteSql( const char *szSql, std::string& Error );
-	};
-}
+		my_ulonglong ExecuteSql( const char *szSql, std::string& Error );
+		/**
+		* @brief
+		执行SQL语句并获得ID的函数。
+
+		* @param [in] const char *szSql  SQL语句\n
+		* @param [out] std::string& Error  错误信息\n
 
+		* @return 返回获得的ID
+		* @return  <=0  失败\n
+		* @return  >0   成功\n
 
-#endif
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		my_ulonglong ExecuteSqlID( const char *szSql, std::string& Error );
+	};
+}
+
+//单件相关定义
+typedef boost::serialization::singleton<YADB::CDBConnPool> singleton_CDBConnPool;
+#define sDBConnPool singleton_CDBConnPool::get_mutable_instance()
+
+#endif // CDBConnPool_h__

+ 18 - 0
db/db_api/CDBConnect.cpp

@@ -182,6 +182,24 @@ namespace YADB
 
 		return mysql_affected_rows( __pConn );
 	}
+	my_ulonglong CDBConnect::ExecuteSqlID( const char * szSql, std::string & Error )
+	{
+		if ( 0 == __pConn )
+		{
+			Error = "Error,not connected to database!";
+			return DB_ERR_NOT_CONNECT_DB;
+		}
+
+		if ( mysql_real_query( __pConn, szSql, strlen( szSql ) ) )
+		{
+			Error = "Failed to execute SQL!";
+			Error += " LastError=";
+			Error += GetLastError();
+			return DB_ERR_EXCUTE_QUERY;
+		}
+
+		return mysql_insert_id( __pConn );
+	}
 
 	my_ulonglong CDBConnect::ExecuteRealSql( const char * szSql, std::string & Error )
 	{

+ 19 - 0
db/db_api/CDBConnect.h

@@ -223,6 +223,25 @@ namespace YADB
 
 	    */
 		my_ulonglong ExecuteRealSql( const char *szSql, std::string& Error );
+		/**
+		* @brief
+		执行SQL语句并获得自动生成的ID函数。
+
+		* @param [in] const char *szSql  SQL语句\n
+		* @param [out] std::string& Error  错误信息\n
+
+		* @return 返回自动生成的ID
+		* @return  <1  失败\n
+		* @return  >=1  成功\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		my_ulonglong ExecuteSqlID( const char *szSql, std::string& Error );
 		/**
 	    * @brief
 	    获得最后一次错误信息函数。

+ 1 - 1
db/db_tool.cpp

@@ -40,7 +40,7 @@ namespace db_tool
 
         auto start = mine_tool_ptr->m_attendance_start_time;
         auto end = mine_tool_ptr->m_attendance_start_time;
-        if(!mine_tool_ptr->is_attendance())//考勤结束时间
+        if(!mine_tool_ptr->m_is_attendance)//考勤结束时间
         {
             end = std::chrono::system_clock::now();
         }

BIN
db/libyadb.a