[asterisk-commits] file: trunk r386731 - in /trunk: ./ addons/ include/asterisk/ main/ res/ tests/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Apr 27 07:01:38 CDT 2013
Author: file
Date: Sat Apr 27 07:01:29 2013
New Revision: 386731
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386731
Log:
Add support for a realtime sorcery module.
This change does the following:
1. Adds the sorcery realtime module
2. Adds unit tests for the sorcery realtime module
3. Changes the realtime core to use an ast_variable list instead of variadic arguments
4. Changes all realtime drivers to accept an ast_variable list
Review: https://reviewboard.asterisk.org/r/2424/
Added:
trunk/res/res_sorcery_realtime.c (with props)
trunk/tests/test_sorcery_realtime.c (with props)
Modified:
trunk/CHANGES
trunk/addons/res_config_mysql.c
trunk/include/asterisk/config.h
trunk/main/config.c
trunk/main/sorcery.c
trunk/res/res_config_curl.c
trunk/res/res_config_ldap.c
trunk/res/res_config_odbc.c
trunk/res/res_config_pgsql.c
trunk/res/res_config_sqlite3.c
Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=386731&r1=386730&r2=386731
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Sat Apr 27 07:01:29 2013
@@ -146,6 +146,12 @@
If any resource is available the device state is considered to be not in use.
If no resources exist or all are unavailable the device state is considered
to be unavailable.
+
+Sorcery
+------------------
+ * All future modules which utilize Sorcery for object persistence must have a
+ column named "id" within their schema when using the Sorcery realtime module.
+ This column must be able to contain a string of up to 128 characters in length.
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 10 to Asterisk 11 --------------------
Modified: trunk/addons/res_config_mysql.c
URL: http://svnview.digium.com/svn/asterisk/trunk/addons/res_config_mysql.c?view=diff&rev=386731&r1=386730&r2=386731
==============================================================================
--- trunk/addons/res_config_mysql.c (original)
+++ trunk/addons/res_config_mysql.c Sat Apr 27 07:01:29 2013
@@ -316,7 +316,7 @@
return orig;
}
-static struct ast_variable *realtime_mysql(const char *database, const char *table, va_list ap)
+static struct ast_variable *realtime_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
{
struct mysql_conn *dbh;
MYSQL_RES *result;
@@ -328,7 +328,7 @@
char *stringp;
char *chunk;
char *op;
- const char *newparam, *newval;
+ const struct ast_variable *field = rt_fields;
struct ast_variable *var=NULL, *prev=NULL;
if (!(dbh = find_database(database, 0))) {
@@ -343,7 +343,7 @@
}
/* Get the first parameter and first value in our list of passed paramater/value pairs */
- if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *))) {
+ if (!field) {
ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
release_database(dbh);
return NULL;
@@ -358,21 +358,20 @@
/* Create the first part of the query using the first parameter/value pairs we just extracted
If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
- if (!strchr(newparam, ' '))
+ if (!strchr(field->name, ' '))
op = " =";
else
op = "";
- ESCAPE_STRING(buf, newval);
- ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, ast_str_buffer(buf));
- while ((newparam = va_arg(ap, const char *))) {
- newval = va_arg(ap, const char *);
- if (!strchr(newparam, ' '))
+ ESCAPE_STRING(buf, field->value);
+ ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, field->name, op, ast_str_buffer(buf));
+ while ((field = field->next)) {
+ if (!strchr(field->name, ' '))
op = " =";
else
op = "";
- ESCAPE_STRING(buf, newval);
- ast_str_append(&sql, 0, " AND %s%s '%s'", newparam, op, ast_str_buffer(buf));
+ ESCAPE_STRING(buf, field->value);
+ ast_str_append(&sql, 0, " AND %s%s '%s'", field->name, op, ast_str_buffer(buf));
}
ast_debug(1, "MySQL RealTime: Retrieve SQL: %s\n", ast_str_buffer(sql));
@@ -417,7 +416,7 @@
return var;
}
-static struct ast_config *realtime_multi_mysql(const char *database, const char *table, va_list ap)
+static struct ast_config *realtime_multi_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
{
struct mysql_conn *dbh;
MYSQL_RES *result;
@@ -430,7 +429,7 @@
char *stringp;
char *chunk;
char *op;
- const char *newparam, *newval;
+ const struct ast_variable *field = rt_fields;
struct ast_variable *var = NULL;
struct ast_config *cfg = NULL;
struct ast_category *cat = NULL;
@@ -454,14 +453,14 @@
}
/* Get the first parameter and first value in our list of passed paramater/value pairs */
- if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *))) {
+ if (!field) {
ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
ast_config_destroy(cfg);
release_database(dbh);
return NULL;
}
- initfield = ast_strdupa(newparam);
+ initfield = ast_strdupa(field->name);
if ((op = strchr(initfield, ' '))) {
*op = '\0';
}
@@ -476,18 +475,17 @@
/* Create the first part of the query using the first parameter/value pairs we just extracted
If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
- if (!strchr(newparam, ' '))
+ if (!strchr(field->name, ' '))
op = " =";
else
op = "";
- ESCAPE_STRING(buf, newval);
- ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, ast_str_buffer(buf));
- while ((newparam = va_arg(ap, const char *))) {
- newval = va_arg(ap, const char *);
- if (!strchr(newparam, ' ')) op = " ="; else op = "";
- ESCAPE_STRING(buf, newval);
- ast_str_append(&sql, 0, " AND %s%s '%s'", newparam, op, ast_str_buffer(buf));
+ ESCAPE_STRING(buf, field->value);
+ ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, field->name, op, ast_str_buffer(buf));
+ while ((field = field->next)) {
+ if (!strchr(field->name, ' ')) op = " ="; else op = "";
+ ESCAPE_STRING(buf, field->value);
+ ast_str_append(&sql, 0, " AND %s%s '%s'", field->name, op, ast_str_buffer(buf));
}
if (initfield) {
@@ -540,11 +538,11 @@
return cfg;
}
-static int update_mysql(const char *database, const char *tablename, const char *keyfield, const char *lookup, va_list ap)
+static int update_mysql(const char *database, const char *tablename, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
{
struct mysql_conn *dbh;
my_ulonglong numrows;
- const char *newparam, *newval;
+ const struct ast_variable *field = rt_fields;
struct ast_str *sql = ast_str_thread_get(&sql_buf, 100), *buf = ast_str_thread_get(&scratch_buf, 100);
struct tables *table;
struct columns *column = NULL;
@@ -574,7 +572,7 @@
}
/* Get the first parameter and first value in our list of passed paramater/value pairs */
- if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *))) {
+ if (!field) {
ast_log(LOG_WARNING, "MySQL RealTime: Realtime update requires at least 1 parameter and 1 value to update.\n");
release_table(table);
release_database(dbh);
@@ -582,8 +580,8 @@
}
/* Check that the column exists in the table */
- if (!(column = find_column(table, newparam))) {
- ast_log(LOG_ERROR, "MySQL RealTime: Updating column '%s', but that column does not exist within the table '%s' (first pair MUST exist)!\n", newparam, tablename);
+ if (!(column = find_column(table, field->name))) {
+ ast_log(LOG_ERROR, "MySQL RealTime: Updating column '%s', but that column does not exist within the table '%s' (first pair MUST exist)!\n", field->name, tablename);
release_table(table);
release_database(dbh);
return -1;
@@ -599,29 +597,27 @@
/* Create the first part of the query using the first parameter/value pairs we just extracted
If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
- ESCAPE_STRING(buf, newval);
- ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, newparam, ast_str_buffer(buf));
+ ESCAPE_STRING(buf, field->value);
+ ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, field->name, ast_str_buffer(buf));
/* If the column length isn't long enough, give a chance to lengthen it. */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
- internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
- }
-
- while ((newparam = va_arg(ap, const char *))) {
- newval = va_arg(ap, const char *);
-
+ internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+ }
+
+ while ((field = field->next)) {
/* If the column is not within the table, then skip it */
- if (!(column = find_column(table, newparam))) {
- ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", newparam, tablename);
+ if (!(column = find_column(table, field->name))) {
+ ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", field->name, tablename);
continue;
}
- ESCAPE_STRING(buf, newval);
- ast_str_append(&sql, 0, ", `%s` = '%s'", newparam, ast_str_buffer(buf));
+ ESCAPE_STRING(buf, field->value);
+ ast_str_append(&sql, 0, ", `%s` = '%s'", field->value, ast_str_buffer(buf));
/* If the column length isn't long enough, give a chance to lengthen it. */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
- internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+ internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
}
}
@@ -653,12 +649,12 @@
return (int)numrows;
}
-static int update2_mysql(const char *database, const char *tablename, va_list ap)
+static int update2_mysql(const char *database, const char *tablename, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
{
struct mysql_conn *dbh;
my_ulonglong numrows;
int first;
- const char *newparam, *newval;
+ const struct ast_variable *field;
struct ast_str *sql = ast_str_thread_get(&sql_buf, 100), *buf = ast_str_thread_get(&scratch_buf, 100);
struct ast_str *where = ast_str_thread_get(&sql2_buf, 100);
struct tables *table;
@@ -697,51 +693,38 @@
}
first = 1;
- while ((newparam = va_arg(ap, const char *))) {
- if (!(column = find_column(table, newparam))) {
- ast_log(LOG_ERROR, "Updating on column '%s', but that column does not exist within the table '%s'!\n", newparam, tablename);
+ for (field = lookup_fields; field; field = field->next) {
+ if (!(column = find_column(table, field->name))) {
+ ast_log(LOG_ERROR, "Updating on column '%s', but that column does not exist within the table '%s'!\n", field->name, tablename);
release_table(table);
release_database(dbh);
return -1;
}
- if (!(newval = va_arg(ap, const char *))) {
- ast_log(LOG_ERROR, "Invalid arguments: no value specified for column '%s' on '%s@%s'\n", newparam, tablename, database);
- release_table(table);
- release_database(dbh);
- return -1;
- }
- ESCAPE_STRING(buf, newval);
- ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", newparam, ast_str_buffer(buf));
+ ESCAPE_STRING(buf, field->value);
+ ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", field->name, ast_str_buffer(buf));
first = 0;
/* If the column length isn't long enough, give a chance to lengthen it. */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
- internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+ internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
}
}
first = 1;
- while ((newparam = va_arg(ap, const char *))) {
- if (!(newval = va_arg(ap, const char *))) {
- ast_log(LOG_ERROR, "Invalid arguments: no value specified for column '%s' on '%s@%s'\n", newparam, tablename, database);
- release_table(table);
- release_database(dbh);
- return -1;
- }
-
+ for (field = update_fields; field; field = field->next) {
/* If the column is not within the table, then skip it */
- if (!(column = find_column(table, newparam))) {
- ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", newparam, tablename);
+ if (!(column = find_column(table, field->name))) {
+ ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", field->name, tablename);
continue;
}
- ESCAPE_STRING(buf, newval);
- ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", newparam, ast_str_buffer(buf));
+ ESCAPE_STRING(buf, field->value);
+ ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", field->name, ast_str_buffer(buf));
first = 0;
/* If the column length isn't long enough, give a chance to lengthen it. */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
- internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+ internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
}
}
@@ -773,14 +756,14 @@
return (int)numrows;
}
-static int store_mysql(const char *database, const char *table, va_list ap)
+static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
{
struct mysql_conn *dbh;
my_ulonglong insertid;
struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
struct ast_str *sql2 = ast_str_thread_get(&sql2_buf, 16);
struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16);
- const char *newparam, *newval;
+ const struct ast_variable *field = rt_fields;
if (!(dbh = find_database(database, 1))) {
ast_log(LOG_WARNING, "MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
@@ -793,7 +776,7 @@
return -1;
}
/* Get the first parameter and first value in our list of passed paramater/value pairs */
- if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *))) {
+ if (!field) {
ast_log(LOG_WARNING, "MySQL RealTime: Realtime storage requires at least 1 parameter and 1 value to search on.\n");
release_database(dbh);
return -1;
@@ -805,20 +788,17 @@
}
/* Create the first part of the query using the first parameter/value pairs we just extracted
If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
- ESCAPE_STRING(buf, newval);
- ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, newparam);
+ ESCAPE_STRING(buf, field->value);
+ ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, field->name);
ast_str_set(&sql2, 0, ") VALUES ('%s'", ast_str_buffer(buf));
- internal_require(database, table, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-
- while ((newparam = va_arg(ap, const char *))) {
- if ((newval = va_arg(ap, const char *))) {
- ESCAPE_STRING(buf, newval);
- } else {
- ast_str_reset(buf);
- }
- if (internal_require(database, table, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL) == 0) {
- ast_str_append(&sql, 0, ", `%s`", newparam);
+ internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+
+ while ((field = field->next)) {
+ ESCAPE_STRING(buf, field->value);
+
+ if (internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL) == 0) {
+ ast_str_append(&sql, 0, ", `%s`", field->name);
ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
}
}
@@ -846,13 +826,13 @@
return (int)insertid;
}
-static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
+static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
{
struct mysql_conn *dbh;
my_ulonglong numrows;
struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16);
- const char *newparam, *newval;
+ const struct ast_variable *field;
if (!(dbh = find_database(database, 1))) {
ast_log(LOG_WARNING, "MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
@@ -884,10 +864,9 @@
If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
ESCAPE_STRING(buf, lookup);
ast_str_set(&sql, 0, "DELETE FROM %s WHERE `%s` = '%s'", table, keyfield, ast_str_buffer(buf));
- while ((newparam = va_arg(ap, const char *))) {
- newval = va_arg(ap, const char *);
- ESCAPE_STRING(buf, newval);
- ast_str_append(&sql, 0, " AND `%s` = '%s'", newparam, ast_str_buffer(buf));
+ for (field = rt_fields; field; field = field->next) {
+ ESCAPE_STRING(buf, field->value);
+ ast_str_append(&sql, 0, " AND `%s` = '%s'", field->name, ast_str_buffer(buf));
}
ast_debug(1, "MySQL RealTime: Delete SQL: %s\n", ast_str_buffer(sql));
Modified: trunk/include/asterisk/config.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/config.h?view=diff&rev=386731&r1=386730&r2=386731
==============================================================================
--- trunk/include/asterisk/config.h (original)
+++ trunk/include/asterisk/config.h Sat Apr 27 07:01:29 2013
@@ -98,12 +98,12 @@
};
typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags, const char *suggested_include_file, const char *who_asked);
-typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
-typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
-typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
-typedef int realtime_update2(const char *database, const char *table, va_list ap);
-typedef int realtime_store(const char *database, const char *table, va_list ap);
-typedef int realtime_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
+typedef struct ast_variable *realtime_var_get(const char *database, const char *table, const struct ast_variable *fields);
+typedef struct ast_config *realtime_multi_get(const char *database, const char *table, const struct ast_variable *fields);
+typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields);
+typedef int realtime_update2(const char *database, const char *table, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields);
+typedef int realtime_store(const char *database, const char *table, const struct ast_variable *fields);
+typedef int realtime_destroy(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields);
/*!
* \brief Function pointer called to ensure database schema is properly configured for realtime use
@@ -305,7 +305,9 @@
* You should use the constant SENTINEL to terminate arguments, in
* order to preserve cross-platform compatibility.
*/
+struct ast_variable *ast_load_realtime_fields(const char *family, const struct ast_variable *fields);
struct ast_variable *ast_load_realtime(const char *family, ...) attribute_sentinel;
+struct ast_variable *ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields);
struct ast_variable *ast_load_realtime_all(const char *family, ...) attribute_sentinel;
/*!
@@ -363,6 +365,7 @@
* \brief Retrieve realtime configuration
*
* \param family which family/config to lookup
+ * \param fields list of fields
*
* \details
* This will use builtin configuration backends to look up a particular
@@ -373,6 +376,23 @@
*
* \return An ast_config with one or more results
* \retval NULL Error or no results returned
+ */
+struct ast_config *ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields);
+
+/*!
+ * \brief Retrieve realtime configuration
+ *
+ * \param family which family/config to lookup
+ *
+ * \details
+ * This will use builtin configuration backends to look up a particular
+ * entity in realtime and return a variable list of its parameters. Unlike
+ * the ast_load_realtime, this function can return more than one entry and
+ * is thus stored inside a traditional ast_config structure rather than
+ * just returning a linked list of variables.
+ *
+ * \return An ast_config with one or more results
+ * \retval NULL Error or no results returned
*
* \note You should use the constant SENTINEL to terminate arguments, in
* order to preserve cross-platform compatibility.
@@ -385,6 +405,21 @@
* \param family which family/config to be updated
* \param keyfield which field to use as the key
* \param lookup which value to look for in the key field to match the entry.
+ * \param fields fields to update
+ *
+ * \details
+ * This function is used to update a parameter in realtime configuration space.
+ *
+ * \return Number of rows affected, or -1 on error.
+ */
+int ast_update_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields);
+
+/*!
+ * \brief Update realtime configuration
+ *
+ * \param family which family/config to be updated
+ * \param keyfield which field to use as the key
+ * \param lookup which value to look for in the key field to match the entry.
*
* \details
* This function is used to update a parameter in realtime configuration space.
@@ -400,6 +435,8 @@
* \brief Update realtime configuration
*
* \param family which family/config to be updated
+ * \param lookup_fields fields used to look up entries
+ * \param update_fields fields to update
*
* \details
* This function is used to update a parameter in realtime configuration space.
@@ -408,6 +445,21 @@
* lookup values and the other to terminate the listing of fields to update.
*
* \return Number of rows affected, or -1 on error.
+ */
+int ast_update2_realtime_fields(const char *family, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields);
+
+/*!
+ * \brief Update realtime configuration
+ *
+ * \param family which family/config to be updated
+ *
+ * \details
+ * This function is used to update a parameter in realtime configuration space.
+ * It includes the ability to lookup a row based upon multiple key criteria.
+ * As a result, this function includes two sentinel values, one to terminate
+ * lookup values and the other to terminate the listing of fields to update.
+ *
+ * \return Number of rows affected, or -1 on error.
*
* \note You should use the constant SENTINEL to terminate arguments, in
* order to preserve cross-platform compatibility.
@@ -418,6 +470,7 @@
* \brief Create realtime configuration
*
* \param family which family/config to be created
+ * \param fields fields themselves
*
* \details
* This function is used to create a parameter in realtime configuration space.
@@ -428,11 +481,44 @@
* On the MySQL engine only, for reasons of backwards compatibility, the return
* value is the insert ID. This value is nonportable and may be changed in a
* future version to match the other engines.
+ */
+int ast_store_realtime_fields(const char *family, const struct ast_variable *fields);
+
+/*!
+ * \brief Create realtime configuration
+ *
+ * \param family which family/config to be created
+ *
+ * \details
+ * This function is used to create a parameter in realtime configuration space.
+ *
+ * \return Number of rows affected, or -1 on error.
+ *
+ * \note
+ * On the MySQL engine only, for reasons of backwards compatibility, the return
+ * value is the insert ID. This value is nonportable and may be changed in a
+ * future version to match the other engines.
*
* \note You should use the constant SENTINEL to terminate arguments, in
* order to preserve cross-platform compatibility.
*/
int ast_store_realtime(const char *family, ...) attribute_sentinel;
+
+/*!
+ * \brief Destroy realtime configuration
+ *
+ * \param family which family/config to be destroyed
+ * \param keyfield which field to use as the key
+ * \param lookup which value to look for in the key field to match the entry.
+ * \param fields fields themselves
+ *
+ * \details
+ * This function is used to destroy an entry in realtime configuration space.
+ * Additional params are used as keys.
+ *
+ * \return Number of rows affected, or -1 on error.
+ */
+int ast_destroy_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields);
/*!
* \brief Destroy realtime configuration
@@ -502,6 +588,19 @@
* \retval 0 if it is not
*/
int ast_realtime_is_mapping_defined(const char *family);
+
+#ifdef TEST_FRAMEWORK
+/*!
+ * \brief Add an explicit mapping for a family
+ *
+ * \param name Family name
+ * \param driver Driver to use
+ * \param database Database to access
+ * \param table Table to use
+ * \param priority Priority of this mapping
+ */
+int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority);
+#endif
/*!
* \brief Exposed initialization method for core process
Modified: trunk/main/config.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/config.c?view=diff&rev=386731&r1=386730&r2=386731
==============================================================================
--- trunk/main/config.c (original)
+++ trunk/main/config.c Sat Apr 27 07:01:29 2013
@@ -2220,7 +2220,11 @@
}
}
-static int append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
+#ifdef TEST_FRAMEWORK
+int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
+#else
+static int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
+#endif
{
struct ast_config_map *map;
char *dst;
@@ -2323,13 +2327,13 @@
continue;
if (!strcasecmp(v->name, "sipfriends")) {
ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
- append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
+ ast_realtime_append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
} else if (!strcasecmp(v->name, "iaxfriends")) {
ast_log(LOG_WARNING, "The 'iaxfriends' table is obsolete, update your config to use iaxusers and iaxpeers, though they can point to the same table.\n");
- append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
- append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
+ ast_realtime_append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
+ ast_realtime_append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
} else
- append_mapping(v->name, driver, database, table, pri);
+ ast_realtime_append_mapping(v->name, driver, database, table, pri);
}
ast_config_destroy(config);
@@ -2517,7 +2521,36 @@
return result;
}
-static struct ast_variable *ast_load_realtime_helper(const char *family, va_list ap)
+static struct ast_variable *realtime_arguments_to_fields(va_list ap)
+{
+ struct ast_variable *first, *fields = NULL;
+ const char *newparam = va_arg(ap, const char *), *newval = va_arg(ap, const char *);
+
+ if (!(first = ast_variable_new(newparam, newval, ""))) {
+ return NULL;
+ }
+
+ while ((newparam = va_arg(ap, const char *))) {
+ struct ast_variable *field;
+
+ newval = va_arg(ap, const char *);
+ if (!(field = ast_variable_new(newparam, newval, ""))) {
+ ast_variables_destroy(fields);
+ ast_variables_destroy(first);
+ return NULL;
+ }
+
+ field->next = fields;
+ fields = field;
+ }
+
+ first->next = fields;
+ fields = first;
+
+ return fields;
+}
+
+struct ast_variable *ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields)
{
struct ast_config_engine *eng;
char db[256];
@@ -2527,7 +2560,7 @@
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
- if (eng->realtime_func && (res = eng->realtime_func(db, table, ap))) {
+ if (eng->realtime_func && (res = eng->realtime_func(db, table, fields))) {
return res;
}
} else {
@@ -2540,26 +2573,28 @@
struct ast_variable *ast_load_realtime_all(const char *family, ...)
{
- struct ast_variable *res;
+ RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
+ struct ast_variable *res = NULL;
va_list ap;
va_start(ap, family);
- res = ast_load_realtime_helper(family, ap);
+ fields = realtime_arguments_to_fields(ap);
va_end(ap);
+ if (fields) {
+ res = ast_load_realtime_all_fields(family, fields);
+ }
+
return res;
}
-struct ast_variable *ast_load_realtime(const char *family, ...)
+struct ast_variable *ast_load_realtime_fields(const char *family, const struct ast_variable *fields)
{
struct ast_variable *res;
struct ast_variable *cur;
struct ast_variable **prev;
- va_list ap;
-
- va_start(ap, family);
- res = ast_load_realtime_helper(family, ap);
- va_end(ap);
+
+ res = ast_load_realtime_all_fields(family, fields);
/* Filter the list. */
prev = &res;
@@ -2588,6 +2623,18 @@
return res;
}
+struct ast_variable *ast_load_realtime(const char *family, ...)
+{
+ RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
+ va_list ap;
+
+ va_start(ap, family);
+ fields = realtime_arguments_to_fields(ap);
+ va_end(ap);
+
+ return ast_load_realtime_fields(family, fields);
+}
+
/*! \brief Check if realtime engine is configured for family */
int ast_check_realtime(const char *family)
{
@@ -2652,19 +2699,17 @@
return res;
}
-struct ast_config *ast_load_realtime_multientry(const char *family, ...)
+struct ast_config *ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields)
{
struct ast_config_engine *eng;
char db[256];
char table[256];
struct ast_config *res = NULL;
- va_list ap;
int i;
- va_start(ap, family);
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
- if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, ap))) {
+ if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, fields))) {
/* If we were returned an empty cfg, destroy it and return NULL */
if (!res->root) {
ast_config_destroy(res);
@@ -2676,103 +2721,152 @@
break;
}
}
+
+ return res;
+}
+
+struct ast_config *ast_load_realtime_multientry(const char *family, ...)
+{
+ RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
+ va_list ap;
+
+ va_start(ap, family);
+ fields = realtime_arguments_to_fields(ap);
va_end(ap);
- return res;
-}
-
-int ast_update_realtime(const char *family, const char *keyfield, const char *lookup, ...)
+ return ast_load_realtime_multientry_fields(family, fields);
+}
+
+int ast_update_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
{
struct ast_config_engine *eng;
int res = -1, i;
char db[256];
char table[256];
- va_list ap;
-
- va_start(ap, lookup);
+
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
/* If the update succeeds, it returns 0. */
- if (eng->update_func && !(res = eng->update_func(db, table, keyfield, lookup, ap))) {
+ if (eng->update_func && !(res = eng->update_func(db, table, keyfield, lookup, fields))) {
break;
}
} else {
break;
}
}
+
+ return res;
+}
+
+int ast_update_realtime(const char *family, const char *keyfield, const char *lookup, ...)
+{
+ RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
+ va_list ap;
+
+ va_start(ap, lookup);
+ fields = realtime_arguments_to_fields(ap);
va_end(ap);
- return res;
-}
-
-int ast_update2_realtime(const char *family, ...)
+ return ast_update_realtime_fields(family, keyfield, lookup, fields);
+}
+
+int ast_update2_realtime_fields(const char *family, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
{
struct ast_config_engine *eng;
int res = -1, i;
char db[256];
char table[256];
- va_list ap;
-
- va_start(ap, family);
+
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
- if (eng->update2_func && !(res = eng->update2_func(db, table, ap))) {
+ if (eng->update2_func && !(res = eng->update2_func(db, table, lookup_fields, update_fields))) {
break;
}
} else {
break;
}
}
+
+ return res;
+}
+
+int ast_update2_realtime(const char *family, ...)
+{
+ RAII_VAR(struct ast_variable *, lookup_fields, NULL, ast_variables_destroy);
+ RAII_VAR(struct ast_variable *, update_fields, NULL, ast_variables_destroy);
+ va_list ap;
+
+ va_start(ap, family);
+ lookup_fields = realtime_arguments_to_fields(ap);
+ update_fields = realtime_arguments_to_fields(ap);
va_end(ap);
- return res;
-}
-
-int ast_store_realtime(const char *family, ...)
+ return ast_update2_realtime_fields(family, lookup_fields, update_fields);
+}
+
+int ast_store_realtime_fields(const char *family, const struct ast_variable *fields)
{
struct ast_config_engine *eng;
int res = -1, i;
char db[256];
char table[256];
- va_list ap;
-
- va_start(ap, family);
+
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
/* If the store succeeds, it returns 0. */
- if (eng->store_func && !(res = eng->store_func(db, table, ap))) {
+ if (eng->store_func && !(res = eng->store_func(db, table, fields))) {
break;
}
} else {
break;
}
}
+
+ return res;
+}
+
+int ast_store_realtime(const char *family, ...)
+{
+ RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
+ va_list ap;
+
+ va_start(ap, family);
+ fields = realtime_arguments_to_fields(ap);
va_end(ap);
- return res;
-}
-
-int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup, ...)
+ return ast_store_realtime_fields(family, fields);
+}
+
+int ast_destroy_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
{
struct ast_config_engine *eng;
int res = -1, i;
char db[256];
char table[256];
- va_list ap;
-
- va_start(ap, lookup);
+
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
- if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, ap))) {
+ if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, fields))) {
break;
}
} else {
break;
}
}
+
+ return res;
+}
+
+int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup, ...)
+{
+ RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
+ va_list ap;
+
+ va_start(ap, lookup);
+ fields = realtime_arguments_to_fields(ap);
va_end(ap);
- return res;
+ return ast_destroy_realtime_fields(family, keyfield, lookup, fields);
}
char *ast_realtime_decode_chunk(char *chunk)
Modified: trunk/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/sorcery.c?view=diff&rev=386731&r1=386730&r2=386731
==============================================================================
--- trunk/main/sorcery.c (original)
+++ trunk/main/sorcery.c Sat Apr 27 07:01:29 2013
@@ -540,7 +540,7 @@
int pos;
va_list args;
- if (!object_type || !object_type->type.item_alloc) {
+ if (!strcmp(type, "id") || !object_type || !object_type->type.item_alloc) {
return -1;
}
Modified: trunk/res/res_config_curl.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_config_curl.c?view=diff&rev=386731&r1=386730&r2=386731
==============================================================================
--- trunk/res/res_config_curl.c (original)
+++ trunk/res/res_config_curl.c Sat Apr 27 07:01:29 2013
@@ -53,18 +53,18 @@
* \brief Execute a curl query and return ast_variable list
* \param url The base URL from which to retrieve data
* \param unused Not currently used
- * \param ap list containing one or more field/operator/value set.
+ * \param fields list containing one or more field/operator/value set.
*
* \retval var on success
* \retval NULL on failure
*/
-static struct ast_variable *realtime_curl(const char *url, const char *unused, va_list ap)
+static struct ast_variable *realtime_curl(const char *url, const char *unused, const struct ast_variable *fields)
{
struct ast_str *query, *buffer;
char buf1[256], buf2[256];
- const char *newparam, *newval;
+ const struct ast_variable *field;
char *stringp, *pair, *key;
- int i;
+ unsigned int start = 1;
struct ast_variable *var = NULL, *prev = NULL;
if (!ast_custom_function_find("CURL")) {
@@ -82,11 +82,11 @@
ast_str_set(&query, 0, "${CURL(%s/single,", url);
- for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
- newval = va_arg(ap, const char *);
- ast_uri_encode(newparam, buf1, sizeof(buf1), ast_uri_http);
- ast_uri_encode(newval, buf2, sizeof(buf2), ast_uri_http);
- ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
+ for (field = fields; field; field = field->next) {
+ ast_uri_encode(field->name, buf1, sizeof(buf1), ast_uri_http);
+ ast_uri_encode(field->value, buf2, sizeof(buf2), ast_uri_http);
+ ast_str_append(&query, 0, "%s%s=%s", !start ? "&" : "", buf1, buf2);
+ start = 0;
}
ast_str_append(&query, 0, ")}");
@@ -124,18 +124,18 @@
* \brief Excute an Select query and return ast_config list
* \param url
* \param unused
- * \param ap list containing one or more field/operator/value set.
+ * \param fields list containing one or more field/operator/value set.
*
* \retval struct ast_config pointer on success
* \retval NULL on failure
*/
-static struct ast_config *realtime_multi_curl(const char *url, const char *unused, va_list ap)
+static struct ast_config *realtime_multi_curl(const char *url, const char *unused, const struct ast_variable *fields)
{
struct ast_str *query, *buffer;
char buf1[256], buf2[256];
- const char *newparam, *newval;
+ const struct ast_variable *field;
char *stringp, *line, *pair, *key, *initfield = NULL;
- int i;
+ int start = 1;
struct ast_variable *var = NULL;
struct ast_config *cfg = NULL;
struct ast_category *cat = NULL;
@@ -155,17 +155,17 @@
ast_str_set(&query, 0, "${CURL(%s/multi,", url);
- for (i = 0; (newparam = va_arg(ap, const char *)); i++) {
- newval = va_arg(ap, const char *);
- if (i == 0) {
+ for (field = fields; field; field = field->next) {
+ if (start) {
char *op;
- initfield = ast_strdupa(newparam);
+ initfield = ast_strdupa(field->name);
if ((op = strchr(initfield, ' ')))
*op = '\0';
}
- ast_uri_encode(newparam, buf1, sizeof(buf1), ast_uri_http);
- ast_uri_encode(newval, buf2, sizeof(buf2), ast_uri_http);
- ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2);
+ ast_uri_encode(field->name, buf1, sizeof(buf1), ast_uri_http);
+ ast_uri_encode(field->value, buf2, sizeof(buf2), ast_uri_http);
+ ast_str_append(&query, 0, "%s%s=%s", !start ? "&" : "", buf1, buf2);
[... 2690 lines stripped ...]
More information about the asterisk-commits
mailing list