[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