From 463cc4021f68debfda850e87e93deb1a3a55b59e Mon Sep 17 00:00:00 2001 From: espiceland Date: Fri, 8 Oct 2010 16:27:31 +0000 Subject: Add option to res_config_mysql and app_mysql to specify a character set that MySQL should use. (closes issue 17948) Reported by qmax. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@290939 f38db490-d61c-443f-a65b-d21fe96a405b --- addons/app_mysql.c | 19 ++++++++++++++----- addons/res_config_mysql.c | 16 ++++++++++++++++ configs/res_config_mysql.conf.sample | 5 ++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/addons/app_mysql.c b/addons/app_mysql.c index 0b1b58f04..b65b5bb93 100644 --- a/addons/app_mysql.c +++ b/addons/app_mysql.c @@ -57,10 +57,10 @@ static const char descrip[] = "Syntax:\n" " MYSQL(Set timeout )\n" " Set the connection timeout, in seconds.\n" -" MYSQL(Connect connid dhhost dbuser dbpass dbname)\n" +" MYSQL(Connect connid dhhost dbuser dbpass dbname [dbcharset])\n" " Connects to a database. Arguments contain standard MySQL parameters\n" -" passed to function mysql_real_connect. Connection identifer returned\n" -" in ${connid}\n" +" passed to function mysql_real_connect. Optional parameter dbcharset\n" +" defaults to 'latin1'. Connection identifer returned in ${connid}\n" " MYSQL(Query resultid ${connid} query-string)\n" " Executes standard MySQL query contained in query-string using established\n" " connection identified by ${connid}. Result of query is stored in ${resultid}.\n" @@ -80,7 +80,7 @@ static const char descrip[] = /* EXAMPLES OF USE : -exten => s,2,MYSQL(Connect connid localhost asterisk mypass credit) +exten => s,2,MYSQL(Connect connid localhost asterisk mypass credit utf8) 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) @@ -315,6 +315,7 @@ static int aMYSQL_connect(struct ast_channel *chan, char *data) AST_APP_ARG(dbuser); AST_APP_ARG(dbpass); AST_APP_ARG(dbname); + AST_APP_ARG(dbcharset); ); MYSQL *mysql; int timeout; @@ -322,7 +323,7 @@ static int aMYSQL_connect(struct ast_channel *chan, char *data) AST_NONSTANDARD_APP_ARGS(args, data, ' '); - if (args.argc != 6) { + if (args.argc < 6) { ast_log(LOG_WARNING, "MYSQL_connect is missing some arguments\n"); return -1; } @@ -336,6 +337,14 @@ static int aMYSQL_connect(struct ast_channel *chan, char *data) if (ctimeout && sscanf(ctimeout, "%30d", &timeout) == 1) { mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&timeout); } + if(args.dbcharset && strlen(args.dbcharset) > 2){ + char set_names[255]; + char statement[512]; + snprintf(set_names, sizeof(set_names), "SET NAMES %s", args.dbcharset); + mysql_real_escape_string(mysql, statement, set_names, sizeof(set_names)); + mysql_options(mysql, MYSQL_INIT_COMMAND, set_names); + mysql_options(mysql, MYSQL_SET_CHARSET_NAME, args.dbcharset); + } if (! mysql_real_connect(mysql, args.dbhost, args.dbuser, args.dbpass, args.dbname, 0, NULL, #ifdef CLIENT_MULTI_STATEMENTS diff --git a/addons/res_config_mysql.c b/addons/res_config_mysql.c index 1ba522485..a626ffd3e 100644 --- a/addons/res_config_mysql.c +++ b/addons/res_config_mysql.c @@ -91,6 +91,7 @@ struct mysql_conn { char user[50]; char pass[50]; char sock[50]; + char charset[50]; int port; int connected; time_t connect_time; @@ -1527,6 +1528,10 @@ static int load_mysql_config(struct ast_config *config, const char *category, st } else ast_copy_string(conn->sock, s, sizeof(conn->sock)); + if ((s = ast_variable_retrieve(config, category, "dbcharset"))) { + ast_copy_string(conn->charset, s, sizeof(conn->charset)); + } + if (!(s = ast_variable_retrieve(config, category, "requirements"))) { ast_log(LOG_WARNING, "MySQL realtime: no requirements setting found, using 'warn' as default.\n"); conn->requirements = RQ_WARN; @@ -1549,6 +1554,8 @@ static int load_mysql_config(struct ast_config *config, const char *category, st ast_debug(1, "MySQL RealTime database name: %s\n", conn->name); ast_debug(1, "MySQL RealTime user: %s\n", conn->user); ast_debug(1, "MySQL RealTime password: %s\n", conn->pass); + if(conn->charset) + ast_debug(1, "MySQL RealTime charset: %s\n", conn->charset); return 1; } @@ -1568,6 +1575,15 @@ reconnect_tryagain: conn->connected = 0; return 0; } + if(conn->charset && strlen(conn->charset) > 2){ + char set_names[255]; + char statement[512]; + snprintf(set_names, sizeof(set_names), "SET NAMES %s", conn->charset); + mysql_real_escape_string(&conn->handle, statement, set_names, sizeof(set_names)); + mysql_options(&conn->handle, MYSQL_INIT_COMMAND, set_names); + mysql_options(&conn->handle, MYSQL_SET_CHARSET_NAME, conn->charset); + } + if (mysql_real_connect(&conn->handle, conn->host, conn->user, conn->pass, conn->name, conn->port, conn->sock, 0)) { #ifdef MYSQL_OPT_RECONNECT /* The default is no longer to automatically reconnect on failure, diff --git a/configs/res_config_mysql.conf.sample b/configs/res_config_mysql.conf.sample index dfbbf49a8..79eaf97d2 100644 --- a/configs/res_config_mysql.conf.sample +++ b/configs/res_config_mysql.conf.sample @@ -4,7 +4,9 @@ ; The value of dbhost may be either a hostname or an IP address. ; If dbhost is commented out or the string "localhost", a connection ; to the local host is assumed and dbsock is used instead of TCP/IP -; to connect to the server. +; to connect to the server. If no dbcharset is specified, the connection +; is made with no extra charset configurations sent to MySQL, leaving all +; configured MySQL charset options and defaults untouched. ; ; Multiple database contexts may be configured, with the caveat that ; all context names should be unique and must not contain the slash ('/') @@ -37,4 +39,5 @@ ;dbpass = mypass ;dbport = 3306 ;dbsock = /tmp/mysql.sock +;dbcharset = latin1 ;requirements=warn ; or createclose or createchar -- cgit v1.2.3