Almost at full release. #9
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -180,9 +180,9 @@ QPushButton#openButton:pressed{
|
|||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QPushButton" name="browseButton">
|
||||
<widget class="QPushButton" name="editButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
|
@ -201,19 +201,19 @@ QPushButton#openButton:pressed{
|
|||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#browseButton {
|
||||
<string notr="true">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);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse</string>
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
|
@ -363,6 +363,9 @@ font: "Noto Sans CJK KR";</string>
|
|||
</item>
|
||||
<item alignment="Qt::AlignLeft|Qt::AlignBottom">
|
||||
<widget class="QLabel" name="authorLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -11,17 +11,22 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) :
|
|||
ui->ingredientsListView->setModel(&this->ingredientsModel);
|
||||
ui->tagsListView->setModel(&this->tagsModel);
|
||||
|
||||
connect(ui->ingredientsListView->selectionModel(),
|
||||
QObject::connect(ui->ingredientsListView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||
this,
|
||||
SLOT(onIngredientsListViewSelectionChanged(QItemSelection)));
|
||||
QObject::connect(ui->tagsListView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this,
|
||||
SLOT(on_ingredientsListView_selectionChanged(QItemSelection)));
|
||||
SLOT(onTagsListViewSelectionChanged(QItemSelection)));
|
||||
}
|
||||
|
||||
OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){
|
||||
this->recipeDB = recipeDB;
|
||||
this->populateIngredientsList();
|
||||
this->populateTagsList();
|
||||
this->populateRecipesTable();
|
||||
this->populateFoodGroupsList();
|
||||
this->populateRecipesTable(this->recipeDB->retrieveAllRecipes());
|
||||
}
|
||||
|
||||
OpenRecipeDialog::~OpenRecipeDialog()
|
||||
|
@ -33,9 +38,8 @@ Recipe OpenRecipeDialog::getSelectedRecipe(){
|
|||
return this->selectedRecipe;
|
||||
}
|
||||
|
||||
void OpenRecipeDialog::populateRecipesTable(){
|
||||
void OpenRecipeDialog::populateRecipesTable(vector<Recipe> recipes){
|
||||
this->recipeTableModel.clear();
|
||||
vector<Recipe> recipes = this->recipeDB->retrieveAllRecipes();
|
||||
this->recipeTableModel.setRecipes(recipes);
|
||||
ui->recipeTableView->resizeColumnsToContents();
|
||||
ui->recipeTableView->show();
|
||||
|
@ -49,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()){
|
||||
|
@ -69,9 +80,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 +92,38 @@ 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){
|
||||
Q_UNUSED(selection);
|
||||
vector<Ingredient> 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));
|
||||
}
|
||||
|
||||
void OpenRecipeDialog::onTagsListViewSelectionChanged(const QItemSelection &selection){
|
||||
Q_UNUSED(selection);
|
||||
vector<RecipeTag> 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<string> 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));
|
||||
}
|
||||
|
|
|
@ -30,7 +30,13 @@ class OpenRecipeDialog : public QDialog
|
|||
|
||||
void on_recipeTableView_doubleClicked(const QModelIndex &index);
|
||||
|
||||
void on_ingredientsListView_selectionChanged(const QItemSelection &selection);
|
||||
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;
|
||||
|
@ -41,9 +47,10 @@ class OpenRecipeDialog : public QDialog
|
|||
IngredientListModel ingredientsModel;
|
||||
TagListModel tagsModel;
|
||||
|
||||
void populateRecipesTable();
|
||||
void populateRecipesTable(vector<Recipe> recipes);
|
||||
void populateIngredientsList();
|
||||
void populateTagsList();
|
||||
void populateFoodGroupsList();
|
||||
};
|
||||
|
||||
#endif // OPENRECIPEDIALOG_H
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1000</width>
|
||||
<width>1064</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -25,15 +25,27 @@
|
|||
<widget class="QWidget" name="searchPanel" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item alignment="Qt::AlignLeft">
|
||||
<widget class="QWidget" name="tagsSearchpanel" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="tagLabel">
|
||||
<property name="text">
|
||||
<string>Tag</string>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>290</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<property name="tabPosition">
|
||||
<enum>QTabWidget::South</enum>
|
||||
</property>
|
||||
<property name="tabShape">
|
||||
<enum>QTabWidget::Rounded</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tagsTab">
|
||||
<attribute name="title">
|
||||
<string>Tags</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QListView" name="tagsListView">
|
||||
<property name="sizePolicy">
|
||||
|
@ -48,27 +60,24 @@
|
|||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="isWrapping" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignLeft">
|
||||
<widget class="QWidget" name="ingredientSearchPanel" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="ingredientLabel">
|
||||
<property name="text">
|
||||
<string>Ingredient</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<widget class="QWidget" name="ingredientsTab">
|
||||
<attribute name="title">
|
||||
<string>Ingredients</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QListView" name="ingredientsListView">
|
||||
<property name="sizePolicy">
|
||||
|
@ -83,6 +92,9 @@
|
|||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="isWrapping" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
@ -93,6 +105,30 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Food Groups</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QListWidget" name="foodGroupsListWidget">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="nameSearchPanel" native="true">
|
||||
|
|
22
main.cpp
22
main.cpp
|
@ -48,18 +48,18 @@ void test(RecipeDatabase *recipeDB){
|
|||
bool success = recipeDB->storeRecipe(rec);
|
||||
printf("Storage successful: %d\n", success);
|
||||
|
||||
vector<string> foodGroups = recipeDB->retrieveAllFoodGroups();
|
||||
printf("Food Groups:\n");
|
||||
for (string s : foodGroups){
|
||||
printf("\t%s\n", s.c_str());
|
||||
}
|
||||
// vector<string> 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<string> 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<string> foodGroupsR = r.getFoodGroups();
|
||||
// printf("Pannenkoeken Food Groups:\n");
|
||||
// for (string s : foodGroupsR){
|
||||
// printf("\t%s\n", s.c_str());
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -158,14 +158,68 @@ Recipe RecipeDatabase::retrieveRandomRecipe(){
|
|||
}
|
||||
return this->readFromResultTable(t);
|
||||
}
|
||||
|
||||
//TODO: Change this to be more efficient! One query per recipe is not good!
|
||||
vector<Recipe> 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<Recipe> RecipeDatabase::retrieveRecipesWithIngredients(vector<Ingredient> ingredients){
|
||||
vector<Recipe> recipes;
|
||||
for (TableRow row : t.rows()){
|
||||
recipes.push_back(this->retrieveRecipe(row.at(0)));
|
||||
}
|
||||
if (ingredients.empty()){
|
||||
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<Recipe> RecipeDatabase::retrieveRecipesWithTags(vector<RecipeTag> tags){
|
||||
vector<Recipe> 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<Recipe> RecipeDatabase::retrieveRecipesWithSubstring(string s){
|
||||
ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE name LIKE '%"+s+"%' COLLATE NOCASE;");
|
||||
return this->readRecipesFromTable(t);
|
||||
}
|
||||
|
||||
vector<Recipe> RecipeDatabase::retrieveRecipesWithFoodGroups(vector<string> groups){
|
||||
vector<Recipe> 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<string> RecipeDatabase::retrieveAllFoodGroups(){
|
||||
|
@ -302,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;");
|
||||
|
@ -360,3 +418,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<Recipe> RecipeDatabase::readRecipesFromTable(ResultTable t){
|
||||
vector<Recipe> recipes;
|
||||
for (unsigned int row = 0; row < t.rowCount(); row++){
|
||||
recipes.push_back(readFromResultTable(t, row));
|
||||
}
|
||||
return recipes;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@ class RecipeDatabase : public Database
|
|||
Recipe retrieveRecipe(string name);
|
||||
Recipe retrieveRandomRecipe();
|
||||
vector<Recipe> retrieveAllRecipes();
|
||||
vector<Recipe> retrieveRecipesWithIngredients(vector<Ingredient> ingredients);
|
||||
vector<Recipe> retrieveRecipesWithTags(vector<RecipeTag> tags);
|
||||
vector<Recipe> retrieveRecipesWithSubstring(string s);
|
||||
vector<Recipe> retrieveRecipesWithFoodGroups(vector<string> groups);
|
||||
vector<string> retrieveAllFoodGroups();
|
||||
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
|
||||
vector<Ingredient> retrieveAllIngredients();
|
||||
|
@ -47,12 +51,16 @@ class RecipeDatabase : public Database
|
|||
bool deleteIngredient(string name);
|
||||
bool deleteUnitOfMeasure(string name);
|
||||
bool deleteTag(RecipeTag tag);
|
||||
|
||||
//Updating.
|
||||
bool updateRecipe(Recipe recipe);
|
||||
private:
|
||||
|
||||
//Utility methods.
|
||||
void ensureTablesExist();
|
||||
//Read a recipe from a row of a result table.
|
||||
Recipe readFromResultTable(ResultTable t, int row=0);
|
||||
vector<Recipe> readRecipesFromTable(ResultTable t);
|
||||
};
|
||||
|
||||
#endif // RECIPEDATABASE_H
|
||||
|
|
Loading…
Reference in New Issue