/* -*- c++ -*- */ /*************************************************************************** * database_gourmet.cc * * Sun Apr 24 18:27:56 CEST 2022 * Copyright 2022 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of Qookie. * * Qookie is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Qookie is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Qookie; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "database_gourmet.h" #include #include #include // https://www.tutorialspoint.com/sqlite/sqlite_c_cpp.htm DatabaseGourmet::DatabaseGourmet(const std::string& file) { auto rc = sqlite3_open(file.data(), &db); // https://sqlite.org/c3ref/open.html if(rc) { std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n'; return; } else { std::cout << "Opened database successfully\n"; } } DatabaseGourmet::~DatabaseGourmet() { sqlite3_close(db); } namespace { std::string getString(sqlite3_stmt *statement, int index) { int size = sqlite3_column_bytes(statement, index); std::string str; str.append((const char*)sqlite3_column_blob(statement, index), size); return str; } } // :: std::deque DatabaseGourmet::getRecipes() { std::deque items; std::string sql = "select id, title, image from recipe"; sqlite3_stmt *statement; if(sqlite3_prepare_v2(db, sql.data(), sql.length(), &statement, 0) != SQLITE_OK) { std::cerr << "sqlite3_prepare_v2 failed: " << sqlite3_errmsg(db) << '\n'; return {}; } int result = 0; while(true) { RecipeItem item; result = sqlite3_step(statement); if(result == SQLITE_ROW) { item.db = DatabaseSource::Gourmet; item.id = sqlite3_column_int(statement, 0); item.title = getString(statement, 1); item.image = getString(statement, 2); } else { break; } items.push_back(item); } return items; } Recipe DatabaseGourmet::getRecipe(int id) { bool found{false}; Recipe recipe; { std::string sql = "select id, title, description, image, instructions, source, link, cuisine, cooktime, preptime, yields, yield_unit, modifications from recipe where id=" + std::to_string(id); sqlite3_stmt *statement; if(sqlite3_prepare_v2(db, sql.data(), sql.length(), &statement, 0) != SQLITE_OK) { std::cerr << "sqlite3_prepare_v2 failed: " << sqlite3_errmsg(db) << '\n'; return {}; } int result = 0; while(true) { result = sqlite3_step(statement); if(result == SQLITE_ROW) { recipe.db = DatabaseSource::Gourmet; recipe.id = sqlite3_column_int(statement, 0); recipe.title = getString(statement, 1); recipe.description = getString(statement, 2); recipe.image = getString(statement, 3); recipe.instructions = getString(statement, 4); recipe.source = getString(statement, 5); if(!recipe.source.empty()) { recipe.source += " "; } recipe.source += getString(statement, 6); recipe.cuisine = getString(statement, 7); recipe.cooktime = sqlite3_column_int(statement, 8); recipe.preptime = sqlite3_column_int(statement, 9); recipe.yields = sqlite3_column_double(statement, 10); recipe.yield_unit = getString(statement, 11); recipe.tags.push_back(getString(statement, 12)); } else { break; } found = true; } } if(!found) { std::cerr << "id " << id << " not found\n"; return {}; } { std::string sql = "select amount, unit, item, inggroup from ingredients where recipe_id=" + std::to_string(id) + " order by position asc"; sqlite3_stmt *statement; if(sqlite3_prepare_v2(db, sql.data(), sql.length(), &statement, 0) != SQLITE_OK) { std::cerr << "sqlite3_prepare_v2 failed: " << sqlite3_errmsg(db) << '\n'; return {}; } recipe.ingredient_groups.push_back({}); // first group is the empty-titled one. int result = 0; while(true) { Ingredient ingredient; result = sqlite3_step(statement); if(result == SQLITE_ROW) { ingredient.amount = sqlite3_column_double(statement, 0); ingredient.unit = getString(statement, 1); ingredient.item = getString(statement, 2); auto group_title = getString(statement, 3); auto* group = &recipe.ingredient_groups.back(); assert(recipe.ingredient_groups.size() > 0); if(group->title != group_title) { recipe.ingredient_groups.push_back({group_title, {}}); group = &recipe.ingredient_groups.back(); } group->ingredients.push_back(ingredient); } else { break; } } } return recipe; }