diff --git a/.vscode/settings.json b/.vscode/settings.json index 5ecea1e..90ab211 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,17 @@ "vector": "cpp", "deque": "cpp", "ostream": "cpp", - "future": "cpp" + "future": "cpp", + "optional": "cpp", + "array": "cpp", + "string_view": "cpp", + "initializer_list": "cpp", + "utility": "cpp", + "mutex": "cpp", + "iostream": "cpp", + "*.tcc": "cpp", + "fstream": "cpp", + "new": "cpp", + "thread": "cpp" } } \ No newline at end of file diff --git a/lib/mysql.hpp b/lib/mysql.hpp index 9b3ca03..ee61078 100644 --- a/lib/mysql.hpp +++ b/lib/mysql.hpp @@ -51,6 +51,8 @@ class sqlQA { sqlQA& set(const string _column_value_pairs); sqlQA& deleteFrom(const string _table); + void print(bool withDetail = false); + // answer methods private: @@ -62,49 +64,29 @@ class mySQL { mutex io; MySQL_Driver *drv; // Connection *con; - vector con; + // vector con; + vector> con; string path, username, password, db; bool isPersistent; uint numOfCon; uint reconTrys = 3; 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 = "", const int con_idx = -1); - bool connect(const int con_idx = -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); - ~mySQL(); -}; - -// class mySQLPool { -// public: - -// struct Drop { -// mySQL* instance; -// bool used = false; -// }; - -// struct Swimmer { -// thread instance; -// bool used = false; -// }; + void getColumns(const string _table, vector &_columns, Connection *ptr_con); // privatno -// mutex io; -// uint maxpools = 0; -// vector droplets; -// bool fixServer = false; -// bool fixScheme = false; -// vector swimmers; + // 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(); -// mySQLPool(const uint _maxpools); -// mySQLPool(const uint _maxpools, const string _path, const string _username, const string _password, const string _db); - -// void exec(sqlQA &sql_qa, const string _db = ""); - - -// }; + ~mySQL(); +}; #endif \ No newline at end of file diff --git a/src/mysql.cpp b/src/mysql.cpp index 7ba1e99..b30de26 100644 --- a/src/mysql.cpp +++ b/src/mysql.cpp @@ -59,6 +59,21 @@ sqlQA& sqlQA::deleteFrom(const string _table) { return *this; } +void sqlQA::print(bool withDetail) { + // istražit da se prikaže u tabeli + for (auto i : result) { + for (auto j: i.second) { + cout << i.first << " : " << j << endl; + } + } + + if (withDetail) { + 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; + } +} void sqlQA::parse_columns(const string _columns) { istringstream iss(_columns); @@ -82,6 +97,8 @@ mySQL::mySQL(const string _path, const string _username, const string _password, isPersistent = _numOfCon > 1 ? true : _isPersistent; numOfCon = _numOfCon; + cout << "Num of con: " << numOfCon << endl; + drv = get_mysql_driver_instance(); if (isPersistent) { @@ -98,56 +115,58 @@ mySQL::mySQL(const string _path, const string _username, const string _password, } -bool mySQL::open(const string _db, const int con_idx) { +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); + con[i].second->setSchema(db); status = false; - io.unlock(); } catch (const SQLException &error) { cout << error.what() << endl; - io.unlock(); } - con_idx != -1 ? i = con.size() : i; + } - + + io.unlock(); return status; } -bool mySQL::connect(const int con_idx) { +bool mySQL::connect() { io.lock(); - uint trys = 0; - bool status = true; + // uint trys = 0; + // bool status = true; + bool Gstatus = true; for (uint i=0; iconnect(path, username, password)); - } - else { - con[i] = drv->connect(path, username, password); - } + 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; - io.unlock(); + Gstatus *= status; } catch (const SQLException &error) { cout << error.what() << endl; usleep(reconnectSleep); - reconTrys == 0 ? trys : trys++; - io.unlock(); - } + reconTrys == unlimited ? trys : trys++; + } } } - return status; + cout << "Num of pairs " << con.size() << endl; + + io.unlock(); + // return status; + return Gstatus; } bool mySQL::disconnect() { @@ -155,16 +174,14 @@ bool mySQL::disconnect() { bool status = true; for (uint i=0; iisValid() && !con[i]->isClosed()) { + if (con[i].second->isValid() && !con[i].second->isClosed()) { try { - con[i]->close(); + con[i].second->close(); status = false; - io.unlock(); } catch (const SQLException &error) { cout << error.what() << endl; status = true; - io.unlock(); } } @@ -173,6 +190,61 @@ bool mySQL::disconnect() { } } + io.unlock(); + return status; +} + +bool mySQL::disconnect_one(Connection *ptr_con) { + bool status = true; + + if (ptr_con->isValid() && !ptr_con->isClosed()) { + try { + ptr_con->close(); + status = false; + } + catch (const SQLException &error) { + cout << error.what() << endl; + status = true; + } + } + + else { + status = false; // već je zatvorena + } + + 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++; + } + } + + return status; +} + +bool mySQL::open_one(Connection *ptr_con) { + bool status = true; // ako true greška je + + try { + ptr_con->setSchema(db); + status = false; + } + catch (const SQLException &error) { + cout << error.what() << endl; + } + return status; } @@ -188,31 +260,28 @@ void mySQL::reconnectTrys(const uint _trys) { void mySQL::exec(sqlQA &sql_qa) { - for (uint i=0; iisValid() || con[i]->isClosed()) { - if (connect(i)) { - throw string("[ERROR] Unable to connect database "); - } + pair workCon = findFreeCon(); - if (open(i)) { - throw string("[ERROR] Unable to open database " + db); - } + if (!isPersistent || !workCon.second->isValid() || workCon.second->isClosed()) { + if (connect_one(workCon.second)) { + throw string("[ERROR] Unable to connect database "); } - } - // find free connection + if (open_one(workCon.second)) { + throw string("[ERROR] Unable to open database " + db); + } + } - io.lock(); /**/ try { vector columns = sql_qa.columns; if (columns.empty() && !sql_qa.table.empty()) { - getColumns(sql_qa.table, columns); + getColumns(sql_qa.table, columns, workCon.second); } Statement *stmt; - stmt = con->createStatement(); + stmt = workCon.second->createStatement(); if (sql_qa.isSelect) { ResultSet *res = stmt->executeQuery(sql_qa.cmd); @@ -225,6 +294,7 @@ void mySQL::exec(sqlQA &sql_qa) { } } + res->close(); delete res; sql_qa.num_columns = columns.size(); sql_qa.num_rows = num_raw_columns/columns.size(); @@ -239,32 +309,33 @@ void mySQL::exec(sqlQA &sql_qa) { sql_qa.executed = stmt->execute(sql_qa.cmd); } + stmt->close(); delete stmt; - io.unlock(); } catch (const SQLException &error) { cout << error.what() << endl; sql_qa.executed = false; - io.unlock(); } catch (const string error) { + workCon.first->unlock(); throw error; - io.unlock(); } /**/ if (!isPersistent) { - if(disconnect()) { + if(disconnect_one(workCon.second)) { throw string("[ERROR] Unable to close database "); } } + workCon.first->unlock(); + } -void mySQL::getColumns(const string _table, vector &_columns) { +void mySQL::getColumns(const string _table, vector &_columns, Connection *ptr_con) { Statement *stmt; - stmt = con->createStatement(); + stmt = ptr_con->createStatement(); ResultSet *columnsRes = stmt->executeQuery("SHOW COLUMNS from " + _table); @@ -272,59 +343,32 @@ void mySQL::getColumns(const string _table, vector &_columns) { _columns.push_back(columnsRes->getString("Field")); } + columnsRes->close(); + stmt->close(); delete columnsRes; delete stmt; } +pair mySQL::findFreeCon() { + io.lock(); + while (true) { + cout << "Tražim konekciju " << endl; + for (uint i=0; itry_lock()) { + cout << "Koristim " << i << " konekciju" << endl; + io.unlock(); + return con[i]; + } + // else { + // usleep(1000); + // } + } + } +} + mySQL::~mySQL() { if(disconnect()) { throw string("[ERROR] Unable to close database "); } -} - -// mySQLPool::mySQLPool(const uint _maxpools) { -// maxpools = _maxpools; -// fixServer = false; -// fixScheme = true; -// } - -// mySQLPool::mySQLPool(const uint _maxpools, const string _path, const string _username, const string _password, const string _db) { -// maxpools = _maxpools; -// fixServer = true; -// fixScheme = !_db.empty(); -// for (uint i=0; iexec(sql_qa); -// }); -// swimmers[i].instance.join(); -// swimmers[i].used = false; -// isRunned = true; -// } -// } -// } -// droplets[i].used = false; -// } -// } - -// } +} \ No newline at end of file diff --git a/test/compile.sh b/test/compile.sh index 42fa51e..b71c1b3 100644 --- a/test/compile.sh +++ b/test/compile.sh @@ -1 +1 @@ -g++ test.cpp ../src/* -o test.o -lmysqlcppconn \ No newline at end of file +g++ test.cpp ../src/* -o test.o -lmysqlcppconn -lpthread \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp index 283e24b..28d1bfa 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,53 +1,95 @@ #include +#include +#include #include "../lib/mysql.hpp" using namespace std; +using namespace chrono; int main() { - - mySQL mydb("tcp://192.168.2.10:3306", "dinio", "H€r5elfInd1aH@nds", "dinio", true); - try { - - sqlQA test_qa; - // id,user_id,zone_id,domain,record_type,auth_key,last_update,enabled - // test_qa.select().from("records").where("enabled = 0").limit(2); - // mydb.exec(test_qa); - - // for (auto i : test_qa.result) { - // for (auto j: i.second) { - // cout << i.first << " : " << j << endl; + mySQL mydb("tcp://92.240.56.92:3306", "dinio", "H€r5elfInd1aH@nds", "dinio", true, 2); + + 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; // } - // } - - - // test_qa.update("records").set("enabled = 1").where("domain = 'bitelex.test'"); - // mydb.exec(test_qa); - // if (test_qa.executed) { - // cout << "Num rows affect " << test_qa.updateCatch << endl; - // } - - // cout << "Num rows " << test_qa.num_rows << " num columns " << test_qa.num_columns << " executed " << test_qa.executed << endl; - - - // test_qa.insertInTo("records", "id,user_id,zone_id,domain,record_type,auth_key,last_update,enabled").values("'5',2,2,'www.bitelex.test','AAAA','jebiga',NULL,1"); - test_qa.deleteFrom("records").where("record_type = AAAA"); - // test_qa.update("records").set("enabled = 0").where("record_type = 'AAAA'"); - cout << test_qa.cmd << endl; - mydb.exec(test_qa); - cout << "Num rows " << test_qa.num_rows << " num columns " << test_qa.num_columns << " catch " << test_qa.updateCatch << " executed " << test_qa.executed << endl; - - - - } - catch (const SQLException error) { + // }); + + // 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("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; + + + } catch (const SQLException error) { cout << error.what() << endl; - } - // catch (const string error) { - // cout << error << endl; - // } - catch (...) { + } catch (const string error) { + cout << error << endl; + } catch (...) { cout << "Jebi ga" << endl; } diff --git a/test/test.o b/test/test.o index f6f4967..9ef803e 100755 Binary files a/test/test.o and b/test/test.o differ