Skip to content

Commit

Permalink
Show question view and edited the save method to flush the buffer imm…
Browse files Browse the repository at this point in the history
…ediately after writing a record (would cause a bug when creating multiple questions as the nonactive status won't be persisted).

Reset action to set any active question to false when returning to a certain view (dashboard in this case).
  • Loading branch information
cristianfrasineanu committed Dec 3, 2016
1 parent 284d7b8 commit adc572f
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 31 deletions.
1 change: 0 additions & 1 deletion app/Console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ void Console::renderNextView(string &viewName)

//this->previousViews.erase(this->previousViews.end() - 1, this->previousViews.end());
this->currentView = View(viewName, nextOptions);
this->lastInput = '\0';

clearScreen();
this->handleView();
Expand Down
18 changes: 15 additions & 3 deletions app/Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@ void Controller::prepareView()
if (this->hasInput(copyChunk))
{
this->controllerAttributions.push_back("input");

// Pass the corresposing action to the repository.
this->prepareAction(copyChunk);
}
if (this->hasOutput(copyChunk))
{
this->controllerAttributions.push_back("output");
}
if (this->hasAction(copyChunk))
{
// Pass the corresposing action to the repository.
this->prepareAction(copyChunk);

if (!this->hasInput(copyChunk))
{
this->model.signalAction(this->userInputs["action"]);
}
}

while (this->hasInput(copyChunk) || this->hasOutput(copyChunk))
{
Expand Down Expand Up @@ -225,6 +232,11 @@ bool Controller::hasOutput(const string &raw)
return raw.find(Controller::userOutputString) != string::npos;
}

bool Controller::hasAction(const string &raw)
{
return raw.find(Controller::actionString) != string::npos;
}

Controller::~Controller()
{
delete[] this->controllerName;
Expand Down
1 change: 1 addition & 0 deletions app/Controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Controller {

bool hasInput(const string &);
bool hasOutput(const string &);
bool hasAction(const string &);

vector<string> &getControllerAttributions();
char *getControllerName();
Expand Down
16 changes: 12 additions & 4 deletions app/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,23 @@ void Model::render(const string &outputAlias)
string entityName = this->parseEntityName(outputAlias),
truncatedAlias = outputAlias;

if (this->repository == NULL)
{
this->attachEntity(entityName);
}
this->attachEntity(entityName);

truncatedAlias.erase(0, entityName.size() + 1);
this->repository->echo(truncatedAlias);
}

void Model::signalAction(const string &actionAlias)
{
string entityName = this->parseEntityName(actionAlias),
truncatedAlias = actionAlias;

this->attachEntity(entityName);

truncatedAlias.erase(0, entityName.size() + 1);
this->repository->apply(truncatedAlias);
}

Model::~Model()
{
delete this->repository;
Expand Down
1 change: 1 addition & 0 deletions app/Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Model {

void confirmInput(const map<string, string> &);
void render(const string &);
void signalAction(const string &);

~Model();
};
1 change: 1 addition & 0 deletions app/ModelInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class ModelInterface {
protected:
map<string, string> attributes;
vector<string> protectedAttributes;

fstream io;
public:
virtual void save() = 0;
Expand Down
59 changes: 49 additions & 10 deletions app/QuestionModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
Question QuestionModel::setAfterUserId(int userId)
{
this->io.seekg(0, this->io.beg);

while (this->io.read(reinterpret_cast<char *>(&this->question), sizeof(question)))
{
if (this->question.user_id == userId)
Expand All @@ -23,12 +22,30 @@ Question QuestionModel::setAfterId(int id)
return this->question;
}

bool QuestionModel::setActiveIfAny()
{
if (this->question.active == true)
{
return true;
}

this->io.seekg(0, this->io.beg);
while (this->io.read(reinterpret_cast<char *>(&this->question), sizeof(Question)))
{
if (this->question.active == true)
{
return true;
}
}

return false;
}

vector<Question> QuestionModel::retrieveAll()
{
vector<Question> questions;

this->io.seekg(0, this->io.beg);

while (this->io.read(reinterpret_cast<char *>(&this->question), sizeof(Question)))
{
if (string(this->question.deleted_at) == "")
Expand All @@ -40,12 +57,31 @@ vector<Question> QuestionModel::retrieveAll()
return questions;
}

int QuestionModel::getId()
{
return this->question.id;
}

char *QuestionModel::getTitle()
{
return this->question.title;
}

char *QuestionModel::getBody()
{
return this->question.body;
}

char *QuestionModel::getCategory()
{
return "category";
}

bool QuestionModel::questionTitleExists(string &title)
{
Question question;

this->io.seekg(0, this->io.beg);

while (this->io.read(reinterpret_cast<char *>(&question), sizeof(Question)))
{
if (question.title == title)
Expand All @@ -68,24 +104,28 @@ void QuestionModel::markAnswered(int id)

void QuestionModel::markAs(const string &status, int id)
{
this->setAfterId(id);
if (id != NULL)
{
this->setAfterId(id);
}

this->question.active = (status == "active") ? true : false;

this->save();
}

// Serialize the object.
// Serialize the question.
void QuestionModel::save()
{
this->io.seekp((this->question.id - 1) * sizeof(Question), this->io.beg);

this->io.clear();

if (!this->io.write(reinterpret_cast<char *>(&this->question), sizeof(Question)))
{
throw system_error(error_code(3, generic_category()), "Failed persisting data to file!");
}

// Flush the buffer and update the destination.
this->io.flush();
}

void QuestionModel::setAttributes(map<string, string> &cleanInputs)
Expand All @@ -112,7 +152,7 @@ void QuestionModel::setAttributes(map<string, string> &cleanInputs)
{
this->question.category_id = 1;

// TODO: get the id from the static map defined in the category model.
// TODO: get the id from the category model.
}
}

Expand All @@ -121,7 +161,7 @@ void QuestionModel::setAttributes(map<string, string> &cleanInputs)
{
time_t t = time(nullptr);
strftime(this->question.created_at, sizeof(this->question.created_at), "%c", localtime(&t));
this->question.active = false;
this->question.active = true;
}

this->question.id = ++this->lastId;
Expand All @@ -137,7 +177,6 @@ void QuestionModel::dumpFile()
if (db.is_open() && dump.is_open())
{
db.seekg(0, db.beg);

while (db.read(reinterpret_cast<char *>(&question), sizeof(Question)))
{
dump << "Id: " << question.id << endl
Expand Down
8 changes: 7 additions & 1 deletion app/QuestionModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,19 @@ class QuestionModel : public ModelInterface {
static void dumpFile();
QuestionModel();

bool setActiveIfAny();
Question setAfterUserId(int);
Question setAfterId(int);
vector<Question> retrieveAll();

int getId();
char *getTitle();
char *getBody();
char *getCategory();

bool questionTitleExists(string &);
void markAnswered(int);
void markAs(const string &, int);
void markAs(const string &, int = NULL);
void save();
void setAttributes(map<string, string> &);

Expand Down
42 changes: 39 additions & 3 deletions app/QuestionRepository.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ void QuestionRepository::defineValidation()
{ "title", "..." },
{ "body", "..." },
{ "category", "..." },
{ "keyword", "..." }
{ "keyword", "..." },
{ "action", "Please provide a valid action!" }
};

Controller::pushError(string(""));
Expand Down Expand Up @@ -82,6 +83,8 @@ void QuestionRepository::receiveCleanInput(map<string, string> &cleanInput)

toast(string("Your question was created!"), string("notification"));
printString("\n");

Controller::hasRedirectTo = "show-question.view";
}
else
{
Expand All @@ -92,8 +95,36 @@ void QuestionRepository::receiveCleanInput(map<string, string> &cleanInput)
// Determine what to output via the model.
void QuestionRepository::echo(const string &alias)
{
if (alias == "")
this->model.setActiveIfAny();

if (alias == "id")
{
printString(to_string(this->model.getId()).c_str());
}
else if (alias == "title")
{
printString(this->model.getTitle());
}
else if (alias == "body")
{
printString(this->model.getBody());
}
else if (alias == "category")
{
printString(this->model.getCategory());
}
}

void QuestionRepository::apply(const string &action)
{
// Forget the active question when the action is triggered.
// TODO: The changes aren't persisted, why? (the question remains active forever)
if (action == "reset")
{
if (this->model.setActiveIfAny())
{
this->model.markAs("nonactive");
}
}
}

Expand All @@ -113,6 +144,7 @@ void QuestionRepository::validateItems(map<string, string> &truncatedInput)
toast("\n\n" + string(e.what()) + "\n", string("error"));
}

// TODO: implement a category model.
if (it->first == "category" && !isInVector(vector<string>({ "something", "tada", "c++" }), it->second))
{
Controller::pushError(string("Please provide a valid category."));
Expand All @@ -123,7 +155,11 @@ void QuestionRepository::validateItems(map<string, string> &truncatedInput)
{
if (truncatedInput.find("action")->second == "create")
{
truncatedInput["userId"] = to_string(this->users.setActive().id);
this->users = new UserModel;
truncatedInput["userId"] = to_string(this->users->setActive().id);

// Prevent multiple IO streams opened at the same time.
delete this->users;
}
this->receiveCleanInput(truncatedInput);
}
Expand Down
3 changes: 2 additions & 1 deletion app/QuestionRepository.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class QuestionRepository : public RepositoryInterface {
static string alias;

QuestionModel model;
UserModel users;
UserModel *users;

void defineValidation();
void receiveCleanInput(map<string, string> &);
Expand All @@ -24,6 +24,7 @@ class QuestionRepository : public RepositoryInterface {

void validateItems(map<string, string> &);
void echo(const string &);
void apply(const string &);

~QuestionRepository();
};
4 changes: 4 additions & 0 deletions app/RepositoryInterface.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "RepositoryInterface.h"

void RepositoryInterface::apply(const string &)
{
}

RepositoryInterface::~RepositoryInterface()
{
}
1 change: 1 addition & 0 deletions app/RepositoryInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class RepositoryInterface {
public:
virtual void validateItems(map<string, string> &) = 0;
virtual void echo(const string &) = 0;
virtual void apply(const string &);

virtual ~RepositoryInterface();
};
8 changes: 4 additions & 4 deletions app/UserModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@ void UserModel::markAs(const string &status, int id)
this->save();
}

// Serialize the object.
// Serialize the user.
void UserModel::save()
{
this->io.seekp((this->user.id - 1) * sizeof(User), this->io.beg);

// Otherwise if we reach the end of the file, the eof flag will be set and write will fail.
this->io.clear();

if (!this->io.write(reinterpret_cast<char *>(&this->user), sizeof(User)))
{
throw system_error(error_code(3, generic_category()), "Failed persisting data to file!");
}

// Flush the intermediate buffer and update the destination.
this->io.flush();
}

void UserModel::setAttributes(map<string, string> &cleanInputs)
Expand Down
Loading

0 comments on commit adc572f

Please sign in to comment.