feat: added remaining subcommands, started reworking manager, streamlined Exception types

This commit is contained in:
moonleay 2025-02-09 19:58:55 +01:00
parent 757a5c123f
commit f735aac94d
Signed by: moonleay
GPG key ID: 82667543CCD715FB
34 changed files with 760 additions and 215 deletions

4
.gitignore vendored
View file

@ -10,3 +10,7 @@
!.gitattributes !.gitattributes
!*/ !*/
build/
**cmake-build-debug/

28
ActiveCommand.cpp Normal file
View file

@ -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

16
ActiveCommand.h Normal file
View file

@ -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

View file

@ -1,9 +1,37 @@
#include "AddCommand.h" #include "AddCommand.h"
#include "Error.h"
#include "Manager.h"
namespace commands { using util::Manager;
AddCommand::AddCommand() : SubCommand("add", 100) {} using util::Util;
using models::AddUser;
using models::AddTask;
using err::Error;
void AddCommand::run(int argc, stringstream& args) { namespace commands
cout << "Add!\n"; {
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

View file

@ -1,3 +1,4 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#include "SubCommand.h" #include "SubCommand.h"
#ifndef ADDCOMMAND_H #ifndef ADDCOMMAND_H

34
AssignCommand.cpp Normal file
View file

@ -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

16
AssignCommand.h Normal file
View file

@ -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

View file

@ -1,14 +1,15 @@
#include "Assignment.h" #include "Assignment.h"
#include "FormatError.h" #include "Error.h"
using err::FormatError; using err::Error;
namespace models { namespace models {
Assignment::Assignment(const int& user_id, const int& task_id) : user_id(user_id), task_id(task_id) {} 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) {} Assignment::Assignment(): user_id(0), task_id(0) {}
ostream& Assignment::write(ostream& stream) { ostream& Assignment::write(ostream& stream) const
stream << this; {
stream << *this;
return stream; return stream;
} }
@ -21,7 +22,7 @@ namespace models {
} }
ostream& operator<<(ostream& os, const Assignment& t) { 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; return os;
} }
@ -29,12 +30,12 @@ namespace models {
int user_id; int user_id;
is >> user_id; is >> user_id;
if (!is) if (!is)
throw FormatError("Userid Nan"); throw Error(602, "Datei hat ein unbekanntes Format.");
int task_id; int task_id;
is >> task_id; is >> task_id;
if (!is) if (!is)
throw FormatError("Taskid Nan"); throw Error(602, "Datei hat ein unbekanntes Format.");
t = {user_id, task_id}; t = {user_id, task_id};
return is; return is;
} }
} } // models

View file

@ -1,3 +1,4 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#ifndef ASSIGNMENT_H #ifndef ASSIGNMENT_H
#define ASSIGNMENT_H #define ASSIGNMENT_H
@ -10,7 +11,7 @@ namespace models {
public: public:
Assignment(const int& user_id, const int& task_id); Assignment(const int& user_id, const int& task_id);
Assignment(); Assignment();
ostream& write(ostream& stream); ostream& write(ostream& stream) const;
int get_user_id() const; int get_user_id() const;
int get_task_id() const; int get_task_id() const;

View file

@ -1,3 +1,4 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#ifndef READINSTATUS_H #ifndef READINSTATUS_H
#define READINSTATUS_H #define READINSTATUS_H
@ -9,7 +10,7 @@ namespace util {
TASK, TASK,
USERTASKINDEX USERTASKINDEX
}; };
} } // util
#endif // READINSTATUS_H #endif // READINSTATUS_H

31
DelCommand.cpp Normal file
View file

@ -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

16
DelCommand.h Normal file
View file

@ -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

32
Error.h Normal file
View file

@ -0,0 +1,32 @@
#pragma once
#include "std_lib_inc.h"
#include <exception>
#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

View file

@ -1,20 +0,0 @@
#include "std_lib_inc.h"
#include <exception>
#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

View file

@ -1,20 +0,0 @@
#include "std_lib_inc.h"
#include <exception>
#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

View file

