ffead.server.doc
CibernateConnectionPool.cpp
1 /*
2  Copyright 2009-2012, Sumeet Chhetri
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 /*+
17  * CibernateConnectionPool.cpp
18  *
19  * Created on: Jan 17, 2010
20  * Author: sumeet
21  */
22 
23 #include "CibernateConnectionPool.h"
24 /*static CibernateConnectionPool *instance = NULL;
25 
26 CibernateConnectionPool* CibernateConnectionPool::getinstance()
27 {
28  if(this==NULL)
29  instance = new CibernateConnectionPool;
30  return instance;
31 }*/
32 CibernateConnectionPool::CibernateConnectionPool(int size,string dbName,string uname,string pass)
33 {
34  logger = Logger::getLogger("CibernateConnectionPool");
35  createPool(size,dbName,uname,pass);
36 }
37 
38 CibernateConnectionPool::~CibernateConnectionPool()
39 {
40  for (int var = 0; var < (int)readConnections.size(); ++var) {
41  delete readConnections.at(var);
42  }
43  for (int var = 0; var < (int)writeConnections.size(); ++var) {
44  delete writeConnections.at(var);
45  }
46  SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
47  logger << "\nDestructed CibernateConnectionPool" << flush;
48 }
49 
50 void CibernateConnectionPool::closeConnection(Connection *conn)
51 {
52  conn->busy = false;
53 }
54 
55 void CibernateConnectionPool::newConnection(bool read)
56 {
57  int V_OD_erg;// result of functions
58  SQLCHAR V_OD_msg[200],V_OD_stat[10]; // Status SQL;
59  SQLSMALLINT V_OD_mlen;
60  SQLINTEGER V_OD_err_s;
61  Connection *connection = new Connection;
62  // 2. allocate connection handle, set timeout
63  V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &(connection->conn));
64  if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
65  {
66  logger << "Error AllocHDB " << V_OD_erg << endl;
67  SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
68  this->initialized = false;
69  return;
70  //exit(0);
71  }
72  SQLSetConnectAttr(connection->conn, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
73  // 3. Connect to the datasource "MySQL-test"
74  V_OD_erg = SQLConnect(connection->conn, (SQLCHAR*) this->dbName.c_str(), this->dbName.length(),
75  (SQLCHAR*) this->uname.c_str(), this->uname.length(),
76  (SQLCHAR*) this->pass.c_str(), this->pass.length());
77  if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
78  {
79  logger << "Error SQLConnect " << V_OD_erg << endl;
80  SQLGetDiagRec(SQL_HANDLE_DBC, connection->conn,1,
81  V_OD_stat, &V_OD_err_s,V_OD_msg,100,&V_OD_mlen);
82  logger << V_OD_msg << " (" << (int)V_OD_err_s << ")" << endl;
83  SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
84  this->initialized = false;
85  return;
86  //exit(0);
87  }
88  connection->busy = false;
89  connection->type = read;
90  if(read)
91  this->readConnections.push_back(connection);
92  else
93  this->writeConnections.push_back(connection);
94 
95 }
96 
97 void CibernateConnectionPool::createPool(int size,string dbName,string uname,string pass)
98 {
99  this->dbName = dbName;
100  this->uname = uname;
101  this->pass = pass;
102  this->readNumber = 0;
103  int reads = round(size/5);
104  if(reads<1)
105  reads = 1;
106  int V_OD_erg;// result of functions
107  // 1. allocate Environment handle and register version
108  this->initialized = true;
109  V_OD_erg=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
110  if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
111  {
112  logger << "Error AllocHandle" << endl;
113  this->initialized = false;
114  }
115  V_OD_erg=SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
116  if((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
117  {
118  logger << "Error SetEnv" << endl;
119  SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
120  this->initialized = false;
121  }
122  for(int i=0;i<reads;i++)
123  {
124  this->newConnection(true);
125  if(!this->initialized)
126  break;
127  }
128  for(int i=0;i<size-reads;i++)
129  {
130  this->newConnection(false);
131  if(!this->initialized)
132  break;
133  }
134  if(!this->initialized)
135  {
136  logger << "Failed to create pool !" << endl;
137  }
138  else
139  {
140  logger << "Created pool successfully !" << endl;
141  }
142 }
143 
144 Connection* CibernateConnectionPool::getReadConnection()
145 {
146  if(this->readNumber==(int)this->readConnections.size())
147  this->readNumber = 0;
148  return this->readConnections.at(this->readNumber++);
149 }
150 Connection* CibernateConnectionPool::getWriteConnection()
151 {
152  Timer t;
153  t.start();
154  while(true)
155  {
156  for(unsigned int i=0;i<this->writeConnections.size();i++)
157  {
158  if(!this->writeConnections.at(i)->busy)
159  return this->writeConnections.at(i);
160  }
161  if(t.elapsedMilliSeconds()>500)
162  {
163  newConnection(false);
164  return this->writeConnections.at(this->writeConnections.size()-1);
165  }
166 
167  }
168 }
169 
170 Connection::Connection()
171 {
172  logger = Logger::getLogger("Connection");
173  logger << "\nCreated Connection" << flush;
174 }
175 
176 Connection::~Connection()
177 {
178  SQLDisconnect(conn);
179  SQLFreeHandle(SQL_HANDLE_DBC,conn);
180  logger << "\nDestructed Connection" << flush;
181 }