Pool connections support, tested

queue v0.3_pool
marcelb 1 year ago
parent 2ea748699e
commit 6905bfe745
  1. 3
      .vscode/settings.json
  2. 22
      lib/mysql.hpp
  3. 181
      src/mysql.cpp
  4. 129
      test/test.cpp
  5. BIN
      test/test.o

@ -15,6 +15,7 @@
"*.tcc": "cpp",
"fstream": "cpp",
"new": "cpp",
"thread": "cpp"
"thread": "cpp",
"chrono": "cpp"
}
}

@ -18,7 +18,7 @@
#include <cppconn/resultset.h>
#define unlimited 0
#define reconnectSleep 100000 // in us
#define reconnectSleep 10000 // in us
using namespace std;
using namespace sql;
@ -60,32 +60,30 @@ class sqlQA {
};
class mySQL {
public:
private:
mutex io;
MySQL_Driver *drv;
// Connection *con;
// vector<Connection*> con;
vector<pair<mutex*, Connection*>> con;
string path, username, password, db;
bool isPersistent;
uint numOfCon;
uint reconTrys = 3;
void getColumns(const string _table, vector<string> &_columns, Connection *ptr_con); // privatno
bool open_one(const uint idx);
bool connect_one(const uint idx);
bool disconnect_one(const uint idx);
uint findFreeCon();
public:
mySQL(const string _path, const string _username, const string _password, const string _db, const bool _isPersistent = false, const uint _numOfCon = 1);
bool open(const string _db = "");
bool connect();
bool disconnect();
void reconnectTrys(const uint _trys);
void exec(sqlQA &sql_qa);
void getColumns(const string _table, vector<string> &_columns, Connection *ptr_con); // privatno
// ove će biti privatne sigurno
bool open_one(Connection *ptr_con);
bool connect_one(Connection *ptr_con);
bool disconnect_one(Connection *ptr_con);
pair<mutex*, Connection*> findFreeCon();
~mySQL();
};

