diff --git a/lib/mysql.hpp b/lib/mysql.hpp index b86a496..f7cc962 100644 --- a/lib/mysql.hpp +++ b/lib/mysql.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -64,24 +65,22 @@ class mySQL { private: mutex io; MySQL_Driver *drv; - vector> con; + deque con; string path, username, password, db; - bool isPersistent; - uint numOfCon; + uint available; uint reconTrys = 3; + bool runBot = true; future bot; void getColumns(const string _table, vector &_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(); + bool open_one(Connection* con_ptr); + Connection* create_con(); + bool disconnect_one(Connection* con_ptr); + Connection* shift_con(); 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(); + mySQL(const string _path, const string _username, const string _password, const string _db, const uint _available = 1); bool disconnect(); void reconnectTrys(const uint _trys); void exec(sqlQA &sql_qa); diff --git a/src/mysql.cpp b/src/mysql.cpp index 95b1f28..b1ed954 100644 --- a/src/mysql.cpp +++ b/src/mysql.cpp @@ -94,83 +94,57 @@ void sqlQA::parse_columns(const string _columns) { } } -mySQL::mySQL(const string _path, const string _username, const string _password, const string _db, const bool _isPersistent, const uint _numOfCon) { +mySQL::mySQL(const string _path, const string _username, const string _password, const string _db, const uint _available) { path = _path; username = _username; password = _password; db = _db; - isPersistent = _numOfCon > 1 ? true : _isPersistent; - numOfCon = _numOfCon > 0 ? _numOfCon : 1; + available = _available > 0 ? _available : 1; drv = get_mysql_driver_instance(); - if (isPersistent) { - if (connect()) { - throw string("[ERROR] Unable to connect database "); - } - - if (!db.empty()) { - if (open()) { - throw string("[ERROR] Unable to open database " + db); - } - } - - bot = async(launch::async, [&]{ - while (runBot) { + bot = async(launch::async, [&]{ + while (runBot) { + while (available>con.size() && runBot) { try { - for (uint i=0; itry_lock()) { - if (!con[i].second->isValid()) { - if (connect_one(i)) { - throw string("[ERROR] Unable to connect database "); - } - - if (!db.empty()) { - if (open_one(i)) { - throw string("[ERROR] Unable to open database " + db); - } - } - } - con[i].first->unlock(); + Connection* new_con_ptr = create_con(); + if (!db.empty()) { + if (open_one(new_con_ptr)) { + throw string("[ERROR] Unable to open database " + db); } } + io.lock(); + con.push_back(new_con_ptr); + io.unlock(); } catch (const SQLException except) { cout << except.what() << endl; } catch (const string except) { cout << except << endl; - } + } } - return; - }); - } - -} - -bool mySQL::connect() { - io.lock(); - bool status = true; + } - for (uint i=0; iconnect(path, username, password))); + Connection* con_can = drv->connect(path, username, password); + status = !con_can->isValid(); + if (!status) { + new_con = con_can; } - else { - con[idx].second = drv->connect(path, username, password); + else if (!con_can->isClosed()) { + disconnect_one(con_can); } - status = !con[idx].second->isValid() && con[idx].second->isClosed() || con[idx].second->isClosed(); } catch (const SQLException &error) { cout << error.what() << endl; @@ -179,7 +153,7 @@ bool mySQL::connect_one(const uint idx) { } } - return status; + return new_con; } bool mySQL::disconnect() { @@ -187,20 +161,20 @@ bool mySQL::disconnect() { bool status = true; for (uint i=0; iisClosed(); +bool mySQL::disconnect_one(Connection* con_ptr) { + bool status = !con_ptr->isClosed(); if (status) { try { - con[idx].second->close(); - status = !con[idx].second->isClosed(); + con_ptr->close(); + status = !con_ptr->isClosed(); } catch (const SQLException &error) { cout << error.what() << endl; @@ -212,32 +186,18 @@ bool mySQL::disconnect_one(const uint idx) { status = false; // već je zatvorena } - delete con[idx].second; - return status; -} - - -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; iisValid()) { - con[idx].second->setSchema(db); + if (con_ptr->isValid()) { + con_ptr->setSchema(db); status = false; } else { @@ -264,55 +224,19 @@ void mySQL::reconnectTrys(const uint _trys) { io.unlock(); } -void mySQL::exec(sqlQA &sql_qa) { - - if (!isPersistent) { - if (connect()) { - throw string("[ERROR] Unable to connect database "); - } - - if (!db.empty()) { - if (open()) { - throw string("[ERROR] Unable to open database " + db); - } - } - } - - const uint idx = findFreeCon(); - if (!isPersistent || con[idx].second->isClosed()) { - if (connect_one(idx)) { - throw string("[ERROR] Unable to connect database "); - } - - if (open_one(idx)) { - throw string("[ERROR] Unable to open database " + db); - } - } - - else if (!con[idx].second->isValid()) { - if(disconnect_one(idx)) { - throw string("[ERROR] Unable to close database "); - } - - if (connect_one(idx)) { - throw string("[ERROR] Unable to connect database "); - } - - if (open_one(idx)) { - throw string("[ERROR] Unable to open database " + db); - } - } +void mySQL::exec(sqlQA &sql_qa) { + Connection* con_ptr = shift_con(); try { vector columns = sql_qa.columns; if (columns.empty() && !sql_qa.table.empty()) { - getColumns(sql_qa.table, columns, con[idx].second); + getColumns(sql_qa.table, columns, con_ptr); } Statement *stmt; - stmt = con[idx].second->createStatement(); + stmt = con_ptr->createStatement(); if (sql_qa.isSelect) { ResultSet *res = stmt->executeQuery(sql_qa.cmd); @@ -342,23 +266,16 @@ void mySQL::exec(sqlQA &sql_qa) { stmt->close(); delete stmt; + disconnect_one(con_ptr); } catch (const SQLException &error) { cout << error.what() << endl; sql_qa.executed = false; } catch (const string error) { - con[idx].first->unlock(); throw error; } - if (!isPersistent) { - if(disconnect_one(idx)) { - throw string("[ERROR] Unable to close database "); - } - } - - con[idx].first->unlock(); } void mySQL::getColumns(const string _table, vector &_columns, Connection *ptr_con) { @@ -377,16 +294,16 @@ void mySQL::getColumns(const string _table, vector &_columns, Connection delete stmt; } -uint mySQL::findFreeCon() { - lock_guard master(io); +Connection* mySQL::shift_con() { while (true) { + io.lock(); for (uint i=0; iisValid()) { - if (con[i].first->try_lock()) { - return i; - } - // } + Connection* con_ptr = con[0]; + con.pop_front(); + io.unlock(); + return con_ptr; } + io.unlock(); } } diff --git a/test/test.cpp b/test/test.cpp index 0a8b6f7..0b019f8 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -9,49 +9,59 @@ using namespace chrono; int main() { try { - mySQL mydb("tcp://192.168.2.10:3306", "dinio", "H€r5elfInd1aH@nds", "dinio", true, 3); + mySQL mydb("tcp://192.168.2.10:3306", "dinio", "H€r5elfInd1aH@nds", "dinio", 1); + + sleep(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 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; + // } + // }); + + // // sleep(2); // thread t2([&](){ // try { // sqlQA test_qa; // test_qa.select().from("zones"); // mydb.exec(test_qa); - // //test_qa.print(true); + // test_qa.print(true); // } catch (const string err) { // cout << err << endl; // } // }); + // // sleep(3); + // thread t3([&](){ // try { // sqlQA test_qa; // test_qa.select().from("users"); // mydb.exec(test_qa); - // //test_qa.print(true); + // test_qa.print(true); // } catch (const string err) { // cout << err << endl; // } // }); + // // sleep(1); + // thread t4([&](){ // try { // sqlQA test_qa; // test_qa.select().from("records").where("enabled = 1"); // mydb.exec(test_qa); - // //test_qa.print(true); + // test_qa.print(true); // } catch (const string err) { // cout << err << endl; // } @@ -62,7 +72,7 @@ int main() { // sqlQA test_qa; // test_qa.select().from("zones"); // mydb.exec(test_qa); - // //test_qa.print(true); + // test_qa.print(true); // } catch (const string err) { // cout << err << endl; // } @@ -73,13 +83,13 @@ int main() { // sqlQA test_qa; // test_qa.select().from("users"); // mydb.exec(test_qa); - // // test_qa.print(true); + // test_qa.print(true); // } catch (const string err) { // cout << err << endl; // } // }); - t1.join(); + // t1.join(); // t2.join(); // t3.join(); // t4.join(); @@ -87,39 +97,41 @@ int main() { // t6.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(end - start); cout << "-------------Izvršilo se za: " << (double)(duration.count() / 1000.0) << " ms"<< endl; + sleep(100); + } catch (const SQLException error) { cout << error.what() << endl; @@ -129,7 +141,6 @@ int main() { cout << "Jebi ga" << endl; } - sleep(100); return 0; diff --git a/test/test.o b/test/test.o index af687d8..4ca51da 100755 Binary files a/test/test.o and b/test/test.o differ