From 350ffcb02b1708b0c6e1d4be95f948550e7133cd Mon Sep 17 00:00:00 2001 From: Naveen Albert <asterisk@phreaknet.org> Date: Fri, 1 Apr 2022 19:49:31 +0000 Subject: [PATCH] db: Notify user if deleted DB entry didn't exist. Currently, if using the CLI to delete a DB entry, "Database entry removed" is always returned, regardless of whether or not the entry actually existed in the first place. This meant that users were never told if entries did not exist. The same issue occurs if trying to delete a DB key using AMI. To address this, new API is added that is more stringent in deleting values from AstDB, which will not return success if the value did not exist in the first place, and will print out specific error details if available. ASTERISK-30001 #close Change-Id: Ic84e3eddcd66c7a6ed7fea91cdfd402568378b18 --- include/asterisk/astdb.h | 11 +++++++++++ main/db.c | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/asterisk/astdb.h b/include/asterisk/astdb.h index c511be8a76..216b8d3d9d 100644 --- a/include/asterisk/astdb.h +++ b/include/asterisk/astdb.h @@ -56,6 +56,17 @@ int ast_db_put(const char *family, const char *key, const char *value); /*! \brief Delete entry in astdb */ int ast_db_del(const char *family, const char *key); +/*! \brief Same as ast_db_del, but with more stringent error checking + * + * \details + * Unlike ast_db_del, if the key does not exist in the first place, + * an error is emitted and -1 is returned. + * + * \retval -1 An error occured (including key not found to begin with) + * \retval 0 Successfully deleted + */ +int ast_db_del2(const char *family, const char *key); + /*! * \brief Delete one or more entries in astdb * diff --git a/main/db.c b/main/db.c index d4479f4e5a..8965014662 100644 --- a/main/db.c +++ b/main/db.c @@ -454,6 +454,38 @@ int ast_db_del(const char *family, const char *key) return res; } +int ast_db_del2(const char *family, const char *key) +{ + char fullkey[MAX_DB_FIELD]; + char tmp[1]; + size_t fullkey_len; + int mres, res = 0; + + if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) { + ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3); + return -1; + } + + fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key); + + ast_mutex_lock(&dblock); + if (ast_db_get(family, key, tmp, sizeof(tmp))) { + ast_log(LOG_WARNING, "AstDB key %s does not exist\n", fullkey); + res = -1; + } else if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) { + ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb)); + res = -1; + } else if ((mres = sqlite3_step(del_stmt) != SQLITE_DONE)) { + ast_log(LOG_WARNING, "AstDB error (%s): %s\n", fullkey, sqlite3_errstr(mres)); + res = -1; + } + sqlite3_reset(del_stmt); + db_sync(); + ast_mutex_unlock(&dblock); + + return res; +} + int ast_db_deltree(const char *family, const char *keytree) { sqlite3_stmt *stmt = deltree_stmt; @@ -678,9 +710,9 @@ static char *handle_cli_database_del(struct ast_cli_entry *e, int cmd, struct as if (a->argc != 4) return CLI_SHOWUSAGE; - res = ast_db_del(a->argv[2], a->argv[3]); + res = ast_db_del2(a->argv[2], a->argv[3]); if (res) { - ast_cli(a->fd, "Database entry does not exist.\n"); + ast_cli(a->fd, "Database entry could not be removed.\n"); } else { ast_cli(a->fd, "Database entry removed.\n"); } @@ -963,9 +995,9 @@ static int manager_dbdel(struct mansession *s, const struct message *m) return 0; } - res = ast_db_del(family, key); + res = ast_db_del2(family, key); if (res) - astman_send_error(s, m, "Database entry not found"); + astman_send_error(s, m, "Database entry could not be deleted"); else astman_send_ack(s, m, "Key deleted successfully"); -- GitLab