Lua 自身并没有提供访问数据库的函数,但是借助外部扩展库我们可以很容易实现对数据库的各种操作,例如LuaSQL,通过它,Lua 可以以统一的方法访问各种流行的数据库(例如PostgreSQL,ODBC,JDBC,MySQL,SQLite,Oracle 和 ADO 等等)。
达梦数据库并未提供luasql的访问驱动,但是可以通过ODBC连接到达梦数据库,再由LuaSQL访问到ODBC执行数据库操作。
1.安装gcc
检查是否安装,如果有则无需安装
[root@localhost opt]# gcc
gcc: fatal error: no input files
compilation terminated.
安装gcc,直接采用yum安装
yum install gcc
2.安装ODBC
1.采用yum安装
yum install unixODBC.x86_64 unixODBC-devel.x86_64 -y
2.源码编译安装
源码包下载地址:http://www.unixodbc.org
上传到服务器后解压编译安装
tar xzvf unixODBC-2.3.0.tar.gz
cd unixODBC-2.3.0/
./configure
make && make install
查看是否安装完成
[root@localhost unixODBC-2.3.7]# odbc_config
Usage: odbc_config
[--prefix]
[--exec-prefix]
[--include-prefix]
[--lib-prefix]
[--bin-prefix]
[--version]
[--libs]
[--static-libs]
[--libtool-libs]
[--cflags]
[--odbcversion]
[--longodbcversion]
[--odbcini]
[--odbcinstini]
[--header]
[--ulen]
3.查看配置路径
[root@localhost unixODBC-2.3.7]# odbcinst -j
unixODBC 2.3.7
DRIVERS............: /usr/local/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
4.配置DM数据源及驱动
根据配置路径可知ODBC驱动配置文件odbcinst.ini及数据源配置文件odbc.ini所在路径。
配置odbc.ini
[DM8]
Description = DM ODBC DSN //描述
DRIVER = DM8 ODBC DRIVER //驱动名称
SERVER = 127.0.0.1 //dm数据库ip地址
UID = SYSDBA //用户名
PWD = SYSDBA //密码
TCP_PORT = 5236 //连接端口
配置odbcinst.ini
[DM8 ODBC DRIVER] //注意 这个名称一定要与odbc.ini中的DRIVER保持一致!!
Description = DM ODBC DRIVER FOR DM8 //描述
Driver = /home/libdodbc.so //dm数据库驱动
[root@bogon nginx]# ldd /home/libdodbc.so
linux-vdso.so.1 => (0x00007fffa6103000)
libdmdpi.so => not found
libdmfldr.so => not found
librt.so.1 => /lib64/librt.so.1 (0x00007fe48fbdf000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe48f9c3000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe48f7be000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fe48f4b6000)
libm.so.6 => /lib64/libm.so.6 (0x00007fe48f1b4000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe48ede5000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe48ebcf000)
/lib64/ld-linux-x86-64.so.2 (0x00005609cf20a000)
如果本机未安装dm数据库驱动,libdodbc.so文件及其依赖链接文件libdmfldr.so,libdmdpi.so可以从达梦所在服务器复制过来,并且配置动态链接库加载路径。在/etc/profile中追加内容
export LD_LIBRARY_PATH=/usr/local/lib
[root@bogon nginx]# vim /etc/profile
[root@bogon nginx]# source /etc/profile
将libdmfldr.so,libdmdpi.so文件拷贝到动态链接库加载路径下。
另外在DM8中,加密模块已不在libdodbc.so中,需要将动态链接库libcrypt.so拷贝到本机目录/usr/lib64或者手动创建软链接。
[root@localhost home]# pwd
/home
[root@localhost home]# ls
libdodbc.so
[root@localhost lib64]# ls -l /usr/lib64/libcrypt.so
lrwxrwxrwx. 1 root root 25 Mar 30 21:31 /usr/lib64/libcrypt.so -> ../../lib64/libcrypt.so.1
再次通过ldd工具查看libdodbc.so依赖动态库
[root@localhost home]# ldd libdodbc.so
linux-vdso.so.1 => (0x00007ffd003c4000)
libdmdpi.so => ./libdmdpi.so (0x00007f7609512000)
libdmfldr.so => ./libdmfldr.so (0x00007f76091f5000)
librt.so.1 => /lib64/librt.so.1 (0x00007f7608fe7000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7608dcb000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f7608bc6000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f76088be000)
libm.so.6 => /lib64/libm.so.6 (0x00007f76085bc000)
libc.so.6 => /lib64/libc.so.6 (0x00007f76081ed000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f7607fd7000)
/lib64/ld-linux-x86-64.so.2 (0x000055f54d7aa000)
如果没有not found,进行下一步;找不到则继续从服务器上copy;
5.ODBC连接达梦数据库
执行isql -v dm8,其中 -v 参数可查看执行失败的报错信息
[root@localhost lib64]# isql -v dm8
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL>
连接成功!
3.安装LuaSQL
1.下载源码
Lua Github 源码地址:GitHub - lunarmodules/luasql: LuaSQL is a simple interface from Lua to a DBMS.
2.修改配置文件
解压进入目录
[root@localhost opt]# unzip luasql-master.zip
[root@localhost opt]# cd luasql-master
[root@localhost luasql-master]# ls
config Makefile Makefile.win Makefile.win.firebird Makefile.win.odbc README src vc6
doc Makefile.mingw Makefile.win.ado Makefile.win.mysql Makefile.win.sqlite3 rockspec tests
修改配置文件config
[root@localhost luasql-master]# cat config
# Installation directories
# Default prefix
PREFIX ?=/usr/local/openresty/luajit //前缀
# Lua version and dirs
LUA_SYS_VER ?= 5.1
LUA_LIBDIR ?= $(PREFIX)/lib //lua链接库
LUA_DIR ?= $(PREFIX)/bin //lua命令参数
LUA_INC ?= $(PREFIX)/include //lua头文件所在目录
# OS dependent
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin) # MacOS
LIB_OPTION ?= -bundle -undefined dynamic_lookup -mmacosx-version-min=10.3
else # Linux/BSD
LIB_OPTION ?= -shared
endif
# - ODBC
DRIVER_LIBS_odbc ?= -L/usr/local/lib -lodbc //odbc动态链接库
DRIVER_INCS_odbc ?= -DUNIXODBC -I/usr/local/include //c头文件目录
# general compilation parameters
WARN= -fPIC $(OPTFLAGS) -Wmissing-prototypes -Wmissing-declarations -ansi -pedantic
INCS = -I$(LUA_INC)
DEFS = -std=gnu99 -fPIC
CFLAGS=$(WARN) $(DRIVER_INCS) $(INCS) -DLUASQL_VERSION_NUMBER='"$V"' $(DEFS)
CC= gcc
仅需要找到对应的数据库修改参数,这里其他数据库参数我删掉了。
本文采用的编译器为集成在openresty中的luajit,因此填写相关安装目录,如果安装的是Lua则相关参数配置可以用whereis lua查找,odbc相关参数如果按上述步骤安装的跟我一样即可。
修改完成后保存退出。
3.生成C程序库
[root@localhost luasql-master]# make odbc install
make: Nothing to be done for `odbc'.
mkdir -p /usr/local/openresty/luajit/lib/luasql
cp src/*.so /usr/local/openresty/luajit/lib/luasql
执行安装命令,生成C 程序库odbc.so文件至相应目录。
4.lua连接达梦数据库
1.编写脚本
编写lua脚本如下,关于luasql数据库api可在安装包的doc文档中查询
local luasql = require "luasql.odbc"
env = luasql.odbc()
con = assert(env:connect ("DM8",--配置odbc的dsn /usr/local/etc/odbc.ini
"SYSDBA", --用户名
"SYSDBA")) --密码
cur = con:execute ("SELECT NAME FROM SYSDBA.TEST1")
row = cur:fetch ({}, "a")
while row do
for k,v in pairs(row) do
ngx.say(v)
end
row=cur:fetch (row, "a")
end
cur:close()
con:close()
env:close()
执行脚本,查看报错信息。
2023/03/31 04:57:25 [error] 81313#0: *1 lua entry thread aborted: runtime error: /usr/local/openresty/nginx/cache_dm.lua:1: module 'luasql.odbc' not found:
no field package.preload['luasql.odbc']
no file '/usr/local/openresty/site/lualib/luasql/odbc.ljbc'
no file '/usr/local/openresty/site/lualib/luasql/odbc/init.ljbc'
no file '/usr/local/openresty/lualib/luasql/odbc.ljbc'
no file '/usr/local/openresty/lualib/luasql/odbc/init.ljbc'
no file '/usr/local/openresty/site/lualib/luasql/odbc.lua'
no file '/usr/local/openresty/site/lualib/luasql/odbc/init.lua'
no file '/usr/local/openresty/lualib/luasql/odbc.lua'
no file '/usr/local/openresty/lualib/luasql/odbc/init.lua'
no file './luasql/odbc.lua'
no file '/usr/local/openresty/luajit/share/luajit-2.1.0-beta3/luasql/odbc.lua'
no file '/usr/local/share/lua/5.1/luasql/odbc.lua'
no file '/usr/local/share/lua/5.1/luasql/odbc/init.lua'
no file '/usr/local/openresty/luajit/share/lua/5.1/luasql/odbc.lua'
no file '/usr/local/openresty/luajit/share/lua/5.1/luasql/odbc/init.lua'
no file '/usr/local/openresty/site/lualib/luasql/odbc.so'
no file '/usr/local/openresty/lualib/luasql/odbc.so'
no file './luasql/odbc.so'
no file '/usr/local/lib/lua/5.1/luasql/odbc.so'
no file '/usr/local/openresty/luajit/lib/lua/5.1/luasql/odbc.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
no file '/usr/local/openresty/site/lualib/luasql.so'
no file '/usr/local/openresty/lualib/luasql.so'
no file './luasql.so'
no file '/usr/local/lib/lua/5.1/luasql.so'
no file '/usr/local/openresty/luajit/lib/lua/5.1/luasql.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
基本意思就是在指定路径下找不到对应文件~~
2.Lua模块加载机制
Lua模块文件不是放在哪个文件目录都行,函数 require 有它自己的文件路径加载策略,它会尝试从 Lua 文件或 C 程序库中加载模块。
require 用于搜索 Lua 文件的路径是存放在全局变量 package.path 中,当 Lua 启动后,会以环境变量 LUA_PATH 的值来初始这个环境变量。如果没有找到该环境变量,则使用一个编译时定义的默认路径来初始化。默认路径可以打印出来查看:
[root@localhost nginx]# /usr/bin/lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print(package.path)
./?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib64/lua/5.1/?.lua;/usr/lib64/lua/5.1/?/init.lua
如果找过目标文件,则会调用 package.loadfile 来加载模块。否则,就会去找 C 程序库。
搜索的文件路径是从全局变量 package.cpath 获取,而这个变量则是通过环境变量 LUA_CPATH 来初始。
[root@localhost nginx]# /usr/bin/lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print(package.cpath)
./?.so;/usr/lib64/lua/5.1/?.so;/usr/lib64/lua/5.1/loadall.so
搜索的策略跟上面的一样,只不过现在换成搜索的是 so 或 dll 类型的文件。如果找得到,那么 require 就会通过 package.loadlib 来加载它。
因此上面的错误是因为没有在指定路径找到我们安装好的odbc.so文件。只要把它拷贝到查找C程序库的第一个路径下即可。
[root@bogon nginx]# find / -name odbc.so
/usr/local/openresty/luajit/lib/luasql/odbc.so
[root@bogon nginx]# cp /usr/local/openresty/luajit/lib/luasql/odbc.so /usr/local/openresty/site/lualib/luasql/
再次执行脚本,成功访问到数据库~~
[root@bogon nginx]# curl http://127.0.0.1:14001
sjw_in_SADASD
xsq
lhx