@ -60,19 +60,24 @@ sqlQA& sqlQA::deleteFrom(const string _table) {
}
void sqlQA::print(bool withDetail) {
// istražit da se prikaže u tabeli
cout << "============================================" << endl;
for (auto i : result) {
for (auto j: i.second) {
cout << i.first << " : " << j << endl;
}
for (auto j: i.second) {
cout << i.first << " : " << j << endl;
}
cout << "--------------------------------------------" << endl;
}
if (withDetail) {
cout << "-----------------DETAILS--------------------" << endl;
cout << "Is executed: " << (executed ? "true" : "false") << endl;
cout << "Update catch: " << updateCatch << endl;
cout << "Num of rows: " << num_rows << endl;
cout << "Num of columns: " << num_columns << endl;
}
cout << "============================================" << endl;
}
void sqlQA::parse_columns(const string _columns) {
@ -95,9 +100,7 @@ mySQL::mySQL(const string _path, const string _username, const string _password,
password = _password;
db = _db;
isPersistent = _numOfCon > 1 ? true : _isPersistent;
numOfCon = _numOfCon;
cout << "Num of con: " << numOfCon << endl;
numOfCon = _numOfCon > 0 ? _numOfCon : 1;
drv = get_mysql_driver_instance();
@ -115,58 +118,40 @@ mySQL::mySQL(const string _path, const string _username, const string _password,
}
bool mySQL::open(const string _db) {
bool mySQL::connect() {
io.lock();
db = _db.empty() ? db : _db;
bool status = true; // ako true greška je
for (uint i=0; i<con.size(); i++) {
try {
con[i].second->setSchema(db);
status = false;
}
catch (const SQLException &error) {
cout << error.what() << endl;
}
bool status = true;
for (uint i=0; i<numOfCon; i++) {
status = connect_one(i);
}
io.unlock();
return status;
}
bool mySQL::connect() {
io.lock();
// uint trys = 0;
// bool status = true;
bool Gstatus = true;
bool mySQL::connect_one(const uint idx) {
uint trys = 0;
bool status = true;
for (uint i=0; i<numOfCon; i++) {
uint trys = 0;
bool status = true;
cout << "Init connection " << i << endl;
while (reconTrys == unlimited ? status : (trys < reconTrys && status)) {
cout << "Try connect " << trys << endl;
try {
while (reconTrys == unlimited ? status : (trys <= reconTrys && status)) {
try {
if (con.size() < numOfCon) {
con.push_back(make_pair(new mutex, drv->connect(path, username, password)));
// con[i].first = new mutex;
// con[i].second = drv->connect(path, username, password);
status = false;
Gstatus *= status;
}
catch (const SQLException &error) {
cout << error.what() << endl;
usleep(reconnectSleep);
reconTrys == unlimited ? trys : trys++;
}
else {
con[idx].second = drv->connect(path, username, password);
}
status = !con[idx].second->isValid() && con[idx].second->isClosed() || con[idx].second->isClosed();
}
catch (const SQLException &error) {
cout << error.what() << endl;
usleep(reconnectSleep);
reconTrys == unlimited ? trys : trys++;
}
}
cout << "Num of pairs " << con.size() << endl;
io.unlock();
// return status;
return Gstatus;
return status;
}
bool mySQL::disconnect() {
@ -174,33 +159,20 @@ bool mySQL::disconnect() {
bool status = true;
for (uint i=0; i<con.size(); i++) {
if (con[i].second->isValid() && !con[i].second->isClosed()) {
try {
con[i].second->close();
status = false;
}
catch (const SQLException &error) {
cout << error.what() << endl;
status = true;
}
}
else {
status = false; // već je zatvorena
}
status = disconnect_one(i) ;
}
io.unlock();
return status;
}
bool mySQL::disconnect_one(Connection *ptr_con) {
bool status = true;
bool mySQL::disconnect_one(const uint idx) {
bool status = !con[idx].second->isClosed();
if (ptr_con->isValid() && !ptr_con->isClosed()) {
if (status) {
try {
ptr_con->close();
status = false;
con[idx].second->close();
status = !con[idx].second->isClosed();
}
catch (const SQLException &error) {
cout << error.what() << endl;
@ -215,34 +187,39 @@ bool mySQL::disconnect_one(Connection *ptr_con) {
return status;
}
bool mySQL::connect_one(Connection *ptr_con) {
uint trys = 0;
bool status = true;
while (reconTrys == unlimited ? status : (trys < reconTrys && status)) {
try {
ptr_con = drv->connect(path, username, password);
status = false;
}
catch (const SQLException &error) {
cout << error.what() << endl;
usleep(reconnectSleep);
reconTrys == unlimited ? trys : trys++;
}
bool mySQL::open(const string _db) {
io.lock();
db = _db.empty() ? db : _db;
bool status = true; // ako true greška je
for (uint i=0; i<con.size(); i++) {
status = open_one(i);
}
io.unlock();
return status;
}
bool mySQL::open_one(Connection *ptr_con) {
bool mySQL::open_one(const uint idx) {
bool status = true; // ako true greška je
uint trys = 0;
try {
ptr_con->setSchema(db);
status = false;
}
catch (const SQLException &error) {
cout << error.what() << endl;
while (reconTrys == unlimited ? status : (trys <= reconTrys && status)) {
try {
if (con[idx].second->isValid()) {
con[idx].second->setSchema(db);
status = false;
}
else {
break;
}
}
catch (const SQLException &error) {
cout << error.what() << endl;
usleep(reconnectSleep);
reconTrys == unlimited ? trys : trys++;
}
}
return status;
@ -259,29 +236,27 @@ void mySQL::reconnectTrys(const uint _trys) {
}
void mySQL::exec(sqlQA &sql_qa) {
const uint idx = findFreeCon();
pair<mutex*, Connection*> workCon = findFreeCon();
if (!isPersistent || !workCon.second->isValid() || workCon.second->isClosed()) {
if (connect_one(workCon.second)) {
if (!isPersistent || !con[idx].second->isValid() || con[idx].second->isClosed()) {
if (connect_one(idx)) {
throw string("[ERROR] Unable to connect database ");
}
if (open_one(workCon.second)) {
if (open_one(idx)) {
throw string("[ERROR] Unable to open database " + db);
}
}
/**/
try {
vector<string> columns = sql_qa.columns;
if (columns.empty() && !sql_qa.table.empty()) {
getColumns(sql_qa.table, columns, workCon.second);
getColumns(sql_qa.table, columns, con[idx].second);
}
Statement *stmt;
stmt = workCon.second->createStatement();
stmt = con[idx].second->createStatement();
if (sql_qa.isSelect) {
ResultSet *res = stmt->executeQuery(sql_qa.cmd);
@ -317,20 +292,17 @@ void mySQL::exec(sqlQA &sql_qa) {
sql_qa.executed = false;
}
catch (const string error) {
workCon.first->unlock();
con[idx].first->unlock();
throw error;
}
/**/
if (!isPersistent) {
if(disconnect_one(workCon.second)) {
if(disconnect_one(idx)) {
throw string("[ERROR] Unable to close database ");
}
}
workCon.first->unlock();
con[idx].first->unlock();
}
void mySQL::getColumns(const string _table, vector<string> &_columns, Connection *ptr_con) {
@ -349,20 +321,13 @@ void mySQL::getColumns(const string _table, vector<string> &_columns, Connection
delete stmt;
}
pair<mutex*, Connection*> mySQL::findFreeCon() {
io.lock();
uint mySQL::findFreeCon() {
lock_guard<mutex> master(io);
while (true) {
cout << "Tražim konekciju " << endl;
for (uint i=0; i<con.size(); i++) {
cout << "Pokušavam s " << i << " konekciju" << endl;
if (con[i].first->try_lock()) {
cout << "Koristim " << i << " konekciju" << endl;
io.unlock();
return con[i];
return i;
}
// else {
// usleep(1000);
// }
}
}
}

@ -9,80 +9,81 @@ using namespace chrono;
int main() {
try {
mySQL mydb("tcp://92.240.56.92:3306", "dinio", "H€r5elfInd1aH@nds", "dinio", true, 2);
mySQL mydb("tcp://192.168.2.10:3306", "dinio", "H€r5elfInd1aH@nds", "dinio", true, 3);
auto start = high_resolution_clock::now();
// thread t1([&](){
// try {
// sqlQA test_qa;
// test_qa.select().from("records").where("enabled = 1");
// mydb.exec(test_qa);
// test_qa.print(true);
// } catch (const string err) {
// cout << err << endl;
// }
// });
// thread t2([&](){
// try {
// sqlQA test_qa;
// test_qa.select().from("zones");
// mydb.exec(test_qa);
// test_qa.print(true);
// } catch (const string err) {
// cout << err << endl;
// }
// });
// thread t3([&](){
// try {
// sqlQA test_qa;
// test_qa.select().from("users");
// mydb.exec(test_qa);
// test_qa.print(true);
// } catch (const string err) {
// cout << err << endl;
// }
// });
// t1.join();
// t2.join();
// t3.join();
thread t1([&](){
try {
sqlQA test_qa;
test_qa.select().from("records").where("enabled = 1");
mydb.exec(test_qa);
test_qa.print(true);
} catch (const string err) {
cout << err << endl;
}
});
thread t2([&](){
try {
sqlQA test_qa;
test_qa.select().from("zones");
mydb.exec(test_qa);
test_qa.print(true);
} catch (const string err) {
cout << err << endl;
}
});
thread t3([&](){
try {
sqlQA test_qa;
test_qa.select().from("users");
mydb.exec(test_qa);
test_qa.print(true);
} catch (const string err) {
cout << err << endl;
}
});
t1.join();
t2.join();
t3.join();
// one by one
try {
sqlQA test_qa;
test_qa.select().from("records").where("enabled = 1");
mydb.exec(test_qa);
test_qa.print(true);
} catch (const string err) {
cout << err << endl;
}
// try {
// sqlQA test_qa;
// test_qa.select().from("records").where("enabled = 1");
// mydb.exec(test_qa);
// test_qa.print(true);
// } catch (const string err) {
// cout << err << endl;
// }
try {
sqlQA test_qa;
test_qa.select().from("users");
mydb.exec(test_qa);
test_qa.print(true);
} catch (const string err) {
cout << err << endl;
}
try {
sqlQA test_qa;
test_qa.select().from("users");
mydb.exec(test_qa);
test_qa.print(true);
} catch (const string err) {
cout << err << endl;
}
// try {
// sqlQA test_qa;
// test_qa.select().from("users");
// mydb.exec(test_qa);
// test_qa.print(true);
// } catch (const string err) {
// cout << err << endl;
// }
// try {
// sqlQA test_qa;
// test_qa.select().from("users");
// mydb.exec(test_qa);
// test_qa.print(true);
// } catch (const string err) {
// cout << err << endl;
// }
auto end = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(end - start);
cout << "-------------Izvršilo se za: " << (double)(duration.count() / 1000.0) << endl;
cout << "-------------Izvršilo se za: " << (double)(duration.count() / 1000.0) << " ms"<< endl;
} catch (const SQLException error) {

Binary file not shown.
Loading…
Cancel
Save