[Freeswitch-trunk] [commit] r14059 - freeswitch/trunk/contrib/ledr/mod_xml_odbc
FreeSWITCH SVN
ledr at freeswitch.org
Tue Jun 30 13:10:54 PDT 2009
Author: ledr
Date: Tue Jun 30 15:10:53 2009
New Revision: 14059
Log:
complete rewrite, totally broken now, don't even try to make this ;)
Modified:
freeswitch/trunk/contrib/ledr/mod_xml_odbc/mod_xml_odbc.c
Modified: freeswitch/trunk/contrib/ledr/mod_xml_odbc/mod_xml_odbc.c
==============================================================================
--- freeswitch/trunk/contrib/ledr/mod_xml_odbc/mod_xml_odbc.c (original)
+++ freeswitch/trunk/contrib/ledr/mod_xml_odbc/mod_xml_odbc.c Tue Jun 30 15:10:53 2009
@@ -23,13 +23,12 @@
*
* Contributor(s):
*
- * Anthony Minessale II <anthm at freeswitch.org>
- * Other FreeSWITCH module contributors that I borrowed code from
+ * All the FreeSWITCH contributors that I borrowed code from
* Leon de Rooij <leon at scarlet-internet.nl>
*
*
- * mod_xml_odbc.c -- use fs odbc to realtime create xml directory
- * perhaps later also config, dialplan, etc ?
+ * mod_xml_odbc.c -- Use FreeSWITCH ODBC to realtime create XML
+ *
*
*/
#include <switch.h>
@@ -45,37 +44,6 @@
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_odbc_shutdown);
SWITCH_MODULE_DEFINITION(mod_xml_odbc, mod_xml_odbc_load, mod_xml_odbc_shutdown, NULL);
-static switch_bool_t debug = SWITCH_FALSE;
-
-static switch_status_t xml_odbc_render_template(char *template, switch_event_t *params, switch_xml_t xml_out, int *off);
-static switch_status_t xml_odbc_render_tag(switch_xml_t xml_in, switch_event_t *params, switch_xml_t xml_out, int *off);
-
-
-/*
-static char *my_dup(const char *s)
-{
- size_t len = strlen(s) + 1;
- void *new = malloc(len);
- switch_assert(new);
-
- return (char *) memcpy(new, s, len);
-}
-
-#ifndef ALLOC
-#define ALLOC(size) malloc(size)
-#endif
-#ifndef DUP
-#define DUP(str) my_dup(str)
-#endif
-#ifndef FREE
-#define FREE(ptr) switch_safe_free(ptr)
-#endif
-*/
-
-
-#define XML_ODBC_SYNTAX "[debug_on|debug_off|render_template]"
-
-
static struct {
char *odbc_dsn;
char *configuration_template_name;
@@ -86,9 +54,25 @@
switch_mutex_t *mutex;
switch_memory_pool_t *pool;
switch_odbc_handle_t *master_odbc;
+ switch_bool_t debug;
} globals;
+static struct xml_odbc_session_helper {
+ switch_memory_pool_t *pool;
+ char *template_name;
+ switch_event_t *event;
+ switch_xml_t xml_in;
+ switch_xml_t xml_out;
+ int *off;
+ int tmp_i;
+} xml_odbc_session_helper_t;
+
+static switch_status_t xml_odbc_render_template(xml_odbc_session_helper_t helper);
+static switch_status_t xml_odbc_render_tag(xml_odbc_session_helper_t helper);
+#define XML_ODBC_SYNTAX "[debug_on|debug_off]"
+
+/* cli commands */
SWITCH_STANDARD_API(xml_odbc_function)
{
if (session) {
@@ -100,20 +84,9 @@
}
if (!strcasecmp(cmd, "debug_on")) {
- debug = SWITCH_TRUE;
+ globals.debug = SWITCH_TRUE;
} else if (!strcasecmp(cmd, "debug_off")) {
- debug = SWITCH_FALSE;
- } else if (!strcasecmp(cmd, "render_template")) {
-// TODO make it configurable what themplate is rendered instead of static "not_found"
- // int off = 0;
- // switch_xml_t xml_out = NULL;
-// switch_hash_t *hash;
- // switch_event_t *params;
-// if (switch_core_hash_init(&hash, globals.pool) != SWITCH_STATUS_SUCCESS) {
-//// need_vars_map = -1; // does it need to be freed ? :)
-// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't init params hash!\n");
-// }
- // xml_odbc_render_template("not_found", params, xml_out, &off);
+ globals.debug = SWITCH_FALSE;
} else {
goto usage;
}
@@ -126,161 +99,152 @@
return SWITCH_STATUS_SUCCESS;
}
-
typedef struct xml_binding {
char *bindings;
} xml_binding_t;
-
-typedef struct xml_odbc_query_helper {
- switch_xml_t xml_in;
- switch_xml_t xml_out;
- int *off;
- switch_event_t *params;
- int rowcount;
-} xml_odbc_query_helper_t;
-
-
static int xml_odbc_query_callback(void *pArg, int argc, char **argv, char **columnName)
{
- xml_odbc_query_helper_t *qh = (xml_odbc_query_helper_t *) pArg;
+ session_helper_t *qh = (session_helper_t *) pArg;
switch_xml_t xml_in_tmp;
int i;
- qh->rowcount++;
+ /* up the row counter */
+ qh->tmp_i++; // TODO THIS WILL GO WRONG FOR NESTED QUERIES.. THINK ABOUT IT !!!
+ /* loop through all columns and store them in qh->event->params */
for (i = 0; i < argc; i++) {
- switch_event_del_header(qh->params, columnName[i]);
- switch_event_add_header_string(qh->params, SWITCH_STACK_BOTTOM, columnName[i], argv[i]);
+ switch_event_del_header(qh->event, columnName[i]);
+ switch_event_add_header_string(qh->event, SWITCH_STACK_BOTTOM, columnName[i], argv[i]);
}
- /* render all xml children */
+ /* render all children of xml_in */
for (xml_in_tmp = qh->xml_in->child; xml_in_tmp; xml_in_tmp = xml_in_tmp->ordered) {
- xml_odbc_render_tag(xml_in_tmp, qh->params, qh->xml_out, qh->off);
+ xml_odbc_render_tag(xml_in_tmp, qh->event, qh->xml_out, qh->off);
}
return 0;
}
-
-static switch_status_t xml_odbc_render_tag(switch_xml_t xml_in, switch_event_t *params, switch_xml_t xml_out, int *off)
+static switch_status_t xml_odbc_do_break_to(xml_odbc_session_helper_t helper)
{
- switch_xml_t xml_in_tmp = NULL;
- int i;
+ char *name = (char *) switch_xml_attr_soft(helper->xml_in, "name");
+ char *value = (char *) switch_xml_attr_soft(helper->xml_in, "value");
+ char *new_value = switch_event_expand_headers(helper->event, value);
- char *name = NULL;
- char *value = NULL, *new_value = NULL;
-
- char *when_name = NULL, *when_value = NULL;
-
- char *empty_result_break_to = NULL;
- char *no_template_break_to = NULL;
-
- xml_odbc_query_helper_t query_helper;
+ helper->template_name = strdup(new_value);
+}
+static switch_status_t xml_odbc_do_replace_header_value(xml_odbc_session_helper_t helper)
+{
+ char *old_header_value = NULL;
+ char *name = (char *) switch_xml_attr_soft(helper->xml_in, "name");
+ char *when_name = (char *) switch_xml_attr_soft(helper->xml_in, "when_name");
+ char *when_value = (char *) switch_xml_attr_soft(helper->xml_in, "when_value");
+ char *value = (char *) switch_xml_attr_soft(helper->xml_in, "value");
+ char *new_value = switch_event_expand_headers(helper->event, value);
switch_status_t status = SWITCH_STATUS_FALSE;
- /* special case xml-odbc-do - this tag is not copied, but action is done */
- if (!strcasecmp(xml_in->name, "xml-odbc-do")) {
- name = (char *) switch_xml_attr_soft(xml_in, "name");
- value = (char *) switch_xml_attr_soft(xml_in, "value");
-
- no_template_break_to = (char *) switch_xml_attr_soft(xml_in, "on-no-template-break-to"); // THIS DOESN'T WORK YET !!
+ if (switch_strlen_zero(when_name)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Ignoring xml-odbc-do name=[%s] because no when_name is given\n", name);
+ goto done;
+ }
- if (switch_strlen_zero(name)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Ignoring xml-odbc-do because no name attribute is given\n");
- goto done;
- }
+ if (switch_strlen_zero(value)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Ignoring xml-odbc-do name=[%s] because no value is given\n", name);
+ goto done;
+ }
- if (switch_strlen_zero(value)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Ignoring xml-odbc-do name=[%s] because no value attr is given\n", name);
- goto done;
+ if ((old_header_value = switch_event_get_header(helper->event, when_name))) {
+ if (switch_strlen_zero(when_value) || !strcasecmp(when_value, old_header_value)) {
+ switch_event_del_header(helper->event, when_name);
+ switch_event_add_header_string(helper->event, SWITCH_STACK_BOTTOM, when_name, new_value);
}
- new_value = switch_event_expand_headers(params, value);
-
- if (!strcasecmp(name, "replace_header_value")) {
- char *old_header_value = NULL;
- /* replace a header value when when_name AND/OR when_value matches */
+ }
- when_name = (char *) switch_xml_attr_soft(xml_in, "when-name");
- when_value = (char *) switch_xml_attr_soft(xml_in, "when-value");
+ status = SWITCH_STATUS_SUCCESS;
- if (switch_strlen_zero(when_name)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Ignoring xml-odbc-do name=[%s] because no when-name is given\n", name);
- goto done;
- }
+ done:
+ return status;
+}
- if ((old_header_value = switch_event_get_header(params, when_name))) {
- if (switch_strlen_zero(when_value) || !strcasecmp(when_value, old_header_value)) {
- switch_event_del_header(params, when_name);
- switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, when_name, new_value);
- }
- }
+static switch_status_t xml_odbc_do_query(xml_odbc_session_helper_t helper)
+{
+ char *name = (char *) switch_xml_attr_soft(helper->xml_in, "name");
+ char *value = (char *) switch_xml_attr_soft(helper->xml_in, "value");
+ char *empty_result_break_to = (char *) switch_xml_attr_soft(xml_in, "on-empty-result-break-to");
+ char *new_value = switch_event_expand_headers(helper->event, value);
+ switch_status_t status = SWITCH_STATUS_FALSE;
- } else if (!strcasecmp(name, "break-to")) {
- /* set a next_template header so xml_odbc_render_template breaks the loop and starts over with a new template */
+ if (globals.debug == SWITCH_TRUE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DEBUG Performing Query:\n%s\n", new_value);
+ }
- switch_event_del_header(params, "next_template_name");
- switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "next_template_name", new_value);
- goto done;
+ if (switch_odbc_handle_callback_exec(globals.master_odbc, new_value, xml_odbc_query_callback, helper) != SWITCH_ODBC_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error running this query: [%s]\n", new_value);
+ goto done;
+ }
- } else if (!strcasecmp(name, "query")) {
- /* create query_helper that is given to callback function on each returned row */
+ if (!switch_strlen_zero(empty_result_break_to) && helper.tmp_i == 0) {
+ helper->template_name = empty_result_break_to;
+ }
+
+ status = SWITCH_STATUS_SUCCESS;
- query_helper.xml_in = xml_in;
- query_helper.xml_out = xml_out;
- query_helper.off = off;
- query_helper.params = params;
- query_helper.rowcount = 0;
+ done:
+ return status;
+}
- if (debug == SWITCH_TRUE) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DEBUG Performing Query:\n%s\n", new_value);
- }
+static switch_status_t xml_odbc_render_tag(xml_odbc_session_helper_t helper)
+{
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ switch_xml_t xml_in_tmp, xml_out_tmp;
+ int i;
- if (switch_odbc_handle_callback_exec(globals.master_odbc, new_value, xml_odbc_query_callback, &query_helper) != SWITCH_ODBC_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error running this query: [%s]\n", new_value);
- goto done;
- }
+ if (!strcasecmp(helper->xml_in->name, "xml-odbc-do")) {
+ char *name = (char *) switch_xml_attr_soft(helper->xml_in, "name");
- empty_result_break_to = (char *) switch_xml_attr_soft(xml_in, "on-empty-result-break-to");
- if (!switch_strlen_zero(empty_result_break_to) && query_helper.rowcount == 0) {
- /* set a next_template header so xml_odbc_render_template breaks the loop and starts over with a new template */
- switch_event_del_header(params, "next_template_name");
- switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "next_template_name", empty_result_break_to);
- goto done;
- }
+ if (switch_strlen_zero(name)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Ignoring xml-odbc-do because no name is given\n");
+ goto done;
+ }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Ignoring unknown xml-odbc-do name=[%s]\n", name);
+ /* special cases for xml-odbc-do */
+ if (!strcasecmp(name, "break-to")) {
+ status = xml_odbc_do_break_to(helper);
+ goto done;
+ } else if (!strcasecmp(name, "replace-header-value")) {
+ status = xml_odbc_do_replace_header_value(helper);
+ goto done;
+ } else if (!strcasecmp(name, "query")) {
+ status = xml_odbc_do_query(helper);
+ goto done;
}
- /* just copy current tag xml_in to xml_out and recurse for all children */
- } else {
+ /* just copy xml_in to xml_out */
+ if (switch_strlen_zero(helper->xml_out->name)) {
+ /* remove all children from helper->xml_out TODO DO THAT HERE !!!!!!!!!!!!!!!!!!!!!! */
- /* set name if current root node */
- if (switch_strlen_zero(xml_out->name)) { // I should match here on off instead of on name == "" ?
- xml_out->name = strdup(xml_in->name);
+ helper->xml_out->name = strdup(helper->xml_in->name);
- /* or create a child */
- } else if (!(xml_out = switch_xml_add_child_d(xml_out, xml_in->name, *off++))) {
+ } else if (!(xml_out_tmp = switch_xml_add_child_d(helper->xml_out, helper->xml_in->name, (helper->off)++))) {
goto done;
}
/* copy all attrs */
- for (i = 0; xml_in->attr[i]; i+=2) {
+ for (i=0; helper->xml_in->attr[i]; i+=2) {
char *tmp_attr;
- tmp_attr = switch_event_expand_headers(params, xml_in->attr[i+1]);
- switch_xml_set_attr(xml_out, xml_in->attr[i], tmp_attr);
-
-// if (tmp_attr != xml_in->attr[i+1]) {
-// switch_safe_free(tmp_attr);
-// }
+ tmp_attr = switch_event_exapand_headers(helper->event, helper->xml_in->attr[i+1]);
+ switch_xml_set_attr(helper->xml_out, helper->xml_in->attr[i], tmp_attr);
+ // if (tmp_attr != helper->xml_in->attr[i+1]) {
+ // switch_safe_free(tmp_attr);
+ // }
}
- /* copy all children and render them */
- for (xml_in_tmp = xml_in->child; xml_in_tmp; xml_in_tmp = xml_in_tmp->ordered) {
- if (xml_odbc_render_tag(xml_in_tmp, params, xml_out, off) != SWITCH_STATUS_SUCCESS) {
+ /* render all children */
+ for (xml_in_tmp = helper->xml_in->child; xml_in_tmp; xml_in_tmp = xml_in_tmp->ordered) {
+ if (xml_odbc_render_tag(xml_in_tmp, helper->event, event->xml_out, helper->off) != SWITCH_STATUS_SUCCESS) {
goto done;
}
}
@@ -290,72 +254,59 @@
status = SWITCH_STATUS_SUCCESS;
done:
-
- if (value != new_value) {
- switch_safe_free(new_value);
- }
-
return status;
}
-
-static switch_status_t xml_odbc_render_template(char *template_name, switch_event_t *params, switch_xml_t xml_out, int *off)
+static switch_status_t xml_odbc_render_template(xml_odbc_session_helper_t helper)
{
switch_xml_t template_tag = NULL, sub_tag = NULL;
- char *next_template_name = NULL;
+ switch_status_t status = SWITCH_STATUS_FALSE;
- if ((template_tag = switch_xml_find_child(globals.templates_tag, "template", "name", template_name))) {
+ if ((template_tag = switch_xml_find_child(globals.templates_tag, "template", "name", helper->template_name))) {
for (sub_tag = template_tag->child; sub_tag; sub_tag = sub_tag->ordered) {
- if (xml_odbc_render_tag(sub_tag, params, xml_out, off) != SWITCH_STATUS_SUCCESS) {
+ if (xml_odbc_render_tag(sub_tag, helper->event, helper->xml_out, helper->off) != SWITCH_STATUS_SUCCESS) {
}
- if ((next_template_name = switch_event_get_header(params, "next_template_name"))) {
+ if ((!switch_strlen_zero(helper->template_name))) {
goto rewind;
}
-
}
goto done;
}
- next_template_name = "not_found";
+ helper->template_name = "not_found";
rewind:
- /* remove next_template_name header from event so xml_odbc_render_template won't go into an infinite loop */
- switch_event_del_header(params, "next_template_name");
-
- /* reset xml_out */
- xml_out->name = "";
-// switch_xml_free(xml_out); // THIS DOESN'T WORK EITHER
-// xml_out = switch_xml_new("");
-
- xml_odbc_render_template(next_template_name, params, xml_out, off);
+ /* remove all children of helper->xml_out here */
+ xml_odbc_render_template(helper);
done:
- return SWITCH_STATUS_SUCCESS;
+ return status;
}
-
static switch_xml_t xml_odbc_search(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data)
{
xml_binding_t *binding = (xml_binding_t *) user_data;
switch_event_header_t *hi;
char *template_name;
+ switch_uuid_t uuid;
+ char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
int off = 0, ret = 1;
-
switch_xml_t xml_out = NULL;
+ session_helper_t helper;
if (!binding) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No bindings... sorry bud returning now\n");
return NULL;
}
+ /* create a new xml_out used to render the template into */
if (!(xml_out = switch_xml_new(""))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Allocation Error\n");
return NULL;
}
- //switch_xml_set_attr_d(xml_out, "type", "freeswitch/xml");
-
+ /* find out what template to render, based on the section */
if (!strcmp(section, "configuration")) {
template_name = strdup(globals.configuration_template_name);
} else if (!strcmp(section, "directory")) {
@@ -369,36 +320,73 @@
return NULL;
}
- if (params) {
+ /* add some headers to params */
+ switch_event_add_header_string(params, SWITCH_STACK_TOP, "hostname", hostname);
+ switch_event_add_header_string(params, SWITCH_STACK_TOP, "section", switch_str_nil(section));
+ switch_event_add_header_string(params, SWITCH_STACK_TOP, "tag_name", switch_str_nil(tag_name));
+ switch_event_add_header_string(params, SWITCH_STACK_TOP, "key_name", switch_str_nil(key_name));
+ switch_event_add_header_string(params, SWITCH_STACK_TOP, "key_value", switch_str_nil(key_value));
+
+ /* generate a new uuid */
+ switch_uuid_get(&uuid);
+ switch_uuid_format(uuid_str, &uuid);
+
+ /* generate a temporary filename to store the generated xml in */
+ switch_snprintf(filename, sizeof(filename), "%s%s.tmp.xml", SWITCH_GLOBAL_dirs.temp_dir, uuid_str);
+
+ /* debug print all switch_event_t params headers */
+ if (globals.debug == SWITCH_TRUE) {
if ((hi = params->headers)) {
for (; hi; hi = hi->next) {
- if (debug == SWITCH_TRUE) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DEBUG in xml_odbc_search, header [%s]=[%s]\n", hi->name, hi->value);
- }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DEBUG in xml_odbc_search, header [%s]=[%s]\n", hi->name, hi->value);
}
- xml_odbc_render_template(template_name, params, xml_out, &off);
}
- } else {
- goto cleanup;
}
- if (debug == SWITCH_TRUE) {
- char *tmp_xml = switch_xml_toxml(xml_out, SWITCH_FALSE);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Debug dump of XML generated:\n%s", tmp_xml);
- switch_safe_free(tmp_xml);
+ /* put all necessary data in session_helper_t helper */
+ // switch_memory_pool_t
+ // template_name
+ // params
+ // xml_out
+ // &off
+
+ /* render xml from template */
+ if (xml_odbc_render_template(helper) == SWITCH_STATUS_SUCCESS) {
+
+ /* dump the generated file to *xml_char */
+ xml_char = switch_xml_toxml(xml_out, SWITCH_TRUE);
+
+ /* debug dump the generated xml to console */
+ if (globals.debug == SWITCH_TRUE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Debug dump of generated XML:\n%s", xml_char);
}
- ret = 0;
+ /* dump *xml_char to disk */
- cleanup:
+ /* close the file */
- switch_safe_free(template_name);
+ /* free *xml_char */
- if (ret) {
- switch_xml_free(xml_out);
- return NULL;
+ /* free switch_memory_pool_t */
+
+ /* free helper ?? */
+
+ /* copy the generated xml to xml_out - this should never happen */
+ if (!(xml_out = switch_xml_parse_file(filename))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n");
}
-
+
+ /* debug by leaving the file behind for review */
+ if (keep_files_around) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Generated XML is in %s\n", filename);
+ } else {
+ if (unlink(filename) != 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Generated XML file [%s] delete failed\n", filename);
+ }
+ }
+
+ /* other things to free ?! */
+
return xml_out;
}
More information about the Freeswitch-trunk
mailing list