[asterisk-addons-commits] tilghman: trunk r916 - in /trunk: apps/ configs/
SVN commits to the Asterisk addons project
asterisk-addons-commits at lists.digium.com
Wed May 20 16:48:12 CDT 2009
Author: tilghman
Date: Wed May 20 16:48:07 2009
New Revision: 916
URL: http://svn.asterisk.org/svn-view/asterisk-addons?view=rev&rev=916
Log:
Allow the NULL value in a mysql database to be retrieved as different values.
(closes issue #15045)
Reported by: chris-mac
Patches:
20090520_bug15045.diff.txt uploaded by chris-mac (license 506)
with additional modifications by myself
Added:
trunk/configs/mysql.conf.sample (with props)
Modified:
trunk/apps/app_addon_sql_mysql.c
Modified: trunk/apps/app_addon_sql_mysql.c
URL: http://svn.asterisk.org/svn-view/asterisk-addons/trunk/apps/app_addon_sql_mysql.c?view=diff&rev=916&r1=915&r2=916
==============================================================================
--- trunk/apps/app_addon_sql_mysql.c (original)
+++ trunk/apps/app_addon_sql_mysql.c Wed May 20 16:48:07 2009
@@ -38,14 +38,17 @@
#include <asterisk/lock.h>
#include <asterisk/options.h>
#include <asterisk/app.h>
+#include <asterisk/config.h>
#define EXTRA_LOG 0
+enum { NULLSTRING, NULLVALUE, EMPTYSTRING } nullvalue = NULLSTRING;
+
static char *app = "MYSQL";
static char *synopsis = "Do several mySQLy things";
-static char *descrip =
+static char *descrip =
"MYSQL(): Do several mySQLy things\n"
"Syntax:\n"
" MYSQL(Set timeout <num>)\n"
@@ -65,19 +68,19 @@
" Assigns returned fields to ${var1} ... ${varn}. ${fetchid} is set TRUE\n"
" if additional rows exist in result set.\n"
" MYSQL(Clear ${resultid})\n"
-" Frees memory and datastructures associated with result set.\n"
+" Frees memory and datastructures associated with result set.\n"
" MYSQL(Disconnect ${connid})\n"
" Disconnects from named connection to MySQL.\n"
" On exit, always returns 0. Sets MYSQL_STATUS to 0 on success and -1 on error.\n";
-/*
-EXAMPLES OF USE :
+/*
+EXAMPLES OF USE :
exten => s,2,MYSQL(Connect connid localhost asterisk mypass credit)
exten => s,3,MYSQL(Query resultid ${connid} SELECT username,credit FROM credit WHERE callerid=${CALLERIDNUM})
exten => s,4,MYSQL(Fetch fetchid ${resultid} datavar1 datavar2)
exten => s,5,GotoIf(${fetchid}?6:8)
-exten => s,6,Festival("User ${datavar1} currently has credit balance of ${datavar2} dollars.")
+exten => s,6,Festival("User ${datavar1} currently has credit balance of ${datavar2} dollars.")
exten => s,7,Goto(s,4)
exten => s,8,MYSQL(Clear ${resultid})
exten => s,9,MYSQL(Disconnect ${connid})
@@ -85,6 +88,7 @@
AST_MUTEX_DEFINE_STATIC(_mysql_mutex);
+#define MYSQL_CONFIG "mysql.conf"
#define AST_MYSQL_ID_DUMMY 0
#define AST_MYSQL_ID_CONNID 1
#define AST_MYSQL_ID_RESID 2
@@ -106,7 +110,7 @@
struct ast_MYSQL_id *i;
void *res=NULL;
int found=0;
-
+
if (AST_LIST_LOCK(headp)) {
ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
} else {
@@ -122,7 +126,7 @@
}
AST_LIST_UNLOCK(headp);
}
-
+
return res;
}
@@ -136,7 +140,7 @@
ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
return -1;
} else {
- i = malloc(sizeof(*i));
+ i = malloc(sizeof(*i));
AST_LIST_TRAVERSE(headp, j, entries) {
if (j->identifier > maxidentifier) {
maxidentifier = j->identifier;
@@ -151,16 +155,17 @@
return i->identifier;
}
-static int del_identifier(int identifier, int identifier_type) {
+static int del_identifier(int identifier, int identifier_type)
+{
struct ast_MYSQL_id *i;
struct MYSQLidshead *headp = &_mysql_ids_head;
int found = 0;
-
+
if (AST_LIST_LOCK(headp)) {
ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
} else {
AST_LIST_TRAVERSE(headp, i, entries) {
- if ((i->identifier == identifier) &&
+ if ((i->identifier == identifier) &&
(i->identifier_type == identifier_type)) {
AST_LIST_REMOVE(headp, i, entries);
free(i);
@@ -170,7 +175,7 @@
}
AST_LIST_UNLOCK(headp);
}
-
+
if (found == 0) {
ast_log(LOG_WARNING, "Could not find identifier %d, identifier_type %d in list to delete\n", identifier, identifier_type);
return -1;
@@ -323,8 +328,8 @@
return -1;
}
-static int aMYSQL_nextresult(struct ast_channel *chan, char *data) {
-
+static int aMYSQL_nextresult(struct ast_channel *chan, char *data)
+{
MYSQL *mysql;
MYSQL_RES *mysqlres;
AST_DECLARE_APP_ARGS(args,
@@ -347,7 +352,7 @@
return -1;
}
- if (mysql_more_results(mysql)) {
+ if (mysql_more_results(mysql)) {
mysql_next_result(mysql);
if ((mysqlres = mysql_store_result(mysql))) {
add_identifier_and_set_asterisk_int(chan, args.resultid, AST_MYSQL_ID_RESID, mysqlres);
@@ -363,8 +368,8 @@
}
-static int aMYSQL_fetch(struct ast_channel *chan, char *data) {
-
+static int aMYSQL_fetch(struct ast_channel *chan, char *data)
+{
MYSQL_RES *mysqlres;
MYSQL_ROW mysqlrow;
AST_DECLARE_APP_ARGS(args,
@@ -373,7 +378,7 @@
AST_APP_ARG(fetchid);
AST_APP_ARG(vars);
);
- char *s5, *s6, *parse;
+ char *s5, *parse;
int resultid = -1, numFields, j;
parse = ast_strdupa(data);
@@ -391,14 +396,17 @@
ast_log(LOG_WARNING, "ast_MYSQL_fetch: More fields (%d) than variables (%d)\n", numFields, j);
break;
}
- s6 = mysqlrow[j];
- pbx_builtin_setvar_helper(chan, s5, s6 ? s6 : "NULL");
+
+ pbx_builtin_setvar_helper(chan, s5, mysqlrow[j] ? mysqlrow[j] :
+ nullvalue == NULLSTRING ? "NULL" :
+ nullvalue == EMPTYSTRING ? "" :
+ NULL);
}
ast_debug(5, "ast_MYSQL_fetch: numFields=%d\n", numFields);
- set_asterisk_int(chan, args.resultvar, 1); // try more rows
+ set_asterisk_int(chan, args.resultvar, 1); /* try more rows */
} else {
ast_debug(5, "ast_MYSQL_fetch : EOF\n");
- set_asterisk_int(chan, args.resultvar, 0); // no more rows
+ set_asterisk_int(chan, args.resultvar, 0); /* no more rows */
}
return 0;
} else {
@@ -441,7 +449,7 @@
} else {
mysql_close(mysql);
del_identifier(id, AST_MYSQL_ID_CONNID);
- }
+ }
return 0;
}
@@ -464,23 +472,23 @@
if (strncasecmp("connect", data, strlen("connect")) == 0) {
result = aMYSQL_connect(chan, ast_strdupa(data));
- } else if (strncasecmp("query", data, strlen("query")) == 0) {
+ } else if (strncasecmp("query", data, strlen("query")) == 0) {
result = aMYSQL_query(chan, ast_strdupa(data));
- } else if (strncasecmp("nextresult", data, strlen("nextresult")) == 0) {
+ } else if (strncasecmp("nextresult", data, strlen("nextresult")) == 0) {
result = aMYSQL_nextresult(chan, ast_strdupa(data));
- } else if (strncasecmp("fetch", data, strlen("fetch")) == 0) {
+ } else if (strncasecmp("fetch", data, strlen("fetch")) == 0) {
result = aMYSQL_fetch(chan, ast_strdupa(data));
- } else if (strncasecmp("clear", data, strlen("clear")) == 0) {
+ } else if (strncasecmp("clear", data, strlen("clear")) == 0) {
result = aMYSQL_clear(chan, ast_strdupa(data));
- } else if (strncasecmp("disconnect", data, strlen("disconnect")) == 0) {
+ } else if (strncasecmp("disconnect", data, strlen("disconnect")) == 0) {
result = aMYSQL_disconnect(chan, ast_strdupa(data));
} else if (strncasecmp("set", data, 3) == 0) {
result = aMYSQL_set(chan, ast_strdupa(data));
} else {
ast_log(LOG_WARNING, "Unknown argument to MYSQL application : %s\n", (char *)data);
- result = -1;
- }
-
+ result = -1;
+ }
+
ast_mutex_unlock(&_mysql_mutex);
snprintf(sresult, sizeof(sresult), "%d", result);
@@ -496,6 +504,25 @@
static int load_module(void)
{
struct MYSQLidshead *headp = &_mysql_ids_head;
+ struct ast_flags config_flags = { 0 };
+ struct ast_config *cfg = ast_config_load(MYSQL_CONFIG, config_flags);
+ const char *temp;
+
+ if (cfg) {
+ if ((temp = ast_variable_retrieve(cfg, "general", "nullvalue"))) {
+ if (!strcasecmp(temp, "nullstring")) {
+ nullvalue = NULLSTRING;
+ } else if (!strcasecmp(temp, "emptystring")) {
+ nullvalue = EMPTYSTRING;
+ } else if (!strcasecmp(temp, "null")) {
+ nullvalue = NULLVALUE;
+ } else {
+ ast_log(LOG_WARNING, "Illegal value for 'nullvalue': '%s' (must be 'nullstring', 'null', or 'emptystring')\n", temp);
+ }
+ }
+ ast_config_destroy(cfg);
+ }
+
AST_LIST_HEAD_INIT(headp);
return ast_register_application(app, MYSQL_exec, synopsis, descrip);
}
Added: trunk/configs/mysql.conf.sample
URL: http://svn.asterisk.org/svn-view/asterisk-addons/trunk/configs/mysql.conf.sample?view=auto&rev=916
==============================================================================
--- trunk/configs/mysql.conf.sample (added)
+++ trunk/configs/mysql.conf.sample Wed May 20 16:48:07 2009
@@ -1,0 +1,18 @@
+; Configuration file for the MYSQL app addon
+
+[general]
+;
+; Nullvalue governs how NULL values are returned from the database. In
+; previous versions, the special NULL value was returned as the "NULL"
+; string. We now provide an option for the behavior, configured globally.
+; nullstring - the string "NULL"
+; emptystring - the string ""
+; null - unset the variable
+;
+; WARNING: setting nullvalue=null may have undesireable consequences, in
+; particular if you use subroutines in AEL or the LOCAL() variable construct.
+; You have been warned. Don't complain if you use that setting in combination
+; with Gosub or AEL and get buggy behavior.
+;
+nullvalue = nullstring
+
Propchange: trunk/configs/mysql.conf.sample
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/configs/mysql.conf.sample
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: trunk/configs/mysql.conf.sample
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-addons-commits
mailing list