Added methods to get food groups of all recipes and individual recipe, revamped access to result table.

This commit is contained in:
Andrew Lalis 2018-03-30 12:29:10 +02:00
parent 6114bdbfa7
commit 35982cd514
12 changed files with 105 additions and 39 deletions

View File

@ -195,6 +195,7 @@ void NewRecipeDialog::on_newUnitButton_clicked(){
QMessageBox::critical(this, "Error", "Unable to store new unit."); QMessageBox::critical(this, "Error", "Unable to store new unit.");
} else { } else {
this->populateUnitsBox(); this->populateUnitsBox();
ui->unitComboBox->setCurrentText(QString::fromStdString(u.getName()));
} }
} }
} }

View File

@ -6,6 +6,8 @@
#include "model/database/recipedatabase.h" #include "model/database/recipedatabase.h"
#include "utils/fileutils.h" #include "utils/fileutils.h"
void test(RecipeDatabase *recipeDB);
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
RecipeDatabase recipeDB(QString(FileUtils::appDataPath+"recipes.db").toStdString()); RecipeDatabase recipeDB(QString(FileUtils::appDataPath+"recipes.db").toStdString());
@ -14,6 +16,18 @@ int main(int argc, char *argv[])
w.show(); w.show();
//TESTING CODE //TESTING CODE
test(&recipeDB);
//END TESTING CODE.
w.loadFromRecipe(recipeDB.retrieveRandomRecipe());
a.exec();
recipeDB.closeConnection();
return 0;
}
void test(RecipeDatabase *recipeDB){
vector<RecipeIngredient> ri; vector<RecipeIngredient> ri;
ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), "")); ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), ""));
ri.push_back(RecipeIngredient("baking powder", "additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), "")); ri.push_back(RecipeIngredient("baking powder", "additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), ""));
@ -29,12 +43,21 @@ int main(int argc, char *argv[])
QTime(0, 25), QTime(0, 25),
10.0f); 10.0f);
bool success = recipeDB.storeRecipe(rec); bool success = recipeDB->storeRecipe(rec);
printf("Storage successful: %d\n", success); printf("Storage successful: %d\n", success);
w.loadFromRecipe(recipeDB.retrieveRandomRecipe()); 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());
}
a.exec();
recipeDB.closeConnection();
return 0;
} }

View File

