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:
Joshua Colp
2013-04-27 12:01:29 +00:00
parent c5f1eecb15
commit 02be50b1ac
12 changed files with 1672 additions and 543 deletions

View File

@@ -61,12 +61,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
***/
static struct ast_config *realtime_sqlite3_load(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);
static struct ast_variable *realtime_sqlite3(const char *database, const char *table, va_list ap);
static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, va_list ap);
static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
static int realtime_sqlite3_update2(const char *database, const char *table, va_list ap);
static int realtime_sqlite3_store(const char *database, const char *table, va_list ap);
static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
static struct ast_variable *realtime_sqlite3(const char *database, const char *table, const struct ast_variable *fields);
static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, const struct ast_variable *fields);
static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields);
static int realtime_sqlite3_update2(const char *database, const char *table, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields);
static int realtime_sqlite3_store(const char *database, const char *table, const struct ast_variable *fields);
static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields);
static int realtime_sqlite3_require(const char *database, const char *table, va_list ap);
static int realtime_sqlite3_unload(const char *database, const char *table);
@@ -648,10 +648,10 @@ static struct ast_config *realtime_sqlite3_load(const char *database, const char
}
/*! \brief Helper function for single and multi-row realtime load functions */
static int realtime_sqlite3_helper(const char *database, const char *table, va_list ap, int is_multi, void *arg)
static int realtime_sqlite3_helper(const char *database, const char *table, const struct ast_variable *fields, int is_multi, void *arg)
{
struct ast_str *sql;
const char *param, *value;
const struct ast_variable *field;
int first = 1;
if (ast_strlen_zero(table)) {
@@ -663,14 +663,14 @@ static int realtime_sqlite3_helper(const char *database, const char *table, va_l
return -1;
}
while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
for (field = fields; field; field = field->next) {
if (first) {
ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
sqlite3_escape_column_op(param), sqlite3_escape_value(value));
sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
first = 0;
} else {
ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param),
sqlite3_escape_value(value));
ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(field->name),
sqlite3_escape_value(field->value));
}
}
@@ -691,11 +691,11 @@ static int realtime_sqlite3_helper(const char *database, const char *table, va_l
/*! \brief Realtime callback for a single row query
* \return ast_variable list for single result on success, NULL on empty/failure
*/
static struct ast_variable *realtime_sqlite3(const char *database, const char *table, va_list ap)
static struct ast_variable *realtime_sqlite3(const char *database, const char *table, const struct ast_variable *fields)
{
struct ast_variable *result_row = NULL;
realtime_sqlite3_helper(database, table, ap, 0, &result_row);
realtime_sqlite3_helper(database, table, fields, 0, &result_row);
return result_row;
}
@@ -703,7 +703,7 @@ static struct ast_variable *realtime_sqlite3(const char *database, const char *t
/*! \brief Realtime callback for a multi-row query
* \return ast_config containing possibly many results on success, NULL on empty/failure
*/
static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, va_list ap)
static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, const struct ast_variable *fields)
{
struct ast_config *cfg;
@@ -711,7 +711,7 @@ static struct ast_config *realtime_sqlite3_multi(const char *database, const cha
return NULL;
}
if (realtime_sqlite3_helper(database, table, ap, 1, cfg)) {
if (realtime_sqlite3_helper(database, table, fields, 1, cfg)) {
ast_config_destroy(cfg);
return NULL;
}
@@ -722,10 +722,10 @@ static struct ast_config *realtime_sqlite3_multi(const char *database, const cha
/*! \brief Realtime callback for updating a row based on a single criteria
* \return Number of rows affected or -1 on error
*/
static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
{
struct ast_str *sql;
const char *key, *value;
const struct ast_variable *field;
int first = 1, res;
if (ast_strlen_zero(table)) {
@@ -737,13 +737,13 @@ static int realtime_sqlite3_update(const char *database, const char *table, cons
return -1;
}
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
for (field = fields; field; field = field->next) {
if (first) {
ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
sqlite3_escape_table(table), sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
first = 0;
} else {
ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
}
}
@@ -758,11 +758,11 @@ static int realtime_sqlite3_update(const char *database, const char *table, cons
/*! \brief Realtime callback for updating a row based on multiple criteria
* \return Number of rows affected or -1 on error
*/
static int realtime_sqlite3_update2(const char *database, const char *table, va_list ap)
static int realtime_sqlite3_update2(const char *database, const char *table, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
{
struct ast_str *sql;
struct ast_str *where_clause;
const char *key, *value;
const struct ast_variable *field;
int first = 1, res;
if (ast_strlen_zero(table)) {
@@ -779,22 +779,22 @@ static int realtime_sqlite3_update2(const char *database, const char *table, va_
return -1;
}
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
for (field = lookup_fields; field; field = field->next) {
if (first) {
ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
first = 0;
} else {
ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
}
}
first = 1;
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
for (field = update_fields; field; field = field->next) {
if (first) {
ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
first = 0;
} else {
ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
}
}
@@ -811,10 +811,10 @@ static int realtime_sqlite3_update2(const char *database, const char *table, va_
/*! \brief Realtime callback for inserting a row
* \return Number of rows affected or -1 on error
*/
static int realtime_sqlite3_store(const char *database, const char *table, va_list ap)
static int realtime_sqlite3_store(const char *database, const char *table, const struct ast_variable *fields)
{
struct ast_str *sql, *values;
const char *column, *value;
const struct ast_variable *field;
int first = 1, res;
if (ast_strlen_zero(table)) {
@@ -831,14 +831,14 @@ static int realtime_sqlite3_store(const char *database, const char *table, va_li
return -1;
}
while ((column = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
for (field = fields; field; field = field->next) {
if (first) {
ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(column));
ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(value));
ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(field->name));
ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(field->value));
first = 0;
} else {
ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(column));
ast_str_append(&values, 0, ", %s", sqlite3_escape_value(value));
ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(field->name));
ast_str_append(&values, 0, ", %s", sqlite3_escape_value(field->value));
}
}
@@ -855,10 +855,10 @@ static int realtime_sqlite3_store(const char *database, const char *table, va_li
/*! \brief Realtime callback for deleting a row
* \return Number of rows affected or -1 on error
*/
static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
{
struct ast_str *sql;
const char *param, *value;
const struct ast_variable *field;
int first = 1, res;
if (ast_strlen_zero(table)) {
@@ -870,13 +870,13 @@ static int realtime_sqlite3_destroy(const char *database, const char *table, con
return -1;
}
while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
for (field = fields; field; field = field->next) {
if (first) {
ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
sqlite3_escape_column_op(param), sqlite3_escape_value(value));
sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
first = 0;
} else {
ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param), sqlite3_escape_value(value));
ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
}
}