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_
#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <iostream>
@ -21,6 +22,40 @@ using namespace std;
using namespace sql;
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 {
public:
mutex io;
@ -32,12 +67,10 @@ class mySQL {
mySQL(const string _path, const string _username, const string _password, const string _db, bool _isPersistent = false);
bool open(const string _db = "");
bool connect();
bool close();
map<string, vector<string>> query(const string sql_command);
bool change(const string sql_command);
string getTable(const string req);
bool disconnect();
void exec(sqlQA &sql_qa);
void getColumns(const string _table, vector<string> &_columns);
~mySQL();
};

@ -1,5 +1,51 @@
#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) {
path = _path;
username = _username;
@ -60,7 +106,7 @@ bool mySQL::connect() {
return status;
}
bool mySQL::close() {
bool mySQL::disconnect() {
io.lock();
bool status = true;
@ -72,14 +118,19 @@ bool mySQL::close() {
}
catch (const SQLException &error) {
cout << error.what() << endl;
status = true;
io.unlock();
}
}
else {
status = false;
}
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 (connect()) {
@ -93,87 +144,47 @@ map<string, vector<string>> mySQL::query(const string sql_command) {
io.lock();
/**/
map<string, vector<string>> maped;
try {
Statement *stmt;
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;
vector<string> columns = sql_qa.columns;
while (columnsRes->next()) {
tableFields.push_back(columnsRes->getString("Field"));
if (columns.empty() && !sql_qa.table.empty()) {
getColumns(sql_qa.table, columns);
}
delete columnsRes;
ResultSet *res = stmt->executeQuery(sql_command);
Statement *stmt;
stmt = con->createStatement();
while (res->next()) {
for (uint i=0; i<tableFields.size(); i++) {
maped[tableFields[i]].push_back(res->getString(tableFields[i]));
if (sql_qa.isSelect) {
ResultSet *res = stmt->executeQuery(sql_qa.cmd);
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 stmt;
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 ");
delete res;
sql_qa.num_columns = columns.size();
sql_qa.num_rows = num_raw_columns/columns.size();
}
}
return maped;
}
bool mySQL::change(const string sql_command) {
if (!isPersistent || !con->isValid() || con->isClosed()) {
if (connect()) {
throw string("[ERROR] Unable to connect database ");
if (sql_qa.isUpdate) {
sql_qa.updateCatch = stmt->executeUpdate(sql_qa.cmd);
sql_qa.executed = true;
}
if (open()) {
throw string("[ERROR] Unable to open database " + db);
else {
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;
io.unlock();
}
catch (const SQLException &error) {
cout << error.what() << endl;
sql_qa.executed = false;
io.unlock();
}
catch (const string error) {
@ -184,29 +195,29 @@ bool mySQL::change(const string sql_command) {
/**/
if (!isPersistent) {
if(close()) {
if(disconnect()) {
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) {
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;
}
ResultSet *columnsRes = stmt->executeQuery("SHOW COLUMNS from " + _table);
while (columnsRes->next()) {
_columns.push_back(columnsRes->getString("Field"));
}
delete columnsRes;
delete stmt;
}
mySQL::~mySQL() {
if(close()) {
if(disconnect()) {
throw string("[ERROR] Unable to close database ");
}
}

@ -10,24 +10,36 @@ int main() {
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) {
for (auto j: i.second) {
cout << i.first << " : " << j << 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;
}
// if (mydb.change("UPDATE records SET enabled = 0 WHERE domain = 'bitelex.ml'")) {
// cout << "Update sucessfuly" << endl;
// }
cout << "Num rows " << test_qa.num_rows << " num columns " << test_qa.num_columns << " executed " << test_qa.executed << endl;
}
catch (const SQLException error) {
cout << error.what() << endl;
}
catch (const string error) {
cout << error << endl;
// catch (const string error) {
// cout << error << endl;
// }
catch (...) {
cout << "Jebi ga" << endl;
}

Binary file not shown.
Loading…
Cancel
Save