feat: got loading working, implemented saving

This commit is contained in:
moonleay 2025-02-09 12:34:07 +01:00
parent 8d356391ae
commit 757a5c123f
Signed by: moonleay
GPG key ID: 82667543CCD715FB
18 changed files with 498 additions and 78 deletions

40
Assignment.cpp Normal file
View file

@ -0,0 +1,40 @@
#include "Assignment.h"
#include "FormatError.h"
using err::FormatError;
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;
return stream;
}
int Assignment::get_task_id() const {
return this->task_id;
}
int Assignment::get_user_id() const {
return this->user_id;
}
ostream& operator<<(ostream& os, const Assignment& t) {
os << t.get_user_id() << " " << t.get_task_id();
return os;
}
istream& operator>>(istream& is, Assignment& t) {
int user_id;
is >> user_id;
if (!is)
throw FormatError("Userid Nan");
int task_id;
is >> task_id;
if (!is)
throw FormatError("Taskid Nan");
t = {user_id, task_id};
return is;
}
}

27
Assignment.h Normal file
View file

@ -0,0 +1,27 @@
#include "std_lib_inc.h"
#ifndef ASSIGNMENT_H
#define ASSIGNMENT_H
namespace models {
class Assignment {
private:
int user_id;
int task_id;
public:
Assignment(const int& user_id, const int& task_id);
Assignment();
ostream& write(ostream& stream);
int get_user_id() const;
int get_task_id() const;
friend ostream& operator<<(ostream& os, const Assignment& t);
friend istream& operator>>(istream& is, Assignment& t);
};
ostream& operator<<(ostream& os, const Assignment& t);
istream& operator>>(istream& is, Assignment& t);
}
#endif // ASSIGNMENT_H

15
DataType.h Normal file
View file

@ -0,0 +1,15 @@
#include "std_lib_inc.h"
#ifndef READINSTATUS_H
#define READINSTATUS_H
namespace util {
enum class DataType {
INIT,
USER,
TASK,
USERTASKINDEX
};
}
#endif // READINSTATUS_H

20
FileError.h Normal file
View file

@ -0,0 +1,20 @@
#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

20
FormatError.h Normal file
View file

@ -0,0 +1,20 @@
#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

107
Manager.cpp Normal file
View file

@ -0,0 +1,107 @@
#include "Manager.h"
#include "FileError.h"
#include <fstream>
using err::FileError;
using util::DataType;
namespace util {
Manager::Manager(): users({}), tasks({}), user_task_index({}), filename("tasks") {
ifstream in (this->filename);
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!");
}
DataType current_type = DataType::INIT;
string d;
char c;
while(true) {
in >> c;
if (in.eof() || c == EOF)
break;
if (c == '\n')
{
in >> d;
continue;
}
if (c == '['){
switch (current_type)
{
case DataType::INIT:
current_type = DataType::TASK;
break;
case DataType::TASK:
current_type = DataType::USER;
break;
case DataType::USER:
current_type = DataType::USERTASKINDEX;
break;
case DataType::USERTASKINDEX:
break; // This should not happen. There is nothing after [assignments]
}
in >> d;
continue;
}
in.putback(c);
switch (current_type) {
case DataType::INIT:
break;
case DataType::TASK:
{
Task t;
in >> t;
this->tasks.push_back(t);
}
break;
case DataType::USER:
{
User u;
in >> u;
this->users.push_back(u);
}
break;
case DataType::USERTASKINDEX:
{
Assignment a;
in >> a;
this->user_task_index.push_back(a);
}
break;
}
}
in.close();
}
void Manager::save() {
ofstream out = ofstream(this->filename);
if (!out)
throw FileError("Could not open file output stream!");
out << "[tasks]\n";
for (Task& t : this->tasks)
t.write(out);
out << "\n[users]\n";
for (User& u : this->users)
u.write(out);
out << "\n[assignments]\n";
for (Assignment& uti: this->user_task_index)
uti.write(out);
out.close();
}
vector<User> Manager::get_users() const {
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;
}
}

