diff --git a/.vscode/settings.json b/.vscode/settings.json index 90ab211..4f6e42a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,6 +15,7 @@ "*.tcc": "cpp", "fstream": "cpp", "new": "cpp", - "thread": "cpp" + "thread": "cpp", + "chrono": "cpp" } } \ No newline at end of file diff --git a/lib/mysql.hpp b/lib/mysql.hpp index ee61078..7d94b5f 100644 --- a/lib/mysql.hpp +++ b/lib/mysql.hpp @@ -18,7 +18,7 @@ #include #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 con; vector> con; string path, username, password, db; bool isPersistent; uint numOfCon; uint reconTrys = 3; + 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(); + + 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 &_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 findFreeCon(); - ~mySQL(); + }; diff --git a/src/mysql.cpp b/src/mysql.cpp index b30de26..fbb9c86 100644 --- a/src/mysql.cpp +++ b/src/mysql.cpp @@ -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; isetSchema(db); - status = false; - } - catch (const SQLException &error) { - cout << error.what() << endl; - } + bool status = true; + for (uint i=0; iconnect(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; iisValid() && !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; isetSchema(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 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 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 &_columns, Connection *ptr_con) { @@ -349,20 +321,13 @@ void mySQL::getColumns(const string _table, vector &_columns, Connection delete stmt; } -pair mySQL::findFreeCon() { - io.lock(); +uint mySQL::findFreeCon() { + lock_guard master(io); while (true) { - cout << "Tražim konekciju " << endl; for (uint i=0; itry_lock()) { - cout << "Koristim " << i << " konekciju" << endl; - io.unlock(); - return con[i]; + return i; } - // else { - // usleep(1000); - // } } } } diff --git a/test/test.cpp b/test/test.cpp index 28d1bfa..30d9714 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -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(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) { diff --git a/test/test.o b/test/test.o index 9ef803e..0bc3010 100755 Binary files a/test/test.o and b/test/test.o differ