2018-03-01 16:19:13 +00:00
# include "recipedatabase.h"
RecipeDatabase : : RecipeDatabase ( string filename ) : Database ( filename ) {
this - > ensureTablesExist ( ) ;
}
2018-03-02 13:14:56 +00:00
bool RecipeDatabase : : storeRecipe ( Recipe recipe ) {
2018-03-29 09:21:00 +00:00
//Some primary checks to avoid garbage in the database.
if ( recipe . getName ( ) . empty ( ) | |
recipe . getInstruction ( ) . getHTML ( ) . empty ( ) | |
recipe . getIngredients ( ) . empty ( ) ) {
return false ;
}
2018-03-10 07:51:17 +00:00
//Store a recipe, if it doesn't already exist. This first tries to create the recipe entry, then all subsequent supporting table entries.
2018-03-31 13:02:35 +00:00
this - > beginTransaction ( ) ;
2018-03-10 07:51:17 +00:00
ResultTable t = this - > selectFrom ( " recipe " , " * " , " WHERE name= " + surroundString ( recipe . getName ( ) , " ' " ) ) ;
2018-03-02 10:30:16 +00:00
if ( ! t . isEmpty ( ) ) {
fprintf ( stderr , " Error storing recipe: Recipe with name %s already exists. \n " , recipe . getName ( ) . c_str ( ) ) ;
} else {
bool success = this - > insertInto ( " recipe " ,
vector < string > ( {
" name " ,
2018-03-31 13:02:35 +00:00
" authorName " ,
2018-03-02 10:30:16 +00:00
" createdDate " ,
" cookTime " ,
" prepTime " ,
" servingCount "
} ) ,
vector < string > ( {
recipe . getName ( ) ,
2018-03-31 13:02:35 +00:00
recipe . getAuthor ( ) ,
2018-03-02 10:30:16 +00:00
recipe . getCreatedDate ( ) . toString ( ) . toStdString ( ) ,
recipe . getCookTime ( ) . toString ( ) . toStdString ( ) ,
recipe . getPrepTime ( ) . toString ( ) . toStdString ( ) ,
std : : to_string ( recipe . getServings ( ) )
} ) ) ;
if ( success ) {
2018-03-03 09:18:38 +00:00
//If successful, proceed to insert instructions, image, and ingredients, and tags.
2018-03-02 13:14:56 +00:00
int recipeId = this - > getLastInsertedRowId ( ) ;
2018-03-03 07:38:32 +00:00
bool ingredientSuccess = true ;
2018-03-02 13:14:56 +00:00
for ( unsigned int i = 0 ; i < recipe . getIngredients ( ) . size ( ) ; i + + ) {
if ( ! this - > storeRecipeIngredient ( recipe . getIngredients ( ) [ i ] , recipeId ) ) {
2018-03-03 07:38:32 +00:00
ingredientSuccess = false ;
break ;
2018-03-02 13:14:56 +00:00
}
}
2018-03-03 09:18:38 +00:00
if ( ingredientSuccess & &
this - > storeInstruction ( recipe . getInstruction ( ) , recipeId ) & &
this - > storeImage ( recipe . getImage ( ) , recipeId ) & &
this - > storeTags ( recipe . getTags ( ) , recipeId ) ) {
2018-03-31 13:02:35 +00:00
this - > commitTransaction ( ) ;
2018-03-03 07:38:32 +00:00
return true ;
2018-03-02 13:14:56 +00:00
}
2018-03-02 10:30:16 +00:00
}
}
2018-03-31 13:02:35 +00:00
this - > rollbackTransaction ( ) ;
2018-03-03 07:38:32 +00:00
return false ;
2018-03-02 10:30:16 +00:00
}
2018-03-02 13:14:56 +00:00
bool RecipeDatabase : : storeRecipeIngredient ( RecipeIngredient ri , int recipeId ) {
2018-03-10 07:51:17 +00:00
int ingId = this - > storeIngredient ( ri ) ;
if ( ingId < 0 ) return false ;
if ( ! this - > storeUnitOfMeasure ( ri . getUnit ( ) ) ) return false ;
2018-03-02 13:14:56 +00:00
return this - > insertInto ( " recipeIngredient " ,
vector < string > ( {
" ingredientId " ,
" recipeId " ,
" quantity " ,
" unitName " ,
" comment "
} ) ,
vector < string > ( {
std : : to_string ( ingId ) ,
std : : to_string ( recipeId ) ,
std : : to_string ( ri . getQuantity ( ) ) ,
ri . getUnit ( ) . getName ( ) ,
ri . getComment ( )
} ) ) ;
2018-03-01 16:28:18 +00:00
}
2018-03-10 07:51:17 +00:00
int RecipeDatabase : : storeIngredient ( Ingredient ingredient ) {
ResultTable t = this - > selectFrom ( " ingredient " , " * " , " WHERE name= " + surroundString ( ingredient . getName ( ) , " ' " ) ) ;
2018-03-02 13:14:56 +00:00
if ( t . isEmpty ( ) ) {
2018-03-10 07:51:17 +00:00
bool success = this - > insertInto ( " ingredient " , vector < string > ( { " foodGroup " , " name " } ) , vector < string > ( { ingredient . getFoodGroup ( ) , ingredient . getName ( ) } ) ) ;
if ( success ) {
return this - > getLastInsertedRowId ( ) ;
} else {
return - 1 ;
}
} else {
2018-03-30 10:29:10 +00:00
return std : : stoi ( t . at ( 0 , 0 ) ) ;
2018-03-02 10:30:16 +00:00
}
}
2018-03-10 07:51:17 +00:00
bool RecipeDatabase : : storeUnitOfMeasure ( UnitOfMeasure u ) {
ResultTable t = this - > selectFrom ( " unitOfMeasure " , " name " , " WHERE name= " + surroundString ( u . getName ( ) , " ' " ) ) ;
if ( ! t . isEmpty ( ) ) {
return true ;
}
bool success = this - > insertInto ( " unitOfMeasure " ,
vector < string > ( {
" name " ,
" plural " ,
" abbreviation " ,
" type " ,
" metricCoefficient "
} ) ,
vector < string > ( {
u . getName ( ) ,
u . getNamePlural ( ) ,
u . getAbbreviation ( ) ,
std : : to_string ( u . getType ( ) ) ,
std : : to_string ( u . getMetricCoefficient ( ) )
} ) ) ;
return success ;
}
2018-03-02 13:14:56 +00:00
bool RecipeDatabase : : storeInstruction ( Instruction instruction , int recipeId ) {
2018-03-03 07:38:32 +00:00
return FileUtils : : saveInstruction ( recipeId , instruction ) ;
2018-03-02 13:14:56 +00:00
}
bool RecipeDatabase : : storeImage ( QImage image , int recipeId ) {
return FileUtils : : saveImage ( recipeId , image ) ;
}
2018-03-03 09:18:38 +00:00
bool RecipeDatabase : : storeTags ( vector < RecipeTag > tags , int recipeId ) {
for ( vector < RecipeTag > : : iterator it = tags . begin ( ) ; it ! = tags . end ( ) ; + + it ) {
bool s = this - > insertInto ( " recipeTag " ,
vector < string > ( {
" recipeId " ,
" tagName "
} ) ,
vector < string > ( {
std : : to_string ( recipeId ) ,
( * it ) . getValue ( )
} ) ) ;
if ( ! s ) {
return false ;
}
}
return true ;
}
2018-03-03 07:48:55 +00:00
Recipe RecipeDatabase : : retrieveRecipe ( string name ) {
2018-03-10 07:51:17 +00:00
ResultTable t = this - > selectFrom ( " recipe " , " * " , " WHERE name= " + surroundString ( name , " ' " ) ) ;
2018-03-03 07:48:55 +00:00
if ( t . isEmpty ( ) ) {
fprintf ( stderr , " Error: No recipe with name %s found! \n " , name . c_str ( ) ) ;
return Recipe ( ) ;
}
2018-03-29 14:09:58 +00:00
return this - > readFromResultTable ( t ) ;
}
Recipe RecipeDatabase : : retrieveRandomRecipe ( ) {
ResultTable t = this - > selectFrom ( " recipe " , " * " , " ORDER BY RANDOM() LIMIT 1 " ) ;
if ( t . isEmpty ( ) ) {
fprintf ( stderr , " Unable to find a random recipe. \n " ) ;
return Recipe ( ) ;
}
return this - > readFromResultTable ( t ) ;
2018-03-03 09:18:38 +00:00
}
2018-03-31 13:02:35 +00:00
2018-03-11 11:53:30 +00:00
vector < Recipe > RecipeDatabase : : retrieveAllRecipes ( ) {
2018-03-30 18:57:14 +00:00
ResultTable t = this - > executeSQL ( " SELECT * FROM recipe ORDER BY name; " ) ;
return this - > readRecipesFromTable ( t ) ;
}
vector < Recipe > RecipeDatabase : : retrieveRecipesWithIngredients ( vector < Ingredient > ingredients ) {
2018-03-11 11:53:30 +00:00
vector < Recipe > recipes ;
2018-03-30 18:57:14 +00:00
if ( ingredients . empty ( ) ) {
return recipes ;
2018-03-11 11:53:30 +00:00
}
2018-03-30 18:57:14 +00:00
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 ) ;
2018-03-30 20:50:02 +00:00
}
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 ) {
2018-03-31 12:01:57 +00:00
ResultTable t = this - > executeSQL ( " SELECT * FROM recipe WHERE name LIKE '% " + s + " %' COLLATE NOCASE ORDER BY name; " ) ;
2018-03-30 20:50:02 +00:00
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 ) ;
2018-03-11 11:53:30 +00:00
}
2018-03-30 10:29:10 +00:00
vector < string > RecipeDatabase : : retrieveAllFoodGroups ( ) {
ResultTable t = this - > executeSQL ( " SELECT DISTINCT foodGroup FROM ingredient ORDER BY foodGroup; " ) ;
vector < string > foodGroups ;
for ( TableRow row : t . rows ( ) ) {
foodGroups . push_back ( row . at ( 0 ) ) ;
}
return foodGroups ;
}
2018-03-03 09:18:38 +00:00
vector < RecipeIngredient > RecipeDatabase : : retrieveRecipeIngredients ( int recipeId ) {
2018-03-10 07:51:17 +00:00
ResultTable t = this - > executeSQL ( " SELECT ingredient.name, ingredient.foodGroup, " //0, 1
" recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment, " //2, 3, 4
" unitOfMeasure.name, unitOfMeasure.plural, unitOfMeasure.abbreviation, unitOfMeasure.type, unitOfMeasure.metricCoefficient " //5, 6, 7, 8, 9
2018-03-03 09:18:38 +00:00
" FROM ingredient "
" INNER JOIN recipeIngredient "
" ON ingredient.ingredientId = recipeIngredient.ingredientId "
2018-03-10 07:51:17 +00:00
" INNER JOIN unitOfMeasure "
" ON recipeIngredient.unitName = unitOfMeasure.name "
" WHERE recipeIngredient.recipeId = " + std : : to_string ( recipeId ) + " ; " ) ;
2018-03-03 09:18:38 +00:00
vector < RecipeIngredient > ings ;
2018-03-30 10:29:10 +00:00
for ( TableRow row : t . rows ( ) ) {
RecipeIngredient r ( row . at ( 0 ) ,
row . at ( 1 ) ,
std : : stof ( row . at ( 2 ) ) ,
UnitOfMeasure ( row . at ( 5 ) , row . at ( 6 ) , row . at ( 7 ) , std : : stoi ( row . at ( 8 ) ) , std : : stod ( row . at ( 9 ) ) ) ,
row . at ( 4 ) ) ;
2018-03-03 09:18:38 +00:00
ings . push_back ( r ) ;
}
return ings ;
2018-03-03 07:48:55 +00:00
}
2018-03-31 10:53:31 +00:00
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 ) ) ;
}
2018-03-10 07:51:17 +00:00
vector < Ingredient > RecipeDatabase : : retrieveAllIngredients ( ) {
2018-03-30 10:29:10 +00:00
ResultTable t = this - > selectFrom ( " ingredient " , " name, foodGroup " , " ORDER BY name " ) ;
2018-03-10 07:51:17 +00:00
vector < Ingredient > ings ;
2018-03-30 10:29:10 +00:00
for ( TableRow row : t . rows ( ) ) {
Ingredient i ( row . at ( 0 ) , row . at ( 1 ) ) ;
2018-03-10 07:51:17 +00:00
ings . push_back ( i ) ;
}
return ings ;
}
vector < UnitOfMeasure > RecipeDatabase : : retrieveAllUnitsOfMeasure ( ) {
2018-03-30 10:29:10 +00:00
ResultTable t = this - > selectFrom ( " unitOfMeasure " , " name, plural, abbreviation, type, metricCoefficient " , " ORDER BY name " ) ;
2018-03-10 07:51:17 +00:00
vector < UnitOfMeasure > units ;
if ( ! t . isEmpty ( ) ) {
2018-03-30 10:29:10 +00:00
for ( TableRow row : t . rows ( ) ) {
UnitOfMeasure u ( row . at ( 0 ) , row . at ( 1 ) , row . at ( 2 ) , std : : stoi ( row . at ( 3 ) ) , std : : stod ( row . at ( 4 ) ) ) ;
2018-03-10 07:51:17 +00:00
units . push_back ( u ) ;
}
}
return units ;
}
2018-03-10 11:36:14 +00:00
vector < RecipeTag > RecipeDatabase : : retrieveTags ( int recipeId ) {
2018-03-30 10:29:10 +00:00
ResultTable t = this - > selectFrom ( " recipeTag " , " tagName " , " WHERE recipeId= " + std : : to_string ( recipeId ) + " ORDER BY tagName " ) ;
2018-03-10 11:36:14 +00:00
vector < RecipeTag > tags ;
if ( ! t . isEmpty ( ) ) {
2018-03-30 10:29:10 +00:00
for ( TableRow row : t . rows ( ) ) {
RecipeTag tag ( row . at ( 0 ) ) ;
2018-03-10 11:36:14 +00:00
tags . push_back ( tag ) ;
}
}
return tags ;
}
vector < RecipeTag > RecipeDatabase : : retrieveAllTags ( ) {
2018-03-30 12:33:48 +00:00
ResultTable t = this - > executeSQL ( " SELECT DISTINCT tagName FROM recipeTag ORDER BY tagName; " ) ;
2018-03-10 11:36:14 +00:00
vector < RecipeTag > tags ;
if ( ! t . isEmpty ( ) ) {
2018-03-30 10:29:10 +00:00
for ( TableRow row : t . rows ( ) ) {
RecipeTag tag ( row . at ( 0 ) ) ;
2018-03-10 11:36:14 +00:00
tags . push_back ( tag ) ;
}
}
return tags ;
}
2018-03-29 07:58:25 +00:00
bool RecipeDatabase : : deleteRecipe ( string name ) {
2018-03-29 14:09:58 +00:00
ResultTable t = this - > selectFrom ( " recipe " , " recipeId " , " WHERE name=' " + name + " ' " ) ;
2018-03-29 09:21:00 +00:00
if ( t . rowCount ( ) ! = 1 ) {
return false ;
}
2018-03-30 10:29:10 +00:00
string recipeId = t . at ( 0 , 0 ) ;
2018-03-29 09:21:00 +00:00
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 ( ) ) {
2018-03-29 14:09:58 +00:00
printf ( " Cannot delete. No recipe with ID %d exists. \n " , recipeId ) ;
2018-03-29 09:21:00 +00:00
return false ;
}
2018-03-31 13:02:35 +00:00
this - > beginTransaction ( ) ;
2018-03-29 09:21:00 +00:00
bool tagsDeleted = this - > deleteFrom ( " recipeTag " , " WHERE recipeId= " + idString ) ;
bool recipeIngredientDeleted = this - > deleteFrom ( " recipeIngredient " , " WHERE recipeId= " + idString ) ;
bool recipeDeleted = this - > deleteFrom ( " recipe " , " WHERE recipeId= " + idString ) ;
2018-03-29 15:17:07 +00:00
bool instructionDeleted = FileUtils : : deleteInstruction ( recipeId ) ;
bool imageDeleted = FileUtils : : deleteImage ( recipeId ) ;
2018-03-30 10:29:10 +00:00
Q_UNUSED ( instructionDeleted ) ;
Q_UNUSED ( imageDeleted ) ;
2018-03-29 09:21:00 +00:00
if ( tagsDeleted & & recipeIngredientDeleted & & recipeDeleted ) {
2018-03-31 13:02:35 +00:00
this - > commitTransaction ( ) ;
2018-03-29 09:21:00 +00:00
return true ;
} else {
2018-03-31 13:02:35 +00:00
this - > rollbackTransaction ( ) ;
2018-03-29 09:21:00 +00:00
return false ;
}
}
bool RecipeDatabase : : deleteIngredient ( string name ) {
2018-03-29 14:09:58 +00:00
ResultTable t = this - > executeSQL ( " SELECT recipeId "
" FROM recipeIngredient "
" INNER JOIN ingredient "
" ON recipeIngredient.ingredientId = ingredient.ingredientId "
" WHERE ingredient.name=' " + name + " '; " ) ;
2018-03-29 09:21:00 +00:00
if ( ! t . isEmpty ( ) ) {
//There is at least one recipe dependent on the ingredient.
return false ;
}
2018-03-29 14:09:58 +00:00
return this - > deleteFrom ( " ingredient " , " WHERE name=' " + name + " ' " ) ;
2018-03-29 09:21:00 +00:00
}
bool RecipeDatabase : : deleteUnitOfMeasure ( string name ) {
2018-03-29 14:09:58 +00:00
ResultTable t = this - > selectFrom ( " recipeIngredient " , " recipeId " , " WHERE unitName=' " + name + " ' " ) ;
2018-03-29 09:21:00 +00:00
if ( ! t . isEmpty ( ) ) {
return false ;
}
2018-03-29 14:09:58 +00:00
return this - > deleteFrom ( " unitOfMeasure " , " WHERE name=' " + name + " ' " ) ;
2018-03-29 09:21:00 +00:00
}
2018-03-29 07:58:25 +00:00
2018-03-29 09:21:00 +00:00
bool RecipeDatabase : : deleteTag ( RecipeTag tag ) {
2018-03-29 14:09:58 +00:00
return this - > deleteFrom ( " recipeTag " , " WHERE tagName=' " + tag . getValue ( ) + " ' " ) ;
2018-03-10 13:56:43 +00:00
}
2018-03-31 10:53:31 +00:00
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 ( ) + " ', "
2018-03-31 13:02:35 +00:00
" authorName = ' " + recipe . getAuthor ( ) + " ', "
2018-03-31 10:53:31 +00:00
" 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 < string > ( {
" recipeId " ,
" tagName "
} ) ,
vector < string > ( {
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 < string > ( {
" recipeId " ,
" ingredientId " ,
" unitName " ,
" quantity " ,
" comment "
} ) ,
vector < string > ( {
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 ;
}
2018-03-30 21:25:28 +00:00
}
2018-03-31 13:02:35 +00:00
bool RecipeDatabase : : addBasicUnits ( ) {
this - > beginTransaction ( ) ;
//Volume
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Teaspoon " , " Teaspoons " , " tsp " , UnitOfMeasure : : VOLUME , 5.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Tablespoon " , " Tablespoons " , " tbsp " , UnitOfMeasure : : VOLUME , 15.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Fluid Ounce " , " Fluid Ounces " , " fl oz " , UnitOfMeasure : : VOLUME , 30.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Cup " , " Cups " , " c " , UnitOfMeasure : : VOLUME , 250.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Milliliter " , " Milliliters " , " mL " , UnitOfMeasure : : VOLUME , 1.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Liter " , " Liters " , " L " , UnitOfMeasure : : VOLUME , 1000.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Gallon " , " Gallons " , " gal " , UnitOfMeasure : : VOLUME , 3800.0 ) ) ;
//Mass/Weight
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Ounce " , " Ounces " , " oz " , UnitOfMeasure : : MASS , 28.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Pound " , " Pounds " , " lb " , UnitOfMeasure : : MASS , 454.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Gram " , " Grams " , " g " , UnitOfMeasure : : MASS , 1.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Milligram " , " Milligrams " , " mg " , UnitOfMeasure : : MASS , 0.001 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Kilogram " , " Kilograms " , " kg " , UnitOfMeasure : : MASS , 1000.0 ) ) ;
//Length
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Inch " , " Inches " , " in " , UnitOfMeasure : : LENGTH , 2.54 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Centimeter " , " Centimeters " , " cm " , UnitOfMeasure : : LENGTH , 1.0 ) ) ;
//MISC
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Piece " , " Pieces " , " pc " , UnitOfMeasure : : MISC , 1.0 ) ) ;
this - > storeUnitOfMeasure ( UnitOfMeasure ( " Item " , " Items " , " " , UnitOfMeasure : : MISC , 1.0 ) ) ;
this - > commitTransaction ( ) ;
return true ;
}
bool RecipeDatabase : : addBasicIngredients ( ) {
this - > beginTransaction ( ) ;
this - > storeIngredient ( Ingredient ( " Flour " , " grains " ) ) ;
this - > storeIngredient ( Ingredient ( " Eggs " , " eggs " ) ) ;
this - > storeIngredient ( Ingredient ( " Milk " , " dairy " ) ) ;
this - > storeIngredient ( Ingredient ( " Cheese " , " dairy " ) ) ;
this - > storeIngredient ( Ingredient ( " Salt " , " spices " ) ) ;
this - > storeIngredient ( Ingredient ( " Sugar " , " sugars " ) ) ;
this - > storeIngredient ( Ingredient ( " Vegetable Oil " , " oils " ) ) ;
this - > storeIngredient ( Ingredient ( " Olive Oil " , " oils " ) ) ;
this - > storeIngredient ( Ingredient ( " Water " , " water " ) ) ;
this - > storeIngredient ( Ingredient ( " Bell Pepper " , " vegetables " ) ) ;
this - > storeIngredient ( Ingredient ( " Onion " , " vegetables " ) ) ;
this - > storeIngredient ( Ingredient ( " Garlic " , " spices " ) ) ;
this - > commitTransaction ( ) ;
return true ;
}
2018-03-01 16:19:13 +00:00
void RecipeDatabase : : ensureTablesExist ( ) {
//Make sure that foreign keys are enabled.
this - > executeSQL ( " PRAGMA foreign_keys = ON; " ) ;
2018-03-03 09:18:38 +00:00
2018-03-31 13:02:35 +00:00
this - > beginTransaction ( ) ;
2018-03-01 16:19:13 +00:00
//Ingredients table.
this - > executeSQL ( " CREATE TABLE IF NOT EXISTS ingredient( "
2018-03-02 08:32:40 +00:00
" ingredientId INTEGER PRIMARY KEY, "
2018-03-01 16:19:13 +00:00
" foodGroup varchar, "
2018-03-03 07:38:32 +00:00
" name varchar UNIQUE); " ) ;
2018-03-10 07:51:17 +00:00
//Unit of Measure table.
this - > executeSQL ( " CREATE TABLE IF NOT EXISTS unitOfMeasure( "
" name varchar UNIQUE PRIMARY KEY, "
" plural varchar, "
" abbreviation varchar, "
" type int, "
" metricCoefficient real); " ) ;
2018-03-02 10:30:16 +00:00
//Recipe table. Each recipe can have at most one instruction, and one image.
2018-03-01 16:19:13 +00:00
this - > executeSQL ( " CREATE TABLE IF NOT EXISTS recipe( "
2018-03-02 08:32:40 +00:00
" recipeId INTEGER PRIMARY KEY, "
2018-03-03 07:38:32 +00:00
" name varchar UNIQUE, "
2018-03-31 13:02:35 +00:00
" authorName varchar, "
2018-03-03 09:18:38 +00:00
" createdDate date, "
2018-03-01 16:19:13 +00:00
" prepTime time, "
2018-03-03 09:18:38 +00:00
" cookTime time, "
2018-03-02 10:30:16 +00:00
" servingCount real); " ) ;
2018-03-01 16:19:13 +00:00
//Recipe tags table.
this - > executeSQL ( " CREATE TABLE IF NOT EXISTS recipeTag( "
2018-03-03 09:18:38 +00:00
" recipeId int, "
2018-03-01 16:19:13 +00:00
" tagName varchar, "
" FOREIGN KEY (recipeId) REFERENCES recipe(recipeId)); " ) ;
//RecipeIngredient table.
this - > executeSQL ( " CREATE TABLE IF NOT EXISTS recipeIngredient( "
" ingredientId int, "
2018-03-02 13:14:56 +00:00
" recipeId int, "
2018-03-01 16:19:13 +00:00
" quantity real, "
" unitName varchar, "
" comment varchar, "
" FOREIGN KEY (ingredientId) REFERENCES ingredient(ingredientId), "
2018-03-10 07:51:17 +00:00
" FOREIGN KEY (recipeId) REFERENCES recipe(recipeId), "
" FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name)); " ) ;
2018-03-31 13:02:35 +00:00
this - > commitTransaction ( ) ;
2018-03-02 08:32:40 +00:00
}
2018-03-29 14:09:58 +00:00
2018-03-30 10:29:10 +00:00
Recipe RecipeDatabase : : readFromResultTable ( ResultTable t , int tRow ) {
2018-03-29 14:09:58 +00:00
Recipe r ;
2018-03-30 10:29:10 +00:00
TableRow row = t . rows ( ) . at ( tRow ) ;
2018-03-31 13:02:35 +00:00
int id = std : : stoi ( row . at ( 0 ) ) ; //id
r . setName ( row . at ( 1 ) ) ; //Name
r . setAuthor ( row . at ( 2 ) ) ; //author
r . setCreatedDate ( QDate : : fromString ( QString : : fromStdString ( row . at ( 3 ) ) ) ) ; //createdDate
r . setPrepTime ( QTime : : fromString ( QString : : fromStdString ( row . at ( 4 ) ) ) ) ; //prepTime
r . setCookTime ( QTime : : fromString ( QString : : fromStdString ( row . at ( 5 ) ) ) ) ; //cookTime
r . setServings ( std : : stof ( row . at ( 6 ) ) ) ; //servings
2018-03-29 14:09:58 +00:00
r . setInstruction ( FileUtils : : loadInstruction ( id ) ) ;
r . setImage ( FileUtils : : loadImage ( id ) ) ;
r . setIngredients ( this - > retrieveRecipeIngredients ( id ) ) ;
r . setTags ( this - > retrieveTags ( id ) ) ;
return r ;
}
2018-03-30 18:57:14 +00:00
//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 ;
}