From e25fb66dbc06c4825a95bf8e1ba9a8da2479af69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ortega=20Froysa?= Date: Fri, 11 Oct 2024 10:43:38 +0200 Subject: [PATCH] Add removal feature. --- src/arg_parse.hpp | 3 +++ src/cmd.cpp | 32 ++++++++++++++++++++++++++++++ src/cmd.hpp | 1 + src/db.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++ src/db.hpp | 9 ++++++--- src/main.cpp | 3 +++ 6 files changed, 95 insertions(+), 3 deletions(-) diff --git a/src/arg_parse.hpp b/src/arg_parse.hpp index 309a584..4dba86c 100644 --- a/src/arg_parse.hpp +++ b/src/arg_parse.hpp @@ -26,6 +26,7 @@ enum cmd_id { CMD_UNKNOWN = 0, CMD_ADD, CMD_LIST, + CMD_DEL, CMD_HELP, CMD_VERSION, }; @@ -33,6 +34,7 @@ enum cmd_id { static const std::map> commands = { { CMD_ADD, {"add", "new"} }, { CMD_LIST, {"list", "ls"} }, + { CMD_DEL, {"del", "rm"} }, { CMD_HELP, {"help", "-h", "--help"} }, { CMD_VERSION, {"version", "-v", "--version"} }, }; @@ -52,6 +54,7 @@ static inline void print_help(void) { std::cout << "COMMANDS:\n" "\tadd, new Add a new recipe to the database.\n" "\tlist, ls List recipes with filters.\n" + "\tdel, rm Delete recipe by ID.\n" "\thelp, -h, --help Show this help information.\n" "\tversion, -v, --version Show version information.\n" << std::endl; diff --git a/src/cmd.cpp b/src/cmd.cpp index f9c970f..828c796 100644 --- a/src/cmd.cpp +++ b/src/cmd.cpp @@ -105,3 +105,35 @@ int command_list(int argc, char *argv[]) { return EXIT_SUCCESS; } + +int command_delete(int argc, char *argv[]) { + int ret = EXIT_SUCCESS; + std::vector recipe_ids; + + if(argc < 1) { + std::cerr << "No specified IDs. Use 'help' for more information." << std::endl; + return EXIT_FAILURE; + } + + if(not db_open()) { + std::cerr << "Failed to open database. Cannot add new entry." << std::endl; + return EXIT_FAILURE; + } + + for(int i = 0; i < argc; ++i) { + const int id = std::stoi(argv[i]); + + if(not db_recipe_exists(id)) { + std::cerr << "No recipe exists with ID " << id << "." << std::endl; + return EXIT_FAILURE; + } else { + recipe_ids.push_back(id); + } + } + + ret = (db_del_recipes(recipe_ids)) ? EXIT_SUCCESS : EXIT_FAILURE; + + db_close(); + + return ret; +} diff --git a/src/cmd.hpp b/src/cmd.hpp index e919a29..58810f4 100644 --- a/src/cmd.hpp +++ b/src/cmd.hpp @@ -19,3 +19,4 @@ int command_add(void); int command_list(int argc, char *argv[]); +int command_delete(int argc, char *argv[]); diff --git a/src/db.cpp b/src/db.cpp index ae3b8e9..e7378a7 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -112,6 +112,56 @@ int db_add_recipe(const std::string &name, const std::string &description) { return db_get_recipe_id(name); } +bool db_del_recipe(const int id) { + if(not db) + return false; + + if(sqlite3_exec(db, std::format("DELETE FROM recipes WHERE id={}", id).c_str(), + nullptr, nullptr, nullptr) not_eq SQLITE_OK) + return false; + + return true; +} + +bool db_del_recipes(const std::vector &ids) { + std::string stmt = "DELETE FROM recipes WHERE id IN ("; + + if(not db) + return false; + + bool first = true; + for(auto id : ids) { + if(first) + first = false; + else + stmt += ","; + + stmt += std::to_string(id); + } + + stmt += ");"; + + if(sqlite3_exec(db, stmt.c_str(), nullptr, nullptr, nullptr) not_eq SQLITE_OK) + return false; + + return true; +} + +bool db_recipe_exists(const int id) { + bool exists = false; + + if(not db) + return false; + + sqlite3_exec(db, std::format("SELECT id FROM recipes WHERE id={}", id).c_str(), + [](void *found,int,char**,char**) { + *static_cast(found) = true; + return 0; + }, &exists, nullptr); + + return exists; +} + int db_get_recipe_id(const std::string &name) { if(not db) return -1; diff --git a/src/db.hpp b/src/db.hpp index 74b8bb9..4bda5b7 100644 --- a/src/db.hpp +++ b/src/db.hpp @@ -38,8 +38,11 @@ void db_close(void); * @return ID of newly created recipe, -1 if DB isn't open, -2 on other failure. */ int db_add_recipe(const std::string &name, const std::string &description); +bool db_del_recipe(const int id); +bool db_del_recipes(const std::vector &ids); int db_get_recipe_id(const std::string &name); -static inline int db_recipe_exists(const std::string &name) { +bool db_recipe_exists(const int id); +static inline bool db_recipe_exists(const std::string &name) { return (db_get_recipe_id(name) > 0); } std::vector db_get_recipes(const std::vector &ingredients, @@ -54,7 +57,7 @@ std::vector db_get_recipes(const std::vector &ingred */ int db_add_ingredient(const std::string &name); int db_get_ingredient_id(const std::string &name); -static inline int db_ingredient_exists(const std::string &name) { +static inline bool db_ingredient_exists(const std::string &name) { return (db_get_ingredient_id(name) > 0); } @@ -67,7 +70,7 @@ static inline int db_ingredient_exists(const std::string &name) { */ int db_add_tag(const std::string &name); int db_get_tag_id(const std::string &name); -static inline int db_tag_exists(const std::string &name) { +static inline bool db_tag_exists(const std::string &name) { return (db_get_tag_id(name) > 0); } diff --git a/src/main.cpp b/src/main.cpp index 8a2db6f..0dc5c1c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,6 +41,9 @@ int main(int argc, char *argv[]) { case CMD_LIST: ret = command_list(argc - 1, argv + 1); break; + case CMD_DEL: + ret = command_delete(argc - 2, argv + 2); + break; case CMD_HELP: print_help(); break;