36
Manager.h Normal file
View file

@ -0,0 +1,36 @@
#include "std_lib_inc.h"
#include "User.h"
#include "Task.h"
#include "Assignment.h"
#include "DataType.h"
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
using models::User;
using models::Task;
using models::Assignment;
namespace util {
class Manager {
private:
vector<User> users;
vector<Task> tasks;
vector<Assignment> user_task_index;
string filename;
public:
Manager();
void save();
vector<User> get_users() const;
vector<Task> get_task() const;
vector<Assignment> get_user_task_index() const;
};
inline DataType operator++(DataType& status);
}
#endif // ENVIRONMENT_H

View file

@ -1,15 +0,0 @@
#include "Model.h"
namespace models {
Model::Model() {}
Model* Model::operator>>(stringstream& stream) {
cout << "Default << operator was not overwritten!\n";
return new Model();
}
string Model::operator<<(Model* model) {
cout << "Default >> operator was not overwritten!\n";
return "";
}
}

16
Model.h
View file

@ -1,16 +0,0 @@
#include "std_lib_inc.h"
#ifndef MODEL_H
#define MODEL_H
namespace models {
class Model {
public:
Model();
virtual Model* operator>>(stringstream& stream);
virtual string operator<<(Model* model);
};
}
#endif // MODEL_H

View file

@ -1,5 +1,34 @@
#include "Task.h"
#include "Util.h"
#include "FormatError.h"
using err::FormatError;
using util::Util;
namespace models {
Task::Task(const int& id, const string& name, const string& description, const vector<int>& children): Model(), 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({}) {}
ostream& Task::write(ostream& stream) {
stream << this;
return stream;
}
int Task::get_id() const {
return this->id;
}
string Task::get_name() const {
return this->name;
}
string Task::get_description() const {
return this->description;
}
vector<int> Task::get_children() const {
return this->children;
}
}

42
Task.h
View file

