[Freeswitch-svn] [commit] r12198 - freeswitch/trunk/src/mod/applications/mod_lcr
FreeSWITCH SVN
rupa at freeswitch.org
Fri Feb 20 12:36:04 PST 2009
Author: rupa
Date: Fri Feb 20 14:36:04 2009
New Revision: 12198
Log:
allow channel vars in custom_sql - unescaped for now
Modified:
freeswitch/trunk/src/mod/applications/mod_lcr/mod_lcr.c
Modified: freeswitch/trunk/src/mod/applications/mod_lcr/mod_lcr.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_lcr/mod_lcr.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_lcr/mod_lcr.c Fri Feb 20 14:36:04 2009
@@ -110,6 +110,9 @@
char *order_by;
char *pre_order;
char *custom_sql;
+ switch_bool_t custom_sql_has_percent;
+ switch_bool_t custom_sql_has_vars;
+
switch_bool_t reorder_by_rate;
};
typedef struct profile_obj profile_t;
@@ -121,6 +124,7 @@
switch_memory_pool_t *pool;
char *lookup_number;
profile_t *profile;
+ switch_core_session_t *session;
};
typedef struct callback_obj callback_t;
@@ -259,25 +263,6 @@
return SWITCH_FALSE;
}
-static switch_bool_t test_lcr_sql(const char *sql)
-{
- char * tsql;
- switch_bool_t retval = SWITCH_FALSE;
- tsql = switch_mprintf(sql, "5555551212");
-
- if (globals.odbc_dsn) {
- if (switch_odbc_handle_exec(globals.master_odbc, tsql, NULL)
- == SWITCH_ODBC_SUCCESS) {
- retval = SWITCH_TRUE;
- } else {
- retval = SWITCH_FALSE;
- }
- }
-
- switch_safe_free(tsql);
- return retval;
-}
-
/* make a new string with digits only */
static char *string_digitsonly(switch_memory_pool_t *pool, const char *str)
{
@@ -302,6 +287,74 @@
return newstr;
}
+/* escape sql */
+#ifdef _WAITING_FOR_ESCAPE
+static char *escape_sql(const char *sql)
+{
+ return switch_string_replace(sql, "'", "''");
+}
+#endif
+
+/* expand the digits */
+static char *expand_digits(switch_memory_pool_t *pool, char *digits)
+{
+ switch_stream_handle_t dig_stream = { 0 };
+ char *ret;
+ char *digits_copy;
+ int n;
+ int digit_len;
+ SWITCH_STANDARD_STREAM(dig_stream);
+
+ digit_len = strlen(digits);
+ digits_copy = switch_core_strdup(pool, digits);
+
+ for (n = digit_len; n > 0; n--) {
+ digits_copy[n] = '\0';
+ dig_stream.write_function(&dig_stream, "%s%s", (n==digit_len ? "" : ", "), digits_copy);
+ }
+
+ ret = switch_core_strdup(pool, dig_stream.data);
+ switch_safe_free(dig_stream.data);
+ return ret;
+}
+
+/* format the custom sql */
+static char *format_custom_sql(const char *custom_sql, callback_t *cb_struct, const char *digits)
+{
+ char * tmpSQL;
+ char * newSQL;
+ switch_channel_t *channel;
+
+ /* first replace %s with digits to maintain backward compat */
+ if(cb_struct->profile->custom_sql_has_percent == SWITCH_TRUE) {
+ tmpSQL = switch_string_replace(custom_sql, "%q", digits);
+ newSQL = tmpSQL;
+ }
+
+ /* expand the vars */
+ if(cb_struct->profile->custom_sql_has_vars == SWITCH_TRUE) {
+ if(cb_struct->session) {
+ channel = switch_core_session_get_channel(cb_struct->session);
+ switch_assert(channel);
+ /*
+ newSQL = switch_channel_expand_variables_escape(channel,
+ tmpSQL ? tmpSQL : custom_sql,
+ escape_sql);
+ */
+ newSQL = switch_channel_expand_variables(channel,
+ tmpSQL ? tmpSQL : custom_sql);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
+ "mod_lcr called without a valid session while using a custom_sql that has channel variables.\n");
+ }
+ }
+
+ if(tmpSQL != newSQL) {
+ switch_safe_free(tmpSQL);
+ }
+ return newSQL;
+}
+
static switch_bool_t lcr_execute_sql_callback(char *sql, switch_core_db_callback_func_t callback, void *pdata)
{
switch_bool_t retval = SWITCH_FALSE;
@@ -438,8 +491,11 @@
switch_stream_handle_t sql_stream = { 0 };
size_t n, digit_len = strlen(digits);
char *digits_copy;
+ char *digits_expanded;
profile_t *profile = cb_struct->profile;
switch_bool_t lookup_status;
+ switch_channel_t *channel;
+ char *id_str;
digits_copy = string_digitsonly(cb_struct->pool, digits);
if (switch_strlen_zero(digits_copy)) {
@@ -454,6 +510,18 @@
/* SWITCH_STANDARD_STREAM doesn't use pools. but we only have to free sql_stream.data */
SWITCH_STANDARD_STREAM(sql_stream);
+
+ digits_expanded = expand_digits(cb_struct->pool, digits_copy);
+
+ /* set some channel vars if we have a session */
+ if(cb_struct->session) {
+ if((channel = switch_core_session_get_channel(cb_struct->session))) {
+ switch_channel_set_variable_var_check(channel, "lcr_query_digits", digits_copy, SWITCH_FALSE);
+ id_str = switch_core_sprintf(cb_struct->pool, "%d", cb_struct->profile->id);
+ switch_channel_set_variable_var_check(channel, "lcr_query_profile", id_str, SWITCH_FALSE);
+ switch_channel_set_variable_var_check(channel, "lcr_query_expanded_digits", digits_expanded, SWITCH_FALSE);
+ }
+ }
/* set up the query to be executed */
if (switch_strlen_zero(profile->custom_sql)) {
@@ -479,12 +547,20 @@
sql_stream.write_function(&sql_stream, ";");
} else {
char *safe_sql;
- safe_sql = switch_mprintf(profile->custom_sql, digits_copy);
+
+ /* format the custom_sql */
+ safe_sql = format_custom_sql(profile->custom_sql, cb_struct, digits_copy);
+ if(!safe_sql) {
+ return SWITCH_STATUS_GENERR;
+ }
sql_stream.write_function(&sql_stream, safe_sql);
- switch_safe_free(safe_sql);
+ if(safe_sql != profile->custom_sql) {
+ /* channel_expand_variables returned the same string to us, no need to free */
+ switch_safe_free(safe_sql);
+ }
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", (char *)sql_stream.data);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL: %s\n", (char *)sql_stream.data);
lookup_status = lcr_execute_sql_callback((char *)sql_stream.data, route_add_callback, cb_struct);
@@ -646,13 +722,13 @@
}
if (!switch_strlen_zero(custom_sql)) {
- if (test_lcr_sql(custom_sql) == SWITCH_TRUE) {
- profile->custom_sql = switch_core_strdup(globals.pool, (char *)custom_sql);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Using custom lcr sql: %s\n", profile->custom_sql);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Custom lcr sql invalid: %s\nDisabling profile: %s\n", custom_sql, name);
- continue;
+ if(switch_string_var_check_const(custom_sql)) {
+ profile->custom_sql_has_vars = SWITCH_TRUE;
}
+ if(strstr(custom_sql, "%")) {
+ profile->custom_sql_has_percent = SWITCH_TRUE;
+ }
+ profile->custom_sql = switch_core_strdup(globals.pool, (char *)custom_sql);
}
if (!switch_strlen_zero(reorder_by_rate)) {
@@ -685,6 +761,7 @@
if (session) {
pool = switch_core_session_get_pool(session);
+ routes.session = session;
} else {
switch_core_new_memory_pool(&pool);
}
@@ -759,6 +836,7 @@
if (session) {
pool = switch_core_session_get_pool(session);
+ routes.session = session;
} else {
switch_core_new_memory_pool(&pool);
}
@@ -816,12 +894,18 @@
switch_memory_pool_t *pool;
switch_status_t lookup_status = SWITCH_STATUS_SUCCESS;
- switch_core_new_memory_pool(&pool);
-
if (switch_strlen_zero(cmd)) {
goto usage;
}
+ if (session) {
+ pool = switch_core_session_get_pool(session);
+ cb_struct.session = session;
+ } else {
+ switch_core_new_memory_pool(&pool);
+ }
+ cb_struct.pool = pool;
+
mydata = switch_core_strdup(pool, cmd);
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
@@ -831,7 +915,6 @@
lcr_profile = argv[1];
}
cb_struct.lookup_number = destination_number;
- cb_struct.pool = pool;
if (!(cb_struct.profile = locate_profile(lcr_profile))) {
stream->write_function(stream, "-ERR Unknown profile: %s\n", lcr_profile);
goto end;
@@ -904,7 +987,9 @@
}
end:
- switch_core_destroy_memory_pool(&pool);
+ if (!session) {
+ switch_core_destroy_memory_pool(&pool);
+ }
return SWITCH_STATUS_SUCCESS;
usage:
stream->write_function(stream, "USAGE: %s\n", LCR_SYNTAX);
@@ -945,6 +1030,8 @@
}
} else {
stream->write_function(stream, " custom sql:\t%s\n", profile->custom_sql);
+ stream->write_function(stream, " has %%:\t\t%s\n", profile->custom_sql_has_percent ? "true" : "false");
+ stream->write_function(stream, " has vars:\t%s\n", profile->custom_sql_has_vars ? "true" : "false");
}
stream->write_function(stream, " Reorder rate:\t%s\n",
profile->reorder_by_rate ? "enabled" : "disabled");
@@ -978,18 +1065,23 @@
return SWITCH_STATUS_FALSE;
#endif
- switch_core_new_memory_pool(&globals.pool);
+ if (switch_core_new_memory_pool(&globals.pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to create global memory pool\n");
+ return SWITCH_STATUS_FALSE;
+ }
if (lcr_load_config() != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to load lcr config file\n");
return SWITCH_STATUS_FALSE;
}
+
if (switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to initialize mutex\n");
}
if (switch_mutex_init(&globals.db_mutex, SWITCH_MUTEX_UNNESTED, globals.pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to initialize db_mutex\n");
}
+
if (set_db_random() == SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Database RANDOM function set to %s\n", db_random);
@@ -1009,6 +1101,7 @@
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_lcr_shutdown)
{
+
switch_odbc_handle_disconnect(globals.master_odbc);
switch_odbc_handle_destroy(&globals.master_odbc);
switch_core_hash_destroy(&globals.profile_hash);
More information about the Freeswitch-svn
mailing list