From 7fb11b34128d3b888b352340c4cb877c6eb09ad1 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Thu, 29 Mar 2018 11:21:00 +0200 Subject: [PATCH] Added the ability to delete a recipe by name or id. --- gui/newrecipedialog.cpp | 2 +- gui/openrecipedialog.cpp | 10 +++--- gui/openrecipedialog.ui | 3 ++ main.cpp | 3 ++ model/database/database.cpp | 14 ++++++++ model/database/database.h | 1 + model/database/recipedatabase.cpp | 53 +++++++++++++++++++++++++++++++ model/database/recipedatabase.h | 5 ++- model/recipe/recipetablemodel.cpp | 2 -- 9 files changed, 84 insertions(+), 9 deletions(-) diff --git a/gui/newrecipedialog.cpp b/gui/newrecipedialog.cpp index 99459dc..ac0c89e 100644 --- a/gui/newrecipedialog.cpp +++ b/gui/newrecipedialog.cpp @@ -160,7 +160,7 @@ void NewRecipeDialog::on_removeTagButton_clicked(){ return; } RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()]; - string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue(); + string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue()+"\nThis will delete the tag for all recipes that use it."; QMessageBox::StandardButton reply = QMessageBox::question(this, QString("Delete Tag"), QString(content.c_str())); if (reply == QMessageBox::Yes){ this->recipeDB->deleteTag(tag); diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp index a910ad5..5991297 100644 --- a/gui/openrecipedialog.cpp +++ b/gui/openrecipedialog.cpp @@ -22,11 +22,11 @@ OpenRecipeDialog::~OpenRecipeDialog() void OpenRecipeDialog::populateRecipesTable(){ vector recipes = this->recipeDB->retrieveAllRecipes(); - printf("Found %d recipes:\n", recipes.size()); - for (Recipe r : recipes){ - r.print(); - printf("\n------------------\n"); - } +// printf("Found %d recipes:\n", recipes.size()); +// for (Recipe r : recipes){ +// r.print(); +// printf("\n------------------\n"); +// } this->recipeTableModel.setRecipes(recipes); ui->recipeTableView->show(); } diff --git a/gui/openrecipedialog.ui b/gui/openrecipedialog.ui index d0fca63..be20dd9 100644 --- a/gui/openrecipedialog.ui +++ b/gui/openrecipedialog.ui @@ -97,6 +97,9 @@ true + + false + diff --git a/main.cpp b/main.cpp index c786362..418b03d 100644 --- a/main.cpp +++ b/main.cpp @@ -48,6 +48,9 @@ int main(int argc, char *argv[]) // printf("Accepted the dialog.\n"); // } + bool success = recipeDB.deleteRecipe(4); + printf("Success: %d\n", success); + recipeDB.selectFrom("recipe", "recipeId, name", "").printData(); w.loadFromRecipe(recipeDB.retrieveRecipe("Generic Bread")); return a.exec(); diff --git a/model/database/database.cpp b/model/database/database.cpp index 636a137..0d3b9a4 100644 --- a/model/database/database.cpp +++ b/model/database/database.cpp @@ -46,6 +46,20 @@ ResultTable Database::selectFrom(string tableName, string columnNames, string co return this->executeSQL(query); } +bool Database::deleteFrom(string tableName, string conditions){ + if (tableName.empty()){ + return false; + } + string query = "DELETE FROM " + tableName + " " + conditions + ";"; + ResultTable t = this->executeSQL(query); + if (t.getReturnCode() != SQLITE_DONE){ + fprintf(stderr, "Can't delete from table %s.Return code: %d\n%s\n", tableName.c_str(), t.getReturnCode(), sqlite3_errmsg(this->db)); + exit(EXIT_FAILURE); + } else { + return true; + } +} + void Database::openConnection(){ this->returnCode = sqlite3_open(this->filename.c_str(), &this->db); if (this->returnCode || this->db == NULL){ diff --git a/model/database/database.h b/model/database/database.h index 4a60447..a110db7 100644 --- a/model/database/database.h +++ b/model/database/database.h @@ -26,6 +26,7 @@ public: ResultTable executeSQL(string statement); bool insertInto(string tableName, vector columnNames, vector values); ResultTable selectFrom(string tableName, string columnNames, string conditions); + bool deleteFrom(string tableName, string conditions); bool tableExists(string tableName); int getLastInsertedRowId(); diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index 81dfb14..54f9bcc 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -5,6 +5,12 @@ RecipeDatabase::RecipeDatabase(string filename) : Database(filename){ } bool RecipeDatabase::storeRecipe(Recipe recipe){ + //Some primary checks to avoid garbage in the database. + if (recipe.getName().empty() || + recipe.getInstruction().getHTML().empty() || + recipe.getIngredients().empty()){ + return false; + } //Store a recipe, if it doesn't already exist. This first tries to create the recipe entry, then all subsequent supporting table entries. this->executeSQL("BEGIN;"); ResultTable t = this->selectFrom("recipe", "*", "WHERE name="+surroundString(recipe.getName(), "'")); @@ -233,7 +239,54 @@ vector RecipeDatabase::retrieveAllTags(){ } bool RecipeDatabase::deleteRecipe(string name){ + ResultTable t = this->selectFrom("recipe", "recipeId", "WHERE name="+name); + if (t.rowCount() != 1){ + return false; + } + string recipeId = t.valueAt(0, 0); + return this->deleteRecipe(std::stoi(recipeId)); +} +bool RecipeDatabase::deleteRecipe(int recipeId){ + string idString = std::to_string(recipeId); + if (this->selectFrom("recipe", "recipeId", "WHERE recipeId="+idString).isEmpty()){ + return false; + } + this->executeSQL("BEGIN;"); + bool tagsDeleted = this->deleteFrom("recipeTag", "WHERE recipeId="+idString); + bool recipeIngredientDeleted = this->deleteFrom("recipeIngredient", "WHERE recipeId="+idString); + bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString); + if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){ + this->executeSQL("COMMIT;"); + return true; + } else { + this->executeSQL("ROLLBACK;"); + return false; + } +} + +bool RecipeDatabase::deleteIngredient(string name){ + ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE ingredientId=(" + "SELECT ingredientId" + "FROM ingredient" + "WHERE name="+name+")"); + if (!t.isEmpty()){ + //There is at least one recipe dependent on the ingredient. + return false; + } + return this->deleteFrom("ingredient", "WHERE name="+name); +} + +bool RecipeDatabase::deleteUnitOfMeasure(string name){ + ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE unitName="+name); + if (!t.isEmpty()){ + return false; + } + return this->deleteFrom("unitOfMeasure", "WHERE name="+name); +} + +bool RecipeDatabase::deleteTag(RecipeTag tag){ + return this->deleteFrom("recipeTag", "WHERE tagName="+tag.getValue()); } void RecipeDatabase::ensureTablesExist(){ diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index c36f061..b240166 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -41,7 +41,10 @@ class RecipeDatabase : public Database //Deletion. bool deleteRecipe(string name); - void deleteTag(RecipeTag tag); + bool deleteRecipe(int recipeId); + bool deleteIngredient(string name); + bool deleteUnitOfMeasure(string name); + bool deleteTag(RecipeTag tag); private: //Utility methods. diff --git a/model/recipe/recipetablemodel.cpp b/model/recipe/recipetablemodel.cpp index 1b00a55..a22c7b6 100644 --- a/model/recipe/recipetablemodel.cpp +++ b/model/recipe/recipetablemodel.cpp @@ -45,8 +45,6 @@ QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation, return "Name"; case 1: return "Created On"; - case 2: - default: return QVariant(); }