From f735aac94db10d72689a89e1f0e9889162b14f4f Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 9 Feb 2025 19:58:55 +0100 Subject: [PATCH] feat: added remaining subcommands, started reworking manager, streamlined Exception types --- .gitignore | 4 + ActiveCommand.cpp | 28 ++++++ ActiveCommand.h | 16 ++++ AddCommand.cpp | 38 ++++++-- AddCommand.h | 1 + AssignCommand.cpp | 34 ++++++++ AssignCommand.h | 16 ++++ Assignment.cpp | 17 ++-- Assignment.h | 3 +- DataType.h | 3 +- DelCommand.cpp | 31 +++++++ DelCommand.h | 16 ++++ Error.h | 32 +++++++ FileError.h | 20 ----- FormatError.h | 20 ----- HelpCommand.cpp | 2 +- HelpCommand.h | 3 +- ListCommand.cpp | 34 ++++++++ ListCommand.h | 16 ++++ Manager.cpp | 208 ++++++++++++++++++++++++++++++-------------- Manager.h | 62 ++++++++----- ShowCommand.cpp | 36 ++++++++ ShowCommand.h | 16 ++++ SubCommand.cpp | 14 ++- SubCommand.h | 26 +++--- Task.cpp | 59 +++++++++++-- Task.h | 32 +++---- UnassignCommand.cpp | 32 +++++++ UnassignCommand.h | 16 ++++ User.cpp | 41 ++++++++- User.h | 15 +++- Util.cpp | 21 +++-- Util.h | 2 + main.cpp | 61 +++++++------ 34 files changed, 760 insertions(+), 215 deletions(-) create mode 100644 ActiveCommand.cpp create mode 100644 ActiveCommand.h create mode 100644 AssignCommand.cpp create mode 100644 AssignCommand.h create mode 100644 DelCommand.cpp create mode 100644 DelCommand.h create mode 100644 Error.h delete mode 100644 FileError.h delete mode 100644 FormatError.h create mode 100644 ListCommand.cpp create mode 100644 ListCommand.h create mode 100644 ShowCommand.cpp create mode 100644 ShowCommand.h create mode 100644 UnassignCommand.cpp create mode 100644 UnassignCommand.h diff --git a/.gitignore b/.gitignore index 9743a70..fdcb1ed 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ !.gitattributes !*/ + +build/ + +**cmake-build-debug/ diff --git a/ActiveCommand.cpp b/ActiveCommand.cpp new file mode 100644 index 0000000..d87042c --- /dev/null +++ b/ActiveCommand.cpp @@ -0,0 +1,28 @@ +#include "ActiveCommand.h" +#include "Error.h" +#include "Manager.h" + +using util::Util; +using util::Manager; +using err::Error; + +namespace commands +{ + ActiveCommand::ActiveCommand() : SubCommand("active", 100, true) + { + } + + void ActiveCommand::run(int argc, stringstream& args) + { + Manager& mgr = Manager::get_instance(); + int user_id; + args >> user_id; + if (!user_id) + throw Error(102, "Ein Parameter eines Befehls konnte nicht gelesen werden"); + User* u = mgr.get_user(user_id); + if (!u) + throw Error(401, "Eine solche BenutzerIn existiert nicht."); + for (Assignment* a : mgr.get_assignments_for_user(user_id)) + cout << a->get_task_id() << "\n"; + } +} // commands diff --git a/ActiveCommand.h b/ActiveCommand.h new file mode 100644 index 0000000..88d3865 --- /dev/null +++ b/ActiveCommand.h @@ -0,0 +1,16 @@ +#pragma once +#include "SubCommand.h" +#ifndef ACTIVECOMMAND_H +#define ACTIVECOMMAND_H + +namespace commands { + + class ActiveCommand : public SubCommand { + public: + ActiveCommand(); + void run(int argc, stringstream& args) override; + }; + +} // commands + +#endif //ACTIVECOMMAND_H diff --git a/AddCommand.cpp b/AddCommand.cpp index c19bb7a..bcb0cec 100644 --- a/AddCommand.cpp +++ b/AddCommand.cpp @@ -1,9 +1,37 @@ #include "AddCommand.h" +#include "Error.h" +#include "Manager.h" -namespace commands { - AddCommand::AddCommand() : SubCommand("add", 100) {} +using util::Manager; +using util::Util; +using models::AddUser; +using models::AddTask; +using err::Error; - void AddCommand::run(int argc, stringstream& args) { - cout << "Add!\n"; +namespace commands +{ + AddCommand::AddCommand() : SubCommand("add", 100, true) + { } -} + + void AddCommand::run(int argc, stringstream& args) + { + const string data_type = Util::read_string(args); + Manager& mgr = Manager::get_instance(); + if (data_type == "user") + { + AddUser u; + args >> u; + mgr.add_user(new User(u)); + } + else if (data_type == "task") + { + AddTask t; + args >> t; + mgr.add_task(new Task(t)); + } + else + throw Error(101, "Befehl ist unbekannt."); + mgr.save(); + } +} // commands diff --git a/AddCommand.h b/AddCommand.h index bef2bd8..dd3730c 100644 --- a/AddCommand.h +++ b/AddCommand.h @@ -1,3 +1,4 @@ +#pragma once #include "std_lib_inc.h" #include "SubCommand.h" #ifndef ADDCOMMAND_H diff --git a/AssignCommand.cpp b/AssignCommand.cpp new file mode 100644 index 0000000..01c6bc7 --- /dev/null +++ b/AssignCommand.cpp @@ -0,0 +1,34 @@ +#include "AssignCommand.h" +#include "Error.h" +#include "Manager.h" + +using util::Util; +using util::Manager; +using err::Error; + +namespace commands +{ + AssignCommand::AssignCommand() : SubCommand("assign", 100, true) + { + } + + void AssignCommand::run(int argc, stringstream& args) + { + Manager& mgr = Manager::get_instance(); + int user_id, task_id; + args >> user_id >> task_id; + if (!args) + throw Error(102, "Ein Parameter eines Befehls konnte nicht gelesen werden"); + const User* u = mgr.get_user(user_id); + if (!u) + throw Error(401, "Eine solche BenutzerIn existiert nicht."); + const Task* t = mgr.get_task(task_id); + if (!t) + throw Error(402, "Eine solche Aufgabe existiert nicht."); + if (mgr.assignment_exists(user_id, task_id)) + throw Error(302, "Eine solche Zuordnung existiert bereits."); + Assignment* a = new Assignment(user_id, task_id); + mgr.add_assignment(a); + mgr.save(); + } +} // commands diff --git a/AssignCommand.h b/AssignCommand.h new file mode 100644 index 0000000..e179e31 --- /dev/null +++ b/AssignCommand.h @@ -0,0 +1,16 @@ +#pragma once +#include "SubCommand.h" +#ifndef ASSIGNCOMMAND_H +#define ASSIGNCOMMAND_H + +namespace commands { + + class AssignCommand : public SubCommand { + public: + AssignCommand(); + void run(int argc, stringstream& args) override; + }; + +} // commands + +#endif //ASSIGNCOMMAND_H diff --git a/Assignment.cpp b/Assignment.cpp index 990a80a..aab5f84 100644 --- a/Assignment.cpp +++ b/Assignment.cpp @@ -1,14 +1,15 @@ #include "Assignment.h" -#include "FormatError.h" +#include "Error.h" -using err::FormatError; +using err::Error; namespace models { Assignment::Assignment(const int& user_id, const int& task_id) : user_id(user_id), task_id(task_id) {} Assignment::Assignment(): user_id(0), task_id(0) {} - ostream& Assignment::write(ostream& stream) { - stream << this; + ostream& Assignment::write(ostream& stream) const + { + stream << *this; return stream; } @@ -21,7 +22,7 @@ namespace models { } ostream& operator<<(ostream& os, const Assignment& t) { - os << t.get_user_id() << " " << t.get_task_id(); + os << t.get_user_id() << " " << t.get_task_id() << "\n"; return os; } @@ -29,12 +30,12 @@ namespace models { int user_id; is >> user_id; if (!is) - throw FormatError("Userid Nan"); + throw Error(602, "Datei hat ein unbekanntes Format."); int task_id; is >> task_id; if (!is) - throw FormatError("Taskid Nan"); + throw Error(602, "Datei hat ein unbekanntes Format."); t = {user_id, task_id}; return is; } -} +} // models diff --git a/Assignment.h b/Assignment.h index 69f0f76..2837caf 100644 --- a/Assignment.h +++ b/Assignment.h @@ -1,3 +1,4 @@ +#pragma once #include "std_lib_inc.h" #ifndef ASSIGNMENT_H #define ASSIGNMENT_H @@ -10,7 +11,7 @@ namespace models { public: Assignment(const int& user_id, const int& task_id); Assignment(); - ostream& write(ostream& stream); + ostream& write(ostream& stream) const; int get_user_id() const; int get_task_id() const; diff --git a/DataType.h b/DataType.h index 40b8667..54dcc1d 100644 --- a/DataType.h +++ b/DataType.h @@ -1,3 +1,4 @@ +#pragma once #include "std_lib_inc.h" #ifndef READINSTATUS_H #define READINSTATUS_H @@ -9,7 +10,7 @@ namespace util { TASK, USERTASKINDEX }; -} +} // util #endif // READINSTATUS_H diff --git a/DelCommand.cpp b/DelCommand.cpp new file mode 100644 index 0000000..5f315d0 --- /dev/null +++ b/DelCommand.cpp @@ -0,0 +1,31 @@ +#include "DelCommand.h" +#include "Error.h" +#include "Manager.h" + +using util::Util; +using util::Manager; +using err::Error; + +namespace commands +{ + DelCommand::DelCommand() : SubCommand("delete", 100, true) + { + } + + void DelCommand::run(int argc, stringstream& args) + { + Manager& mgr = Manager::get_instance(); + const string data_type = Util::read_string(args); + int id; + args >> id; + if (!args) + throw Error(102, "Ein Parameter eines Befehls konnte nicht gelesen werden"); + if (data_type == "user") + mgr.del_user(id); + else if (data_type == "task") + mgr.del_task(id); + else + throw Error(101, "Befehl ist unbekannt."); + mgr.save(); + } +} // commands diff --git a/DelCommand.h b/DelCommand.h new file mode 100644 index 0000000..a0d889c --- /dev/null +++ b/DelCommand.h @@ -0,0 +1,16 @@ +#pragma once +#ifndef DELCOMMAND_H +#define DELCOMMAND_H +#include "SubCommand.h" + +namespace commands { + + class DelCommand : public SubCommand { + public: + DelCommand(); + void run(int argc, stringstream& args) override; + }; + +} // commands + +#endif //DELCOMMAND_H diff --git a/Error.h b/Error.h new file mode 100644 index 0000000..c781346 --- /dev/null +++ b/Error.h @@ -0,0 +1,32 @@ +#pragma once +#include "std_lib_inc.h" +#include +#ifndef FILEERROR_H +#define FILEERROR_H + +namespace err +{ + class Error final : public exception + { + private: + string why; + int return_no; + + public: + Error(const int& return_no, const string& msg) : exception(), why(msg), return_no(return_no) + { + } + + int get_nr() const + { + return this->return_no; + } + + string what() + { + return this->why; + } + }; +} // err + +#endif // FILEERROR_H diff --git a/FileError.h b/FileError.h deleted file mode 100644 index 4505ff9..0000000 --- a/FileError.h +++ /dev/null @@ -1,20 +0,0 @@ -#include "std_lib_inc.h" -#include -#ifndef FILEERROR_H -#define FILEERROR_H - -namespace err { - class FileError : public exception { - private: - string what; - - public: - FileError(const string& msg) : exception(), what(msg) {} - string why() { - return this->what; - } - }; -} - -#endif // FILEERROR_H - diff --git a/FormatError.h b/FormatError.h deleted file mode 100644 index 95078cc..0000000 --- a/FormatError.h +++ /dev/null @@ -1,20 +0,0 @@ -#include "std_lib_inc.h" -#include -#ifndef FORMATERROR_H -#define FORMATERROR_H - -namespace err { - class FormatError : public exception { - private: - string what; - - public: - FormatError(const string& msg) : exception(), what(msg) {} - string why() { - return this->what; - } - }; -} - -#endif // FORMATERROR_H - diff --git a/HelpCommand.cpp b/HelpCommand.cpp index 96e713d..9148a24 100644 --- a/HelpCommand.cpp +++ b/HelpCommand.cpp @@ -1,7 +1,7 @@ #include "HelpCommand.h" namespace commands { - HelpCommand::HelpCommand(): SubCommand("help", 100) {} + HelpCommand::HelpCommand(): SubCommand("help", 100, false) {} void HelpCommand::run(int argc, stringstream& args) { cout << "Projekt 5\n"; diff --git a/HelpCommand.h b/HelpCommand.h index 910a91f..6c56847 100644 --- a/HelpCommand.h +++ b/HelpCommand.h @@ -1,3 +1,4 @@ +#pragma once #include "std_lib_inc.h" #include "SubCommand.h" #ifndef HELPCOMMAND_H @@ -9,6 +10,6 @@ namespace commands { HelpCommand(); void run(int argc, stringstream& args) override; }; -} +} // commands #endif // HELPCOMMAND_H diff --git a/ListCommand.cpp b/ListCommand.cpp new file mode 100644 index 0000000..b74a50c --- /dev/null +++ b/ListCommand.cpp @@ -0,0 +1,34 @@ +#include "ListCommand.h" + +#include "Error.h" +#include "Manager.h" + +using util::Manager; +using models::User; +using models::Task; +using models::Assignment; +using err::Error; + +namespace commands +{ + ListCommand::ListCommand() : SubCommand("list", 100, true) + { + } + + void ListCommand::run(int argc, stringstream& args) + { + Manager& mgr = Manager::get_instance(); + const string data_type = Util::read_string(args); + if (data_type == "user") + for (User* u : mgr.get_users()) + cout << *u; + else if (data_type == "task") + for (Task* t : mgr.get_tasks()) + cout << *t; + else if (data_type == "assignment") + for (Assignment* a : mgr.get_assignments()) + cout << *a; + else + throw Error(101, "Befehl ist unbekannt."); + } +} // commands diff --git a/ListCommand.h b/ListCommand.h new file mode 100644 index 0000000..393ce9a --- /dev/null +++ b/ListCommand.h @@ -0,0 +1,16 @@ +#pragma once +#ifndef LISTCOMMAND_H +#define LISTCOMMAND_H +#include "SubCommand.h" + +namespace commands { + +class ListCommand : public SubCommand{ +public: + ListCommand(); + void run(int argc, stringstream& args) override; +}; + +} // commands + +#endif //LISTCOMMAND_H diff --git a/Manager.cpp b/Manager.cpp index 458a3ed..88094bd 100644 --- a/Manager.cpp +++ b/Manager.cpp @@ -1,107 +1,187 @@ #include "Manager.h" -#include "FileError.h" +#include "Error.h" #include +#include "DataType.h" -using err::FileError; +using err::Error; using util::DataType; -namespace util { - Manager::Manager(): users({}), tasks({}), user_task_index({}), filename("tasks") { - ifstream in (this->filename); +namespace util +{ + Manager::Manager(): users({}), tasks({}), assignments({}), user_id_index(0), task_id_index(0), filename("tasks") + { + //Open File + ifstream in(this->filename, ios_base::in); if (!in) { - // throw FileError("Could not open file input stream!"); this->save(); in.clear(); in.open(this->filename); if (!in) - throw FileError("Could not open file input stream!"); + throw Error(601, "Datei kann nicht geöffnet werden."); } + map> buffer; DataType current_type = DataType::INIT; - string d; + string d; // dump char c; - while(true) { - in >> c; - if (in.eof() || c == EOF) - break; - if (c == '\n') + string line, section; + //Parse all Lines until EOF + while (getline(in, line)) + { + // Check if the line starts with '[' + if (!line.empty() && line[0] == '[') { - in >> d; - continue; - } - if (c == '['){ - switch (current_type) - { - case DataType::INIT: + if (line == "[tasks]") current_type = DataType::TASK; - break; - case DataType::TASK: + else if (line == "[users]") current_type = DataType::USER; - break; - case DataType::USER: + else if (line == "[assignments]") current_type = DataType::USERTASKINDEX; - break; - case DataType::USERTASKINDEX: - break; // This should not happen. There is nothing after [assignments] - } - in >> d; + else + throw Error(602, "Datei hat ein unbekanntes Format."); continue; } - in.putback(c); - switch (current_type) { - case DataType::INIT: - break; + //Lehre Zeilen überspringen. + if (line.empty()) + continue; + //Speichern im Buffer + buffer[current_type].push_back(line); + } //Data is parsed + in.close(); + + // Reihenfolge der Verabeitung + vector sections = {DataType::USER, DataType::TASK, DataType::USERTASKINDEX}; + for (DataType type : sections) + { + // Keine Data -> Continue + if (buffer.find(type) == buffer.end()) continue; + const vector& lines = buffer[type]; + //Iteriere über die Gebufferten Strings. + for (const string& bufferd_line : lines) + { + switch (type) + { case DataType::TASK: { - Task t; - in >> t; - this->tasks.push_back(t); + Task task; + in >> task; + this->tasks[task.get_id()] = new Task(task); } break; case DataType::USER: { - User u; - in >> u; - this->users.push_back(u); + User user; + in >> user; + this->users[user.get_id()] = new User(user); } break; case DataType::USERTASKINDEX: { - Assignment a; - in >> a; - this->user_task_index.push_back(a); + Assignment assignment; + in >> assignment; + this->assignments.push_back(new Assignment(assignment)); } break; + default: + break; + } } } - in.close(); + this->update_indexes(); } - void Manager::save() { - ofstream out = ofstream(this->filename); + void Manager::update_user_id_index() + { + int i = 0; + for (const auto& user_pair : this->users) + if (user_pair.second && user_pair.second->get_id() >= i) + i = user_pair.second->get_id() + 1; + this->user_id_index = i; + } + + void Manager::update_task_id_index() + { + int i = 0; + for (const auto& task_pair : this->users) + if (task_pair.second && task_pair.second->get_id() >= i) + i = task_pair.second->get_id() + 1; + this->task_id_index = i; + } + + void Manager::update_indexes() + { + this->update_user_id_index(); + this->update_task_id_index(); + } + + int Manager::get_user_id() + { + int value = this->user_id_index; + ++this->user_id_index; + return value; + } + + int Manager::get_task_id() + { + int value = this->task_id_index; + ++this->task_id_index; + return value; + } + + Manager* Manager::INSTANCE; + + Manager& Manager::get_instance() + { + if (!INSTANCE) + INSTANCE = new Manager(); + return *INSTANCE; + } + vector const Manager::get_users() { + vector user_vector; + for (const auto& pair : this->users) { + if (pair.second) { // Ensure it's not a nullptr + user_vector.push_back(pair.second); + } + } + return user_vector; + + }; + vector get_tasks(); + vector get_assignments(); + void Manager::save() + { + ofstream out = ofstream(this->filename, ios_base::trunc); if (!out) - throw FileError("Could not open file output stream!"); + throw Error(603, "Datei kann nicht geschrieben werden."); out << "[tasks]\n"; - for (Task& t : this->tasks) - t.write(out); + for (const auto& task_pair : this->users) + { + //Nullpointer Check + if (task_pair.second) + { + task_pair.second->write(out); + } + } out << "\n[users]\n"; - for (User& u : this->users) - u.write(out); + for (const auto& user_pair : this->users) + { + //Nullpointer Check + if (user_pair.second) + { + user_pair.second->write(out); + } + } + out << "\n[assignments]\n"; - for (Assignment& uti: this->user_task_index) - uti.write(out); + for (Assignment* assignment : this->assignments) + { + //Nullpointer Check + if (assignment) + { + assignment->write(out); + } + } out.close(); } - vector Manager::get_users() const { - return this->users; - } - - vector Manager::get_task() const { - return this->tasks; - } - - vector Manager::get_user_task_index() const { - return this->user_task_index; - } -} +} // util diff --git a/Manager.h b/Manager.h index 98e9eb9..797431c 100644 --- a/Manager.h +++ b/Manager.h @@ -1,8 +1,8 @@ +#pragma once #include "std_lib_inc.h" #include "User.h" #include "Task.h" #include "Assignment.h" -#include "DataType.h" #ifndef ENVIRONMENT_H #define ENVIRONMENT_H @@ -10,27 +10,49 @@ using models::User; using models::Task; using models::Assignment; -namespace util { - class Manager { - private: - vector users; - vector tasks; - vector user_task_index; - string filename; +namespace util +{ + class Manager + { + private: + static Manager* INSTANCE; - public: - Manager(); + map users; + map tasks; + vector assignments; + int user_id_index; + int task_id_index; - void save(); + string filename; - vector get_users() const; - vector get_task() const; - vector get_user_task_index() const; + Manager(); + void update_user_id_index(); + void update_task_id_index(); + + public: + static Manager& get_instance(); + + void save(); + void update_indexes(); + int get_user_id(); + int get_task_id(); + + vector get_users(); + vector get_tasks(); + vector get_assignments(); + + User* get_user(const int& id); + Task* get_task(const int& id); + vector get_assignments_for_user(const int& id); + bool assignment_exists(const int& user_id, const int& task_id); + + void add_user(const User* user); + void add_task(const Task* task); + void add_assignment(const Assignment* as); + + void del_user(const int& id); + void del_task(const int& id); + void del_assignment(const Assignment& as); }; - - - inline DataType operator++(DataType& status); -} - +} // util #endif // ENVIRONMENT_H - diff --git a/ShowCommand.cpp b/ShowCommand.cpp new file mode 100644 index 0000000..223e68f --- /dev/null +++ b/ShowCommand.cpp @@ -0,0 +1,36 @@ +#include "ShowCommand.h" + +#include "Error.h" +#include "Util.h" +#include "Manager.h" + +using util::Manager; +using util::Util; +using models::AddUser; +using models::AddTask; +using err::Error; + +namespace commands +{ + ShowCommand::ShowCommand() : SubCommand("show", 100, false) + { + } + + void ShowCommand::run(int argc, stringstream& args) + { + Manager& mgr = Manager::get_instance(); + const string data_type = Util::read_string(args); + if (data_type == "user") + for (User* u : mgr.get_users()) { + AddUser au = {*u}; + cout << au; + } + else if (data_type == "task") + for (Task* t : mgr.get_tasks()) { + AddTask at = {*t}; + cout << at; + } + else + throw Error(101, "Befehl ist unbekannt."); + } +} // commands diff --git a/ShowCommand.h b/ShowCommand.h new file mode 100644 index 0000000..5b02372 --- /dev/null +++ b/ShowCommand.h @@ -0,0 +1,16 @@ +#pragma once +#include "SubCommand.h" +#ifndef SHOWCOMMAND_H +#define SHOWCOMMAND_H + +namespace commands { + + class ShowCommand : public SubCommand { + public: + ShowCommand(); + void run(int argc, stringstream& args) override; + }; + +} // commands + +#endif //SHOWCOMMAND_H diff --git a/SubCommand.cpp b/SubCommand.cpp index 6e39e2a..3d47485 100644 --- a/SubCommand.cpp +++ b/SubCommand.cpp @@ -2,7 +2,7 @@ #include namespace commands { - SubCommand::SubCommand(const string& name, const int& return_value): name(name), return_value(return_value) {} + SubCommand::SubCommand(const string& name, const int& return_value, const bool show_result): name(name), return_value(return_value), show_result(show_result) {} void SubCommand::run(int argc, stringstream& args) { cout << "Not impl!\n"; @@ -11,4 +11,14 @@ namespace commands { string SubCommand::get_name() { return this->name; } -} + + int SubCommand::get_value() const { + return this->return_value; + } + + bool SubCommand::should_display_result() const + { + return this->show_result; + } + +} // commands diff --git a/SubCommand.h b/SubCommand.h index 4f85771..d1f20b9 100644 --- a/SubCommand.h +++ b/SubCommand.h @@ -1,20 +1,26 @@ +#pragma once #include "std_lib_inc.h" -#include "parameter_reader.h" #ifndef SUBCOMMAND_H #define SUBCOMMAND_H -namespace commands { - class SubCommand { +namespace commands +{ + class SubCommand + { + private: string name; + bool show_result; + + protected: int return_value; - public: - SubCommand(const string& indicator, const int& value); - string get_name(); - int get_value(); - virtual void run(int argc, stringstream& args); + public: + SubCommand(const string& indicator, const int& value, const bool show_result); + string get_name(); + int get_value() const; + bool should_display_result() const; + virtual void run(int argc, stringstream& args); }; -} +} // commands #endif // SUBCOMMAND_H - diff --git a/Task.cpp b/Task.cpp index 4c03f8e..a5738a4 100644 --- a/Task.cpp +++ b/Task.cpp @@ -1,17 +1,20 @@ #include "Task.h" #include "Util.h" -#include "FormatError.h" +#include "Manager.h" +#include "Error.h" -using err::FormatError; +using err::Error; using util::Util; +using util::Manager; namespace models { Task::Task(const int& id, const string& name, const string& description, const vector& children): id(id), name(name), description(description), children(children) {} Task::Task(): id(0), name(""), description(""), children({}) {} - ostream& Task::write(ostream& stream) { - stream << this; + ostream& Task::write(ostream& stream) const + { + stream << *this; return stream; } @@ -30,5 +33,51 @@ namespace models { vector Task::get_children() const { return this->children; } + + AddTask::AddTask(): Task() {} + AddTask::AddTask(Task& t): Task(t) {} -} + ostream& operator<<(ostream& os, const Task& t) { + os << t.get_id() << " %" << t.get_name() << "% %" << t.get_description() << "%\n"; + return os; + } + + istream& operator>>(istream& is, Task& t) { + int id; + is >> id; + if (!is) + throw Error(602, "Datei hat ein unbekanntes Format."); + + try { + string name = Util::read_string_between_percent(is); + string description = Util::read_string_between_percent(is); + vector children = Util::read_numbers(is); + t = {id, name, description, children}; + return is; + } catch (Error& _) { + throw Error(602, "Datei hat ein unbekanntes Format."); + } + } + + ostream& operator<<(ostream& os, const AddTask& t) { + os << t.get_name() << " " << t.get_description() << "\n"; + return os; + } + + istream& operator>>(istream& is, AddTask& t) { + Manager& mgr = Manager::get_instance(); + int id = mgr.get_task_id(); + + try { + const string name = Util::read_string_between_percent(is); + const string description = Util::read_string_between_percent(is); + const vector children = Util::read_numbers(is); + Task ft = {id, name, description, children}; + + t = {ft}; + return is; + } catch (Error& _) { + throw Error(102, "Ein Parameter eines Befehls konnte nicht gelesen werden"); + } + } +} // models diff --git a/Task.h b/Task.h index 8d5cfad..8fa5963 100644 --- a/Task.h +++ b/Task.h @@ -1,10 +1,9 @@ +#pragma once #include "std_lib_inc.h" -#include "FormatError.h" #include "Util.h" #ifndef TASK_H #define TASK_H -using err::FormatError; using util::Util; namespace models { @@ -19,7 +18,7 @@ namespace models { Task(); - ostream& write(ostream& stream); + ostream& write(ostream& stream) const; istream& read(istream&); int get_id() const; @@ -32,23 +31,20 @@ namespace models { friend istream& operator>>(istream& is, Task& t); }; - inline ostream& operator<<(ostream& os, const Task& t) { - os << t.get_id() << " " << t.get_name() << " " << t.get_description(); - return os; - } - inline istream& operator>>(istream& is, Task& t) { - int id; - is >> id; - if (!is) - throw FormatError("Id NaN."); + class AddTask : public Task{ + private: + public: + AddTask(); + AddTask(Task& t); - string name = Util::read_string_between_percent(is); - string description = Util::read_string_between_percent(is); - vector children = Util::read_numbers(is); + friend ostream& operator<<(ostream& os, const AddTask& t); + friend istream& operator>>(istream& is, AddTask& t); + }; + ostream& operator<<(ostream& os, const AddTask& t); + istream& operator>>(istream& is, AddTask& t); - t = {id, name, description, children}; - return is; - } + ostream& operator<<(ostream& os, const Task& t); + istream& operator>>(istream& is, Task& t); } #endif // TASK_H diff --git a/UnassignCommand.cpp b/UnassignCommand.cpp new file mode 100644 index 0000000..38364f1 --- /dev/null +++ b/UnassignCommand.cpp @@ -0,0 +1,32 @@ +#include "UnassignCommand.h" +#include "Error.h" +#include "Manager.h" + +using util::Manager; +using err::Error; + +namespace commands +{ + UnassignCommand::UnassignCommand() : SubCommand("unassign", 100, true) + { + } + + void UnassignCommand::run(int argc, stringstream& args) + { + Manager& mgr = Manager::get_instance(); + int user_id, task_id; + args >> user_id >> task_id; + if (!args) + throw Error(102, "Ein Parameter eines Befehls konnte nicht gelesen werden"); + const User* u = mgr.get_user(user_id); + if (!u) + throw Error(401, "Eine solche BenutzerIn existiert nicht."); + const Task* t = mgr.get_task(task_id); + if (!t) + throw Error(401, "Eine solche Zuordnung existiert nicht."); + if (!mgr.assignment_exists(user_id, task_id)) + throw Error(302, "Eine solche Zuordnung existiert bereits."); + mgr.del_assignment({user_id, task_id}); + mgr.save(); + } +} // commands diff --git a/UnassignCommand.h b/UnassignCommand.h new file mode 100644 index 0000000..13abdb0 --- /dev/null +++ b/UnassignCommand.h @@ -0,0 +1,16 @@ +#pragma once +#include "SubCommand.h" +#ifndef UNASSIGNCOMMAND_H +#define UNASSIGNCOMMAND_H + +namespace commands { + + class UnassignCommand : public SubCommand { + public: + UnassignCommand(); + void run(int argc, stringstream& args) override; + }; + +} // commands + +#endif //UNASSIGNCOMMAND_H diff --git a/User.cpp b/User.cpp index 649180b..0f6c812 100644 --- a/User.cpp +++ b/User.cpp @@ -1,12 +1,18 @@ #include "User.h" +#include "Error.h" +#include "Manager.h" + +using util::Manager; +using err::Error; + namespace models { User::User(const int& id, const string& name, const string& surname): id(id), name(name), surname(surname) {} User::User(): id(0), name(""), surname("") {} ostream& User::write(ostream& stream) { - stream << this; + stream << *this; return stream; } @@ -21,10 +27,15 @@ namespace models { string User::get_surname() const { return this->surname; } + + + AddUser::AddUser(): User() {} + + AddUser::AddUser(User& u): User(u) {} ostream& operator<<(ostream& os, const User& u) { - os << u.get_id() << " " << u.get_name() << " " << u.get_surname(); + os << u.get_id() << " " << u.get_name() << " " << u.get_surname() << "\n"; return os; } @@ -33,12 +44,34 @@ namespace models { int id; is >> id; if (!is) - throw FormatError("User id NaN."); + throw Error(602, "Datei hat ein unbekanntes Format."); + string name, surname; is >> name >> surname; if (!is) - throw FormatError("Could not read user name and surname"); + throw Error(602, "Datei hat ein unbekanntes Format."); + u = {id, name, surname}; return is; } + + ostream& operator<<(ostream& os, const AddUser& u) { + os << u.get_name() << " " << u.get_surname(); + return os; + } + + + istream& operator>>(istream& is, AddUser& u) { + Manager& mgr = Manager::get_instance(); + int id = mgr.get_user_id(); + + string name, surname; + is >> name >> surname; + if (!is) + throw Error(602, "Could not read user name and surname"); + + User ut = {id, name, surname}; + u = {ut}; + return is; + } } diff --git a/User.h b/User.h index c69203a..26e612e 100644 --- a/User.h +++ b/User.h @@ -1,10 +1,9 @@ +#pragma once #include "std_lib_inc.h" -#include "FormatError.h" #include "Util.h" #ifndef USER_H #define USER_H -using err::FormatError; using util::Util; namespace models { @@ -27,8 +26,20 @@ namespace models { friend istream& operator>>(istream& is, User& u); }; + class AddUser : public User { + private: + public: + AddUser(); + AddUser(User& u); + friend ostream& operator<<(ostream& os, const AddUser& u); + friend istream& operator>>(istream& is, AddUser& u); + }; + ostream& operator<<(ostream& os, const User& u); istream& operator>>(istream& is, User& u); + + ostream& operator<<(ostream& os, const AddUser& u); + istream& operator>>(istream& is, AddUser& u); } #endif // USER_H diff --git a/Util.cpp b/Util.cpp index b7c97e6..d45bf65 100644 --- a/Util.cpp +++ b/Util.cpp @@ -1,10 +1,9 @@ #include "Util.h" -#include "FormatError.h" -#include +#include "Error.h" #include #include -using err::FormatError; +using err::Error; namespace util { string Util::read_string_between_percent(istream& is) { @@ -16,7 +15,7 @@ namespace util { while (true) { is >> c; if (!is) - throw FormatError("Could not read char!"); + throw Error(700, "Could not read char!"); if (c == '%') { read = !read; break; @@ -35,14 +34,14 @@ namespace util { string until_eol; getline(is, until_eol); - vector numbers_as_string = Util::split(until_eol); + vector numbers_as_string = split(until_eol); vector nums; try { for(string s : numbers_as_string) nums.push_back(stoi(s)); } catch (exception& _) { - throw FormatError("Could not convert string to int"); + throw Error(700, "Could not convert string to int."); } return nums; @@ -65,4 +64,12 @@ namespace util { return strs; } -} + + string Util::read_string(istream &s) { + string result; + s >> result; + if (!s) + throw Error(700, "Could not read stream from stream!"); + return result; + } +} // util diff --git a/Util.h b/Util.h index 7806cc4..4cd3622 100644 --- a/Util.h +++ b/Util.h @@ -1,3 +1,4 @@ +#pragma once #include "std_lib_inc.h" #ifndef UTIL_H #define UTIL_H @@ -8,6 +9,7 @@ namespace util { static string read_string_between_percent(istream& is); static vector read_numbers(istream& is); static vector split(const string& s); + static string read_string(istream& s); }; } diff --git a/main.cpp b/main.cpp index feee681..70ad143 100644 --- a/main.cpp +++ b/main.cpp @@ -1,26 +1,39 @@ +#pragma once +#include "ActiveCommand.h" #include "std_lib_inc.h" #include "parameter_reader.h" -#include "SubCommand.h" #include "HelpCommand.h" #include "AddCommand.h" -#include "User.h" -#include "Manager.h" -#include - -#include "FileError.h" +#include "AssignCommand.h" +#include "DelCommand.h" +#include "Error.h" +#include "ListCommand.h" +#include "UnassignCommand.h" using commands::SubCommand; using commands::HelpCommand; using commands::AddCommand; -using util::Manager; -using err::FileError; -using err::FormatError; +using commands::ListCommand; +using commands::DelCommand; +using commands::AssignCommand; +using commands::UnassignCommand; +using commands::ActiveCommand; +using err::Error; -const vector handlers = { new HelpCommand(), new AddCommand() }; +const vector handlers = { + new HelpCommand(), + new AddCommand(), + new ListCommand(), + new DelCommand(), + new AssignCommand(), + new UnassignCommand(), + new ActiveCommand(), +}; int main(int argc, char** argv) { - if (argc < 2) { + if (argc < 2) + { cout << "There are not enough args!\n"; return 0; } @@ -29,25 +42,21 @@ int main(int argc, char** argv) string command; parameter >> command; - try { - for (SubCommand* sc : handlers) { - if (sc->get_name() == command) { + try + { + for (SubCommand* sc : handlers) + { + if (sc->get_name() == command) + { sc->run(argc, parameter); - return sc->get_value(); + return 0; } } } - catch (FormatError& e) { - cout << e.why() << "\n"; - } - catch (FileError& e) + catch (Error& e) { - cout << e.why() << "\n"; + cout << e.get_nr() << ": " << e.what() << "\n"; } - catch (exception& e) { - cout << e.what() << "\n"; - } - return 101; + cout << "101: Befehl ist unbekannt.\n"; + return 0; } - -