diff options
author | Tilghman Lesher <tilghman@meg.abyt.es> | 2007-08-17 13:45:44 +0000 |
---|---|---|
committer | Tilghman Lesher <tilghman@meg.abyt.es> | 2007-08-17 13:45:44 +0000 |
commit | c78ddffb047767ecdffccbd0a426f3ca91722c24 (patch) | |
tree | e07fb49c38779c0bf93a55a1335855b9ed6b13a3 /res/res_config_sqlite.c | |
parent | 646234bd1097024c3a3ca46f0b1ec473ed95fa36 (diff) |
store and destroy implementations for sqlite (closes issue #10446) and odbc (closes issue #10447)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@79860 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_config_sqlite.c')
-rw-r--r-- | res/res_config_sqlite.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/res/res_config_sqlite.c b/res/res_config_sqlite.c index fd28ef62d..34912eaac 100644 --- a/res/res_config_sqlite.c +++ b/res/res_config_sqlite.c @@ -433,6 +433,46 @@ static int realtime_update_handler(const char *database, const char *table, va_list ap); /*! + * \brief Asterisk callback function for RealTime configuration (variable + * create/store). + * + * Asterisk will call this function each time a variable has been created + * internally and must be stored in the backend engine. + * are used to find the row to update, e.g. ap is a list of parameters and + * values with the same format as the other realtime functions. + * + * \param database the database to use (ignored) + * \param table the table to use + * \param ap list of parameters and new values to insert into the database + * \retval the rowid of inserted row. + * \retval -1 if an error occurred. + */ +static int realtime_store_handler(const char *database, const char *table, + va_list ap); + +/*! + * \brief Asterisk callback function for RealTime configuration (destroys + * variable). + * + * Asterisk will call this function each time a variable has been destroyed + * internally and must be removed from the backend engine. keyfield and entity + * are used to find the row to delete, e.g. <code>DELETE FROM table WHERE + * keyfield = 'entity';</code>. ap is a list of parameters and values with the + * same format as the other realtime functions. + * + * \param database the database to use (ignored) + * \param table the table to use + * \param keyfield the column of the matching cell + * \param entity the value of the matching cell + * \param ap list of additional parameters for cell matching + * \retval the number of affected rows. + * \retval -1 if an error occurred. + */ +static int realtime_destroy_handler(const char *database, const char *table, + const char *keyfield, const char *entity, + va_list ap); + +/*! * \brief Asterisk callback function for the CLI status command. * * \param fd file descriptor provided by Asterisk to use with ast_cli() @@ -476,6 +516,8 @@ static struct ast_config_engine sqlite_engine = .load_func = config_handler, .realtime_func = realtime_handler, .realtime_multi_func = realtime_multi_handler, + .store_func = realtime_store_handler, + .destroy_func = realtime_destroy_handler, .update_func = realtime_update_handler }; @@ -1171,6 +1213,176 @@ static int realtime_update_handler(const char *database, const char *table, return rows_num; } +static int realtime_store_handler(const char *database, const char *table, va_list ap) { + char *errormsg, *tmp_str, *tmp_keys, *tmp_keys2, *tmp_vals, *tmp_vals2; + const char **params, **vals; + size_t params_count; + int error, rows_id; + size_t i; + + if (!table) { + ast_log(LOG_WARNING, "Table name unspecified\n"); + return -1; + } + + if (!(params_count = get_params(ap, ¶ms, &vals))) + return -1; + +/* \cond DOXYGEN_CAN_PARSE_THIS */ +#undef QUERY +#define QUERY "INSERT into '%q' (%s) VALUES (%s);" +/* \endcond */ + + tmp_keys2 = NULL; + tmp_vals2 = NULL; + for (i = 0; i < params_count; i++) { + if ( tmp_keys2 ) { + tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]); + sqlite_freemem(tmp_keys2); + } else { + tmp_keys = sqlite_mprintf("%q", params[i]); + } + if (!tmp_keys) { + ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); + ast_free(params); + ast_free(vals); + return -1; + } + + if ( tmp_vals2 ) { + tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, params[i]); + sqlite_freemem(tmp_vals2); + } else { + tmp_vals = sqlite_mprintf("'%q'", params[i]); + } + if (!tmp_vals) { + ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); + ast_free(params); + ast_free(vals); + return -1; + } + + + tmp_keys2 = tmp_keys; + tmp_vals2 = tmp_vals; + } + + ast_free(params); + ast_free(vals); + + if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) { + ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); + return -1; + } + + sqlite_freemem(tmp_keys); + sqlite_freemem(tmp_vals); + + ast_debug(1, "SQL query: %s\n", tmp_str); + + ast_mutex_lock(&mutex); + + RES_SQLITE_BEGIN + error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg); + RES_SQLITE_END(error) + + if (!error) { + rows_id = sqlite_last_insert_rowid(db); + } else { + rows_id = -1; + } + + ast_mutex_unlock(&mutex); + + sqlite_freemem(tmp_str); + + if (error) { + ast_log(LOG_WARNING, "%s\n", errormsg); + ast_free(errormsg); + } + + return rows_id; +} + +static int realtime_destroy_handler(const char *database, const char *table, + const char *keyfield, const char *entity, + va_list ap) +{ + char *query, *errormsg, *tmp_str; + const char **params, **vals; + size_t params_count; + int error, rows_num; + size_t i; + + if (!table) { + ast_log(LOG_WARNING, "Table name unspecified\n"); + return -1; + } + + if (!(params_count = get_params(ap, ¶ms, &vals))) + return -1; + +/* \cond DOXYGEN_CAN_PARSE_THIS */ +#undef QUERY +#define QUERY "DELETE FROM '%q' WHERE" +/* \endcond */ + + if (!(query = sqlite_mprintf(QUERY, table))) { + ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); + ast_free(params); + ast_free(vals); + return -1; + } + + for (i = 0; i < params_count; i++) { + tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]); + sqlite_freemem(query); + + if (!tmp_str) { + ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); + ast_free(params); + ast_free(vals); + return -1; + } + + query = tmp_str; + } + + ast_free(params); + ast_free(vals); + if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) { + ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); + return -1; + } + sqlite_freemem(query); + query = tmp_str; + + ast_debug(1, "SQL query: %s\n", query); + + ast_mutex_lock(&mutex); + + RES_SQLITE_BEGIN + error = sqlite_exec(db, query, NULL, NULL, &errormsg); + RES_SQLITE_END(error) + + if (!error) + rows_num = sqlite_changes(db); + else + rows_num = -1; + + ast_mutex_unlock(&mutex); + + sqlite_freemem(query); + + if (error) { + ast_log(LOG_WARNING, "%s\n", errormsg); + ast_free(errormsg); + } + + return rows_num; +} + + static int cli_status(int fd, int argc, char *argv[]) { ast_cli(fd, "SQLite database path: %s\n", dbfile); |