diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index d2de990..bc09378 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -95,11 +95,12 @@ void MainWindow::on_exitButton_clicked(){
void MainWindow::on_editButton_clicked(){
NewRecipeDialog d(this->recipeDB, this->currentRecipe, this);
+ string originalName = this->currentRecipe.getName();
d.show();
d.exec();
if (d.isAccepted()){
Recipe r = d.getRecipe();
- if (!this->recipeDB->storeRecipe(r)){
+ if (!this->recipeDB->updateRecipe(r, originalName)){
QMessageBox::critical(this, QString("Unable to Save Recipe"), QString("The program was not able to successfully save the recipe. Make sure to give the recipe a name, instructions, and some ingredients!"));
} else {
this->loadFromRecipe(r);
diff --git a/gui/newrecipedialog.ui b/gui/newrecipedialog.ui
index 937ee33..a42a7a2 100644
--- a/gui/newrecipedialog.ui
+++ b/gui/newrecipedialog.ui
@@ -100,7 +100,6 @@
- 16
3
false
false
@@ -142,7 +141,7 @@
0
1999
12
- 24
+ 23
@@ -352,6 +351,9 @@
QAbstractItemView::MultiSelection
+
+ QAbstractItemView::ScrollPerPixel
+
@@ -667,6 +669,9 @@
QAbstractItemView::MultiSelection
+
+ QAbstractItemView::ScrollPerPixel
+
100
@@ -746,16 +751,6 @@
background-color: rgb(250, 250, 255);
- -
-
-
- Instructions
-
-
- Qt::AlignCenter
-
-
-
-
@@ -769,7 +764,7 @@
- I
+ Italic
true
@@ -789,7 +784,7 @@
- B
+ Bold
true
@@ -827,7 +822,7 @@
Qt::LeftToRight
- true
+ false
background-color: rgb(255, 255, 255);
diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp
index 184ea18..c0458b8 100644
--- a/gui/openrecipedialog.cpp
+++ b/gui/openrecipedialog.cpp
@@ -127,3 +127,11 @@ void OpenRecipeDialog::on_foodGroupsListWidget_itemSelectionChanged(){
}
this->populateRecipesTable(this->recipeDB->retrieveRecipesWithFoodGroups(groups));
}
+
+void OpenRecipeDialog::on_clearSearchButton_clicked(){
+ ui->nameEdit->clear();
+ ui->foodGroupsListWidget->selectionModel()->clearSelection();
+ ui->tagsListView->selectionModel()->clearSelection();
+ ui->ingredientsListView->selectionModel()->clearSelection();
+ this->populateRecipesTable(this->recipeDB->retrieveAllRecipes());
+}
diff --git a/gui/openrecipedialog.h b/gui/openrecipedialog.h
index 8e63496..f0989da 100644
--- a/gui/openrecipedialog.h
+++ b/gui/openrecipedialog.h
@@ -38,6 +38,8 @@ class OpenRecipeDialog : public QDialog
void on_foodGroupsListWidget_itemSelectionChanged();
+ void on_clearSearchButton_clicked();
+
private:
Ui::OpenRecipeDialog *ui;
RecipeDatabase *recipeDB;
diff --git a/gui/openrecipedialog.ui b/gui/openrecipedialog.ui
index 93cb94b..460e738 100644
--- a/gui/openrecipedialog.ui
+++ b/gui/openrecipedialog.ui
@@ -147,13 +147,9 @@
-
-
+
-
-
-
-
- :/images/images/search_icon.png:/images/images/search_icon.png
+ Clear search criteria
diff --git a/model/database/database.cpp b/model/database/database.cpp
index db53c3f..6e914b0 100644
--- a/model/database/database.cpp
+++ b/model/database/database.cpp
@@ -14,12 +14,11 @@ ResultTable Database::executeSQL(string statement){
sqlite3_stmt* stmt;
this->sql = statement;
this->returnCode = sqlite3_prepare_v2(this->db, statement.c_str(), -1, &stmt, NULL);
- ResultTable t(statement);
if (this->returnCode != SQLITE_OK){
fprintf(stderr, "Unable to successfully prepare SQL statement. Error code: %d\n\tError Message: %s\n", this->returnCode, sqlite3_errmsg(this->db));
- return t;
+ return ResultTable(this->returnCode);
}
-
+ ResultTable t(statement);
t.extractData(stmt);
this->returnCode = sqlite3_finalize(stmt);
@@ -78,6 +77,18 @@ void Database::closeConnection(){
this->dbIsOpen = false;
}
+void Database::beginTransaction(){
+ this->executeSQL("BEGIN;");
+}
+
+void Database::commitTransaction(){
+ this->executeSQL("COMMIT;");
+}
+
+void Database::rollbackTransaction(){
+ this->executeSQL("ROLLBACK;");
+}
+
string Database::combineVector(std::vector strings, string mid){
if (strings.empty()){
return "";
diff --git a/model/database/database.h b/model/database/database.h
index d0bd435..0ccc9fd 100644
--- a/model/database/database.h
+++ b/model/database/database.h
@@ -35,6 +35,10 @@ public:
void closeConnection();
+ void beginTransaction();
+ void commitTransaction();
+ void rollbackTransaction();
+
protected:
string surroundString(string s, string surround);
diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp
index 1a9f83a..0ebd528 100644
--- a/model/database/recipedatabase.cpp
+++ b/model/database/recipedatabase.cpp
@@ -253,6 +253,18 @@ vector RecipeDatabase::retrieveRecipeIngredients(int recipeId)
return ings;
}
+int RecipeDatabase::retrieveIngredientId(string ingredientName){
+ return std::stoi(this->selectFrom("ingredient", "ingredientId", "WHERE name = '"+ingredientName+"'").at(0, 0));
+}
+
+bool RecipeDatabase::deleteRecipeTags(int recipeId){
+ return this->deleteFrom("recipeTag", "WHERE recipeId = "+std::to_string(recipeId));
+}
+
+bool RecipeDatabase::deleteRecipeIngredients(int recipeId){
+ return this->deleteFrom("recipeIngredient", "WHERE recipeId = "+std::to_string(recipeId));
+}
+
vector RecipeDatabase::retrieveAllIngredients(){
ResultTable t = this->selectFrom("ingredient", "name, foodGroup", "ORDER BY name");
vector ings;
@@ -356,8 +368,71 @@ bool RecipeDatabase::deleteTag(RecipeTag tag){
return this->deleteFrom("recipeTag", "WHERE tagName='"+tag.getValue()+"'");
}
-bool RecipeDatabase::updateRecipe(Recipe recipe){
-
+bool RecipeDatabase::updateRecipe(Recipe recipe, string originalName) {
+ string idS = this->selectFrom("recipe", "recipeId", "WHERE name="+surroundString(originalName, "'")).at(0, 0);
+ int id = std::stoi(idS);
+ this->beginTransaction();
+ ResultTable t = this->executeSQL("UPDATE recipe "
+ "SET name = '"+recipe.getName()+"', "
+ "createdDate = '"+recipe.getCreatedDate().toString().toStdString()+"', "
+ "prepTime = '"+recipe.getPrepTime().toString().toStdString()+"', "
+ "cookTime = '"+recipe.getCookTime().toString().toStdString()+"', "
+ "servingCount = "+std::to_string(recipe.getServings())+" "
+ "WHERE recipeId = "+idS+";");
+ bool recipeSuccess = t.getReturnCode() == SQLITE_DONE;
+ if (!recipeSuccess){
+ this->rollbackTransaction();
+ return false;
+ }
+ bool tagsSuccess = this->deleteRecipeTags(id);
+ for (RecipeTag tag : recipe.getTags()){
+ tagsSuccess = tagsSuccess && this->insertInto(
+ "recipeTag",
+ vector({
+ "recipeId",
+ "tagName"
+ }),
+ vector({
+ idS,
+ tag.getValue()
+ }));
+ }
+ if (!tagsSuccess){
+ this->rollbackTransaction();
+ return false;
+ }
+ bool ingredientsSuccess = this->deleteRecipeIngredients(id);
+ for (RecipeIngredient ri : recipe.getIngredients()){
+ ingredientsSuccess = ingredientsSuccess && this->insertInto(
+ "recipeIngredient",
+ vector({
+ "recipeId",
+ "ingredientId",
+ "unitName",
+ "quantity",
+ "comment"
+ }),
+ vector({
+ idS,
+ std::to_string(this->retrieveIngredientId(ri.getName())),
+ ri.getUnit().getName(),
+ std::to_string(ri.getQuantity()),
+ ri.getComment()
+ }));
+ }
+ if (!ingredientsSuccess){
+ this->rollbackTransaction();
+ return false;
+ }
+ bool instructionSuccess = FileUtils::saveInstruction(id, recipe.getInstruction());
+ bool imageSuccess = FileUtils::saveImage(id, recipe.getImage());
+ if (!(instructionSuccess && imageSuccess)){
+ this->rollbackTransaction();
+ return false;
+ } else {
+ this->commitTransaction();
+ return true;
+ }
}
void RecipeDatabase::ensureTablesExist(){
diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h
index c68b0c9..2b80d95 100644
--- a/model/database/recipedatabase.h
+++ b/model/database/recipedatabase.h
@@ -26,9 +26,6 @@ class RecipeDatabase : public Database
bool storeRecipeIngredient(RecipeIngredient ri, int recipeId);
int storeIngredient(Ingredient ingredient);
bool storeUnitOfMeasure(UnitOfMeasure u);
- bool storeInstruction(Instruction instruction, int recipeId);
- bool storeImage(QImage image, int recipeId);
- bool storeTags(vector tags, int recipeId);
//Retrieval.
Recipe retrieveRecipe(string name);
@@ -39,10 +36,8 @@ class RecipeDatabase : public Database
vector retrieveRecipesWithSubstring(string s);
vector retrieveRecipesWithFoodGroups(vector groups);
vector retrieveAllFoodGroups();
- vector retrieveRecipeIngredients(int recipeId);
vector retrieveAllIngredients();
vector retrieveAllUnitsOfMeasure();
- vector retrieveTags(int recipeId);
vector retrieveAllTags();
//Deletion.
@@ -53,7 +48,7 @@ class RecipeDatabase : public Database
bool deleteTag(RecipeTag tag);
//Updating.
- bool updateRecipe(Recipe recipe);
+ bool updateRecipe(Recipe recipe, string originalName);
private:
//Utility methods.
@@ -61,6 +56,20 @@ class RecipeDatabase : public Database
//Read a recipe from a row of a result table.
Recipe readFromResultTable(ResultTable t, int row=0);
vector readRecipesFromTable(ResultTable t);
+
+ //Storage
+ bool storeInstruction(Instruction instruction, int recipeId);
+ bool storeImage(QImage image, int recipeId);
+ bool storeTags(vector tags, int recipeId);
+
+ //Retrieval
+ vector retrieveTags(int recipeId);
+ vector retrieveRecipeIngredients(int recipeId);
+ int retrieveIngredientId(string ingredientName);
+
+ //Deletion
+ bool deleteRecipeTags(int recipeId);
+ bool deleteRecipeIngredients(int recipeId);
};
#endif // RECIPEDATABASE_H
diff --git a/model/database/resulttable.cpp b/model/database/resulttable.cpp
index ac96d7b..a8a3ac0 100644
--- a/model/database/resulttable.cpp
+++ b/model/database/resulttable.cpp
@@ -8,6 +8,10 @@ ResultTable::ResultTable(string query){
this->originalQuery = query;
}
+ResultTable::ResultTable(int resultCode){
+ this->queryCode = resultCode;
+}
+
void ResultTable::extractData(sqlite3_stmt *stmt){
this->values.clear();
int res = sqlite3_step(stmt);
@@ -30,6 +34,7 @@ void ResultTable::processRow(sqlite3_stmt *stmt){
}
void ResultTable::printData(){
+ printf("--> Result Code: [%d] <--\n", this->getReturnCode());
if (this->isEmpty()){
printf("Result table is empty.\n");
return;
diff --git a/model/database/resulttable.h b/model/database/resulttable.h
index a4dcd84..361f75c 100644
--- a/model/database/resulttable.h
+++ b/model/database/resulttable.h
@@ -21,6 +21,8 @@ class ResultTable
ResultTable();
//Constructs a table with the original query saved.
ResultTable(string query);
+ //Constructs an empty table with a result code.
+ ResultTable(int resultCode);
//Gets all the data from the result set and stores it internally as strings.
void extractData(sqlite3_stmt* stmt);