Formater: select, from, where, update, set. Fix bug in disconnect/close. SQLQA type. Exec/query refactor

queue v0.2_beta
marcelb 1 year ago
parent 701ebef06f
commit 5482d71558
  1. 2
      .gitignore
  2. 43
      lib/mysql.hpp
  3. 165
      src/mysql.cpp
  4. 32
      test/test.cpp
  5. BIN
      test/test.o

2
.gitignore vendored

@ -0,0 +1,2 @@
example
test/test.o

@ -2,6 +2,7 @@
#define _MYSQL_ #define _MYSQL_
#include <string> #include <string>
#include <sstream>
#include <vector> #include <vector>
#include <map> #include <map>
#include <iostream> #include <iostream>
@ -21,6 +22,40 @@ using namespace std;
using namespace sql; using namespace sql;
using namespace mysql; using namespace mysql;
class sqlQA {
public:
// query
string cmd;
string table;
vector<string> columns;
bool isUpdate = false;
bool isSelect = false;
// answer
uint updateCatch = 0;
bool executed = false;
map<string, vector<string>> result;
uint num_rows = 0;
uint num_columns = 0;
// query methods
sqlQA& select(const string _select = "*");
sqlQA& from(const string _tablename);
sqlQA& where(const string _condition);
// sqlQA& limit();
// sqlQA& insertInTo(string _tablename, string _columns);
// sqlQA& values(); // proizvoljan broj argumenata
sqlQA& update(const string _tablename);
sqlQA& set(const string _column_value_pairs);
// sqlQA& deleteFrom();
// answer methods
private:
void parse_columns(const string _cloumns);
};
class mySQL { class mySQL {
public: public:
mutex io; mutex io;
@ -32,12 +67,10 @@ class mySQL {
mySQL(const string _path, const string _username, const string _password, const string _db, bool _isPersistent = false); mySQL(const string _path, const string _username, const string _password, const string _db, bool _isPersistent = false);
bool open(const string _db = ""); bool open(const string _db = "");
bool connect(); bool connect();
bool close(); bool disconnect();
map<string, vector<string>> query(const string sql_command); void exec(sqlQA &sql_qa);
bool change(const string sql_command); void getColumns(const string _table, vector<string> &_columns);
string getTable(const string req);
~mySQL(); ~mySQL();
}; };

@ -1,5 +1,51 @@
#include "../lib/mysql.hpp" #include "../lib/mysql.hpp"
sqlQA& sqlQA::select(const string _columns) {
if (_columns != "*") {
parse_columns(_columns);
}
isSelect = true;
cmd += "SELECT " + _columns + " ";
return *this;
}
sqlQA& sqlQA::from(const string _table) {
table = _table;
cmd += "FROM " + _table + " ";
return *this;
}
sqlQA& sqlQA::where(const string _condition) {
cmd += "WHERE " + _condition + " ";
return *this;
}
sqlQA& sqlQA::update(const string _table) {
isUpdate = true;
cmd += "UPDATE " + _table + " ";
return *this;
}
sqlQA& sqlQA::set(const string _column_value_pairs) {
cmd += "SET " + _column_value_pairs + " ";
return *this;
}
void sqlQA::parse_columns(const string _columns) {
istringstream iss(_columns);
string columnName;
while (getline(iss, columnName, ',')) {
size_t startPos = columnName.find_first_not_of(" ");
size_t endPos = columnName.find_last_not_of(" ");
if (startPos != string::npos && endPos != string::npos) {
columns.push_back(columnName.substr(startPos, endPos - startPos + 1));
}
}
}
mySQL::mySQL(const string _path, const string _username, const string _password, const string _db, bool _isPersistent) { mySQL::mySQL(const string _path, const string _username, const string _password, const string _db, bool _isPersistent) {
path = _path; path = _path;
username = _username; username = _username;
@ -60,7 +106,7 @@ bool mySQL::connect() {
return status; return status;
} }
bool mySQL::close() { bool mySQL::disconnect() {
io.lock(); io.lock();
bool status = true; bool status = true;
@ -72,14 +118,19 @@ bool mySQL::close() {
} }
catch (const SQLException &error) { catch (const SQLException &error) {
cout << error.what() << endl; cout << error.what() << endl;
status = true;
io.unlock(); io.unlock();
} }
} }
else {
status = false;
}
return status; return status;
} }
map<string, vector<string>> mySQL::query(const string sql_command) { void mySQL::exec(sqlQA &sql_qa) {
if (!isPersistent || !con->isValid() || con->isClosed()) { if (!isPersistent || !con->isValid() || con->isClosed()) {
if (connect()) { if (connect()) {
@ -93,87 +144,47 @@ map<string, vector<string>> mySQL::query(const string sql_command) {
io.lock(); io.lock();
/**/ /**/
map<string, vector<string>> maped;
try { try {
Statement *stmt; vector<string> columns = sql_qa.columns;
stmt = con->createStatement();
const string table = getTable(sql_command);
if (table.empty()) {
throw string ("[ERROR] SQL command not have table ");
}
ResultSet *columnsRes = stmt->executeQuery("SHOW COLUMNS from " + table);
vector<string> tableFields;
while (columnsRes->next()) { if (columns.empty() && !sql_qa.table.empty()) {
tableFields.push_back(columnsRes->getString("Field")); getColumns(sql_qa.table, columns);
} }
delete columnsRes; Statement *stmt;
stmt = con->createStatement();
ResultSet *res = stmt->executeQuery(sql_command);
while (res->next()) { if (sql_qa.isSelect) {
for (uint i=0; i<tableFields.size(); i++) { ResultSet *res = stmt->executeQuery(sql_qa.cmd);
maped[tableFields[i]].push_back(res->getString(tableFields[i])); sql_qa.executed = true;
uint num_raw_columns = 0;
while (res->next()) {
for (uint i=0; i<columns.size(); i++) {
sql_qa.result[columns[i]].push_back(res->getString(columns[i]));
num_raw_columns++;
}
} }
}
delete res; delete res;
delete stmt; sql_qa.num_columns = columns.size();
sql_qa.num_rows = num_raw_columns/columns.size();
io.unlock();
}
catch (const SQLException &error) {
cout << error.what() << endl;
io.unlock();
}
catch (const string error) {
throw error;
io.unlock();
}
/**/
if (!isPersistent) {
if(close()) {
throw string("[ERROR] Unable to close database ");
} }
}
return maped; if (sql_qa.isUpdate) {
} sql_qa.updateCatch = stmt->executeUpdate(sql_qa.cmd);
sql_qa.executed = true;
bool mySQL::change(const string sql_command) {
if (!isPersistent || !con->isValid() || con->isClosed()) {
if (connect()) {
throw string("[ERROR] Unable to connect database ");
} }
if (open()) { else {
throw string("[ERROR] Unable to open database " + db); sql_qa.executed = stmt->execute(sql_qa.cmd);
} }
}
io.lock();
/**/
bool status = false;
try {
Statement *stmt;
stmt = con->createStatement();
uint changeCatch = stmt->executeUpdate(sql_command);
status = (bool)changeCatch;
delete stmt; delete stmt;
io.unlock(); io.unlock();
} }
catch (const SQLException &error) { catch (const SQLException &error) {
cout << error.what() << endl; cout << error.what() << endl;
sql_qa.executed = false;
io.unlock(); io.unlock();
} }
catch (const string error) { catch (const string error) {
@ -184,29 +195,29 @@ bool mySQL::change(const string sql_command) {
/**/ /**/
if (!isPersistent) { if (!isPersistent) {
if(close()) { if(disconnect()) {
throw string("[ERROR] Unable to close database "); throw string("[ERROR] Unable to close database ");
} }
} }
return status;
} }
void mySQL::getColumns(const string _table, vector<string> &_columns) {
Statement *stmt;
stmt = con->createStatement();
string mySQL::getTable(const string req) { ResultSet *columnsRes = stmt->executeQuery("SHOW COLUMNS from " + _table);
size_t from = req.find("FROM") < req.find("from") ? req.find("FROM") : req.find("from");
size_t ends = req.find(" ", from+5) < req.length() ? req.find(" ", from+5) : req.length();
if (from > req.length()) {
return "";
}
string table = req.substr(from+5, ends-from-5);
return table;
}
while (columnsRes->next()) {
_columns.push_back(columnsRes->getString("Field"));
}
delete columnsRes;
delete stmt;
}
mySQL::~mySQL() { mySQL::~mySQL() {
if(close()) { if(disconnect()) {
throw string("[ERROR] Unable to close database "); throw string("[ERROR] Unable to close database ");
} }
} }

@ -10,24 +10,36 @@ int main() {
try { try {
auto res = mydb.query("SELECT * FROM records WHERE enabled = 1;"); sqlQA test_qa;
// id,user_id,zone_id,domain,record_type,auth_key,last_update,enabled
// test_qa.select().from("records").where("enabled = 1");
// mydb.exec(test_qa);
// for (auto i : test_qa.result) {
// for (auto j: i.second) {
// cout << i.first << " : " << j << endl;
// }
// }
for (auto i : res) { test_qa.update("records").set("enabled = 1").where("domain = 'bitelex.test'");
for (auto j: i.second) { mydb.exec(test_qa);
cout << i.first << " : " << j << endl; if (test_qa.executed) {
} cout << "Num rows affect " << test_qa.updateCatch << endl;
} }
// if (mydb.change("UPDATE records SET enabled = 0 WHERE domain = 'bitelex.ml'")) { cout << "Num rows " << test_qa.num_rows << " num columns " << test_qa.num_columns << " executed " << test_qa.executed << endl;
// cout << "Update sucessfuly" << endl;
// }
} }
catch (const SQLException error) { catch (const SQLException error) {
cout << error.what() << endl; cout << error.what() << endl;
} }
catch (const string error) { // catch (const string error) {
cout << error << endl; // cout << error << endl;
// }
catch (...) {
cout << "Jebi ga" << endl;
} }

Binary file not shown.
Loading…
Cancel
Save