@ -1,7 +1,7 @@
#include "HelpCommand.h" #include "HelpCommand.h"
namespace commands { namespace commands {
HelpCommand::HelpCommand(): SubCommand("help", 100) {} HelpCommand::HelpCommand(): SubCommand("help", 100, false) {}
void HelpCommand::run(int argc, stringstream& args) { void HelpCommand::run(int argc, stringstream& args) {
cout << "Projekt 5\n"; cout << "Projekt 5\n";

View file

@ -1,3 +1,4 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#include "SubCommand.h" #include "SubCommand.h"
#ifndef HELPCOMMAND_H #ifndef HELPCOMMAND_H
@ -9,6 +10,6 @@ namespace commands {
HelpCommand(); HelpCommand();
void run(int argc, stringstream& args) override; void run(int argc, stringstream& args) override;
}; };
} } // commands
#endif // HELPCOMMAND_H #endif // HELPCOMMAND_H

34
ListCommand.cpp Normal file
View file

@ -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

16
ListCommand.h Normal file
View file

@ -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

View file

@ -1,107 +1,187 @@
#include "Manager.h" #include "Manager.h"
#include "FileError.h" #include "Error.h"
#include <fstream> #include <fstream>
#include "DataType.h"
using err::FileError; using err::Error;
using util::DataType; using util::DataType;
namespace util { namespace util
Manager::Manager(): users({}), tasks({}), user_task_index({}), filename("tasks") { {
ifstream in (this->filename); 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) if (!in)
{ {
// throw FileError("Could not open file input stream!");
this->save(); this->save();
in.clear(); in.clear();
in.open(this->filename); in.open(this->filename);
if (!in) if (!in)
throw FileError("Could not open file input stream!"); throw Error(601, "Datei kann nicht geöffnet werden.");
} }
map<DataType, vector<string>> buffer;
DataType current_type = DataType::INIT; DataType current_type = DataType::INIT;
string d; string d; // dump
char c; char c;
while(true) { string line, section;
in >> c; //Parse all Lines until EOF
if (in.eof() || c == EOF) while (getline(in, line))
break;
if (c == '\n')
{ {
in >> d; // Check if the line starts with '['
continue; if (!line.empty() && line[0] == '[')
}
if (c == '['){
switch (current_type)
{ {
case DataType::INIT: if (line == "[tasks]")
current_type = DataType::TASK; current_type = DataType::TASK;
break; else if (line == "[users]")
case DataType::TASK:
current_type = DataType::USER; current_type = DataType::USER;
break; else if (line == "[assignments]")
case DataType::USER:
current_type = DataType::USERTASKINDEX; current_type = DataType::USERTASKINDEX;
break; else
case DataType::USERTASKINDEX: throw Error(602, "Datei hat ein unbekanntes Format.");
break; // This should not happen. There is nothing after [assignments]
}
in >> d;
continue; continue;
} }
in.putback(c); //Lehre Zeilen überspringen.
switch (current_type) { if (line.empty())
case DataType::INIT: continue;
break; //Speichern im Buffer
buffer[current_type].push_back(line);
} //Data is parsed
in.close();
// Reihenfolge der Verabeitung
vector<DataType> sections = {DataType::USER, DataType::TASK, DataType::USERTASKINDEX};
for (DataType type : sections)
{
// Keine Data -> Continue
if (buffer.find(type) == buffer.end()) continue;
const vector<string>& lines = buffer[type];
//Iteriere über die Gebufferten Strings.
for (const string& bufferd_line : lines)
{
switch (type)
{
case DataType::TASK: case DataType::TASK:
{ {
Task t; Task task;
in >> t; in >> task;
this->tasks.push_back(t); this->tasks[task.get_id()] = new Task(task);
} }
break; break;
case DataType::USER: case DataType::USER:
{ {
User u; User user;
in >> u; in >> user;
this->users.push_back(u); this->users[user.get_id()] = new User(user);
} }
break; break;
case DataType::USERTASKINDEX: case DataType::USERTASKINDEX:
{ {
Assignment a; Assignment assignment;
in >> a; in >> assignment;
this->user_task_index.push_back(a); this->assignments.push_back(new Assignment(assignment));
} }
break; break;
default:
break;
} }
} }
in.close(); }
this->update_indexes();
} }
void Manager::save() { void Manager::update_user_id_index()
ofstream out = ofstream(this->filename); {
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<User*> const Manager::get_users() {
vector<User*> 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<Task*> get_tasks();
vector<Assignment*> get_assignments();
void Manager::save()
{
ofstream out = ofstream(this->filename, ios_base::trunc);
if (!out) if (!out)
throw FileError("Could not open file output stream!"); throw Error(603, "Datei kann nicht geschrieben werden.");
out << "[tasks]\n"; out << "[tasks]\n";
for (Task& t : this->tasks) for (const auto& task_pair : this->users)
t.write(out); {
//Nullpointer Check
if (task_pair.second)
{
task_pair.second->write(out);
}
}
out << "\n[users]\n"; out << "\n[users]\n";
for (User& u : this->users) for (const auto& user_pair : this->users)
u.write(out); {
//Nullpointer Check
if (user_pair.second)
{
user_pair.second->write(out);
}
}
out << "\n[assignments]\n"; out << "\n[assignments]\n";
for (Assignment& uti: this->user_task_index) for (Assignment* assignment : this->assignments)
uti.write(out); {
//Nullpointer Check
if (assignment)
{
assignment->write(out);
}
}
out.close(); out.close();
} }
vector<User> Manager::get_users() const { } // util
return this->users;
}
vector<Task> Manager::get_task() const {
return this->tasks;
}
vector<Assignment> Manager::get_user_task_index() const {
return this->user_task_index;
}
}

View file

@ -1,8 +1,8 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#include "User.h" #include "User.h"
#include "Task.h" #include "Task.h"
#include "Assignment.h" #include "Assignment.h"
#include "DataType.h"
#ifndef ENVIRONMENT_H #ifndef ENVIRONMENT_H
#define ENVIRONMENT_H #define ENVIRONMENT_H
@ -10,27 +10,49 @@ using models::User;
using models::Task; using models::Task;
using models::Assignment; using models::Assignment;
namespace util { namespace util
class Manager { {
class Manager
{
private: private:
vector<User> users; static Manager* INSTANCE;
vector<Task> tasks;
vector<Assignment> user_task_index; map<int, User*> users;
map<int, Task*> tasks;
vector<Assignment*> assignments;
int user_id_index;
int task_id_index;
string filename; string filename;
public:
Manager(); Manager();
void update_user_id_index();
void update_task_id_index();
public:
static Manager& get_instance();
void save(); void save();
void update_indexes();
int get_user_id();
int get_task_id();
vector<User> get_users() const; vector<User*> get_users();
vector<Task> get_task() const; vector<Task*> get_tasks();
vector<Assignment> get_user_task_index() const; vector<Assignment*> get_assignments();
User* get_user(const int& id);
Task* get_task(const int& id);
vector<Assignment*> 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);
}; };
} // util
inline DataType operator++(DataType& status);
}
#endif // ENVIRONMENT_H #endif // ENVIRONMENT_H