@ -88,7 +88,7 @@ int RecipeDatabase::storeIngredient(Ingredient ingredient){
return -1; return -1;
} }
} else { } else {
return std::stoi(t.valueAt(0, 0)); return std::stoi(t.at(0, 0));
} }
} }
@ -162,12 +162,21 @@ Recipe RecipeDatabase::retrieveRandomRecipe(){
vector<Recipe> RecipeDatabase::retrieveAllRecipes(){ vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
ResultTable t = this->selectFrom("recipe", "name", "ORDER BY name"); ResultTable t = this->selectFrom("recipe", "name", "ORDER BY name");
vector<Recipe> recipes; vector<Recipe> recipes;
for (unsigned int row = 0; row < t.rowCount(); row++){ for (TableRow row : t.rows()){
recipes.push_back(this->retrieveRecipe(t.valueAt(row, 0))); recipes.push_back(this->retrieveRecipe(row.at(0)));
} }
return recipes; return recipes;
} }
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;
}
vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){ vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
ResultTable t = this->executeSQL("SELECT ingredient.name, ingredient.foodGroup, "//0, 1 ResultTable t = this->executeSQL("SELECT ingredient.name, ingredient.foodGroup, "//0, 1
"recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment,"//2, 3, 4 "recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment,"//2, 3, 4
@ -179,33 +188,33 @@ vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId)
"ON recipeIngredient.unitName = unitOfMeasure.name " "ON recipeIngredient.unitName = unitOfMeasure.name "
"WHERE recipeIngredient.recipeId = "+std::to_string(recipeId)+";"); "WHERE recipeIngredient.recipeId = "+std::to_string(recipeId)+";");
vector<RecipeIngredient> ings; vector<RecipeIngredient> ings;
for (unsigned int row = 0; row < t.rowCount(); row++){ for (TableRow row : t.rows()){
RecipeIngredient r(t.valueAt(row, 0), RecipeIngredient r(row.at(0),
t.valueAt(row, 1), row.at(1),
std::stof(t.valueAt(row, 2)), std::stof(row.at(2)),
UnitOfMeasure(t.valueAt(row, 5), t.valueAt(row, 6), t.valueAt(row, 7), std::stoi(t.valueAt(row, 8)), std::stod(t.valueAt(row, 9))), UnitOfMeasure(row.at(5), row.at(6), row.at(7), std::stoi(row.at(8)), std::stod(row.at(9))),
t.valueAt(row, 4)); row.at(4));
ings.push_back(r); ings.push_back(r);
} }
return ings; return ings;
} }
vector<Ingredient> RecipeDatabase::retrieveAllIngredients(){ vector<Ingredient> RecipeDatabase::retrieveAllIngredients(){
ResultTable t = this->selectFrom("ingredient", "*", "ORDER BY name"); ResultTable t = this->selectFrom("ingredient", "name, foodGroup", "ORDER BY name");
vector<Ingredient> ings; vector<Ingredient> ings;
for (unsigned int row = 0; row < t.rowCount(); row++){ for (TableRow row : t.rows()){
Ingredient i(t.valueAt(row, 2), t.valueAt(row, 1)); Ingredient i(row.at(0), row.at(1));
ings.push_back(i); ings.push_back(i);
} }
return ings; return ings;
} }
vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){ vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
ResultTable t = this->selectFrom("unitOfMeasure", "*", "ORDER BY name"); ResultTable t = this->selectFrom("unitOfMeasure", "name, plural, abbreviation, type, metricCoefficient", "ORDER BY name");
vector<UnitOfMeasure> units; vector<UnitOfMeasure> units;
if (!t.isEmpty()){ if (!t.isEmpty()){
for (unsigned int row = 0; row < t.rowCount(); row++){ for (TableRow row : t.rows()){
UnitOfMeasure u(t.valueAt(row, 0), t.valueAt(row, 1), t.valueAt(row, 2), std::stoi(t.valueAt(row, 3)), std::stod(t.valueAt(row, 4))); UnitOfMeasure u(row.at(0), row.at(1), row.at(2), std::stoi(row.at(3)), std::stod(row.at(4)));
units.push_back(u); units.push_back(u);
} }
} }
@ -213,11 +222,11 @@ vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
} }
vector<RecipeTag> RecipeDatabase::retrieveTags(int recipeId){ vector<RecipeTag> RecipeDatabase::retrieveTags(int recipeId){
ResultTable t = this->selectFrom("recipeTag", "tagName", "WHERE recipeId="+std::to_string(recipeId)); ResultTable t = this->selectFrom("recipeTag", "tagName", "WHERE recipeId="+std::to_string(recipeId)+" ORDER BY tagName");
vector<RecipeTag> tags; vector<RecipeTag> tags;
if (!t.isEmpty()){ if (!t.isEmpty()){
for (unsigned int row = 0; row < t.rowCount(); row++){ for (TableRow row : t.rows()){
RecipeTag tag(t.valueAt(row, 0)); RecipeTag tag(row.at(0));
tags.push_back(tag); tags.push_back(tag);
} }
} }
@ -228,8 +237,8 @@ vector<RecipeTag> RecipeDatabase::retrieveAllTags(){
ResultTable t = this->selectFrom("recipeTag", "tagName", "ORDER BY tagName"); ResultTable t = this->selectFrom("recipeTag", "tagName", "ORDER BY tagName");
vector<RecipeTag> tags; vector<RecipeTag> tags;
if (!t.isEmpty()){ if (!t.isEmpty()){
for (unsigned int row = 0; row < t.rowCount(); row++){ for (TableRow row : t.rows()){
RecipeTag tag(t.valueAt(row, 0)); RecipeTag tag(row.at(0));
tags.push_back(tag); tags.push_back(tag);
} }
} }
@ -241,7 +250,7 @@ bool RecipeDatabase::deleteRecipe(string name){
if (t.rowCount() != 1){ if (t.rowCount() != 1){
return false; return false;
} }
string recipeId = t.valueAt(0, 0); string recipeId = t.at(0, 0);
return this->deleteRecipe(std::stoi(recipeId)); return this->deleteRecipe(std::stoi(recipeId));
} }
@ -257,6 +266,8 @@ bool RecipeDatabase::deleteRecipe(int recipeId){
bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString); bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString);
bool instructionDeleted = FileUtils::deleteInstruction(recipeId); bool instructionDeleted = FileUtils::deleteInstruction(recipeId);
bool imageDeleted = FileUtils::deleteImage(recipeId); bool imageDeleted = FileUtils::deleteImage(recipeId);
Q_UNUSED(instructionDeleted);
Q_UNUSED(imageDeleted);
if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){ if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){
this->executeSQL("COMMIT;"); this->executeSQL("COMMIT;");
return true; return true;
@ -334,14 +345,15 @@ void RecipeDatabase::ensureTablesExist(){
this->executeSQL("COMMIT;"); this->executeSQL("COMMIT;");
} }
Recipe RecipeDatabase::readFromResultTable(ResultTable t, int row){ Recipe RecipeDatabase::readFromResultTable(ResultTable t, int tRow){
Recipe r; Recipe r;
int id = std::stoi(t.valueAt(row, 0)); TableRow row = t.rows().at(tRow);
r.setName(t.valueAt(row, 1)); int id = std::stoi(row.at(0));
r.setCreatedDate(QDate::fromString(QString::fromStdString(t.valueAt(row, 2)))); r.setName(row.at(1));
r.setPrepTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 3)))); r.setCreatedDate(QDate::fromString(QString::fromStdString(row.at(2))));
r.setCookTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 4)))); r.setPrepTime(QTime::fromString(QString::fromStdString(row.at(3))));
r.setServings(std::stof(t.valueAt(row, 5))); r.setCookTime(QTime::fromString(QString::fromStdString(row.at(4))));
r.setServings(std::stof(row.at(5)));
r.setInstruction(FileUtils::loadInstruction(id)); r.setInstruction(FileUtils::loadInstruction(id));
r.setImage(FileUtils::loadImage(id)); r.setImage(FileUtils::loadImage(id));
r.setIngredients(this->retrieveRecipeIngredients(id)); r.setIngredients(this->retrieveRecipeIngredients(id));

