pgmoon
一个用纯 Lua(MoonScript)编写的 PostgreSQL 客户端库
$ opm get agentzh/pgmoon
pgmoon
[!构建状态](https://travis-ci.org/leafo/pgmoon)
pgmoon 是一个用纯 Lua(MoonScript)编写的 PostgreSQL 客户端库。
pgmoon 最初是为了在 [OpenResty][5] 中使用而设计的,它利用 [cosocket api][4] 来提供异步查询,但它也可以在使用 [LuaSocket][1] 的普通 Lua 环境中使用(并可选地使用 [LuaCrypto][2] 进行 MD5 身份验证和 [LuaSec][6] 进行 SSL 连接)。
它是运行您的查询的完美选择,无论是在 OpenResty 的环境中还是在命令行(例如测试)中,在像 [Lapis][3] 这样的 Web 框架中。
安装
$ luarocks install pgmoon
示例
local pgmoon = require("pgmoon")
local pg = pgmoon.new({
host = "127.0.0.1",
port = "5432",
database = "mydb",
user = "postgres"
})
assert(pg:connect())
local res = assert(pg:query("select * from users where username = " ..
pg:escape_literal("leafo")))
如果您使用的是 OpenResty,您应该在完成对套接字的操作后释放它,以便它可以在将来的请求中被重用。
pg:keepalive()
参考
require("pgmoon")
返回的表中的函数
new(options={})
创建一个新的 Postgres
对象。不会自动连接。接受一个选项表。该表可以包含以下键:
"host"
: 要连接的主机(默认值:"127.0.0.1"
)"port"
: 要连接的端口(默认值:"5432"
)"user"
: 用于身份验证的数据库用户名(默认值:"postgres"
)"database"
: 要连接的数据库名称 必需"password"
: 用于身份验证的密码,可选,具体取决于服务器配置"ssl"
: 启用 ssl"ssl_verify"
: 验证服务器证书"ssl_required"
: 如果服务器不支持 SSL 连接,则中止连接
new
返回的 Postgres
对象上的方法
success, err = postgres:connect()
使用 new
调用中指定的凭据连接到 Postgres 服务器。成功时返回 true
,失败时返回 nil
和错误消息。
success, err = postgres:disconnect()
如果套接字已打开,则关闭到服务器的套接字。在此之后,不应在该对象上调用其他方法,除了再次调用 connect。
success, err = postgres:keepalive(...)
通过 setkeepalive
方法将套接字释放到 OpenResty 套接字池。此处传递的任何参数也会传递给 setkeepalive
。
result, num_queries = postgres:query(query_string)
result, err, partial, num_queries = postgres:query(query_string)
向服务器发送查询。失败时返回 nil
和错误消息。
成功时返回一个结果,具体取决于发送的查询类型。
SELECT
查询、带有 returning
的 INSERT
或任何其他返回结果集的查询将返回结果的数组表。每个结果都是一个哈希表,其中键是列的名称,值是结果集中该行的结果。
local res = pg:query("select id, name from users")
可能返回
{
{
id = 123,
name = "Leafo"
},
{
id = 234,
name = "Lee"
}
}
任何影响行的查询,如 UPDATE
、DELETE
或 INSERT
,都会返回一个表结果,其中 affected_rows
字段设置为受影响的行数。
local res = pg:query("delete from users")
可能返回
{
affected_rows = 2
}
任何没有结果集或更新行的查询都会返回 true
。
此方法还支持通过用 ;
分隔来一次发送多个查询。执行的查询数量作为第二个返回值在结果对象之后返回。当执行多个查询时,结果对象会略有变化。它变成一个数组表,包含所有单个结果。
local res, num_queries = pg:query([[
select id, name from users;
select id, title from posts
]])
可能返回
num_queries = 2
res = {
{
{
id = 123,
name = "Leafo"
},
{
id = 234,
name = "Lee"
}
},
{
{
id = 546,
title = "My first post"
}
}
}
类似地,对于返回受影响行或只是 true
的查询,当有多个查询时,它们将被包装在额外的数组表中。您也可以根据需要混合使用不同的查询类型。
因为 Postgres 一次执行一个查询,所以前面的查询可能成功,而后面的查询可能失败。如果多个查询发生错误,则错误消息之后将返回部分结果和部分执行的查询数量。
escaped = postgres:escape_literal(val)
转义 Lua 值以用作 Postgres 值,插入到查询字符串中。当将用户提供的数据发送到查询中时,您应该使用此方法来防止 SQL 注入攻击。
escaped = postgres:escape_identifier(val)
转义 Lua 值以用作 Postgres 标识符。这包括表名或列名。这并不包括常规值,您应该使用 escape_literal
来处理常规值。当名称与内置语言关键字冲突时,需要进行标识符转义。
str = tostring(postgres)
返回 Postgres
对象当前状态的字符串表示形式。
SSL 连接
pgmoon 可以建立与 Postgres 服务器的 SSL 连接。如果服务器不支持 SSL,它也可以拒绝连接。正如 pgmoon 在 OpenResty 之外的使用依赖于 LuaSocket 一样,它在这些环境中依赖于 LuaSec 进行 SSL 连接。
local pgmoon = require("pgmoon")
local pg = pgmoon.new({
host = "127.0.0.1",
ssl = true, -- enable SSL
ssl_verify = true, -- verify server certificate
ssl_required = true, -- abort if the server does not support SSL connections
cafile = "...", -- certificate authority (LuaSec only)
cert = "...", -- client certificate (LuaSec only)
key = "...", -- client key (LuaSec only)
})
assert(pg:connect())
在 OpenResty 中,如果要验证服务器证书,请确保配置 [lua_ssl_trusted_certificate][7] 指令,因为 LuaSec 独有的选项在这种情况下变得无关紧要。
身份验证类型
Postgres 有几种身份验证类型。pgmoon 目前支持 Trust 和 MD5 身份验证。
类型转换
Postgres 内置了一组非常丰富的类型。pgmoon 会尽力将任何 Postgres 类型转换为适当的 Lua 类型。
所有整数、浮点数和数字类型都转换为 Lua 的 number 类型。布尔类型转换为 Lua 布尔值。JSON 类型使用 Lua CJSON 解码为 Lua 表。Lua 表可以像下面描述的那样编码为 JSON。
任何数组类型都会自动转换为 Lua 数组表。如果您需要将 Lua 中的数组编码为 Postgres 的数组语法,可以使用 pgmoon.arrays
模块。见下文。
任何其他类型都作为 Lua 字符串返回。
处理数组
数组在从查询中返回时会自动解码。数字、字符串和布尔类型会根据情况自动加载。嵌套数组也受支持。
使用 encode_array
将 Lua 表编码为查询的数组语法
local pgmoon = require("pgmoon")
local pg = pgmoon.new(auth)
pg:connect()
local encode_array = require("pgmoon.arrays").encode_array
local my_array = {1,2,3,4,5}
pg:query("insert into some_table (some_arr_col) values(" .. encode_array(my_array) .. ")")
处理 JSON
json
和 jsonb
类型在从查询中返回时会自动解码。
使用 encode_json
将 Lua 表编码为查询的 JSON 语法
local pgmoon = require("pgmoon")
local pg = pgmoon.new(auth)
pg:connect()
local encode_json = require("pgmoon.json").encode_json
local my_tbl = {hello = "world"}
pg:query("insert into some_table (some_json_col) values(" .. encode_json(my_tbl) .. ")")
处理 hstore
因为 hstore
是一个扩展类型,所以需要一个查询来找出类型 ID,然后 pgmoon 才能自动解码它。在连接后,在连接对象上调用 setup_hstore
方法来设置它。
local pgmoon = require("pgmoon")
local pg = pgmoon.new(auth)
pg:connect()
pg:setup_hstore()
使用 encode_hstore
将 Lua 表编码为更新和插入时的 hstore 语法
local encode_hstore = require("pgmoon.hstore").encode_hstore
local tbl = {foo = "bar"}
pg:query("insert into some_table (hstore_col) values(" .. encode_hstore(tbl) .. ")")
您可以使用 decode_hstore
函数手动从字符串中解码 hstore 值。这只有在您没有调用 setup_hstore
时才需要。
local decode_hstore = require("pgmoon.hstore").decode_hstore
local res = pg:query("select * from some_table")
local hstore_tbl = decode_hstore(res[1].hstore_col)
转换 NULL
默认情况下,Postgres 中的 NULL
转换为 nil
,这意味着它们在结果表中不可见。如果您想将 NULL
转换为某个可见值,请在 Postgres
对象上将 convert_null
设置为 true
local pgmoon = require("pgmoon")
local pg = pgmoon.new(auth)
pg:connect()
pg.convert_null = true
local res = pg:query("select NULL the_null")
assert(pg.NULL == res[1].the_null)
如上所示,NULL
值设置为 pg.NULL
。您可以更改此值,使 pgmoon 使用其他东西作为 NULL
。例如,如果您使用的是 OpenResty,您可能希望重用 ngx.null
。
联系
作者:Leaf Corcoran (leafo) (@moonscript) 电子邮件:leafot@gmail.com 主页:<http://leafo.net>
变更日志
1.6.0 — 2016-07-21 — 添加对 json 和 jsonb 数组解码的支持
1.5.0 — 2016-07-12 — 添加 SSL 支持 (@thibaultCha),添加 UUID 数组类型 (@edan),添加对通知的支持 (@starius)
1.4.0 — 2016-02-18 — 添加对解码 jsonb 的支持,添加 json 序列化器 (@thibaultCha)
1.3.0 — 2016-02-11 — 修复解析看起来像数字的字符串失败的错误,添加在 init 上下文中在 ngx 中使用的支持 (@thibaultCha),添加明文密码身份验证,修复 md5 身份验证的警告
1.2.0 — 2015-07-10 — 添加对 PostgreSQL 数组的支持
1.1.1 — 2014-08-12 — 修复 md5 身份验证的错误
1.1.0 — 2014-05-21 — 添加对一次调用中使用多个查询的支持
1.0.0 — 2014-05-19 — 初始版本
许可证 (MIT)
版权所有 (C) 2016 by Leaf Corcoran
特此授予任何人免费获得本软件副本和相关文档文件(“软件”)的副本,不受限制地处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件的权利,以及允许获得软件的人员这样做,但须符合以下条件:
以上版权声明和本许可声明应包含在软件的所有副本或重要部分中。
软件按“原样”提供,不提供任何形式的明示或暗示保证,包括但不限于适销性、特定用途的适用性和非侵权的保证。在任何情况下,作者或版权持有人均不对因使用或其他与软件相关的任何索赔、损害或其他责任承担任何责任,无论是基于合同、侵权或其他方式造成的,即使已告知此类损害的可能性。
[1]: http://w3.impa.br/~diego/software/luasocket/ [2]: http://mkottman.github.io/luacrypto/ [3]: http://leafo.net/lapis [4]: http://wiki.nginx.org/HttpLuaModule#ngx.socket.tcp [5]: https://openresty.org.cn/ [6]: https://github.com/brunoos/luasec [7]: https://github.com/openresty/lua-nginx-module#lua_ssl_trusted_certificate
作者
Leaf Corcoran (leafo)
许可证
mit
版本
-
agentzh/pgmoon 1.6.0一个用纯 Lua (MoonScript) 编写的 PostgreSQL 客户端库 2016-09-29 00:57:42
-
2016-09-29 00:29:24
-
2016-09-29 00:18:44
-
2016-09-29 00:16:13
-
2016-09-29 00:10:13
-
2016-09-29 00:02:44