diff --git a/RecipeDB.pro b/RecipeDB.pro index 4503a07..2c957a5 100644 --- a/RecipeDB.pro +++ b/RecipeDB.pro @@ -24,7 +24,8 @@ SOURCES += model/recipe/instruction.cpp \ model/recipe/tags/recipetag.cpp \ SQLite/sqlite3.c \ model/database/resulttable.cpp \ - model/database/recipedatabase.cpp + model/database/recipedatabase.cpp \ + utils/fileutils.cpp HEADERS += model/recipe/instruction.h \ model/recipe/recipe.h \ @@ -39,8 +40,7 @@ HEADERS += model/recipe/instruction.h \ SQLite/sqlite3ext.h \ model/database/resulttable.h \ model/database/recipedatabase.h \ - utils/fileutils.h \ - utils/stringutils.h + utils/fileutils.h LIBS += -ldl \ diff --git a/main.cpp b/main.cpp index 98c1306..0deb267 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,6 @@ #include "model/database/database.h" #include "model/database/recipedatabase.h" -#include "utils/fileutils.h" int main(int argc, char *argv[]) { @@ -14,12 +13,12 @@ int main(int argc, char *argv[]) //TESTING CODE RecipeDatabase recipeDB("recipes"); - recipeDB.storeIngredient(Ingredient("Apple", "Fruit")); - recipeDB.storeIngredient(Ingredient("Corn", "Vegetable")); - recipeDB.storeIngredient(Ingredient("Lettuce", "Vegetable")); - recipeDB.storeIngredient(Ingredient("Carrot", "Vegetable")); +// recipeDB.storeIngredient(Ingredient("Apple", "Fruit")); +// recipeDB.storeIngredient(Ingredient("Corn", "Vegetable")); +// recipeDB.storeIngredient(Ingredient("Lettuce", "Vegetable")); +// recipeDB.storeIngredient(Ingredient("Carrot", "Vegetable")); - recipeDB.executeSQL("SELECT * FROM ingredient;").printData(); +// recipeDB.executeSQL("SELECT * FROM ingredient;").printData(); //TESTING CODE vector ri; @@ -28,6 +27,11 @@ int main(int argc, char *argv[]) Recipe rec("Example", ri, Instruction("BOLDiTaLiCs"), QImage(), vector(), QDate::currentDate(), QTime(0, 30), QTime(0, 25), 10.0f); + bool success = recipeDB.storeRecipe(rec); + printf("Storage successful: %d\n", success); + + recipeDB.executeSQL("SELECT * FROM recipeIngredient;").printData(); + w.loadFromRecipe(rec); return a.exec(); diff --git a/model/database/database.cpp b/model/database/database.cpp index 0b843d5..d4d533d 100644 --- a/model/database/database.cpp +++ b/model/database/database.cpp @@ -34,7 +34,6 @@ bool Database::insertInto(string tableName, vector columnNames, vectorexecuteSQL(query); return true; } diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index 5069fe0..231d5c9 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -4,11 +4,12 @@ RecipeDatabase::RecipeDatabase(string filename) : Database(filename){ this->ensureTablesExist(); } -void RecipeDatabase::storeRecipe(Recipe recipe){ +bool RecipeDatabase::storeRecipe(Recipe recipe){ ///TODO: Implement this in a smart way using transaction. ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE name='"+recipe.getName()+"';"); if (!t.isEmpty()){ fprintf(stderr, "Error storing recipe: Recipe with name %s already exists.\n", recipe.getName().c_str()); + return false; } else { bool success = this->insertInto("recipe", vector({ @@ -27,24 +28,70 @@ void RecipeDatabase::storeRecipe(Recipe recipe){ })); if (success){ //If successful, proceed to insert instructions, image, and ingredients. - + int recipeId = this->getLastInsertedRowId(); + for (unsigned int i = 0; i < recipe.getIngredients().size(); i++){ + if (!this->storeRecipeIngredient(recipe.getIngredients()[i], recipeId)){ + return false; + } + } + if (!this->storeInstruction(recipe.getInstruction(), recipeId)){ + return false; + } + if (!this->storeImage(recipe.getImage(), recipeId)){ + return false; + } + return true; + } else { + return false; } } } -void RecipeDatabase::storeRecipeIngredient(RecipeIngredient ri){ - +bool RecipeDatabase::storeRecipeIngredient(RecipeIngredient ri, int recipeId){ + //First check if the base ingredient has been added to the database. This is done within storeIngredient(). + ResultTable t = this->executeSQL("SELECT ingredientId FROM ingredient WHERE name='"+ri.getName()+"';"); + int ingId = 0; + if (t.isEmpty()){ + if (!this->insertInto("ingredient", vector({"foodGroup", "name"}), vector({ri.getFoodGroup(), ri.getName()}))){ + return false; + } + ingId = this->getLastInsertedRowId(); + } else { + ingId = std::stoi(t.valueAt(0, 0)); + } + return this->insertInto("recipeIngredient", + vector({ + "ingredientId", + "recipeId", + "quantity", + "unitName", + "comment" + }), + vector({ + std::to_string(ingId), + std::to_string(recipeId), + std::to_string(ri.getQuantity()), + ri.getUnit().getName(), + ri.getComment() + })); } void RecipeDatabase::storeIngredient(Ingredient ingredient){ ResultTable t = this->executeSQL("SELECT * FROM ingredient WHERE name='"+ingredient.getName()+"';"); - if (!t.isEmpty()){ - fprintf(stderr, "Error during storeIngredient: ingredient with name %s already exists.\n", ingredient.getName().c_str()); - } else { + if (t.isEmpty()){ this->insertInto("ingredient", vector({"foodGroup", "name"}), vector({ingredient.getFoodGroup(), ingredient.getName()})); } } +bool RecipeDatabase::storeInstruction(Instruction instruction, int recipeId){ + bool success = FileUtils::saveInstruction(recipeId, instruction); + return success; +} + +bool RecipeDatabase::storeImage(QImage image, int recipeId){ + return FileUtils::saveImage(recipeId, image); +} + void RecipeDatabase::ensureTablesExist(){ //Make sure that foreign keys are enabled. this->executeSQL("PRAGMA foreign_keys = ON;"); @@ -69,7 +116,7 @@ void RecipeDatabase::ensureTablesExist(){ //RecipeIngredient table. this->executeSQL("CREATE TABLE IF NOT EXISTS recipeIngredient(" "ingredientId int," - "recipeId INTEGER PRIMARY KEY," + "recipeId int," "quantity real," "unitName varchar," "comment varchar," diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index 9c52876..72cfa2d 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -5,6 +5,7 @@ #include "database.h" #include "model/recipe/recipe.h" +#include "utils/fileutils.h" using namespace std; @@ -18,11 +19,13 @@ class RecipeDatabase : public Database RecipeDatabase(string filename); //Stores a full recipe in the database. - void storeRecipe(Recipe recipe); + bool storeRecipe(Recipe recipe); //SQL Helper methods. - void storeRecipeIngredient(RecipeIngredient ri); + bool storeRecipeIngredient(RecipeIngredient ri, int recipeId); void storeIngredient(Ingredient ingredient); + bool storeInstruction(Instruction instruction, int recipeId); + bool storeImage(QImage image, int recipeId); private: //Utility methods. diff --git a/utils/fileutils.cpp b/utils/fileutils.cpp new file mode 100644 index 0000000..a453c57 --- /dev/null +++ b/utils/fileutils.cpp @@ -0,0 +1,64 @@ +#include "fileutils.h" + +namespace FileUtils{ + +void ensureAppDataFolderExists(){ + QDir folder(appDataPath); + if (!folder.exists()){ + folder.mkpath("."); + } +} + +bool saveInstruction(int nr, Instruction instruction){ + ensureAppDataFolderExists(); + QString filename = appDataPath + QString::fromStdString(std::to_string(nr)) +".html"; + QFile file(filename); + if (file.open(QIODevice::WriteOnly)){ + QTextStream stream(&file); + stream< #include #include +#include #include "model/recipe/instruction.h" -namespace FileUtils { +namespace FileUtils{ - QString appDataPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.recipeDB/"; + const QString appDataPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.recipeDB/"; - void ensureAppDataFolderExists(){ - QDir folder(appDataPath); - if (!folder.exists()){ - folder.mkpath("."); - } - } + void ensureAppDataFolderExists(); - string saveInstruction(int nr, Instruction instruction){ - ensureAppDataFolderExists(); - QString filename = appDataPath + QString::fromStdString(std::to_string(nr)) +".html"; - QFile file(filename); - if (file.open(QIODevice::WriteOnly)){ - QTextStream stream(&file); - stream< -#include - -namespace StringUtils{ - - - -} - -#endif // STRINGUTILS_H