1Name
2 lua-rds-parser - Resty-DBD-Stream (RDS) parser for Lua written in C
3
4Status
5 This module is production ready.
6
7Synopsis
8 local parser = require "rds.parser"
9
10 local res, err = parser.parse(rds)
11
12 if res == nil then
13 error("failed to parse: " .. err)
14 end
15
16 print(res.errcode)
17 print(res.errstr)
18 print(res.insert_id)
19 print(res.affected_rows)
20
21 local rows = res.resultset
22 if rows then
23 for i, row in ipairs(rows) do
24 for col, val in pairs(row) do
25 if val ~= parser.null then
26 print(col .. ": " .. val)
27 end
28 end
29 end
30 end
31
32Description
33 This Lua library can be used to parse the Resty-DBD-Stream formatted data
34 generated by ngx_drizzle (http://wiki.nginx.org/HttpDrizzleModule )
35 and ngx_postgres (http://github.com/FRiCKLE/ngx_postgres/ ) into Lua
36 data structures. In the past, we have to use JSON as the intermediate data
37 format which is quite inefficient in terms of both memory and CPU time.
38
39 To maximize speed and minimize memory footprint, this library is implemented
40 in pure C.
41
42 Null values in RDS are turned into the light user data "parser.null"
43 where "parser" is the module object returned by Lua's "require".
44
45JSON Serialization
46 If you want to serialize the parsed result into JSON, please
47 use the lua-cjson library (http://www.kyne.com.au/~mark/software/lua-cjson.php )
48 instead of lua-yajl, because lua-cjson is faster than lua-yajl
49 in many common cases, and more importantly,
50
51 parser.null == cjson.null ~= yajl.null
52
53Using with HttpDrizzleModule
54 To use with ngx_drizzle, here is a small example:
55
56 upstream backend {
57 drizzle_server 127.0.0.1:3306 protocol=mysql
58 dbname=ngx_test user=ngx_test password=ngx_test;
59 drizzle_keepalive max=10 overflow=ignore mode=single;
60 }
61
62 server {
63 ...
64
65 location /mysql {
66 drizzle_query $echo_request_body;
67 drizzle_pass backend;
68 }
69
70 location /api {
71 content_by_lua '
72 local sql = "select * from cats"
73 local resp = ngx.location.capture("/mysql", {
74 method = ngx.HTTP_POST, body = sql
75 })
76 if resp.status ~= ngx.HTTP_OK or not resp.body then
77 error("failed to query mysql")
78 end
79
80 local parser = require "rds.parser"
81 local res, err = parser.parse(resp.body)
82 if res == nil then
83 error("failed to parse RDS: " .. err)
84 end
85
86 local rows = res.resultset
87 if not rows or #rows == 0 then
88 ngx.say("empty resultset")
89 ngx.exit(0)
90 end
91
92 for i, row in ipairs(rows) do
93 ngx.print("row ", i, ": ")
94 for col, val in pairs(row) do
95 if val ~= parser.null then
96 ngx.print(col, "=", val, " ")
97 else
98 ngx.print(col, "=null ")
99 end
100 end
101 ngx.say()
102 end
103 ';
104 }
105 }
106
107 On my machine, GET /api will yield
108
109 row 1: id=2 name=null
110 row 2: id=3 name=bob
111
112 of course, the actual output depends on the structure and contents of the
113 "cats" table in the mysql database.
114
115 You can use this Lua library with the ngx_postgres module in a similar way.
116
117Installation
118 Build requirements
119 * Lua (http://www.lua.org/)
120
121 * or LuaJIT (http://www.luajit.org/)
122
123 Gnu make and gcc is required to build this module.
124
125 Linux/BSD/Solaris
126 gmake CC=gcc
127 gmake install CC=gcc
128
129 Mac OS X
130 make LDFLAGS='-bundle -undefined dynamic_lookup' CC=gcc
131 make install
132
133 If your Lua or LuaJIT is not installed into the system, specify its
134 include directory like this:
135
136 make LUA_INCLUDE_DIR=/opt/luajit/include/luajit-2.0
137
138 You can specify a custom path for the installation target:
139
140 make install LUA_LIB_DIR=/opt/lualib
141
142 The "DESTDIR" variable is also supported, to ease RPM packaging.
143
144TODO
145 * add support for option "compact" to generate a compact
146 Lua table for the "resultset" field.
147
148Known Issues
149 * The endianness flag in RDS is not supported yet in this library,
150 and it will assume it's of the host's endian. So do not
151 try parsing the RDS stream that is generated by another
152 machine of a different endian.
153
154Author
155 Zhang "agentzh" Yichun <agentzh@gmail.com>
156
157Copyright & License
158 This module is licenced under the BSD license.
159
160 Copyright (C) 2011, Zhang "agentzh" Yichun (章亦春) <agentzh@gmail.com>.
161
162 All rights reserved.
163
164 Redistribution and use in source and binary forms, with or without
165 modification, are permitted provided that the following conditions
166 are met:
167
168 * Redistributions of source code must retain the above copyright
169 notice, this list of conditions and the following disclaimer.
170
171 * Redistributions in binary form must reproduce the above copyright
172 notice, this list of conditions and the following disclaimer in the
173 documentation and/or other materials provided with the distribution.
174
175 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
177 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
178 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
179 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
180 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
181 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
182 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
183 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
184 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
185 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
186
187