/***************************************************************************
                Database Connection Pool
                -----------------------------------------
	begin      : 2012/05/13
	copyright  : (C) 2011 SolutionBox Inc.
	author     : Service 1 Team
	email      : svc1@solbox.com
	version    : 3.1.0

    CopyRight(C) 2011 SolutionBox Inc. All Rights reserved.
    Redistribution and use in source and binary forms, with or with out
    modification, are not permitted in outside of SolutionBox Inc.
***************************************************************************/
#ifndef __DATABASE_CONNECTION_POOL__
#define __DATABASE_CONNECTION_POOL__

#include <errno.h>
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#include <list>
#include <algorithm>

using namespace std;

class DataBase;

class CDataBaseInfo
{
public:
	CDataBaseInfo() {}
	~CDataBaseInfo() {}
public:
	string	m_hostaddr;
	int		m_port;
	string	m_dbname;
	string	m_user;
	string	m_pw;
};

class CDBConnPool
{
public:
	enum POOL_STATUSE
	{
		POOL_ERR	=	-1,
		POOL_FREE	=	0,
		POOL_USE	=	1
	};
public:
	CDBConnPool(CDataBaseInfo info);
	virtual ~CDBConnPool();

	int	CreatePool( int poolcnt = 4 );
	int	ReCreatePool( int poolcnt = 4 );
	int DestroyPool();
	DataBase* GetConnFromPool(int timeout = 10);
	void ReleaseConnToPool(DataBase * t, bool success = true);
	int SetKeepAliveTimeout(int sec);

	void printstatus(string prefixed = "");

	int GetFreePoolCnt();

	bool IsExit() { return m_exitpool; }
	bool IsTimeoutAlive();
	bool SendAliveMsg();

	void			SetCDataBaseInfo(CDataBaseInfo info)	{ m_dbinfo = info; }
	CDataBaseInfo   GetCDataBaseInfo()	{ return m_dbinfo; }
	size_t GetPoolSize()	{ return m_poolmap.size(); }

	// 2014.06.06 dadamin
	// 현재 DB 형상 체크
	bool	SetTargetTableType(DataBase * d);
	// 작업할 메타 테이블명
	string	GetMetaTableName(const char * tranid);
	// display_name 컬럼 사용 유무
	bool	UseDisplayname() {return (m_tabletype == 1); }

private:
	static void* KeepPoolAlive(void*);

private:
	CDataBaseInfo			m_dbinfo;	
	map<DataBase*, short>	m_poolmap;
	pthread_mutex_t			m_mutex;
	bool					m_exitpool;
	DataBase*				m_lastset;
	
	int						m_alivetime;
	pthread_t				m_keepalive;
	pthread_cond_t			m_alivecond;
	pthread_mutex_t			m_alivemutex;

	// 2014.06.04 dadamin
	// -1: unset, 0: t_dav_resource, 1: t_meat_[sp_svc_tran_id]
	int						m_tabletype;

	int						m_poolsize;
};

class CMasterDBPool : public CDBConnPool
{
public:
	static	void			init(CDataBaseInfo info);
	static	CMasterDBPool*	getInstance();
	static	int				release();

private:
	CMasterDBPool(CDataBaseInfo info);
	~CMasterDBPool();

private:
	static CMasterDBPool*		m_inst;
};

class CSlaveDBPool : public CDBConnPool
{
public:
	static	void			init(CDataBaseInfo info);
	static	CSlaveDBPool*	getInstance();
	static	int				release();

private:
	CSlaveDBPool(CDataBaseInfo info);
	~CSlaveDBPool();

private:
	static CSlaveDBPool*		m_inst;
};

#endif // __DATABASE_CONNECTION_POOL__
