Compare commits

..

No commits in common. "684a3210407e7f4f1a692d09c686f2b125188c8f" and "ca572b6fb542d5095f8a41c649e1f41496f81700" have entirely different histories.

7 changed files with 120 additions and 152 deletions

View file

@ -16,12 +16,12 @@ namespace models {
int get_user_id() const; int get_user_id() const;
int get_task_id() const; int get_task_id() const;
friend ostream& operator<<(ostream& os, const Assignment& assignment); friend ostream& operator<<(ostream& os, const Assignment& t);
friend istream& operator>>(istream& is, Assignment& assignment); friend istream& operator>>(istream& is, Assignment& t);
}; };
ostream& operator<<(ostream& os, const Assignment& assignment); ostream& operator<<(ostream& os, const Assignment& t);
istream& operator>>(istream& is, Assignment& assignment); istream& operator>>(istream& is, Assignment& t);
} }
#endif // ASSIGNMENT_H #endif // ASSIGNMENT_H

View file

@ -1,16 +1,19 @@
#include "Manager.h" #include "Manager.h"
#include "Error.h"
#include <fstream> #include <fstream>
#include "DataType.h" #include "DataType.h"
#include "Error.h"
using err::Error; using err::Error;
using util::DataType; using util::DataType;
namespace util { namespace util
Manager::Manager() : users({}), tasks({}), assignments({}), user_id_index(0), task_id_index(0), filename("tasks") { {
// Open File Manager::Manager(): users({}), tasks({}), assignments({}), user_id_index(0), task_id_index(0), filename("tasks")
{
//Open File
ifstream in = ifstream(this->filename, ios_base::in); ifstream in = ifstream(this->filename, ios_base::in);
if (!in) { if (!in)
{
this->save(); this->save();
in.clear(); in.clear();
in.open(this->filename, ios_base::in); in.open(this->filename, ios_base::in);
@ -21,10 +24,12 @@ namespace util {
DataType current_type = DataType::INIT; DataType current_type = DataType::INIT;
string d; // dump string d; // dump
string line, section; string line, section;
// Parse all Lines until EOF //Parse all Lines until EOF
while (getline(in, line)) { while (getline(in, line))
{
// Check if the line starts with '[' // Check if the line starts with '['
if (!line.empty() && line[0] == '[') { if (!line.empty() && line[0] == '[')
{
if (line == "[tasks]") if (line == "[tasks]")
current_type = DataType::TASK; current_type = DataType::TASK;
else if (line == "[users]") else if (line == "[users]")
@ -35,162 +40,188 @@ namespace util {
throw Error(602, "Datei hat ein unbekanntes Format."); throw Error(602, "Datei hat ein unbekanntes Format.");
continue; continue;
} }
// Lehre Zeilen überspringen. //Lehre Zeilen überspringen.
if (line.empty()) if (line.empty())
continue; continue;
// Speichern im Buffer //Speichern im Buffer
buffer[current_type].push_back(line); buffer[current_type].push_back(line);
} // Data is parsed } //Data is parsed
in.close(); in.close();
// Reihenfolge der Verabeitung // Reihenfolge der Verabeitung
vector<DataType> sections = {DataType::USER, DataType::TASK, DataType::ASSIGNMENT}; vector<DataType> sections = { DataType::USER, DataType::TASK, DataType::ASSIGNMENT };
for (DataType type: sections) { for (DataType type : sections)
{
// Keine Data -> Continue // Keine Data -> Continue
if (buffer.find(type) == buffer.end()) if (buffer.find(type) == buffer.end())
continue; continue;
const vector<string> &lines = buffer[type]; const vector<string>& lines = buffer[type];
// Iteriere über die Gebufferten Strings. //Iteriere über die Gebufferten Strings.
for (const string &buffered_line: lines) { for (const string& buffered_line : lines)
{
stringstream string_stream(buffered_line); stringstream string_stream(buffered_line);
switch (type) { switch (type)
case DataType::TASK: { {
case DataType::TASK:
{
Task task; Task task;
string_stream >> task; string_stream >> task;
this->tasks[task.get_id()] = new Task(task); this->tasks[task.get_id()] = new Task(task);
} break; }
case DataType::USER: { break;
case DataType::USER:
{
User user; User user;
string_stream >> user; string_stream >> user;
this->users[user.get_id()] = new User(user); this->users[user.get_id()] = new User(user);
} break; }
case DataType::ASSIGNMENT: { break;
case DataType::ASSIGNMENT:
{
Assignment assignment; Assignment assignment;
string_stream >> assignment; string_stream >> assignment;
this->assignments.push_back(new Assignment(assignment)); this->assignments.push_back(new Assignment(assignment));
} break; }
default: break;
break; default:
break;
} }
} }
} }
this->update_indexes(); this->update_indexes();
} }
void Manager::update_user_id_index() { void Manager::update_user_id_index()
{
int i = 0; int i = 0;
for (const auto &user_pair: this->users) for (const auto& user_pair : this->users)
if (user_pair.second && user_pair.second->get_id() >= i) if (user_pair.second && user_pair.second->get_id() >= i)
i = user_pair.second->get_id() + 1; i = user_pair.second->get_id() + 1;
this->user_id_index = i; this->user_id_index = i;
} }
void Manager::update_task_id_index() { void Manager::update_task_id_index()
{
int i = 0; int i = 0;
for (const auto &task_pair: this->tasks) for (const auto& task_pair : this->tasks)
if (task_pair.second && task_pair.second->get_id() >= i) if (task_pair.second && task_pair.second->get_id() >= i)
i = task_pair.second->get_id() + 1; i = task_pair.second->get_id() + 1;
this->task_id_index = i; this->task_id_index = i;
} }
void Manager::update_indexes() { void Manager::update_indexes()
{
this->update_user_id_index(); this->update_user_id_index();
this->update_task_id_index(); this->update_task_id_index();
} }
int Manager::get_user_id() { int Manager::get_user_id()
{
const int value = this->user_id_index; const int value = this->user_id_index;
++this->user_id_index; ++this->user_id_index;
return value; return value;
} }
int Manager::get_task_id() { int Manager::get_task_id()
{
const int value = this->task_id_index; const int value = this->task_id_index;
++this->task_id_index; ++this->task_id_index;
return value; return value;
} }
Manager *Manager::INSTANCE = nullptr; Manager* Manager::INSTANCE = nullptr;
Manager *Manager::get_instance() { Manager* Manager::get_instance()
{
if (INSTANCE == nullptr) if (INSTANCE == nullptr)
INSTANCE = new Manager(); INSTANCE = new Manager();
return INSTANCE; return INSTANCE;
} }
vector<User *> Manager::get_users() const { vector<User*> Manager::get_users() const
vector<User *> user_vector; {
for (const auto &pair: this->users) vector<User*> user_vector;
for (const auto& pair : this->users)
if (pair.second) // Ensure it's not a nullptr if (pair.second) // Ensure it's not a nullptr
user_vector.push_back(pair.second); user_vector.push_back(pair.second);
return user_vector; return user_vector;
} }
vector<Task *> Manager::get_tasks() const { vector<Task*> Manager::get_tasks() const
vector<Task *> task_vector; {
for (const auto &pair: this->tasks) vector<Task*> task_vector;
for (const auto& pair : this->tasks)
if (pair.second) // Ensure it's not a nullptr if (pair.second) // Ensure it's not a nullptr
task_vector.push_back(pair.second); task_vector.push_back(pair.second);
return task_vector; return task_vector;
} }
vector<Assignment *> Manager::get_assignments() { return this->assignments; } vector<Assignment*> Manager::get_assignments()
{
return this->assignments;
}
User *Manager::get_user(const int id) { User* Manager::get_user(const int id)
{
if (this->users.count(id) == 0) if (this->users.count(id) == 0)
return nullptr; return nullptr;
return this->users[id]; return this->users[id];
} }
Task *Manager::get_task(const int id) { Task* Manager::get_task(const int id)
{
if (this->tasks.count(id) == 0) if (this->tasks.count(id) == 0)
return nullptr; return nullptr;
return this->tasks[id]; return this->tasks[id];
} }
Vector<Assignment *> Manager::get_assignments_for_user(const int user_id) { Vector<Assignment*> Manager::get_assignments_for_user(const int user_id)
Vector<Assignment *> user_assignments; {
Vector<Assignment*> user_assignments;
if (this->get_user(user_id) == nullptr) if (this->get_user(user_id) == nullptr)
throw Error(401, "Eine solche BenutzerIn existiert nicht."); throw Error(401, "Eine solche BenutzerIn existiert nicht.");
for (Assignment *as: this->assignments) for (Assignment* as : this->assignments)
if (as->get_user_id() == user_id) if (as->get_user_id() == user_id)
user_assignments.push_back(as); user_assignments.push_back(as);
return user_assignments; return user_assignments;
} }
Vector<Assignment *> Manager::get_assignments_for_task(const int task_id) { Vector<Assignment*> Manager::get_assignments_for_task(const int task_id)
Vector<Assignment *> task_assignments; {
Vector<Assignment*> task_assignments;
if (this->get_task(task_id) == nullptr) if (this->get_task(task_id) == nullptr)
throw Error(401, "Eine solche BenutzerIn existiert nicht."); throw Error(401, "Eine solche BenutzerIn existiert nicht.");
for (Assignment *as: this->assignments) for (Assignment* as : this->assignments)
if (as->get_task_id() == task_id) if (as->get_task_id() == task_id)
task_assignments.push_back(as); task_assignments.push_back(as);
return task_assignments; return task_assignments;
} }
bool Manager::assignment_exists(const int user_id, const int task_id) const { bool Manager::assignment_exists(int user_id, int task_id) {
for (Assignment const *as: this->assignments) { for ( Assignment* as : this->assignments)
if (as->get_user_id() == user_id && as->get_task_id() == task_id) if (as->get_user_id() == user_id && as->get_task_id() == task_id)
return true; return true;
}
return false; return false;
} }
void Manager::add_user(User *user) { void Manager::add_user(User* user)
{
if (this->users.count(user->get_id()) == 1) if (this->users.count(user->get_id()) == 1)
return; return;
this->users[user->get_id()] = user; this->users[user->get_id()] = user;
} }
void Manager::add_task(Task *task) { void Manager::add_task(Task* task)
{
if (this->tasks.count(task->get_id()) == 1) if (this->tasks.count(task->get_id()) == 1)
return; return;
this->tasks[task->get_id()] = task; this->tasks[task->get_id()] = task;
} }
void Manager::add_assignment(Assignment *as) { void Manager::add_assignment(Assignment* as)
{
if (this->get_user(as->get_user_id()) == nullptr) if (this->get_user(as->get_user_id()) == nullptr)
throw Error(401, "Eine solche BenutzerIn existiert nicht."); throw Error(401, "Eine solche BenutzerIn existiert nicht.");
@ -200,24 +231,25 @@ namespace util {
this->assignments.push_back(as); this->assignments.push_back(as);
} }
void Manager::del_user(const int id) { void Manager::del_user(const int id)
{
if (this->users.count(id) == 0) if (this->users.count(id) == 0)
throw Error(401, "Eine solche BenutzerIn existiert nicht."); throw Error(401, "Eine solche BenutzerIn existiert nicht.");
// Assigment //Assigment
if (!this->get_assignments_for_user(id).empty()) { if (!this->get_assignments_for_user(id).empty()) {
throw Error(201, "Benutzer kann nicht gelöscht werden."); throw Error(201, "Benutzer kann nicht gelöscht werden.");
} }
this->users.erase(id); this->users.erase(id);
} }
void Manager::del_task(const int id) { void Manager::del_task(const int id)
{
if (this->tasks.count(id) == 0) if (this->tasks.count(id) == 0)
throw Error(402, "Eine solche Aufgabe existiert nicht."); throw Error(402, "Eine solche Aufgabe existiert nicht.");
if (!this->get_assignments_for_task(id).empty()) { if (!this->get_assignments_for_task(id).empty()) {
throw Error(202, "Aufgabe kann nicht gelöscht werden."); throw Error(202, "Aufgabe kann nicht gelöscht werden.");
} }
// TODO: Zudem kann eine Aufgabe nur gelöscht werden, wenn Sie nicht Nachfolgerin einer anderen Aufgabe ist -> //TODO: Zudem kann eine Aufgabe nur gelöscht werden, wenn Sie nicht Nachfolgerin einer anderen Aufgabe ist -> Ensure its no Child
// Ensure its no Child
/*for (Task* task : this->get_tasks()) { /*for (Task* task : this->get_tasks()) {
for (int child_id : task->get_children()) { for (int child_id : task->get_children()) {
if (id == child_id) { if (id == child_id) {
@ -225,19 +257,20 @@ namespace util {
} }
} }
}*/ }*/
if (!this->get_task(id)->is_active()) { if (! this->get_task(id)->is_active()) {
throw Error(202, "Aufgabe kann nicht gelöscht werden."); throw Error(202, "Aufgabe kann nicht gelöscht werden.");
} }
this->tasks.erase(id); this->tasks.erase(id);
} }
void Manager::del_assignment(Assignment const &as) { void Manager::del_assignment(Assignment& as)
{
if (!this->assignment_exists(as.get_user_id(), as.get_task_id())) if (!this->assignment_exists(as.get_user_id(), as.get_task_id()))
throw Error(301, "Eine solche Zuordnung existiert nicht."); throw Error(301, "Eine solche Zuordnung existiert nicht.");
int assignment_nr = 0; int assignment_nr = 0;
for (int i = 0; i < this->assignments.size(); ++i) { for (int i = 0; i < this->assignments.size(); ++i) {
if (this->assignments[i]->get_user_id() == as.get_user_id() && if (this->assignments[i]->get_user_id() == as.get_user_id() && this->assignments[i]->get_task_id() == as.get_task_id()) {
this->assignments[i]->get_task_id() == as.get_task_id()) {
assignment_nr = i; assignment_nr = i;
break; break;
} }
@ -245,26 +278,27 @@ namespace util {
this->assignments.erase(this->assignments.begin() + assignment_nr); this->assignments.erase(this->assignments.begin() + assignment_nr);
}; };
void Manager::save() { void Manager::save()
{
ofstream out = ofstream(this->filename, ios_base::trunc); ofstream out = ofstream(this->filename, ios_base::trunc);
if (!out) if (!out)
throw Error(603, "Datei kann nicht geschrieben werden."); throw Error(603, "Datei kann nicht geschrieben werden.");
out << "[tasks]\n"; out << "[tasks]\n";
for (const auto &task_pair: this->tasks) { for (const auto& task_pair : this->tasks)
if (task_pair.second) if (task_pair.second)
task_pair.second->write(out); task_pair.second->write(out);
}
out << "\n[users]\n"; out << "\n[users]\n";
for (const auto &user_pair: this->users) { for (const auto& user_pair : this->users)
if (user_pair.second) if (user_pair.second)
user_pair.second->write(out); user_pair.second->write(out);
}
out << "\n[assignments]\n"; out << "\n[assignments]\n";
for (Assignment *assignment: this->assignments) { for (Assignment* assignment : this->assignments)
if (assignment) if (assignment)
assignment->write(out); assignment->write(out);
}
out.close(); out.close();
} }
} // namespace util } // util

View file

@ -12,118 +12,50 @@ using models::Assignment;
namespace util namespace util
{ {
/// Verwalter von Benutzern, Aufgaben und deren Zuordnungen.
class Manager class Manager
{ {
private: private:
//Singelton Instanz des Managers
static Manager* INSTANCE; static Manager* INSTANCE;
//Container für Zeiger auf alle User anhand der Id
map<int, User*> users; map<int, User*> users;
//Container für Zeiger auf alle Task anhand der Id
map<int, Task*> tasks; map<int, Task*> tasks;
/// Speichert Zuordnungen von Benutzern zu Aufgaben.
vector<Assignment*> assignments; vector<Assignment*> assignments;
//Nächste freie User Id
int user_id_index; int user_id_index;
//Nächste frei Task Id
int task_id_index; int task_id_index;
//Dateiname für den persistenten Speicher
string filename; string filename;
/// Erstellt eine Instanz des Managers und lädt vorhandene Daten.
Manager(); Manager();
/// Aktualisiert die Benutzer-ID.
void update_user_id_index(); void update_user_id_index();
/// Aktualisiert die Aufgaben-ID.
void update_task_id_index(); void update_task_id_index();
public: public:
Manager(const Manager&) = delete; Manager(const Manager&) = delete;
Manager& operator=(const Manager&) = delete; Manager& operator=(const Manager&) = delete;
/// Holt die Singleton-Instanz des Managers.
/// @return Ein Zeiger auf die Instanz.
static Manager* get_instance(); static Manager* get_instance();
/// Speichert die aktuellen Daten in einer Datei.
void save(); void save();
/// Aktualisiert die Benutzer- und Aufgaben-IDs.
void update_indexes(); void update_indexes();
/// Holt eine eindeutige Benutzer-ID.
/// @return Eine neue Benutzer-ID.
int get_user_id(); int get_user_id();
/// Holt eine eindeutige Aufgaben-ID.
/// @return Eine neue Aufgaben-ID.
int get_task_id(); int get_task_id();
/// Holt eine Liste aller Benutzer.
/// @return Ein Vektor von Benutzerzeigern.
vector<User*> get_users() const; vector<User*> get_users() const;
/// Holt eine Liste aller Aufgaben.
/// @return Ein Vektor von Aufgabenzeigern.
vector<Task*> get_tasks() const; vector<Task*> get_tasks() const;
/// Holt eine Liste aller Zuordnungen.
/// @return Ein Vektor von Zuordnungen.
vector<Assignment*> get_assignments(); vector<Assignment*> get_assignments();
/// Holt einen Benutzer anhand der ID.
/// @param id Die Benutzer-ID.
/// @return Ein Zeiger auf den Benutzer oder nullptr.
User* get_user(int id); User* get_user(int id);
/// Holt eine Aufgabe anhand der ID.
/// @param id Die Aufgaben-ID.
/// @return Ein Zeiger auf die Aufgabe oder nullptr.
Task* get_task(int id); Task* get_task(int id);
/// Holt alle Zuordnungen für einen Benutzer.
/// @param user_id Die Benutzer-ID.
/// @return Ein Vektor von Zuordnungen.
vector<Assignment *> get_assignments_for_user(int user_id); vector<Assignment *> get_assignments_for_user(int user_id);
/// Holt alle Zuordnungen für eine Aufgabe.
/// @param task_id Die Aufgaben-ID.
/// @return Ein Vektor von Zuordnungen.
vector<Assignment *> get_assignments_for_task(int task_id); vector<Assignment *> get_assignments_for_task(int task_id);
bool assignment_exists(int user_id, int task_id);
/// Prüft, ob eine Zuordnung existiert.
/// @param user_id Die Benutzer-ID.
/// @param task_id Die Aufgaben-ID.
/// @return Wahr, falls die Zuordnung existiert.
bool assignment_exists(int user_id, int task_id) const;
/// Fügt einen neuen Benutzer hinzu.
/// @param user Ein Zeiger auf den Benutzer.
void add_user(User* user); void add_user(User* user);
/// Fügt eine neue Aufgabe hinzu.
/// @param task Ein Zeiger auf die Aufgabe.
void add_task(Task* task); void add_task(Task* task);
/// Fügt eine neue Zuordnung hinzu.
/// @param as Ein Zeiger auf die Zuordnung.
void add_assignment(Assignment* as); void add_assignment(Assignment* as);
/// Löscht einen Benutzer anhand der ID.
/// @param id Die Benutzer-ID.
void del_user(int id); void del_user(int id);
/// Löscht eine Aufgabe anhand der ID.
/// @param id Die Aufgaben-ID.
void del_task(int id); void del_task(int id);
void del_assignment(Assignment& as);
/// Löscht eine Zuordnung.
/// @param as Die Zuordnung.
void del_assignment(Assignment const &as);
}; };
} // util } // util
#endif // ENVIRONMENT_H #endif // ENVIRONMENT_H

View file

@ -39,11 +39,12 @@ namespace models
*/ */
bool Task::is_active() const { bool Task::is_active() const {
const Manager * mgr = Manager::get_instance(); Manager* mgr = Manager::get_instance();
for (const Task * task : mgr->get_tasks()) { for (Task* task : mgr->get_tasks()) {
for (const int child_id : task->get_children()) { for (int child_id : task->get_children()) {
// Aktiver Task ist Child von Einem andern Task -> Nicht aktiv // Aktiver Task ist Child von Einem andern Task -> Nicht aktiv
if (this->id == child_id) { if (this->id == child_id) {
// cout << this->id << " = " << child_id << endl;
return false; return false;
} }
} }
@ -74,7 +75,7 @@ namespace models
ostream& operator<<(ostream& os, const Task& t) ostream& operator<<(ostream& os, const Task& t)
{ {
os << t.get_id() << " %" << t.get_name() << "% %" << t.get_description() << "%"; os << t.get_id() << " %" << t.get_name() << "% %" << t.get_description() << "%";
// Fügt Children Task mit passenden Leerzeichen hinzu // Fügt Childen Task mit passenden Lehrzeichen hinzu
if (!t.children.empty()) if (!t.children.empty())
os << " "; os << " ";
for (size_t i = 0; i < t.children.size(); ++i) for (size_t i = 0; i < t.children.size(); ++i)

1
Task.h
View file

@ -25,6 +25,7 @@ namespace models
explicit Task(const AddTask& t); explicit Task(const AddTask& t);
ostream& write(ostream& stream) const; ostream& write(ostream& stream) const;
istream& read(istream&);
int get_id() const; int get_id() const;
bool is_active() const; bool is_active() const;

View file

@ -30,6 +30,7 @@ namespace util {
} }
vector<int> Util::read_numbers(istream &is) { vector<int> Util::read_numbers(istream &is) {
int i;
string until_eol; string until_eol;
getline(is, until_eol); getline(is, until_eol);

View file

@ -35,7 +35,6 @@ const vector<SubCommand*> handlers = {
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
//TODO:: THis needs to be removed?
if (argc < 2) if (argc < 2)
{ {
cout << "There are not enough args!\n"; cout << "There are not enough args!\n";