View File

@ -34,6 +34,7 @@ class RecipeDatabase : public Database
Recipe retrieveRecipe(string name); Recipe retrieveRecipe(string name);
Recipe retrieveRandomRecipe(); Recipe retrieveRandomRecipe();
vector<Recipe> retrieveAllRecipes(); vector<Recipe> retrieveAllRecipes();
vector<string> retrieveAllFoodGroups();
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId); vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
vector<Ingredient> retrieveAllIngredients(); vector<Ingredient> retrieveAllIngredients();
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure(); vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();

View File

@ -47,7 +47,7 @@ bool ResultTable::isEmpty(){
return this->values.empty(); return this->values.empty();
} }
string ResultTable::valueAt(unsigned int row, unsigned int col){ string ResultTable::at(unsigned int row, unsigned int col){
if (isIndexValid(row, col)){ if (isIndexValid(row, col)){
return this->values[row][col]; return this->values[row][col];
} else { } else {
@ -78,6 +78,10 @@ unsigned int ResultTable::rowCount(){
return this->values.size(); return this->values.size();
} }
vector<vector<string> > ResultTable::rows(){
return this->values;
}
string ResultTable::convertToString(sqlite3_value *val){ string ResultTable::convertToString(sqlite3_value *val){
const unsigned char* raw_text = sqlite3_value_text(val); const unsigned char* raw_text = sqlite3_value_text(val);
if (raw_text == 0){ if (raw_text == 0){

View File

@ -12,6 +12,8 @@ using namespace std;
* @brief The ResultTable class is an object that contains the results of an SQL query, in string form. * @brief The ResultTable class is an object that contains the results of an SQL query, in string form.
*/ */
typedef vector<string> TableRow;
class ResultTable class ResultTable
{ {
public: public:
@ -28,11 +30,12 @@ class ResultTable
void printData(); void printData();
bool isEmpty(); bool isEmpty();
string valueAt(unsigned int row, unsigned int col); string at(unsigned int row, unsigned int col);
int getReturnCode(); int getReturnCode();
string getOriginalQuery(); string getOriginalQuery();
unsigned int columnCount(); unsigned int columnCount();
unsigned int rowCount(); unsigned int rowCount();
vector<vector<string>> rows();
private: private:
vector<vector<string>> values; vector<vector<string>> values;
int queryCode; int queryCode;

View File

@ -21,7 +21,17 @@ string Recipe::getName() const{
} }
vector<RecipeIngredient> Recipe::getIngredients() const{ vector<RecipeIngredient> Recipe::getIngredients() const{
return this->ingredients; return this->ingredients;
}
vector<string> Recipe::getFoodGroups() const{
vector<string> foodGroups;
for (RecipeIngredient ri : this->ingredients){
if (find(foodGroups.begin(), foodGroups.end(), ri.getFoodGroup()) == foodGroups.end()){
foodGroups.push_back(ri.getFoodGroup());
}
}
return foodGroups;
} }
Instruction Recipe::getInstruction() const{ Instruction Recipe::getInstruction() const{

View File

@ -6,6 +6,7 @@
#include <QDate> #include <QDate>
#include <QTime> #include <QTime>
#include <QImage> #include <QImage>
#include <algorithm>
#include "model/recipe/ingredients/recipeingredient.h" #include "model/recipe/ingredients/recipeingredient.h"
#include "model/recipe/instruction.h" #include "model/recipe/instruction.h"
@ -38,6 +39,7 @@ public:
//Getters //Getters
string getName() const; string getName() const;
vector<RecipeIngredient> getIngredients() const; vector<RecipeIngredient> getIngredients() const;
vector<string> getFoodGroups() const;
Instruction getInstruction() const; Instruction getInstruction() const;
QImage getImage() const; QImage getImage() const;
vector<RecipeTag> getTags() const; vector<RecipeTag> getTags() const;

View File

@ -72,8 +72,8 @@ void RecipeTableModel::setRecipes(vector<Recipe> recipes){
endInsertRows(); endInsertRows();
} }
Recipe RecipeTableModel::getRecipeAt(int index){ Recipe RecipeTableModel::getRecipeAt(unsigned int index){
if (index < 0 || index >= this->recipes.size()){ if (index >= this->recipes.size()){
return Recipe(); return Recipe();
} }
return this->recipes[index]; return this->recipes[index];

View File

@ -20,7 +20,7 @@ class RecipeTableModel : public QAbstractTableModel
//Normal methods. //Normal methods.
void setRecipes(vector<Recipe> recipes); void setRecipes(vector<Recipe> recipes);
Recipe getRecipeAt(int index); Recipe getRecipeAt(unsigned int index);
void clear(); void clear();
private: private:
vector<Recipe> recipes; vector<Recipe> recipes;

View File

@ -29,4 +29,13 @@ std::string toString(float val){
return s; return s;
} }
void printVector(std::vector<std::string> &vect){
std::printf("Vector of %ld elements:\n", vect.size());
int c = 0;
for (std::string s : vect){
std::printf("\t[%d] = %s\n", c, s.c_str());
c++;
}
}
} }

View File

@ -2,6 +2,7 @@
#define STRINGUTILS_H #define STRINGUTILS_H
#include <string> #include <string>
#include <vector>
#include <cmath> #include <cmath>
namespace StringUtils{ namespace StringUtils{