From e0dda644128aea9cc32cf023e4771d90400bc6a3 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Fri, 30 Mar 2018 19:43:39 +0200 Subject: [PATCH 1/4] Added screenshot to readme. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b84335d..e46c739 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Recipe DB +![screenshot](http://i.imgur.com/FbltFit.png) + Recipe DB is a simple, lightweight database powered by Qt and SQLite to allow you to save, retrieve, and search through many recipes without needing to be connected to the internet. Meant as a tool for those who enjoy making recipes their own, this tool lets you edit recipes, search by ingredients or food groups, and filter out recipes that meet certain criteria. Recipe DB was created initially out of a desire to organize my many recipes in one uniform way, as simply as possible, while still making sure that retrieving any given recipe is as effortless as possible. I wanted something where I could save recipes offline, change them if I need to, convert units on-the-fly, and add a few other small utilities that would save a few precious minutes in the kitchen. ### How it works -- 2.34.1 From 4170df7fc8657a867b202e0aaff5ce2fc6b8b509 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Fri, 30 Mar 2018 20:57:14 +0200 Subject: [PATCH 2/4] Added filtering by ingredient to search window. --- gui/openrecipedialog.cpp | 23 +++++++++-------- gui/openrecipedialog.h | 4 +-- model/database/recipedatabase.cpp | 41 +++++++++++++++++++++++++++---- model/database/recipedatabase.h | 2 ++ 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp index 648beb9..4c961cd 100644 --- a/gui/openrecipedialog.cpp +++ b/gui/openrecipedialog.cpp @@ -11,17 +11,17 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) : ui->ingredientsListView->setModel(&this->ingredientsModel); ui->tagsListView->setModel(&this->tagsModel); - connect(ui->ingredientsListView->selectionModel(), - SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + QObject::connect(ui->ingredientsListView->selectionModel(), + SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, - SLOT(on_ingredientsListView_selectionChanged(QItemSelection))); + SLOT(onIngredientsListViewSelectionChanged(QItemSelection))); } OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){ this->recipeDB = recipeDB; this->populateIngredientsList(); this->populateTagsList(); - this->populateRecipesTable(); + this->populateRecipesTable(this->recipeDB->retrieveAllRecipes()); } OpenRecipeDialog::~OpenRecipeDialog() @@ -33,9 +33,8 @@ Recipe OpenRecipeDialog::getSelectedRecipe(){ return this->selectedRecipe; } -void OpenRecipeDialog::populateRecipesTable(){ +void OpenRecipeDialog::populateRecipesTable(vector recipes){ this->recipeTableModel.clear(); - vector recipes = this->recipeDB->retrieveAllRecipes(); this->recipeTableModel.setRecipes(recipes); ui->recipeTableView->resizeColumnsToContents(); ui->recipeTableView->show(); @@ -69,9 +68,10 @@ void OpenRecipeDialog::on_deleteRecipeButton_clicked(){ bool success = this->recipeDB->deleteRecipe(r.getName()); if (!success){ QMessageBox::critical(this, QString::fromStdString("Unable to Delete"), QString::fromStdString("Could not delete recipe "+r.getName())); + } else { + this->populateRecipesTable(this->recipeDB->retrieveAllRecipes()); } } - this->populateRecipesTable(); } } @@ -80,13 +80,12 @@ void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index this->close(); } -void OpenRecipeDialog::on_ingredientsListView_selectionChanged(const QItemSelection &selection){ - printf("Selection changed!\n"); +void OpenRecipeDialog::onIngredientsListViewSelectionChanged(const QItemSelection &selection){ vector ingredients; - for (QModelIndex index : selection.indexes()){ + QModelIndexList indexes = ui->ingredientsListView->selectionModel()->selectedRows(); + for (QModelIndex index : indexes){ Ingredient i = this->ingredientsModel.getIngredients().at(index.row()); ingredients.push_back(i); - printf("Selected: %s\n", i.getName().c_str()); } - + this->populateRecipesTable(this->recipeDB->retrieveRecipesWithIngredients(ingredients)); } diff --git a/gui/openrecipedialog.h b/gui/openrecipedialog.h index 44c56f9..753c206 100644 --- a/gui/openrecipedialog.h +++ b/gui/openrecipedialog.h @@ -30,7 +30,7 @@ class OpenRecipeDialog : public QDialog void on_recipeTableView_doubleClicked(const QModelIndex &index); - void on_ingredientsListView_selectionChanged(const QItemSelection &selection); + void onIngredientsListViewSelectionChanged(const QItemSelection &selection); private: Ui::OpenRecipeDialog *ui; @@ -41,7 +41,7 @@ class OpenRecipeDialog : public QDialog IngredientListModel ingredientsModel; TagListModel tagsModel; - void populateRecipesTable(); + void populateRecipesTable(vector recipes); void populateIngredientsList(); void populateTagsList(); }; diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index 1eeebd3..7e8ab6c 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -158,14 +158,35 @@ Recipe RecipeDatabase::retrieveRandomRecipe(){ } return this->readFromResultTable(t); } - +//TODO: Change this to be more efficient! One query per recipe is not good! vector RecipeDatabase::retrieveAllRecipes(){ - ResultTable t = this->selectFrom("recipe", "name", "ORDER BY name"); + ResultTable t = this->executeSQL("SELECT * FROM recipe ORDER BY name;"); + return this->readRecipesFromTable(t); +} + +vector RecipeDatabase::retrieveRecipesWithIngredients(vector ingredients){ vector recipes; - for (TableRow row : t.rows()){ - recipes.push_back(this->retrieveRecipe(row.at(0))); + if (ingredients.empty()){ + return recipes; } - return recipes; + string filterList = surroundString(ingredients.at(0).getName(), "'"); + for (unsigned int i = 1; i < ingredients.size(); i++){ + filterList += ", " + surroundString(ingredients[i].getName(), "'"); + } + filterList = '(' + filterList + ')'; + ResultTable t = this->executeSQL("SELECT * " + "FROM recipe " + "WHERE recipeId IN (" + " SELECT recipeIngredient.recipeId " + " FROM recipeIngredient " + " INNER JOIN (" + " SELECT ingredientId " + " FROM ingredient " + " WHERE name IN "+filterList+"" + " ) filteredIngredients " + " ON recipeIngredient.ingredientId = filteredIngredients.ingredientId" + ") ORDER BY name;"); + return this->readRecipesFromTable(t); } vector RecipeDatabase::retrieveAllFoodGroups(){ @@ -360,3 +381,13 @@ Recipe RecipeDatabase::readFromResultTable(ResultTable t, int tRow){ r.setTags(this->retrieveTags(id)); return r; } + +//Retrieves recipes from a table with the following format: +// id, name, createdDate, prepTime, cookTime, servings +vector RecipeDatabase::readRecipesFromTable(ResultTable t){ + vector recipes; + for (unsigned int row = 0; row < t.rowCount(); row++){ + recipes.push_back(readFromResultTable(t, row)); + } + return recipes; +} diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index 79ff7bd..f58dd19 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -34,6 +34,7 @@ class RecipeDatabase : public Database Recipe retrieveRecipe(string name); Recipe retrieveRandomRecipe(); vector retrieveAllRecipes(); + vector retrieveRecipesWithIngredients(vector ingredients); vector retrieveAllFoodGroups(); vector retrieveRecipeIngredients(int recipeId); vector retrieveAllIngredients(); @@ -53,6 +54,7 @@ class RecipeDatabase : public Database void ensureTablesExist(); //Read a recipe from a row of a result table. Recipe readFromResultTable(ResultTable t, int row=0); + vector readRecipesFromTable(ResultTable t); }; #endif // RECIPEDATABASE_H -- 2.34.1 From f13432a2feebe3dfa9616dc61feb73f7b2e9f0d7 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Fri, 30 Mar 2018 22:50:02 +0200 Subject: [PATCH 3/4] Added search by food group. --- gui/openrecipedialog.cpp | 38 +++++++ gui/openrecipedialog.h | 7 ++ gui/openrecipedialog.ui | 172 ++++++++++++++++++------------ model/database/recipedatabase.cpp | 33 ++++++ model/database/recipedatabase.h | 3 + 5 files changed, 185 insertions(+), 68 deletions(-) diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp index 4c961cd..184ea18 100644 --- a/gui/openrecipedialog.cpp +++ b/gui/openrecipedialog.cpp @@ -15,12 +15,17 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) : SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(onIngredientsListViewSelectionChanged(QItemSelection))); + QObject::connect(ui->tagsListView->selectionModel(), + SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, + SLOT(onTagsListViewSelectionChanged(QItemSelection))); } OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){ this->recipeDB = recipeDB; this->populateIngredientsList(); this->populateTagsList(); + this->populateFoodGroupsList(); this->populateRecipesTable(this->recipeDB->retrieveAllRecipes()); } @@ -48,6 +53,13 @@ void OpenRecipeDialog::populateTagsList(){ this->tagsModel.setTags(this->recipeDB->retrieveAllTags()); } +void OpenRecipeDialog::populateFoodGroupsList(){ + for (string s : this->recipeDB->retrieveAllFoodGroups()){ + ui->foodGroupsListWidget->addItem(QString::fromStdString(s)); + } + //ui->foodGroupsListWidget->show(); +} + void OpenRecipeDialog::on_deleteRecipeButton_clicked(){ QItemSelectionModel *selectModel = ui->recipeTableView->selectionModel(); if (!selectModel->hasSelection()){ @@ -81,6 +93,7 @@ void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index } void OpenRecipeDialog::onIngredientsListViewSelectionChanged(const QItemSelection &selection){ + Q_UNUSED(selection); vector ingredients; QModelIndexList indexes = ui->ingredientsListView->selectionModel()->selectedRows(); for (QModelIndex index : indexes){ @@ -89,3 +102,28 @@ void OpenRecipeDialog::onIngredientsListViewSelectionChanged(const QItemSelectio } this->populateRecipesTable(this->recipeDB->retrieveRecipesWithIngredients(ingredients)); } + +void OpenRecipeDialog::onTagsListViewSelectionChanged(const QItemSelection &selection){ + Q_UNUSED(selection); + vector tags; + QModelIndexList indexes = ui->tagsListView->selectionModel()->selectedRows(); + for (QModelIndex index : indexes){ + RecipeTag t = this->tagsModel.getTags().at(index.row()); + tags.push_back(t); + } + this->populateRecipesTable(this->recipeDB->retrieveRecipesWithTags(tags)); +} + +void OpenRecipeDialog::on_nameEdit_textChanged(const QString &arg1){ + Q_UNUSED(arg1); + this->populateRecipesTable(this->recipeDB->retrieveRecipesWithSubstring(ui->nameEdit->text().toStdString())); +} + +void OpenRecipeDialog::on_foodGroupsListWidget_itemSelectionChanged(){ + vector groups; + for (QModelIndex index : ui->foodGroupsListWidget->selectionModel()->selectedRows()){ + QListWidgetItem *item = ui->foodGroupsListWidget->item(index.row()); + groups.push_back(item->text().toStdString()); + } + this->populateRecipesTable(this->recipeDB->retrieveRecipesWithFoodGroups(groups)); +} diff --git a/gui/openrecipedialog.h b/gui/openrecipedialog.h index 753c206..8e63496 100644 --- a/gui/openrecipedialog.h +++ b/gui/openrecipedialog.h @@ -32,6 +32,12 @@ class OpenRecipeDialog : public QDialog void onIngredientsListViewSelectionChanged(const QItemSelection &selection); + void onTagsListViewSelectionChanged(const QItemSelection &selection); + + void on_nameEdit_textChanged(const QString &arg1); + + void on_foodGroupsListWidget_itemSelectionChanged(); + private: Ui::OpenRecipeDialog *ui; RecipeDatabase *recipeDB; @@ -44,6 +50,7 @@ class OpenRecipeDialog : public QDialog void populateRecipesTable(vector recipes); void populateIngredientsList(); void populateTagsList(); + void populateFoodGroupsList(); }; #endif // OPENRECIPEDIALOG_H diff --git a/gui/openrecipedialog.ui b/gui/openrecipedialog.ui index 0e51715..93cb94b 100644 --- a/gui/openrecipedialog.ui +++ b/gui/openrecipedialog.ui @@ -6,7 +6,7 @@ 0 0 - 1000 + 1064 480 @@ -25,73 +25,109 @@ - - - - - - Tag - - - - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QAbstractItemView::ExtendedSelection - - - false - - - false - - - - - - - - - - - - - Ingredient - - - - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QAbstractItemView::ExtendedSelection - - - false - - - true - - - - + + + + 290 + 0 + + + + QTabWidget::South + + + QTabWidget::Rounded + + + 2 + + + + Tags + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::ScrollPerPixel + + + false + + + true + + + + + + + + Ingredients + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::ScrollPerPixel + + + false + + + true + + + + + + + + Food Groups + + + + + + QFrame::NoFrame + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::ScrollPerPixel + + + true + + + + + diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index 7e8ab6c..c05355b 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -189,6 +189,39 @@ vector RecipeDatabase::retrieveRecipesWithIngredients(vector return this->readRecipesFromTable(t); } +vector RecipeDatabase::retrieveRecipesWithTags(vector tags){ + vector recipes; + if (tags.empty()){ + return recipes; + } + string filterList = surroundString(tags.at(0).getValue(), "'"); + for (unsigned int i = 1; i < tags.size(); i++){ + filterList += ", " + surroundString(tags[i].getValue(), "'"); + } + filterList = '(' + filterList + ')'; + ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE recipeId IN (SELECT recipeId FROM recipeTag WHERE tagName IN "+filterList+" );"); + return this->readRecipesFromTable(t); +} + +vector RecipeDatabase::retrieveRecipesWithSubstring(string s){ + ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE name LIKE '%"+s+"%' COLLATE NOCASE;"); + return this->readRecipesFromTable(t); +} + +vector RecipeDatabase::retrieveRecipesWithFoodGroups(vector groups){ + vector recipes; + if (groups.empty()){ + return recipes; + } + string filterList = surroundString(groups.at(0), "'"); + for (unsigned int i = 1; i < groups.size(); i++){ + filterList += ", " + surroundString(groups.at(i), "'"); + } + filterList = '(' + filterList + ')'; + ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE recipeId IN (SELECT recipeId FROM recipeIngredient WHERE ingredientId IN (SELECT ingredientId FROM ingredient WHERE foodGroup IN "+filterList+" ) ) ORDER BY name;"); + return this->readRecipesFromTable(t); +} + vector RecipeDatabase::retrieveAllFoodGroups(){ ResultTable t = this->executeSQL("SELECT DISTINCT foodGroup FROM ingredient ORDER BY foodGroup;"); vector foodGroups; diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index f58dd19..34c767d 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -35,6 +35,9 @@ class RecipeDatabase : public Database Recipe retrieveRandomRecipe(); vector retrieveAllRecipes(); vector retrieveRecipesWithIngredients(vector ingredients); + vector retrieveRecipesWithTags(vector tags); + vector retrieveRecipesWithSubstring(string s); + vector retrieveRecipesWithFoodGroups(vector groups); vector retrieveAllFoodGroups(); vector retrieveRecipeIngredients(int recipeId); vector retrieveAllIngredients(); -- 2.34.1 From 6597efa646dbc5df0c98373e584c99aee0e14e4d Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Fri, 30 Mar 2018 23:25:28 +0200 Subject: [PATCH 4/4] Added ability to edit recipe (WIP). --- gui/mainwindow.cpp | 15 +++++++++++++++ gui/mainwindow.h | 3 +++ gui/mainwindow.ui | 15 +++++++++------ gui/newrecipedialog.cpp | 11 +++++++++++ gui/newrecipedialog.h | 1 + main.cpp | 22 +++++++++++----------- model/database/recipedatabase.cpp | 4 ++++ model/database/recipedatabase.h | 3 +++ 8 files changed, 57 insertions(+), 17 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 7db6bbe..d2de990 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -31,6 +31,7 @@ void MainWindow::loadFromRecipe(Recipe recipe){ setCookTime(recipe.getCookTime()); setServings(recipe.getServings()); setTags(recipe.getTags()); + this->currentRecipe = recipe; } void MainWindow::setRecipeName(string name){ @@ -91,3 +92,17 @@ void MainWindow::on_openButton_clicked(){ void MainWindow::on_exitButton_clicked(){ this->close(); } + +void MainWindow::on_editButton_clicked(){ + NewRecipeDialog d(this->recipeDB, this->currentRecipe, this); + d.show(); + d.exec(); + if (d.isAccepted()){ + Recipe r = d.getRecipe(); + if (!this->recipeDB->storeRecipe(r)){ + 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/mainwindow.h b/gui/mainwindow.h index 03e802a..3ce5cf4 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -36,11 +36,14 @@ public: void on_exitButton_clicked(); + void on_editButton_clicked(); + private: Ui::MainWindow *ui; RecipeDatabase *recipeDB; RecipeIngredientListModel ingredientModel; TagListModel tagsListModel; + Recipe currentRecipe; //Hidden manipulation methods. void setRecipeName(string name); diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index 4ac1f88..23922da 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -180,9 +180,9 @@ QPushButton#openButton:pressed{ - + - false + true @@ -201,19 +201,19 @@ QPushButton#openButton:pressed{ false - QPushButton#browseButton { + QPushButton#editButton { background-color: rgb(215, 215, 255); border: 0px; } -QPushButton#browseButton:hover{ +QPushButton#editButton:hover{ background-color: rgb(225, 225, 255); } -QPushButton#browseButton:pressed{ +QPushButton#editButton:pressed{ background-color: rgb(255, 255, 255); } - Browse + Edit false @@ -363,6 +363,9 @@ font: "Noto Sans CJK KR"; + + false + 0 diff --git a/gui/newrecipedialog.cpp b/gui/newrecipedialog.cpp index c105333..3825ad1 100644 --- a/gui/newrecipedialog.cpp +++ b/gui/newrecipedialog.cpp @@ -21,6 +21,17 @@ NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, QWidget *parent) : NewRecip this->populateTagsBox(); } +NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, Recipe recipe, QWidget *parent) : NewRecipeDialog(db, parent){ + ui->recipeNameEdit->setText(QString::fromStdString(recipe.getName())); + ui->prepTimeEdit->setTime(recipe.getPrepTime()); + ui->cookTimeEdit->setTime(recipe.getCookTime()); + ui->servingsSpinBox->setValue((double)recipe.getServings()); + ui->instructionsTextEdit->setHtml(QString::fromStdString(recipe.getInstruction().getHTML())); + ui->imageDisplayLabel->setPixmap(QPixmap::fromImage(recipe.getImage())); + this->tagsListModel.setTags(recipe.getTags()); + this->ingredientListModel.setIngredients(recipe.getIngredients()); +} + NewRecipeDialog::~NewRecipeDialog(){ delete ui; } diff --git a/gui/newrecipedialog.h b/gui/newrecipedialog.h index 181cea2..105cd37 100644 --- a/gui/newrecipedialog.h +++ b/gui/newrecipedialog.h @@ -26,6 +26,7 @@ class NewRecipeDialog : public QDialog public: explicit NewRecipeDialog(QWidget *parent = 0); NewRecipeDialog(RecipeDatabase *db, QWidget *parent = 0); + NewRecipeDialog(RecipeDatabase *db, Recipe recipe, QWidget *parent = 0); ~NewRecipeDialog(); Recipe getRecipe(); diff --git a/main.cpp b/main.cpp index 2a70cec..940cd9d 100644 --- a/main.cpp +++ b/main.cpp @@ -48,18 +48,18 @@ void test(RecipeDatabase *recipeDB){ bool success = recipeDB->storeRecipe(rec); printf("Storage successful: %d\n", success); - vector foodGroups = recipeDB->retrieveAllFoodGroups(); - printf("Food Groups:\n"); - for (string s : foodGroups){ - printf("\t%s\n", s.c_str()); - } +// vector foodGroups = recipeDB->retrieveAllFoodGroups(); +// printf("Food Groups:\n"); +// for (string s : foodGroups){ +// printf("\t%s\n", s.c_str()); +// } //Get food groups from recipe. - Recipe r = recipeDB->retrieveRecipe("Pannenkoeken"); - vector foodGroupsR = r.getFoodGroups(); - printf("Pannenkoeken Food Groups:\n"); - for (string s : foodGroupsR){ - printf("\t%s\n", s.c_str()); - } +// Recipe r = recipeDB->retrieveRecipe("Pannenkoeken"); +// vector foodGroupsR = r.getFoodGroups(); +// printf("Pannenkoeken Food Groups:\n"); +// for (string s : foodGroupsR){ +// printf("\t%s\n", s.c_str()); +// } } diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index c05355b..1a9f83a 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -356,6 +356,10 @@ bool RecipeDatabase::deleteTag(RecipeTag tag){ return this->deleteFrom("recipeTag", "WHERE tagName='"+tag.getValue()+"'"); } +bool RecipeDatabase::updateRecipe(Recipe recipe){ + +} + void RecipeDatabase::ensureTablesExist(){ //Make sure that foreign keys are enabled. this->executeSQL("PRAGMA foreign_keys = ON;"); diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index 34c767d..c68b0c9 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -51,6 +51,9 @@ class RecipeDatabase : public Database bool deleteIngredient(string name); bool deleteUnitOfMeasure(string name); bool deleteTag(RecipeTag tag); + + //Updating. + bool updateRecipe(Recipe recipe); private: //Utility methods. -- 2.34.1