@ -1,10 +1,14 @@
#include "std_lib_inc.h"
#include "Model.h"
#include "FormatError.h"
#include "Util.h"
#ifndef TASK_H
#define TASK_H
using err::FormatError;
using util::Util;
namespace models {
class Task : public Model {
class Task {
private:
int id;
string name;
@ -12,9 +16,39 @@ namespace models {
vector<int> children;
public:
Task(const int& id, const string& name, const string& description, const vector<int>& children);
Model* operator>>(stringstream& stream) override;
string operator<<(Model& model) override;
Task();
ostream& write(ostream& stream);
istream& read(istream&);
int get_id() const;
string get_name() const;
string get_description() const;
vector<int> get_children() const;
friend ostream& operator<<(ostream& os, const Task& t);
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.");
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;
}
}
#endif // TASK_H

View file

@ -1,11 +1,44 @@
#include "User.h"
#include <sstream>
namespace models {
User::User(const int& id, const string& name, const string& surname): Model(), id(id), name(name), surname(surname) {}
Model* User::operator>>(stringstream& stream) {
cout << "Custom impl.";
return new User(0, "", "");
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;
return stream;
}
int User::get_id() const {
return this->id;
}
string User::get_name() const {
return this->name;
}
string User::get_surname() const {
return this->surname;
}
ostream& operator<<(ostream& os, const User& u)
{
os << u.get_id() << " " << u.get_name() << " " << u.get_surname();
return os;
}
istream& operator>>(istream& is, User& u)
{
int id;
is >> id;
if (!is)
throw FormatError("User id NaN.");
string name, surname;
is >> name >> surname;
if (!is)
throw FormatError("Could not read user name and surname");
u = {id, name, surname};
return is;
}
}

22
User.h
View file

@ -1,10 +1,14 @@
#include "std_lib_inc.h"
#include "Model.h"
#include "FormatError.h"
#include "Util.h"
#ifndef USER_H
#define USER_H
using err::FormatError;
using util::Util;
namespace models {
class User : public Model {
class User {
private:
int id;
string name;
@ -12,9 +16,19 @@ namespace models {
public:
User(const int& id, const string& name, const string& surname);
Model* operator>>(stringstream& stream) override;
string operator<<(Model* model) override;
User();
ostream& write(ostream& stream);
int get_id() const;
string get_name() const;
string get_surname() const;
friend ostream& operator<<(ostream& os, const User& u);
friend istream& operator>>(istream& is, User& u);
};
ostream& operator<<(ostream& os, const User& u);
istream& operator>>(istream& is, User& u);
}
#endif // USER_H

View file

@ -1,5 +0,0 @@
#include "UserTaskIndex.h"
namespace models {
UserTaskIndex::UserTaskIndex(const int& user_id, const int& task_id) : Model(), user_id(user_id), task_id(task_id) {}
}

View file

@ -1,19 +0,0 @@
#include "std_lib_inc.h"
#include "Model.h"
#ifndef USERTASKINDEX_H
#define USERTASKINDEX_H
namespace models {
class UserTaskIndex : public Model{
private:
int user_id;
int task_id;
public:
UserTaskIndex(const int& user_id, const int& task_id);
Model* operator>>(stringstream& stream) override;
string operator<<(Model& model) override;
};
}
#endif // USERTASKINDEX_H

68
Util.cpp Normal file
View file

@ -0,0 +1,68 @@
#include "Util.h"
#include "FormatError.h"
#include <cstdio>
#include <exception>
#include <string>
using err::FormatError;
namespace util {
string Util::read_string_between_percent(istream& is) {
char c;
string s = "";
bool read = false;
for(int i = 0; i < 2; ++i) {
while (true) {
is >> c;
if (!is)
throw FormatError("Could not read char!");
if (c == '%') {
read = !read;
break;
}
if (!read)
continue;
s += c;
}
}
return s;
}
vector<int> Util::read_numbers(istream &is) {
int i;
string until_eol;
getline(is, until_eol);
vector<string> numbers_as_string = Util::split(until_eol);
vector<int> nums;
try {
for(string s : numbers_as_string)
nums.push_back(stoi(s));
} catch (exception& _) {
throw FormatError("Could not convert string to int");
}
return nums;
}
vector<string> Util::split(const string& s) {
vector<string> strs;
string result = "";
for(char c : s) {
if (c == ' ') {
if (result != "") {
strs.push_back(result);
result = "";
}
break;
}
result += c;
}
return strs;
}
}

14
Util.h Normal file
View file

@ -0,0 +1,14 @@
#include "std_lib_inc.h"
#ifndef UTIL_H
#define UTIL_H
namespace util {
class Util {
public:
static string read_string_between_percent(istream& is);
static vector<int> read_numbers(istream& is);
static vector<string> split(const string& s);
};
}
#endif // UTIL_H

View file

@ -3,33 +3,51 @@
#include "SubCommand.h"
#include "HelpCommand.h"
#include "AddCommand.h"
#include "User.h"
#include "Manager.h"
#include <exception>
#include "FileError.h"
using commands::SubCommand;
using commands::HelpCommand;
using commands::AddCommand;
using util::Manager;
using err::FileError;
using err::FormatError;
const vector<SubCommand*> handlers = { new HelpCommand(), new AddCommand() };
// Mein Leben auf IMDB, nur 7/10.
int main(int argc, char** argv)
{
if (argc < 2) {
cout << "There are not enough args!\n";
return 0;
}
stringstream parameter = make_string_stream(argc, argv);
string command;
parameter >> command;
try {
for (SubCommand* sc : handlers) {
if (sc->get_name() == command) {
sc->run(argc, parameter);
return 0;
return sc->get_value();
}
}
cout << "I don't know this command!\n";
return 0;
}
catch (FormatError& e) {
cout << e.why() << "\n";
}
catch (FileError& e)
{
cout << e.why() << "\n";
}
catch (exception& e) {
cout << e.what() << "\n";
}
return 101;
}