Skip to content

implement connection mysql server with charset (default charset is utf8) #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -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, ")")

Expand All @@ -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)
Expand Down Expand Up @@ -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.

Expand Down
76 changes: 70 additions & 6 deletions lib/resty/mysql.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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),
Expand Down