From 7052aa151ca9a813fa48fe5f7611e5535dd03c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BB=BA=E5=B9=B3?= Date: Fri, 30 Aug 2013 13:57:03 +0800 Subject: [PATCH 1/2] implement connection mysql server with charset (default charset is utf8) using charsets which is supported by mysql server 5.6 --- lib/resty/mysql.lua | 76 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/lib/resty/mysql.lua b/lib/resty/mysql.lua index 44f0ad2..29d2ac4 100644 --- a/lib/resty/mysql.lua +++ b/lib/resty/mysql.lua @@ -23,8 +23,8 @@ local unpack = unpack local setmetatable = setmetatable local error = error local tonumber = tonumber - - +local ipairs =ipairs +local strfmt=string.format module(...) _VERSION = '0.13' @@ -160,9 +160,68 @@ local function _compute_token(password, scramble) end return strchar(unpack(bytes)) +end +-- +local mysql={ charset={}}; +-- input charset name for get mysqlserver charset id +-- return id,errormsg +local function _getcharset(charset) + --local mysql={ charset={}}; + local cid=mysql.charset.utf8 + if not cid then + local charsetlist={"armscii8_general_ci","armscii8","32", + "ascii_general_ci","ascii","11", + "big5_chinese_ci","big5","1", + "binary","binary","63", + "cp1250_general_ci","cp1250","26", + "cp1251_general_ci","cp1251","51", + "cp1256_general_ci","cp1256","57", + "cp1257_general_ci","cp1257","59", + "cp850_general_ci","cp850","4", + "cp852_general_ci","cp852","40", + "cp866_general_ci","cp866","36", + "cp932_japanese_ci","cp932","95", + "dec8_swedish_ci","dec8","3", + "eucjpms_japanese_ci","eucjpms","97", + "euckr_korean_ci","euckr","19", + "gb2312_chinese_ci","gb2312","24", + "gbk_chinese_ci","gbk","28", + "geostd8_general_ci","geostd8","92", + "greek_general_ci","greek","25", + "hebrew_general_ci","hebrew","16", + "hp8_english_ci","hp8","6", + "keybcs2_general_ci","keybcs2","37", + "koi8r_general_ci","koi8r","7", + "koi8u_general_ci","koi8u","22", + "latin1_swedish_ci","latin1","8", + "latin2_general_ci","latin2","9", + "latin5_turkish_ci","latin5","30", + "latin7_general_ci","latin7","41", + "macce_general_ci","macce","38", + "macroman_general_ci","macroman","39", + "sjis_japanese_ci","sjis","13", + "swe7_swedish_ci","swe7","10", + "tis620_thai_ci","tis620","18", + "ucs2_general_ci","ucs2","35", + "ujis_japanese_ci","ujis","12", + "utf16_general_ci","utf16","54", + "utf32_general_ci","utf32","60", + "utf8_general_ci","utf8","33", + "utf8mb4_general_ci","utf8mb4","45"} + for i,v in ipairs(charsetlist) do + if i%3==1 then + local tab=charsetlist; + local index =i; + mysql.charset[tab[i+1]]=tab[index+2] + end + end + end + local id=mysql.charset[charset]; + if not id then + return id, "charset " .. (charset or "nil") .. "is not supported"; + end + return id; end - - function _send_packet(self, req, size) local sock = self.sock @@ -597,11 +656,16 @@ function connect(self, opts) local client_flags = 260047; --print("token: ", _dump(token)) - + local _charset=opts.charset or "utf8" + local _cid,err=_getcharset(_charset) + if not _cid then + return nil, "set charset error" .. err + end local req = { _set_byte4(client_flags), _set_byte4(self._max_packet_size), - "\0", -- TODO: add support for charset encoding + --"\0", -- TODO: add support for charset encoding, + strchar(_cid), strrep("\0", 23), _to_cstring(user), _to_binary_coded_string(token), From c4b49212b231aa5abd184da0d4bc2b6d9ac1b036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BB=BA=E5=B9=B3?= Date: Fri, 30 Aug 2013 14:22:43 +0800 Subject: [PATCH 2/2] implement connection mysql server with charset (default charset is utf8) --- README.markdown | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/README.markdown b/README.markdown index 991c20f..3aacd02 100644 --- a/README.markdown +++ b/README.markdown @@ -29,6 +29,7 @@ Synopsis server { location /test { + default_type 'text/plain;charset=utf-8'; content_by_lua ' local mysql = require "resty.mysql" local db, err = mysql:new() @@ -54,8 +55,10 @@ Synopsis database = "ngx_test", user = "ngx_test", password = "ngx_test", - max_packet_size = 1024 * 1024 } - + max_packet_size = 1024 * 1024 , + charset=utf8 + } + -- default charset is utf8 if not ok then ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate) return @@ -83,12 +86,12 @@ Synopsis res, err, errno, sqlstate = db:query("insert into cats (name) " - .. "values (\'Bob\'),(\'\'),(null)") + .. "values (\'Bob\'),(\'\'),(null),(\'春哥,你好\')") if not res then ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".") return end - + ngx.say(res.affected_rows, " rows inserted into table cats ", "(last insert id: ", res.insert_id, ")") @@ -101,7 +104,16 @@ Synopsis local cjson = require "cjson" ngx.say("result: ", cjson.encode(res)) - + ngx.say("show mysql charsets info ;") + + res, err, errno, sqlstate = + db:query("show variables like \'%%char%%\'") + if not res then + ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".") + return + end + ngx.say("mysql charsets info result", cjson.encode(res)) + -- put it into the connection pool of size 100, -- with 0 idle timeout local ok, err = db:set_keepalive(0, 100) @@ -155,6 +167,8 @@ The `options` argument is a Lua table holding the following keys: : the name for the MySQL connection pool. if omitted, an ambiguous pool name will be generated automatically with the string template `user:database:host:port` or `user:database:path`. (this option was first introduced in `v0.08`.) * `compact_arrays` : when this option is set to true, then the `query` and `read_result` methods will return the array-of-arrays structure for the resultset, rather than the default array-of-hashes structure. +* `charset` +: the lua mysql client charset (default to utf8 ) more charset please check `SELECT id, collation_name FROM information_schema.collations ORDER BY id;` Before actually resolving the host name and connecting to the remote backend, this method will always look up the connection pool for matched idle connections created by previous calls of this method.