#include "Database.h" #define EXECUTE_SQL_QUERY_WITH_CODE(req, res, return_value, code_if_fail, code_if_syntax_fail) \ do{\ try\ {\ if (!_db.CheckSyntax(req)) \ {\ std::cout << req << " is invalid !\n" ; \ code_if_syntax_fail; \ return return_value;\ } \ res = _db.ExecuteQuery(req);\ }\ catch (wxSQLite3Exception e)\ {\ std::cerr << e.GetMessage().mb_str() << "\n" ;\ code_if_fail; \ return return_value;\ }\ } while(0); #define EXECUTE_SQL_QUERY(req, res, return_value) EXECUTE_SQL_QUERY_WITH_CODE(req, res, return_value, {}, {}) Database::Database() { std::ifstream bdd_file; bdd_file.open(BDD_FILE); if (!bdd_file) { CreateDatabase(); } else _db.Open(_(BDD_FILE)); bdd_file.close(); } void Database::CreateDatabase() { std::ifstream init_script; std::string line; wxString wxline; wxMessageBox(_("No database found, creating a new one"), _("KissCount"), wxICON_EXCLAMATION | wxOK ); init_script.open(INIT_SCRIPT); if (!init_script) { wxMessageBox(_(INIT_SCRIPT " not found, aborting"), _("Error"), wxICON_ERROR | wxOK ); throw "init.sql not found, aborting"; } _db.Open(_(BDD_FILE)); do { getline(init_script, line); wxline = wxString(line.c_str(), wxConvUTF8); wxline.Trim(false); if (!wxline.Length() || wxline.StartsWith(_("#"))) continue; if (!_db.CheckSyntax(wxline)) { std::cout << line << " is invalid !\n" ; continue; } try { _db.ExecuteUpdate(wxline); } catch (...) { wxMessageBox(_("Error creating original database"), _("Error"), wxICON_ERROR | wxOK ); remove(BDD_FILE); throw line; } } while (init_script); init_script.close(); } std::list Database::GetUsers() { std::list res; // Check whether value exists in table wxSQLite3ResultSet set ; EXECUTE_SQL_QUERY(_("SELECT name FROM user ORDER BY name"), set, res); while (set.NextRow()) { res.push_front(set.GetAsString(0)); } set.Finalize(); return res; } bool Database::IsValidUser(wxString user, wxString password) { bool res; blk_SHA_CTX sha_ctx; unsigned char sha[20]; wxString req, wxSHA; wxSQLite3ResultSet set; blk_SHA1_Init(&sha_ctx); blk_SHA1_Update(&sha_ctx, password.c_str(), password.Length()); blk_SHA1_Final(sha, &sha_ctx); for(int i=0; i<20; i++) wxSHA += wxString::Format(wxT("%02F"), (int)sha[i]); req = _("SELECT name FROM user WHERE name='") + user + _("' AND password='") + wxSHA + _("'"); req.Printf(_("req : %s\n")); EXECUTE_SQL_QUERY(req, set, false); res = set.NextRow() ; set.Finalize(); return res; } User* Database::LoadUser(wxString name) { wxSQLite3ResultSet set; wxString req; User* user; Account* account; std::list::iterator it; req = _("SELECT * FROM user WHERE name='") + name + _("'"); EXECUTE_SQL_QUERY(req, set, NULL); if (!set.NextRow()) return NULL; user = new User(); user->_id = set.GetAsString(_("id")); user->_name = set.GetAsString(_("name")); user->_password = _("") ; // Security reasons set.GetAsString("password"); set.Finalize(); req = _("SELECT * FROM account WHERE user='") + user->_id + _("' ORDER BY default DESC, name ASC"); EXECUTE_SQL_QUERY_WITH_CODE(req, set, NULL, {delete user;}); while (set.NextRow()) { account = new Account(); account->_id = set.GetAsString(_("id")); account->_name = set.GetAsString(_("name")); account->_number = set.GetAsString(_("number")); account->_amount = set.GetInt(_("amount")); account->_shared = set.GetBool(_("shared")); account->_default = set.GetBool(_("default_account")); user->_accounts.push_back(account); } set.Finalize(); if (!user->_accounts.empty()) { it = user->_accounts.begin(); req = _("SELECT DISTINCT year FROM operation WHERE account IN(") + (*it)->_id; it++; for (;it != user->_accounts.end(); it++) { req += _(", ") + (*it)->_id ; } req += _(") ORDER BY year ASC"); EXECUTE_SQL_QUERY_WITH_CODE(req, set, NULL, {delete user;}); while (set.NextRow()) { user->_operations[set.GetInt(_("year"))] = NULL; } set.Finalize(); } return user; }