Deque implementation done, dev tested

queue v0.5_queue
marcelb 10 months ago
parent 774151e534
commit 4c4fdcc938
  1. 19
      lib/mysql.hpp
  2. 163
      src/mysql.cpp
  3. 93
      test/test.cpp
  4. BIN
      test/test.o

@ -4,6 +4,7 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <deque>
#include <map> #include <map>
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
@ -64,24 +65,22 @@ class mySQL {
private: private:
mutex io; mutex io;
MySQL_Driver *drv; MySQL_Driver *drv;
vector<pair<mutex*, Connection*>> con; deque<Connection*> con;
string path, username, password, db; string path, username, password, db;
bool isPersistent; uint available;
uint numOfCon;
uint reconTrys = 3; uint reconTrys = 3;
bool runBot = true; bool runBot = true;
future<void> bot; future<void> bot;
void getColumns(const string _table, vector<string> &_columns, Connection *ptr_con); // privatno void getColumns(const string _table, vector<string> &_columns, Connection *ptr_con); // privatno
bool open_one(const uint idx); bool open_one(Connection* con_ptr);
bool connect_one(const uint idx); Connection* create_con();
bool disconnect_one(const uint idx); bool disconnect_one(Connection* con_ptr);
uint findFreeCon(); Connection* shift_con();
public: public:
mySQL(const string _path, const string _username, const string _password, const string _db, const bool _isPersistent = false, const uint _numOfCon = 1); mySQL(const string _path, const string _username, const string _password, const string _db, const uint _available = 1);
bool open(const string _db = "");
bool connect();
bool disconnect(); bool disconnect();
void reconnectTrys(const uint _trys); void reconnectTrys(const uint _trys);
void exec(sqlQA &sql_qa); void exec(sqlQA &sql_qa);

@ -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; path = _path;
username = _username; username = _username;
password = _password; password = _password;
db = _db; db = _db;
isPersistent = _numOfCon > 1 ? true : _isPersistent; available = _available > 0 ? _available : 1;
numOfCon = _numOfCon > 0 ? _numOfCon : 1;
drv = get_mysql_driver_instance(); 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, [&]{ bot = async(launch::async, [&]{
while (runBot) { while (runBot) {
while (available>con.size() && runBot) {
try { try {
for (uint i=0; i<con.size(); i++) { Connection* new_con_ptr = create_con();
if (con[i].first->try_lock()) {
if (!con[i].second->isValid()) {
if (connect_one(i)) {
throw string("[ERROR] Unable to connect database ");
}
if (!db.empty()) { if (!db.empty()) {
if (open_one(i)) { if (open_one(new_con_ptr)) {
throw string("[ERROR] Unable to open database " + db); throw string("[ERROR] Unable to open database " + db);
} }
} }
} io.lock();
con[i].first->unlock(); con.push_back(new_con_ptr);
} io.unlock();
}
} catch (const SQLException except) { } catch (const SQLException except) {
cout << except.what() << endl; cout << except.what() << endl;
} catch (const string except) { } catch (const string except) {
cout << except << endl; cout << except << endl;
} }
} }
return;
});
}
} }
bool mySQL::connect() { return;
io.lock(); });
bool status = true;
for (uint i=0; i<numOfCon; i++) {
status = connect_one(i);
} }
io.unlock();
return status;
}
bool mySQL::connect_one(const uint idx) { Connection* mySQL::create_con() {
uint trys = 0; uint trys = 0;
bool status = true; bool status = true;
Connection* new_con = NULL;
while (reconTrys == unlimited ? status : (trys <= reconTrys && status)) { while (reconTrys == unlimited ? status : (trys <= reconTrys && status)) {
try { try {
if (con.size() < numOfCon) { Connection* con_can = drv->connect(path, username, password);
con.push_back(make_pair(new mutex, drv->connect(path, username, password))); status = !con_can->isValid();
if (!status) {
new_con = con_can;
} }
else { else if (!con_can->isClosed()) {
con[idx].second = drv->connect(path, username, password); disconnect_one(con_can);
} }
status = !con[idx].second->isValid() && con[idx].second->isClosed() || con[idx].second->isClosed();
} }
catch (const SQLException &error) { catch (const SQLException &error) {
cout << error.what() << endl; cout << error.what() << endl;
@ -179,7 +153,7 @@ bool mySQL::connect_one(const uint idx) {
} }
} }
return status; return new_con;
} }
bool mySQL::disconnect() { bool mySQL::disconnect() {
@ -187,20 +161,20 @@ bool mySQL::disconnect() {
bool status = true; bool status = true;
for (uint i=0; i<con.size(); i++) { for (uint i=0; i<con.size(); i++) {
status = disconnect_one(i) ; status = disconnect_one(con[i]) ;
} }
io.unlock(); io.unlock();
return status; return status;
} }
bool mySQL::disconnect_one(const uint idx) { bool mySQL::disconnect_one(Connection* con_ptr) {
bool status = !con[idx].second->isClosed(); bool status = !con_ptr->isClosed();
if (status) { if (status) {
try { try {
con[idx].second->close(); con_ptr->close();
status = !con[idx].second->isClosed(); status = !con_ptr->isClosed();
} }
catch (const SQLException &error) { catch (const SQLException &error) {
cout << error.what() << endl; cout << error.what() << endl;
@ -212,32 +186,18 @@ bool mySQL::disconnect_one(const uint idx) {
status = false; // već je zatvorena status = false; // već je zatvorena
} }
delete con[idx].second; delete con_ptr;
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; i<con.size(); i++) {
status = open_one(i);
}
io.unlock();
return status; return status;
} }
bool mySQL::open_one(const uint idx) { bool mySQL::open_one(Connection* con_ptr) {
bool status = true; // ako true greška je bool status = true; // ako true greška je
uint trys = 0; uint trys = 0;
while (reconTrys == unlimited ? status : (trys <= reconTrys && status)) { while (reconTrys == unlimited ? status : (trys <= reconTrys && status)) {
try { try {
if (con[idx].second->isValid()) { if (con_ptr->isValid()) {
con[idx].second->setSchema(db); con_ptr->setSchema(db);
status = false; status = false;
} }
else { else {
@ -264,55 +224,19 @@ void mySQL::reconnectTrys(const uint _trys) {
io.unlock(); 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)) { void mySQL::exec(sqlQA &sql_qa) {
throw string("[ERROR] Unable to connect database "); Connection* con_ptr = shift_con();
}
if (open_one(idx)) {
throw string("[ERROR] Unable to open database " + db);
}
}
try { try {
vector<string> columns = sql_qa.columns; vector<string> columns = sql_qa.columns;
if (columns.empty() && !sql_qa.table.empty()) { if (columns.empty() && !sql_qa.table.empty()) {
getColumns(sql_qa.table, columns, con[idx].second); getColumns(sql_qa.table, columns, con_ptr);
} }
Statement *stmt; Statement *stmt;
stmt = con[idx].second->createStatement(); stmt = con_ptr->createStatement();
if (sql_qa.isSelect) { if (sql_qa.isSelect) {
ResultSet *res = stmt->executeQuery(sql_qa.cmd); ResultSet *res = stmt->executeQuery(sql_qa.cmd);
@ -342,23 +266,16 @@ void mySQL::exec(sqlQA &sql_qa) {
stmt->close(); stmt->close();
delete stmt; delete stmt;
disconnect_one(con_ptr);
} }
catch (const SQLException &error) { catch (const SQLException &error) {
cout << error.what() << endl; cout << error.what() << endl;
sql_qa.executed = false; sql_qa.executed = false;
} }
catch (const string error) { catch (const string error) {
con[idx].first->unlock();
throw error; 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<string> &_columns, Connection *ptr_con) { void mySQL::getColumns(const string _table, vector<string> &_columns, Connection *ptr_con) {
@ -377,16 +294,16 @@ void mySQL::getColumns(const string _table, vector<string> &_columns, Connection
delete stmt; delete stmt;
} }
uint mySQL::findFreeCon() { Connection* mySQL::shift_con() {
lock_guard<mutex> master(io);
while (true) { while (true) {
io.lock();
for (uint i=0; i<con.size(); i++) { for (uint i=0; i<con.size(); i++) {
// if (con[i].second->isValid()) { Connection* con_ptr = con[0];
if (con[i].first->try_lock()) { con.pop_front();
return i; io.unlock();
} return con_ptr;
// }
} }
io.unlock();
} }
} }

@ -9,49 +9,59 @@ using namespace chrono;
int main() { int main() {
try { 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(); auto start = high_resolution_clock::now();
thread t1([&](){
try { // thread t1([&](){
sqlQA test_qa; // try {
test_qa.select().from("records").where("enabled = 1"); // sqlQA test_qa;
mydb.exec(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) { // } catch (const string err) {
cout << err << endl; // cout << err << endl;
} // }
}); // });
// // sleep(2);
// thread t2([&](){ // thread t2([&](){
// try { // try {
// sqlQA test_qa; // sqlQA test_qa;
// test_qa.select().from("zones"); // test_qa.select().from("zones");
// mydb.exec(test_qa); // mydb.exec(test_qa);
// //test_qa.print(true); // test_qa.print(true);
// } catch (const string err) { // } catch (const string err) {
// cout << err << endl; // cout << err << endl;
// } // }
// }); // });
// // sleep(3);
// thread t3([&](){ // thread t3([&](){
// try { // try {
// sqlQA test_qa; // sqlQA test_qa;
// test_qa.select().from("users"); // test_qa.select().from("users");
// mydb.exec(test_qa); // mydb.exec(test_qa);
// //test_qa.print(true); // test_qa.print(true);
// } catch (const string err) { // } catch (const string err) {
// cout << err << endl; // cout << err << endl;
// } // }
// }); // });
// // sleep(1);
// thread t4([&](){ // thread t4([&](){
// try { // try {
// sqlQA test_qa; // sqlQA test_qa;
// test_qa.select().from("records").where("enabled = 1"); // test_qa.select().from("records").where("enabled = 1");
// mydb.exec(test_qa); // mydb.exec(test_qa);
// //test_qa.print(true); // test_qa.print(true);
// } catch (const string err) { // } catch (const string err) {
// cout << err << endl; // cout << err << endl;
// } // }
@ -62,7 +72,7 @@ int main() {
// sqlQA test_qa; // sqlQA test_qa;
// test_qa.select().from("zones"); // test_qa.select().from("zones");
// mydb.exec(test_qa); // mydb.exec(test_qa);
// //test_qa.print(true); // test_qa.print(true);
// } catch (const string err) { // } catch (const string err) {
// cout << err << endl; // cout << err << endl;
// } // }
@ -73,13 +83,13 @@ int main() {
// sqlQA test_qa; // sqlQA test_qa;
// test_qa.select().from("users"); // test_qa.select().from("users");
// mydb.exec(test_qa); // mydb.exec(test_qa);
// // test_qa.print(true); // test_qa.print(true);
// } catch (const string err) { // } catch (const string err) {
// cout << err << endl; // cout << err << endl;
// } // }
// }); // });
t1.join(); // t1.join();
// t2.join(); // t2.join();
// t3.join(); // t3.join();
// t4.join(); // t4.join();
@ -87,39 +97,41 @@ int main() {
// t6.join(); // t6.join();
// one by one // one by one
// try { try {
// sqlQA test_qa; sqlQA test_qa;
// test_qa.select().from("records").where("enabled = 1"); test_qa.select().from("records").where("enabled = 1");
// mydb.exec(test_qa); mydb.exec(test_qa);
// test_qa.print(true); test_qa.print(true);
// } catch (const string err) { } catch (const string err) {
// cout << err << endl; cout << err << endl;
// } }
// try { try {
// sqlQA test_qa; sqlQA test_qa;
// test_qa.select().from("users"); test_qa.select().from("users");
// mydb.exec(test_qa); mydb.exec(test_qa);
// test_qa.print(true); test_qa.print(true);
// } catch (const string err) { } catch (const string err) {
// cout << err << endl; cout << err << endl;
// } }
// try { try {
// sqlQA test_qa; sqlQA test_qa;
// test_qa.select().from("users"); test_qa.select().from("users");
// mydb.exec(test_qa); mydb.exec(test_qa);
// test_qa.print(true); test_qa.print(true);
// } catch (const string err) { } catch (const string err) {
// cout << err << endl; cout << err << endl;
// } }
auto end = high_resolution_clock::now(); auto end = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(end - start); auto duration = duration_cast<microseconds>(end - start);
cout << "-------------Izvršilo se za: " << (double)(duration.count() / 1000.0) << " ms"<< endl; cout << "-------------Izvršilo se za: " << (double)(duration.count() / 1000.0) << " ms"<< endl;
sleep(100);
} catch (const SQLException error) { } catch (const SQLException error) {
cout << error.what() << endl; cout << error.what() << endl;
@ -129,7 +141,6 @@ int main() {
cout << "Jebi ga" << endl; cout << "Jebi ga" << endl;
} }
sleep(100);
return 0; return 0;

Binary file not shown.
Loading…
Cancel
Save