mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 03:20:57 +00:00
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/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@386731 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -316,7 +316,7 @@ static char *decode_chunk(char *chunk)
|
||||
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 @@ static struct ast_variable *realtime_mysql(const char *database, const char *tab
|
||||
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 @@ static struct ast_variable *realtime_mysql(const char *database, const char *tab
|
||||
}
|
||||
|
||||
/* 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 @@ static struct ast_variable *realtime_mysql(const char *database, const char *tab
|
||||
/* 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 @@ static struct ast_variable *realtime_mysql(const char *database, const char *tab
|
||||
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 @@ static struct ast_config *realtime_multi_mysql(const char *database, const char
|
||||
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 @@ static struct ast_config *realtime_multi_mysql(const char *database, const char
|
||||
}
|
||||
|
||||
/* 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 @@ static struct ast_config *realtime_multi_mysql(const char *database, const char
|
||||
/* 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 @@ static struct ast_config *realtime_multi_mysql(const char *database, const char
|
||||
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 @@ static int update_mysql(const char *database, const char *tablename, const char
|
||||
}
|
||||
|
||||
/* 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 @@ static int update_mysql(const char *database, const char *tablename, const char
|
||||
}
|
||||
|
||||
/* 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 @@ static int update_mysql(const char *database, const char *tablename, const char
|
||||
/* 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);
|
||||
internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
|
||||
}
|
||||
|
||||
while ((newparam = va_arg(ap, const char *))) {
|
||||
newval = va_arg(ap, const char *);
|
||||
|
||||
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 @@ static int update_mysql(const char *database, const char *tablename, const char
|
||||
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 @@ static int update2_mysql(const char *database, const char *tablename, va_list ap
|
||||
}
|
||||
|
||||
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 @@ static int update2_mysql(const char *database, const char *tablename, va_list ap
|
||||
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 @@ static int store_mysql(const char *database, const char *table, va_list ap)
|
||||
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 @@ static int store_mysql(const char *database, const char *table, va_list ap)
|
||||
}
|
||||
/* 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);
|
||||
internal_require(database, table, field->name, 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);
|
||||
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 @@ static int store_mysql(const char *database, const char *table, va_list ap)
|
||||
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 @@ static int destroy_mysql(const char *database, const char *table, const char *ke
|
||||
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));
|
||||
|
Reference in New Issue
Block a user