diff --git a/init.sql b/init.sql index dadb70c..ac65a4d 100644 --- a/init.sql +++ b/init.sql @@ -1,10 +1,12 @@ CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR(255), password VARCHAR(255)); -CREATE TABLE account(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255), number VARCHAR(255), shared CHAR(1), default CHAR(1)); -CREATE TABLE operation(id INTEGER PRIMARY KEY, account REFERENCES account(id), year INTEGER, month INTEGER, day INTEGER, description VARCHAR(255), category VARCHAR(255), fix_cost CHAR(1)); +CREATE TABLE account(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255), number VARCHAR(255), amount INTEGER, shared CHAR(1), default_account CHAR(1)); +CREATE TABLE operation(id INTEGER PRIMARY KEY, user REFERENCES user(id), account REFERENCES account(id), year INTEGER, month INTEGER, day INTEGER, amount INTEGER, description VARCHAR(255), category VARCHAR(255), fix_cost CHAR(1)); CREATE TABLE preference(id INTEGER PRIMARY KEY, user REFERENCES user(id), type VARCHAR(255), name VARCHAR(255), value VARCHAR(255)); CREATE TABLE default_preference(id INTEGER PRIMARY KEY, type VARCHAR(255), name VARCHAR(255), value VARCHAR(255)); INSERT INTO default_preference ("type", "value") VALUES ("category", "Fixe"); INSERT INTO default_preference ("type", "value") VALUES ("category", "Courses"); INSERT INTO default_preference ("type", "value") VALUES ("category", "Loisirs"); INSERT INTO default_preference ("type", "value") VALUES ("category", "Frais de fonctionnement"); -INSERT INTO default_preference ("type", "value") VALUES ("category", "Exceptionnel"); \ No newline at end of file +INSERT INTO default_preference ("type", "value") VALUES ("category", "Exceptionnel"); +INSERT INTO user ("id", "name", "password") VALUES ("0", "Greg", "da39a3ee5e6b4b0d3255bfef95601890afd80709"); +INSERT INTO account ("id", "user", "name", "number", "amount", "shared", "default_account") VALUES ("0", "0", "Compte courant", "000", "1234", "0", "1"); diff --git a/model/Account.cpp b/model/Account.cpp new file mode 100644 index 0000000..b235d8d --- /dev/null +++ b/model/Account.cpp @@ -0,0 +1,7 @@ +#include "Account.h" + + +Account::~Account() +{ + +} diff --git a/model/Account.h b/model/Account.h index 42b60f0..d486f83 100644 --- a/model/Account.h +++ b/model/Account.h @@ -3,24 +3,28 @@ #include #include - +#include struct operation { + wxString id; unsigned int day; unsigned int month; unsigned int year; - unsigned int amount; - std::string description; - std::string category; + int amount; + wxString description; + wxString category; bool fix_cost; } ; class Account { -private: - std::string _name; - std::string _number; - std::map > > _operations; +public: + ~Account(); + + wxString _id; + wxString _name; + wxString _number; + int _amount; bool _shared; bool _default; }; diff --git a/model/Database.cpp b/model/Database.cpp index 2a34f74..af91b23 100644 --- a/model/Database.cpp +++ b/model/Database.cpp @@ -1,5 +1,26 @@ #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() { @@ -21,6 +42,7 @@ void Database::CreateDatabase() { std::ifstream init_script; std::string line; + wxString wxline; wxMessageBox(_("No database found, creating a new one"), _("KissCount"), wxICON_EXCLAMATION | wxOK ); @@ -37,18 +59,22 @@ void Database::CreateDatabase() do { getline(init_script, line); - if (!_db.CheckSyntax(line.data())) + 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(line.data()); + _db.ExecuteUpdate(wxline); } catch (...) { wxMessageBox(_("Error creating original database"), _("Error"), wxICON_ERROR | wxOK ); + remove(BDD_FILE); throw line; } } while (init_script); @@ -62,15 +88,8 @@ std::list Database::GetUsers() // Check whether value exists in table wxSQLite3ResultSet set ; - try - { - set = _db.ExecuteQuery(wxT("SELECT name FROM user")); - } - catch (wxSQLite3Exception e) - { - std::cerr << e.GetMessage().mb_str() << "\n" ; - return res; - } + + EXECUTE_SQL_QUERY(_("SELECT name FROM user ORDER BY name"), set, res); while (set.NextRow()) { @@ -97,19 +116,75 @@ bool Database::IsValidUser(wxString user, wxString password) wxSHA += wxString::Format(wxT("%02F"), (int)sha[i]); req = _("SELECT name FROM user WHERE name='") + user + _("' AND password='") + wxSHA + _("'"); - // Check whether value exists in table - try - { - set = _db.ExecuteQuery(req); - } - catch (wxSQLite3Exception e) - { - std::cerr << e.GetMessage().mb_str() << "\n" ; - return false; - } + 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; +} diff --git a/model/Database.h b/model/Database.h index 78252ae..9a0445c 100644 --- a/model/Database.h +++ b/model/Database.h @@ -1,12 +1,15 @@ #ifndef DATABASE_H #define DATABASE_H +#include #include #include #include #include #include +#include "model.h" + #define BDD_FILE "kc.bdd" #define INIT_SCRIPT "init.sql" @@ -17,6 +20,8 @@ class Database std::list GetUsers(); bool IsValidUser(wxString user, wxString password); + + User* LoadUser(wxString name); private: wxSQLite3Database _db; diff --git a/model/Preferences.h b/model/Preferences.h index ada5868..f5a7330 100644 --- a/model/Preferences.h +++ b/model/Preferences.h @@ -6,8 +6,9 @@ class Preferences { -private: - std::map _colors; +public: + std::map _colors; + std::list _categories; }; #endif diff --git a/model/User.cpp b/model/User.cpp new file mode 100644 index 0000000..77f167a --- /dev/null +++ b/model/User.cpp @@ -0,0 +1,21 @@ +#include "User.h" + + +User::~User() +{ + std::map >* >::iterator it; + + while (!_accounts.empty()) + { + delete _accounts.front(); + _accounts.pop_front(); + } + + for (it = _operations.begin(); it != _operations.end(); it++) + { + if (_operations[it->first]) + { + delete it->second; + } + } +} diff --git a/model/User.h b/model/User.h index 9a4db61..59e4ab2 100644 --- a/model/User.h +++ b/model/User.h @@ -4,14 +4,19 @@ #include #include "Account.h" +#include "Preferences.h" class User { -private: - unsigned int _id; +public: + ~User(); + + wxString _id; wxString _name; wxString _password; - std::list _accounts; + std::list _accounts; + std::map >* > _operations; + Preferences _preferences; }; #endif diff --git a/model/model.h b/model/model.h new file mode 100644 index 0000000..e1ac579 --- /dev/null +++ b/model/model.h @@ -0,0 +1,8 @@ +#ifndef MODEL_H +#define MODEL_H + +#include "User.h" +#include "Account.h" +#include "Preferences.h" + +#endif diff --git a/view/UsersDialog.cpp b/view/UsersDialog.cpp index 78895ba..fa78b7a 100644 --- a/view/UsersDialog.cpp +++ b/view/UsersDialog.cpp @@ -29,6 +29,8 @@ UsersDialog::UsersDialog(KissCount* kiss, wxUI *parent) : wxDialog(&(*parent), - _users->Append(*i); } + _users->Select(0); + vbox1->Add(_users); vbox1->Add(-1, 10); vbox1->Add(_password);