36
ShowCommand.cpp Normal file
View file

@ -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

16
ShowCommand.h Normal file
View file

@ -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

View file

@ -2,7 +2,7 @@
#include <sstream> #include <sstream>
namespace commands { 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) { void SubCommand::run(int argc, stringstream& args) {
cout << "Not impl!\n"; cout << "Not impl!\n";
@ -11,4 +11,14 @@ namespace commands {
string SubCommand::get_name() { string SubCommand::get_name() {
return this->name; return this->name;
} }
}
int SubCommand::get_value() const {
return this->return_value;
}
bool SubCommand::should_display_result() const
{
return this->show_result;
}
} // commands

View file

@ -1,20 +1,26 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#include "parameter_reader.h"
#ifndef SUBCOMMAND_H #ifndef SUBCOMMAND_H
#define SUBCOMMAND_H #define SUBCOMMAND_H
namespace commands { namespace commands
class SubCommand { {
class SubCommand
{
private:
string name; string name;
bool show_result;
protected:
int return_value; int return_value;
public: public:
SubCommand(const string& indicator, const int& value); SubCommand(const string& indicator, const int& value, const bool show_result);
string get_name(); string get_name();
int get_value(); int get_value() const;
bool should_display_result() const;
virtual void run(int argc, stringstream& args); virtual void run(int argc, stringstream& args);
}; };
} } // commands
#endif // SUBCOMMAND_H #endif // SUBCOMMAND_H

View file

@ -1,17 +1,20 @@
#include "Task.h" #include "Task.h"
#include "Util.h" #include "Util.h"
#include "FormatError.h" #include "Manager.h"
#include "Error.h"
using err::FormatError; using err::Error;
using util::Util; using util::Util;
using util::Manager;
namespace models { namespace models {
Task::Task(const int& id, const string& name, const string& description, const vector<int>& children): id(id), name(name), description(description), children(children) {} Task::Task(const int& id, const string& name, const string& description, const vector<int>& children): id(id), name(name), description(description), children(children) {}
Task::Task(): id(0), name(""), description(""), children({}) {} Task::Task(): id(0), name(""), description(""), children({}) {}
ostream& Task::write(ostream& stream) { ostream& Task::write(ostream& stream) const
stream << this; {
stream << *this;
return stream; return stream;
} }
@ -31,4 +34,50 @@ namespace models {
return this->children; 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<int> 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<int> 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

32
Task.h
View file

@ -1,10 +1,9 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#include "FormatError.h"
#include "Util.h" #include "Util.h"
#ifndef TASK_H #ifndef TASK_H
#define TASK_H #define TASK_H
using err::FormatError;
using util::Util; using util::Util;
namespace models { namespace models {
@ -19,7 +18,7 @@ namespace models {
Task(); Task();
ostream& write(ostream& stream); ostream& write(ostream& stream) const;
istream& read(istream&); istream& read(istream&);
int get_id() const; int get_id() const;
@ -32,23 +31,20 @@ namespace models {
friend istream& operator>>(istream& is, Task& t); friend istream& operator>>(istream& is, Task& t);
}; };
inline ostream& operator<<(ostream& os, const Task& t) { class AddTask : public Task{
os << t.get_id() << " " << t.get_name() << " " << t.get_description(); private:
return os; public:
} AddTask();
inline istream& operator>>(istream& is, Task& t) { AddTask(Task& t);
int id;
is >> id;
if (!is)
throw FormatError("Id NaN.");
string name = Util::read_string_between_percent(is); friend ostream& operator<<(ostream& os, const AddTask& t);
string description = Util::read_string_between_percent(is); friend istream& operator>>(istream& is, AddTask& t);
vector<int> children = Util::read_numbers(is); };
ostream& operator<<(ostream& os, const AddTask& t);
istream& operator>>(istream& is, AddTask& t);
t = {id, name, description, children}; ostream& operator<<(ostream& os, const Task& t);
return is; istream& operator>>(istream& is, Task& t);
}
} }
#endif // TASK_H #endif // TASK_H

32
UnassignCommand.cpp Normal file
View file

@ -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

16
UnassignCommand.h Normal file
View file

@ -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

View file

@ -1,12 +1,18 @@
#include "User.h" #include "User.h"
#include "Error.h"
#include "Manager.h"
using util::Manager;
using err::Error;
namespace models { namespace models {
User::User(const int& id, const string& name, const string& surname): id(id), name(name), surname(surname) {} User::User(const int& id, const string& name, const string& surname): id(id), name(name), surname(surname) {}
User::User(): id(0), name(""), surname("") {} User::User(): id(0), name(""), surname("") {}
ostream& User::write(ostream& stream) { ostream& User::write(ostream& stream) {
stream << this; stream << *this;
return stream; return stream;
} }
@ -22,9 +28,14 @@ namespace models {
return this->surname; return this->surname;
} }
AddUser::AddUser(): User() {}
AddUser::AddUser(User& u): User(u) {}
ostream& operator<<(ostream& os, const 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; return os;
} }
@ -33,12 +44,34 @@ namespace models {
int id; int id;
is >> id; is >> id;
if (!is) if (!is)
throw FormatError("User id NaN."); throw Error(602, "Datei hat ein unbekanntes Format.");
string name, surname; string name, surname;
is >> name >> surname; is >> name >> surname;
if (!is) if (!is)
throw FormatError("Could not read user name and surname"); throw Error(602, "Datei hat ein unbekanntes Format.");
u = {id, name, surname}; u = {id, name, surname};
return is; 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;
}
} }

15
User.h
View file

@ -1,10 +1,9 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#include "FormatError.h"
#include "Util.h" #include "Util.h"
#ifndef USER_H #ifndef USER_H
#define USER_H #define USER_H
using err::FormatError;
using util::Util; using util::Util;
namespace models { namespace models {
@ -27,8 +26,20 @@ namespace models {
friend istream& operator>>(istream& is, User& u); 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); ostream& operator<<(ostream& os, const User& u);
istream& operator>>(istream& is, User& u); istream& operator>>(istream& is, User& u);
ostream& operator<<(ostream& os, const AddUser& u);
istream& operator>>(istream& is, AddUser& u);
} }
#endif // USER_H #endif // USER_H

View file

@ -1,10 +1,9 @@
#include "Util.h" #include "Util.h"
#include "FormatError.h" #include "Error.h"
#include <cstdio>
#include <exception> #include <exception>
#include <string> #include <string>
using err::FormatError; using err::Error;
namespace util { namespace util {
string Util::read_string_between_percent(istream& is) { string Util::read_string_between_percent(istream& is) {
@ -16,7 +15,7 @@ namespace util {
while (true) { while (true) {
is >> c; is >> c;
if (!is) if (!is)
throw FormatError("Could not read char!"); throw Error(700, "Could not read char!");
if (c == '%') { if (c == '%') {
read = !read; read = !read;
break; break;
@ -35,14 +34,14 @@ namespace util {
string until_eol; string until_eol;
getline(is, until_eol); getline(is, until_eol);
vector<string> numbers_as_string = Util::split(until_eol); vector<string> numbers_as_string = split(until_eol);
vector<int> nums; vector<int> nums;
try { try {
for(string s : numbers_as_string) for(string s : numbers_as_string)
nums.push_back(stoi(s)); nums.push_back(stoi(s));
} catch (exception& _) { } catch (exception& _) {
throw FormatError("Could not convert string to int"); throw Error(700, "Could not convert string to int.");
} }
return nums; return nums;
@ -65,4 +64,12 @@ namespace util {
return strs; 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

2
Util.h
View file

@ -1,3 +1,4 @@
#pragma once
#include "std_lib_inc.h" #include "std_lib_inc.h"
#ifndef UTIL_H #ifndef UTIL_H
#define UTIL_H #define UTIL_H
@ -8,6 +9,7 @@ namespace util {
static string read_string_between_percent(istream& is); static string read_string_between_percent(istream& is);
static vector<int> read_numbers(istream& is); static vector<int> read_numbers(istream& is);
static vector<string> split(const string& s); static vector<string> split(const string& s);
static string read_string(istream& s);
}; };
} }

View file

@ -1,26 +1,39 @@
#pragma once
#include "ActiveCommand.h"
#include "std_lib_inc.h" #include "std_lib_inc.h"
#include "parameter_reader.h" #include "parameter_reader.h"
#include "SubCommand.h"
#include "HelpCommand.h" #include "HelpCommand.h"
#include "AddCommand.h" #include "AddCommand.h"
#include "User.h" #include "AssignCommand.h"
#include "Manager.h" #include "DelCommand.h"
#include <exception> #include "Error.h"
#include "ListCommand.h"
#include "FileError.h" #include "UnassignCommand.h"
using commands::SubCommand; using commands::SubCommand;
using commands::HelpCommand; using commands::HelpCommand;
using commands::AddCommand; using commands::AddCommand;
using util::Manager; using commands::ListCommand;
using err::FileError; using commands::DelCommand;
using err::FormatError; using commands::AssignCommand;
using commands::UnassignCommand;
using commands::ActiveCommand;
using err::Error;
const vector<SubCommand*> handlers = { new HelpCommand(), new AddCommand() }; const vector<SubCommand*> handlers = {
new HelpCommand(),
new AddCommand(),
new ListCommand(),
new DelCommand(),
new AssignCommand(),
new UnassignCommand(),
new ActiveCommand(),
};
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
if (argc < 2) { if (argc < 2)
{
cout << "There are not enough args!\n"; cout << "There are not enough args!\n";
return 0; return 0;
} }
@ -29,25 +42,21 @@ int main(int argc, char** argv)
string command; string command;
parameter >> command; parameter >> command;
try { try
for (SubCommand* sc : handlers) {
if (sc->get_name() == command) {
sc->run(argc, parameter);
return sc->get_value();
}
}
}
catch (FormatError& e) {
cout << e.why() << "\n";
}
catch (FileError& e)
{ {
cout << e.why() << "\n"; for (SubCommand* sc : handlers)
{
if (sc->get_name() == command)
{
sc->run(argc, parameter);
return 0;
} }
catch (exception& e) {
cout << e.what() << "\n";
} }
return 101; }
catch (Error& e)
{
cout << e.get_nr() << ": " << e.what() << "\n";
}
cout << "101: Befehl ist unbekannt.\n";
return 0;
} }