Symfoware

Symfowareについての考察blog

lua nginx moduleからMariaDB(MySQL)に接続する(lua-sql-mysql)

Debian 8にインストールしたlua nginx moduleでいろいろ試しています。
apt-getでDebian 8 + lua nginx moduleの環境構築(nginx-extras)
lua nginx moduleでjson形式のレスポンスを返す(cjson)

MariaDB(MySQL)への接続を試してみます。


lua-sql-mysql



luaからMariaDBに接続する方法を調べてみると、lua-sql-mysqlを使用するのが良さそうでした。
https://keplerproject.github.io/luasql/

apt-getでインストールします。


# apt-get install lua-sql-mysql




同じサーバーにMariaDBをインストール。
「sample」データベース、「t」テーブルを作成しておきました。


  1. create table t (
  2. id int not null,
  3. value varchar(100) not null
  4. );






サンプル



「t」テーブルにデータを登録。
結果をjson形式で表示してみます。


  1. local driver = require 'luasql.mysql'
  2. env = assert (driver.mysql())
  3. con = assert (env:connect('sample', 'root', 'P@ssw0rd', 'localhost', 3306))
  4. -- 接続文字コードを変更
  5. assert (con:execute('SET NAMES utf8mb4'))
  6. -- 一旦テーブルの内容を削除
  7. assert (con:execute('DELETE FROM t'))
  8. -- 登録するデータ
  9. list = {
  10. { id=1, value='日本語テスト1', },
  11. { id=2, value='日本語テスト2', },
  12. }
  13. for i, row in pairs (list) do
  14. res = assert (con:execute(string.format([[
  15.     INSERT INTO t
  16.     VALUES (%s, '%s')]], row.id, con:escape(row.value))
  17. ))
  18. end
  19. -- 結果を取得
  20. result = {}
  21. cur = assert (con:execute("SELECT id, value from t"))
  22. row = cur:fetch ({}, "a")
  23. while row do
  24. local copy_row = {}
  25. for field in pairs(row) do
  26. copy_row[field] = row[field]
  27. end
  28. table.insert(result, copy_row)
  29. row = cur:fetch (row, "a")
  30. end
  31. -- close everything
  32. cur:close() -- already closed because all the result set was consumed
  33. con:close()
  34. env:close()
  35. local cjson = require "cjson"
  36. json_text = cjson.encode(result)
  37. ngx.say(json_text)






コネクション作成時の「env:connect」の引数は
データベース名,ID,パスワード,ホスト,ポート
となっており文字コードの指定はありません。

「SET NAMES utf8mb4」を実行して変更してやればうまく日本語が登録できました。

ブラウザで結果を表示してみます。

740_01.png




もう少し汎用的に



postで実行するsql文を受け取るように変更してみます。


  1. local cjson = require "cjson"
  2. -- bodyの解析
  3. ngx.req.read_body()
  4. -- body_dataを取得してみる
  5. local req_body = ngx.req.get_body_data()
  6. -- もし取得できていなかったら、データはファイルに行っている
  7. if not req_body then
  8.     -- テンポラリのファイル名を取得。内容を全部読み込む
  9.     local req_body_file_name = ngx.req.get_body_file()
  10.     if req_body_file_name then
  11.         local file = io.open(req_body_file_name, 'rb')
  12.         req_body = file:read('*a')
  13.         file:close()
  14.     end
  15. end
  16. if not req_body then
  17.     ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
  18. end
  19. -- postされた値を解析
  20. local post = cjson.decode(req_body)
  21. local driver = require 'luasql.mysql'
  22. env = assert (driver.mysql())
  23. con = assert (env:connect('sample', 'root', 'P@ssw0rd', 'localhost', 3306))
  24. -- 接続文字コードを変更
  25. assert (con:execute('SET NAMES utf8mb4'))
  26. -- 結果を取得
  27. result = {}
  28. cur = assert (con:execute(post.query))
  29. row = cur:fetch ({}, "a")
  30. while row do
  31. local copy_row = {}
  32. for field in pairs(row) do
  33. copy_row[field] = row[field]
  34. end
  35. table.insert(result, copy_row)
  36. row = cur:fetch (row, "a")
  37. end
  38. -- close everything
  39. cur:close() -- already closed because all the result set was consumed
  40. con:close()
  41. env:close()
  42. json_text = cjson.encode(result)
  43. ngx.say(json_text)




結果を要求するクライアントはPythonで作成してみました。


  1. # -*- coding:utf-8 -*-
  2. import urllib2
  3. import json
  4. data = json.dumps({u'query':u'select * from t where id = 2'})
  5. f = urllib2.urlopen('http://192.168.1.104/', data)
  6. json_text = f.read()
  7. json_data = json.loads(json_text)
  8. for row in json_data:
  9.     print row['id'], row['value']




狙い通りの実行結果です。


$ python sample.py
2 日本語テスト2





【参考URL】

LuaスクリプトからMySQLを利用するサンプル
https://keplerproject.github.io/luasql/examples.html
Luaのお勉強 テーブルの操作
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/04/09(日) 18:49:25|
  2. Lua
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<lua nginx moduleでMessagePackのデータを使用(lua-MessagePack) | ホーム | lua nginx moduleでjson形式のレスポンスを返す(cjson)>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1973-60902091
この記事にトラックバックする(FC2ブログユーザー)