Actually Usable Version #7
|
@ -160,7 +160,7 @@ void NewRecipeDialog::on_removeTagButton_clicked(){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()];
|
RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()];
|
||||||
string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue();
|
string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue()+"\nThis will delete the tag for all recipes that use it.";
|
||||||
QMessageBox::StandardButton reply = QMessageBox::question(this, QString("Delete Tag"), QString(content.c_str()));
|
QMessageBox::StandardButton reply = QMessageBox::question(this, QString("Delete Tag"), QString(content.c_str()));
|
||||||
if (reply == QMessageBox::Yes){
|
if (reply == QMessageBox::Yes){
|
||||||
this->recipeDB->deleteTag(tag);
|
this->recipeDB->deleteTag(tag);
|
||||||
|
|
|
@ -22,11 +22,11 @@ OpenRecipeDialog::~OpenRecipeDialog()
|
||||||
|
|
||||||
void OpenRecipeDialog::populateRecipesTable(){
|
void OpenRecipeDialog::populateRecipesTable(){
|
||||||
vector<Recipe> recipes = this->recipeDB->retrieveAllRecipes();
|
vector<Recipe> recipes = this->recipeDB->retrieveAllRecipes();
|
||||||
printf("Found %d recipes:\n", recipes.size());
|
// printf("Found %d recipes:\n", recipes.size());
|
||||||
for (Recipe r : recipes){
|
// for (Recipe r : recipes){
|
||||||
r.print();
|
// r.print();
|
||||||
printf("\n------------------\n");
|
// printf("\n------------------\n");
|
||||||
}
|
// }
|
||||||
this->recipeTableModel.setRecipes(recipes);
|
this->recipeTableModel.setRecipes(recipes);
|
||||||
ui->recipeTableView->show();
|
ui->recipeTableView->show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,9 @@
|
||||||
<property name="sortingEnabled">
|
<property name="sortingEnabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
3
main.cpp
3
main.cpp
|
@ -48,6 +48,9 @@ int main(int argc, char *argv[])
|
||||||
// printf("Accepted the dialog.\n");
|
// printf("Accepted the dialog.\n");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
bool success = recipeDB.deleteRecipe(4);
|
||||||
|
printf("Success: %d\n", success);
|
||||||
|
recipeDB.selectFrom("recipe", "recipeId, name", "").printData();
|
||||||
w.loadFromRecipe(recipeDB.retrieveRecipe("Generic Bread"));
|
w.loadFromRecipe(recipeDB.retrieveRecipe("Generic Bread"));
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
|
|
@ -46,6 +46,20 @@ ResultTable Database::selectFrom(string tableName, string columnNames, string co
|
||||||
return this->executeSQL(query);
|
return this->executeSQL(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Database::deleteFrom(string tableName, string conditions){
|
||||||
|
if (tableName.empty()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
string query = "DELETE FROM " + tableName + " " + conditions + ";";
|
||||||
|
ResultTable t = this->executeSQL(query);
|
||||||
|
if (t.getReturnCode() != SQLITE_DONE){
|
||||||
|
fprintf(stderr, "Can't delete from table %s.Return code: %d\n%s\n", tableName.c_str(), t.getReturnCode(), sqlite3_errmsg(this->db));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Database::openConnection(){
|
void Database::openConnection(){
|
||||||
this->returnCode = sqlite3_open(this->filename.c_str(), &this->db);
|
this->returnCode = sqlite3_open(this->filename.c_str(), &this->db);
|
||||||
if (this->returnCode || this->db == NULL){
|
if (this->returnCode || this->db == NULL){
|
||||||
|
|
|
@ -26,6 +26,7 @@ public:
|
||||||
ResultTable executeSQL(string statement);
|
ResultTable executeSQL(string statement);
|
||||||
bool insertInto(string tableName, vector<string> columnNames, vector<string> values);
|
bool insertInto(string tableName, vector<string> columnNames, vector<string> values);
|
||||||
ResultTable selectFrom(string tableName, string columnNames, string conditions);
|
ResultTable selectFrom(string tableName, string columnNames, string conditions);
|
||||||
|
bool deleteFrom(string tableName, string conditions);
|
||||||
|
|
||||||
bool tableExists(string tableName);
|
bool tableExists(string tableName);
|
||||||
int getLastInsertedRowId();
|
int getLastInsertedRowId();
|
||||||
|
|
|
@ -5,6 +5,12 @@ RecipeDatabase::RecipeDatabase(string filename) : Database(filename){
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecipeDatabase::storeRecipe(Recipe recipe){
|
bool RecipeDatabase::storeRecipe(Recipe recipe){
|
||||||
|
//Some primary checks to avoid garbage in the database.
|
||||||
|
if (recipe.getName().empty() ||
|
||||||
|
recipe.getInstruction().getHTML().empty() ||
|
||||||
|
recipe.getIngredients().empty()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
//Store a recipe, if it doesn't already exist. This first tries to create the recipe entry, then all subsequent supporting table entries.
|
//Store a recipe, if it doesn't already exist. This first tries to create the recipe entry, then all subsequent supporting table entries.
|
||||||
this->executeSQL("BEGIN;");
|
this->executeSQL("BEGIN;");
|
||||||
ResultTable t = this->selectFrom("recipe", "*", "WHERE name="+surroundString(recipe.getName(), "'"));
|
ResultTable t = this->selectFrom("recipe", "*", "WHERE name="+surroundString(recipe.getName(), "'"));
|
||||||
|
@ -233,7 +239,54 @@ vector<RecipeTag> RecipeDatabase::retrieveAllTags(){
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecipeDatabase::deleteRecipe(string name){
|
bool RecipeDatabase::deleteRecipe(string name){
|
||||||
|
ResultTable t = this->selectFrom("recipe", "recipeId", "WHERE name="+name);
|
||||||
|
if (t.rowCount() != 1){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
string recipeId = t.valueAt(0, 0);
|
||||||
|
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()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this->executeSQL("BEGIN;");
|
||||||
|
bool tagsDeleted = this->deleteFrom("recipeTag", "WHERE recipeId="+idString);
|
||||||
|
bool recipeIngredientDeleted = this->deleteFrom("recipeIngredient", "WHERE recipeId="+idString);
|
||||||
|
bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString);
|
||||||
|
if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){
|
||||||
|
this->executeSQL("COMMIT;");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
this->executeSQL("ROLLBACK;");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RecipeDatabase::deleteIngredient(string name){
|
||||||
|
ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE ingredientId=("
|
||||||
|
"SELECT ingredientId"
|
||||||
|
"FROM ingredient"
|
||||||
|
"WHERE name="+name+")");
|
||||||
|
if (!t.isEmpty()){
|
||||||
|
//There is at least one recipe dependent on the ingredient.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this->deleteFrom("ingredient", "WHERE name="+name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RecipeDatabase::deleteUnitOfMeasure(string name){
|
||||||
|
ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE unitName="+name);
|
||||||
|
if (!t.isEmpty()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this->deleteFrom("unitOfMeasure", "WHERE name="+name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RecipeDatabase::deleteTag(RecipeTag tag){
|
||||||
|
return this->deleteFrom("recipeTag", "WHERE tagName="+tag.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecipeDatabase::ensureTablesExist(){
|
void RecipeDatabase::ensureTablesExist(){
|
||||||
|
|
|
@ -41,7 +41,10 @@ class RecipeDatabase : public Database
|
||||||
|
|
||||||
//Deletion.
|
//Deletion.
|
||||||
bool deleteRecipe(string name);
|
bool deleteRecipe(string name);
|
||||||
void deleteTag(RecipeTag tag);
|
bool deleteRecipe(int recipeId);
|
||||||
|
bool deleteIngredient(string name);
|
||||||
|
bool deleteUnitOfMeasure(string name);
|
||||||
|
bool deleteTag(RecipeTag tag);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//Utility methods.
|
//Utility methods.
|
||||||
|
|
|
@ -45,8 +45,6 @@ QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation,
|
||||||
return "Name";
|
return "Name";
|
||||||
case 1:
|
case 1:
|
||||||
return "Created On";
|
return "Created On";
|
||||||
case 2:
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue