https://freeswitch.org/confluence/display/FREESWITCH/Lua+with+Database
Lua脚本允许连接数据库和外部资源。如果你正在使用Lua开发某种FreeSWITCH APP,需要用到DBMS,那么,你有两种可选方案。
1. 访问数据库
Lua提供两种访问数据库的方式:LuaSQL和freeswitch.Dbh。Dbh方式是首选方案,因为它使用了数据库handle pooling技术,可以提升效率和访问速度。
使用LuaSQL,不仅可以查询ODBC 数据源,还可以通过本地驱动访问PostgreSQL、Oracle或MySQL。LuaSQL模块自己会连接数据库。LuaSQL没有提供像freeswitch.Dbh那样的连接池技术。
2. LuaSQL
Lua开发人员最常用的替代方案是使用LuaSQL(http://keplerproject.org/luasql/)。通过Luasql,你可以轻松连接ODBC、ADO、Oracle、MySQL、SQLite,以及PostgreSQL数据库。
2.1 LuaSQL 实例
-- this example of how to connect to postgres from Lua
local luasql = require "luasql.postgres"
--
-- Database connection settings
--
DBHOST = '127.0.0.1'
DBNAME = 'dbname'
DBUSER = 'dbusername'
DBPASS = 'dbpassword'
DBPORT = 5432
local env = assert (luasql.postgres())
local dbcon = env:connect(DBNAME, DBUSER, DBPASS, DBHOST, DBPORT)
sql = 'SELECT pin, name FROM customer'
res, serr = dbcon:execute(sql)
dbcon:close()
env:close()
3. freeswitch.Dbh
另一种解决方案是使用the freeswitch.Dbh。
这种方案的优势是利用FreeSWITCH提供的连接池提升速度,这比为每个LuaSQL env:connect()建立一条新的TCP连接要高效得多。
接口定义:
local dbh = freeswitch.Dbh("dsn","user","pass") -- when using ODBC (deprecated)
-- OR --
local dbh = freeswitch.Dbh("core:my_db") -- when using sqlite (deprecated, if you have to use this to make it work you should upgrade your FS installation)
-- OR --
local dbh = freeswitch.Dbh("sqlite://my_db") -- sqlite database in subdirectory "db"
-- OR --
local dbh = freeswitch.Dbh("odbc://my_db:uname:passwd") -- connect to ODBC database
assert(dbh:connected()) -- exits the script if we didn't connect properly
dbh:test_reactive("SELECT * FROM my_table",
"DROP TABLE my_table",
"CREATE TABLE my_table (id INTEGER(8), name VARCHAR(255))")
dbh:query("INSERT INTO my_table VALUES(1, 'foo')") -- populate the table
dbh:query("INSERT INTO my_table VALUES(2, 'bar')") -- with some test data
dbh:query("SELECT id, name FROM my_table", function(row)
stream:write(string.format("%5s : %s\n", row.id, row.name))
end)
dbh:query("UPDATE my_table SET name = 'changed'")
stream:write("Affected rows: " .. dbh:affected_rows() .. "\n")
dbh:release() -- optional
- freeswitch.Dbh(odbc://my_db:uname:passwd) 从连接池里获取一个ODBC db 句柄。
- freeswitch.Dbh("sqlite://my_db") 从连接池中获取一个内核DB句柄 (sqlite) ,如果不存在,则会自动创建。
- dbh:connected() :检查句柄的连接状态,连接返回true,否则返回false。
- dbh:test_reactive("test_sql", "drop_sql", "reactive_sql") :执行 test_sql,如果失败执行 drop_sql 和reactive_sql (方便用于建表初始化)
- dbh:query("query", function()): 将查询作为一个字符串,携带一个可选的Lua回调函数,对DB返回的每一行执行操作
- 对于每次循环迭代,都会向回调函数传递一张表,这张表描述当前行的内容。
- 每一行的语法是这样的: { ["column_name_1"] = "value_1", ["column_name_2"] = "value_2" }.
- 如果你需要打破循环,可以让回调函数返回一个非零值。
- dbh:affected_rows(): 返回上一次在句柄上执行INSERT、DELETE或UPDATE影响的行数。它对SELECT 操作没响应。
- dbh:release() :(可选的) 释放句柄,把它归还给连接池,以便其它线程可以复用它。当dbh超出作用域范围时(比如说脚本返回),会有垃圾回收,这时会自动执行释放操作。对于很长的脚本来说,在不需要时显式释放句柄还是有必要的。
freeswitch.Dbh 代码实例
-- this is an example of how to connect to Postgres using ODBC from Lua
local dbh = freeswitch.Dbh("odbc://my_db:uname:passwd") -- connect to ODBC database
assert(dbh:connected()) -- exits the script if we didn't connect properly
dbh:query("SELECT pin, name FROM customer", function(row)
stream:write(string.format("%5s : %s\n", row.id, row.name))
end)
dbh:release() -- optional