mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
Implement AstData API data providers as part of the GSOC 2010 project,
midterm evaluation. Review: https://reviewboard.asterisk.org/r/757/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@274727 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
101
res/res_odbc.c
101
res/res_odbc.c
@@ -52,6 +52,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include "asterisk/app.h"
|
||||
#include "asterisk/strings.h"
|
||||
#include "asterisk/threadstorage.h"
|
||||
#include "asterisk/data.h"
|
||||
|
||||
/*** DOCUMENTATION
|
||||
<function name="ODBC" language="en_US">
|
||||
@@ -167,6 +168,17 @@ struct odbc_txn_frame {
|
||||
char name[0]; /*!< Name of this transaction ID */
|
||||
};
|
||||
|
||||
#define DATA_EXPORT_ODBC_CLASS(MEMBER) \
|
||||
MEMBER(odbc_class, name, AST_DATA_STRING) \
|
||||
MEMBER(odbc_class, dsn, AST_DATA_STRING) \
|
||||
MEMBER(odbc_class, username, AST_DATA_STRING) \
|
||||
MEMBER(odbc_class, password, AST_DATA_PASSWORD) \
|
||||
MEMBER(odbc_class, limit, AST_DATA_INTEGER) \
|
||||
MEMBER(odbc_class, count, AST_DATA_INTEGER) \
|
||||
MEMBER(odbc_class, forcecommit, AST_DATA_BOOLEAN)
|
||||
|
||||
AST_DATA_STRUCTURE(odbc_class, DATA_EXPORT_ODBC_CLASS);
|
||||
|
||||
static const char *isolation2text(int iso)
|
||||
{
|
||||
if (iso == SQL_TXN_READ_COMMITTED) {
|
||||
@@ -1589,6 +1601,94 @@ static struct ast_custom_function odbc_function = {
|
||||
static const char * const app_commit = "ODBC_Commit";
|
||||
static const char * const app_rollback = "ODBC_Rollback";
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Implements the channels provider.
|
||||
*/
|
||||
static int data_odbc_provider_handler(const struct ast_data_search *search,
|
||||
struct ast_data *root)
|
||||
{
|
||||
struct ao2_iterator aoi, aoi2;
|
||||
struct odbc_class *class;
|
||||
struct odbc_obj *current;
|
||||
struct ast_data *data_odbc_class, *data_odbc_connections, *data_odbc_connection;
|
||||
struct ast_data *enum_node;
|
||||
int count;
|
||||
|
||||
aoi = ao2_iterator_init(class_container, 0);
|
||||
while ((class = ao2_iterator_next(&aoi))) {
|
||||
data_odbc_class = ast_data_add_node(root, "class");
|
||||
if (!data_odbc_class) {
|
||||
ao2_ref(class, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_data_add_structure(odbc_class, data_odbc_class, class);
|
||||
|
||||
if (!ao2_container_count(class->obj_container)) {
|
||||
ao2_ref(class, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
data_odbc_connections = ast_data_add_node(data_odbc_class, "connections");
|
||||
if (!data_odbc_connections) {
|
||||
ao2_ref(class, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_data_add_bool(data_odbc_class, "shared", !class->haspool);
|
||||
/* isolation */
|
||||
enum_node = ast_data_add_node(data_odbc_class, "isolation");
|
||||
if (!enum_node) {
|
||||
ao2_ref(class, -1);
|
||||
continue;
|
||||
}
|
||||
ast_data_add_int(enum_node, "value", class->isolation);
|
||||
ast_data_add_str(enum_node, "text", isolation2text(class->isolation));
|
||||
|
||||
count = 0;
|
||||
aoi2 = ao2_iterator_init(class->obj_container, 0);
|
||||
while ((current = ao2_iterator_next(&aoi2))) {
|
||||
data_odbc_connection = ast_data_add_node(data_odbc_connections, "connection");
|
||||
if (!data_odbc_connection) {
|
||||
ao2_ref(current, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_mutex_lock(¤t->lock);
|
||||
ast_data_add_str(data_odbc_connection, "status", current->used ? "in use" :
|
||||
current->up && ast_odbc_sanity_check(current) ? "connected" : "disconnected");
|
||||
ast_data_add_bool(data_odbc_connection, "transactional", current->tx);
|
||||
ast_mutex_unlock(¤t->lock);
|
||||
|
||||
if (class->haspool) {
|
||||
ast_data_add_int(data_odbc_connection, "number", ++count);
|
||||
}
|
||||
|
||||
ao2_ref(current, -1);
|
||||
}
|
||||
ao2_ref(class, -1);
|
||||
|
||||
if (!ast_data_search_match(search, data_odbc_class)) {
|
||||
ast_data_remove_node(root, data_odbc_class);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief /asterisk/res/odbc/listprovider.
|
||||
*/
|
||||
static const struct ast_data_handler odbc_provider = {
|
||||
.version = AST_DATA_HANDLER_VERSION,
|
||||
.get = data_odbc_provider_handler
|
||||
};
|
||||
|
||||
static const struct ast_data_entry odbc_providers[] = {
|
||||
AST_DATA_ENTRY("/asterisk/res/odbc", &odbc_provider),
|
||||
};
|
||||
|
||||
static int reload(void)
|
||||
{
|
||||
struct odbc_cache_tables *table;
|
||||
@@ -1676,6 +1776,7 @@ static int load_module(void)
|
||||
if (load_odbc_config() == -1)
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
ast_cli_register_multiple(cli_odbc, ARRAY_LEN(cli_odbc));
|
||||
ast_data_register_multiple(odbc_providers, ARRAY_LEN(odbc_providers));
|
||||
ast_register_application_xml(app_commit, commit_exec);
|
||||
ast_register_application_xml(app_rollback, rollback_exec);
|
||||
ast_custom_function_register(&odbc_function);
|
||||
|
Reference in New Issue
Block a user