存档

文章标签 ‘LUA’

PostgreSQL and Lua

2012年2月16日 16hot 没有评论

Today was the third meeting of the OrlandoPg Meetup group that I host. A member Steven wanted to talk about how he could interact with PostgreSQL using Lua. I informed the group about PostgreSQL’s architecture that allows stored procedures to be written in nearly any programming language. We also talked about how pretty much every language I can think of has a database interaction library of some sort.

That led to some quick googling and we spent the rest of the meeting in a coding dojo like environment to see if we could set up and work with PL/Lua and luasql-postgres. This post will detail how to set up the environment, create a simple stored procedure in PL/Lua, and write a program using the luasql-postgres package or “rock”.

The set up: I’m using a mac for development. OS 10.6.6 to be exact.

To install the Lua programming language I used Mac-Ports.
“sudo port install luarocks +curl openssl”

is the command I used. I actually already had lua installed, so I just installed the luarocks package manager. If you do not have lua installed, this command will install it as well.

Next I needed to get the lua package (rock) luasql-postgres.
“sudo luarocks install –from=http://luarocks.org/repositories/rocks-cvs/ luasql-postgres POSTGRES_DIR=/usr/local/pgsql”

makes that happen. This assumes you already have PostgreSQL installed. If you don’t use macports to install that and adjust your POSTGRES_DIR accordingly. I always install PostgreSQL from source myself.

Next we need to get the PL/Lua extension for PostgreSQL. It can be downloaded from: PgFoundry Once you have it un-tar it and edit the Makefile. Adjust the lines:

LUAINC = -I/opt/local/include

LUALIB = -L/opt/local/lib -llua

Save the file the run
“sudo make && make install”

You now need to install the language into your database. Head over to your contrib directory, mine is:

“/usr/local/pgsql/share/contrib/”
and run

“psql -f pllua.sql DATABASENAME”.

This registers the language handler within your database.

Now you can create a stored procedure using Lua. Example:

create or replace function hello(_name text) returns text as
$$
return string.format(“Hello, %s!”, _name)
$$ Language pllua;

Now you can create a simple lua script to call this function. Example:

require “luasql.postgres”

env = assert ( luasql.postgres() )

con = assert ( env:connect( “DBNAME”,”USERNAME”,”PASS”,”DBHOST” ) )

cur = assert ( con:execute( “SELECT * FROM hello(‘World!’);” ) )

row = assert ( cur:fetch() )

print(row)

One non-standard thing I had to do to get this script to “see” the luasql.postgres extension was to make a symlink:

“sudo ln -s /opt/local/var/luarocks/lib/lua/5.1/luasql/postgres.so /opt/local/lib/lua/5.1/luasql.so”

This is necessary because MacPorts and LuaRocks are not really working together.

You can execute the lua script with the command “”lua SCRIPTNAME” and get the expected output of:

References:

http://www.nessie.de/mroth/lunit/

http://www.lua.org/manual/5.1/manual.html

http://pllua.projects.postgresql.org/

http://www.keplerproject.org/luasql/index.html

分类: LUA, Mac OSX, MacOSX, PostgreSQL 标签: , ,

lua日期与时间操作

2011年12月20日 16hot 没有评论

os.time() <== 返回当前系统的日历时间
os.date() <== 返回本地化的时间字符串,这里是”11/28/08 17:23:37″
os.date(“%x”, os.time()) <== 返回自定义格式化时间字符串(完整的格式化参数),这里是”11/28/08″
os.clock() <== 返回执行该程序CPU花去的时钟秒数,这里是1156.726
附录
完整的格式化参数
这些时间输出的字符串表示是经过本地化的。所以如果是在巴西(葡萄牙语系),”%B” 得到的就是 “setembro”(译者按:大概是葡萄牙语九月?),”%x” 得到的就是 “16/09/98″(月日次序不同)。标记的意义和显示实例总结如下表。实例的时间是在1998年九月16日,星期三,23:48:10。返回值为数字形式的还列出了它们的范围。(都是按照英语系的显示描述的,也比较简单,就不烦了)
%a abbreviated weekday name (e.g., Wed)
%A full weekday name (e.g., Wednesday)
%b abbreviated month name (e.g., Sep)
%B full month name (e.g., September)
%c date and time (e.g., 09/16/98 23:48:10)
%d day of the month (16) [01-31]
%H hour, using a 24-hour clock (23) [00-23]
%I hour, using a 12-hour clock (11) [01-12]
%M minute (48) [00-59]
%m month (09) [01-12]
%p either “am” or “pm” (pm)
%S second (10) [00-61]
%w weekday (3) [0-6 = Sunday-Saturday]
%x date (e.g., 09/16/98)
%X time (e.g., 23:48:10)
%Y full year (1998)
%y two-digit year (98) [00-99]
%% the character ‘%’
事实上如果不使用任何参数就调用date,就是以%c的形式输出。这样就是得到经过格式化的完整时间信息。
注意%x、%X和%c由所在地区和计算机系统的改变会发生变化。
如果该字符串要确定下来(例如确定为mm/dd/yyyy),可以使用明确的字符串格式方式(例如”%m/%d/%Y”)。

分类: LUA 标签:

LUA中的字符串函数库

2011年12月20日 16hot 没有评论

Lua解释器对字符串的支持很有限。一个程序可以创建字符串并连接字符串,但不能截取子串,检查字符串的大小,检测字符串的内容。在Lua中操纵字符串的功能基本来自于string库。

字符串库中的一些函数是非常简单的:

string.len(s) 返回字符串s的长度;
string.rep(s, n) 返回重复n次字符串s的串;你使用string.rep(“a”, 2^20)可以创建一个1M bytes的字符串(比如,为了测试需要);
string.lower(s) 将s中的大写字母转换成小写(string.upper将小写转换成大写)。如果你想不关心大小写对一个数组进行排序的话,你可以这样:
table.sort(a, function (a, b) return string.lower(a) < string.lower(b) end)
string.upper(s) 将s中的小写字母转换成大写
string.upper和string.lower都依赖于本地环境变量。所以,如果你在 European Latin-1环境下,表达式:
string.upper("a??o") --> “A??O”
string.sub(s,i,j) 函数截取字符串s的从第i个字符到第j个字符之间的串。Lua中,字符串的第一个字符索引从1开始。你也可以使用负索引,负索引从字符串的结尾向前计数:-1指向最后一个字符,-2指向倒数第二个,以此类推。所以, string.sub(s, 1, j)返回字符串s的长度为j的前缀;string.sub(s, j, -1)返回从第j个字符开始的后缀。如果不提供第3个参数,默认为-1,因此我们将最后一个调用写为string.sub(s, j);string.sub(s, 2, -2)返回去除第一个和最后一个字符后的子串。
s = “[in brackets]”
print(string.sub(s, 2, -2)) –> in brackets
记住:Lua中的字符串是恒定不变的。string.sub函数以及Lua中其他的字符串操作函数都不会改变字符串的值,而是返回一个新的字符串。一个常见的错误是:
string.sub(s, 2, -2)
认为上面的这个函数会改变字符串s的值。如果你想修改一个字符串变量的值,你必须将变量赋给一个新的字符串:
s = string.sub(s, 2, -2)
string.char函数和string.byte函数用来将字符在字符和数字之间转换。string.char获取0个或多个整数,将每一个数字转换成字符,然后返回一个所有这些字符连接起来的字符串。string.byte(s, i)将字符串s的第i个字符的转换成整数;第二个参数是可选的,缺省情况下i=1。下面的例子中,我们假定字符用ASCII表示:

print(string.char(97)) –> a
i = 99; print(string.char(i, i+1, i+2)) –> cde
print(string.byte(“abc”)) –> 97
print(string.byte(“abc”, 2)) –> 98
print(string.byte(“abc”, -1)) –> 99

上面最后一行,我们使用负数索引访问字符串的最后一个字符。
Lua提供了string.format()函数来生成具有特定格式的字符串, 函数的第一个参数是格式(formatstring), 之后是对应格式中每个代号的各种数据. 由于格式字符串的存在, 使得产生的长字符串可读性大大提高了. 这个函数的格式很像C语言中的printf().函数string.format在用来对字符串进行格式化的时候,特别是字符串输出,是功能强大的工具。这个函数有两个参数,你完全可以照C语言的printf来使用这个函数。第一个参数为格式化串:由指示符和控制格式的字符组成。指示符后的控制格式的字符可以为:十进制’d';十六进制’x';八进制’o';浮点数’f';字符串’s'。在指示符’%'和控制格式字符之间还可以有其他的选项:用来控制更详细的格式,比如一个浮点数的小数的位数:
格式字符串可能包含以下的转义码:
%c – 接受一个数字, 并将其转化为ASCII码表中对应的字符
%d, %i – 接受一个数字并将其转化为有符号的整数格式
%o – 接受一个数字并将其转化为八进制数格式
%u – 接受一个数字并将其转化为无符号整数格式
%x – 接受一个数字并将其转化为十六进制数格式, 使用小写字母
%X – 接受一个数字并将其转化为十六进制数格式, 使用大写字母
%e – 接受一个数字并将其转化为科学记数法格式, 使用小写字母e
%E – 接受一个数字并将其转化为科学记数法格式, 使用大写字母E
%f – 接受一个数字并将其转化为浮点数格式
%g(%G) – 接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式
%q – 接受一个字符串并将其转化为可安全被Lua编译器读入的格式
%s – 接受一个字符串并按照给定的参数格式化该字符串
为进一步细化格式, 可以在%号后添加参数. 参数将以如下的顺序读入:
(1) 符号: 一个+号表示其后的数字转义符将让正数显示正号. 默认情况下只有负数显示符号.
(2) 占位符: 一个0, 在后面指定了字串宽度时占位用. 不填时的默认占位符是空格.
(3) 对齐标识: 在指定了字串宽度时, 默认为右对齐, 增加-号可以改为左对齐.
(4) 宽度数值
(5) 小数位数/字串裁切: 在宽度数值后增加的小数部分n, 若后接f(浮点数转义符, 如%6.3f)则设定该浮点数的小数只保留n位, 若后接s(字符串转义符, 如%5.3s)则设定该字符串只显示前n位.
在这些参数的后面则是上述所列的转义码类型(c, d, i, f, …).

print(string.format(“pi = %.4f”, PI))
–> pi = 3.1416
d = 5; m = 11; y = 1990
print(string.format(“%02d/%02d/%04d”, d, m, y))
–> 05/11/1990
tag, title = “h1″, “a title”
print(string.format(“<%s>%s“, tag, title, tag))
–>

a title

第一个例子,%.4f代表小数点后面有4位小数的浮点数。第二个例子%02d代表以固定的两位显示十进制数,不足的前面补0。而%2d前面没有指定0,不足两位时会以空白补足。对于格式串部分指示符得详细描述清参考lua手册,或者参考C手册,因为Lua调用标准C的printf函数来实现最终的功能。

以下是一些例子:

string.format(“%%c: %c”, 83) 输出S
string.format(“%+d”, 17.0) 输出+17
string.format(“%05d”, 17) 输出00017
string.format(“%o”, 17) 输出21
string.format(“%u”, 3.14) 输出3
string.format(“%x”, 13) 输出d
string.format(“%X”, 13) 输出D
string.format(“%e”, 1000) 输出1.000000e+03
string.format(“%E”, 1000) 输出1.000000E+03
string.format(“%6.3f”, 13) 输出13.000
string.format(“%q”, “One\nTwo”) 输出”One\
  Two”
string.format(“%s”, “monkey”) 输出monkey
string.format(“%10s”, “monkey”) 输出 monkey
string.format(“%5.3s”, “monkey”) 输出 mon

分类: LUA, 转载 标签:

解决FreeBSD下编译LuaJIT的问题

2011年10月29日 16hot 没有评论

在FreeBSD下编译LuaJIT时,报如下错误:

CC lj_err.o
lj_err.c:189:20: error: unwind.h: No such file or directory
lj_err.c:199: error: expected declaration specifiers or '...' before '_Unwind_Action'
lj_err.c:200: error: expected declaration specifiers or '...' before '_Unwind_Exception_Class'
lj_err.c:201: warning: 'struct _Unwind_Context' declared inside parameter list
lj_err.c:201: warning: its scope is only this definition or declaration, which is probably not what you want
lj_err.c:201: warning: 'struct _Unwind_Exception' declared inside parameter list
lj_err.c: In function 'lj_err_unwind_dwarf':
lj_err.c:206: error: '_URC_FATAL_PHASE1_ERROR' undeclared (first use in this function)
lj_err.c:206: error: (Each undeclared identifier is reported only once
lj_err.c:206: error: for each function it appears in.)
lj_err.c:207: error: 'uexclass' undeclared (first use in this function)
lj_err.c:208: warning: implicit declaration of function '_Unwind_GetCFA'
lj_err.c:208: warning: cast to pointer from integer of different size
lj_err.c:210: error: 'actions' undeclared (first use in this function)
lj_err.c:210: error: '_UA_SEARCH_PHASE' undeclared (first use in this function)
lj_err.c:213: error: '_URC_CONTINUE_UNWIND' undeclared (first use in this function)
lj_err.c:218: error: '_URC_HANDLER_FOUND' undeclared (first use in this function)
lj_err.c:220: error: '_UA_CLEANUP_PHASE' undeclared (first use in this function)
lj_err.c:225: error: '_UA_HANDLER_FRAME' undeclared (first use in this function)
lj_err.c:226: warning: implicit declaration of function '_Unwind_DeleteException'
lj_err.c:231: error: '_UA_FORCE_UNWIND' undeclared (first use in this function)
lj_err.c:234: warning: implicit declaration of function '_Unwind_SetGR'
lj_err.c:235: warning: implicit declaration of function '_Unwind_SetIP'
lj_err.c:235: error: '_Unwind_Ptr' undeclared (first use in this function)
lj_err.c:238: error: '_URC_INSTALL_CONTEXT' undeclared (first use in this function)
lj_err.c:246: error: expected ')' before 'lj_vm_unwind_rethrow'
lj_err.c: In function 'err_raise_ext':
lj_err.c:271: error: invalid use of undefined type 'struct _Unwind_Exception'
lj_err.c:271: error: '_Unwind_Exception_Class' undeclared (first use in this function)
lj_err.c:272: error: invalid use of undefined type 'struct _Unwind_Exception'
lj_err.c:273: warning: implicit declaration of function '_Unwind_RaiseException'
gmake: *** [lj_err.o] 错误 1

只需要拷贝一个头文件,并且改名即可:

/usr/src/contrib/gcc/unwind-generic.h /usr/include/unwind.h

分类: BSD/linux, LUA 标签: , ,

用LUA做程序配置文件

2011年10月27日 16hot 没有评论

本来想用bison、flex来写一个配置文件的。但是看了看资料,不容易懂,而且也不灵活。还是放弃了。
后来想起了lua,现在流行用lua来做服务程序的配置文件。强大、灵活,而且与C可以紧密结合。

下面是C程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
 
/*
 * getcfg.c
 * cc -o getcfg getcfg.c -I/usr/local/include/lua51 -L/usr/local/lib/lua51 -llua -lm
 */
 
#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <stdio.h>
 
 
int
main(void)
{
    int status, result, ind;
	const char       *key, *value;
    double sum;
    lua_State *L;
 
    /*
     * All Lua contexts are held in this structure. We work with it almost
     * all the time.
     */
    L = luaL_newstate();
 
    luaL_openlibs(L); /* Load Lua libraries */
 
    /* Load the file containing the script we are going to run */
    if ( luaL_loadfile(L, "server.cfg") || lua_pcall(L, 0, 0, 0) ) {
        /* If something went wrong, error message is at the top of */
        /* the stack */
        fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));
		lua_pop(L, 1);
        exit(1);
    }
 
	lua_getglobal(L, "socket" );
	const char *socket = lua_tostring(L, -1);
 
	printf( "socket %s\n", lua_tostring(L, -1));
 
	lua_pop(L, 2);
 
	lua_getglobal(L, "servers"); 
 
	if (!lua_istable(L, -1))
	{
		fprintf(stderr, "%s\n", lua_tostring(L, -1));
		lua_pop(L, 1); // remove the error-msg 
		return -1; 
	}
	ind = lua_gettop(L);
	printf( "index: %d\n", ind );
	lua_pushnil(L);	
	while (lua_next(L, -2) != 0)
	{
		/** 获取服务索引名 */
			key = lua_tostring(L, -2);
			printf( "key name: %s\n", key );
		if (lua_istable(L, -1))
		{
			ind = 1;
			lua_pushnil(L);
 
 
			while (lua_next(L, -2) != 0)
			{
				/** 获取服务配置 */
				key = lua_tostring(L, -2);
				if(strcmp("bin", key) == 0)
				{
					printf( "bin %s\n", lua_tostring(L, -1) );
				}
				else if(strcmp("pid", key) == 0)
				{
					printf( "pid %s\n", lua_tostring(L, -1) );
				}
				else if(strcmp("params", key) == 0)
				{
					printf( "params %s\n", lua_tostring(L, -1) );
				}
				else if(strcmp("config", key) == 0)
				{
					printf( "config %s\n", lua_tostring(L, -1) );
				}
			    else {
					printf("Unkonw key: %s\n", key );
				}
				lua_pop( L, 1 );
			}
 
		}
		lua_pop(L, 1); 
	}
 
 
    lua_close(L);   /* Cya, Lua */
 
    return 0;
}

下面是LUA代码:

1
2
3
4
5
6
7
8
9
10
11
12
 
daemon = false
 
socket = "/var/run/daemon-server.sock"
 
servers = {
	["phpd"] = { 
		pid = "/var/run/phpd.pid",
		bin = "/usr/local/sbin/phpd",
		delay = 300, 
	}
}
分类: C/C++, LUA 标签: ,

nginx + luafcgid 运行lua

2011年9月24日 16hot 没有评论

可以配置nginx和luafcgid来运行lua脚本WEB程序。

网站: https://github.com/STPeters/luafcgid

安装和配置都很简单,在该网站下载源码包回来,直接gmake 就可以编译了。前提是已经安装好fcgi-2.4.0。
nginx部分的配置也及其简单,基本照抄文档里的配置即可。
   location ~ \.lua$ {

	  # for BSD/Linux
      fastcgi_pass   unix:/var/tmp/luafcgid.sock;

	  fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      include        fastcgi_params;
   }
分类: BSD/linux, LUA 标签: ,

一颗璀璨的月光宝石–Lua(转)

2010年5月16日 16hot 没有评论

1993年在巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro in Brazil)诞生了一门编程语言,发明者是该校的三位研究人员,他们给这门语言取了个浪漫的名字——Lua,在葡萄牙语里代表美丽的月亮。事实证明她没 有糟蹋这个优美的单词,Lua语言正如它名字所预示的那样成长为一门简洁、优雅且富有乐趣的语言。

Lua从一开始就是作为一门方便嵌入(其它应用程序)并可扩展的轻量级脚本语言来设计的,因此她一直遵从着简单、小巧、可移植、快速的原则,官 方实现完全采用ANSI C编写,能以C程序库的形式嵌入到宿主程序中。Lua的每个版本都保持着开放源码的传统,不过各版采用的许可协议并不相同,自5.0版(最新版是5.1) 开始她采用的是著名的MIT许可协议。正由于上述特点,所以Lua在游戏开发、机器人控制、分布式应用、图像处理、生物信息学等各种各样的领域中得到了越 来越广泛的应用。其中尤以游戏开发为最,许多著名的游戏,比如Escape from Monkey Island、World of Warcraft、大话西游,都采用了Lua来配合引擎完成数据描述、配置管理和逻辑控制等任务。

作为一门过程型动态语言,Lua有着如下的特性:

1、变量名没有类型,值才有类型,变量名在运行时可与任何类型的值绑定;

2、语言只提供唯一一种数据结构,称为表(table),它类似key-value关联数组,可以用任何类型的值作为key和value。提供 了一致且富有表达力的表构造语法,使得Lua很适合描述复杂的数据;

3、函数是一等类型,支持匿名函数和正则尾递归(proper tail recursion);

4、支持词法定界(lexical scoping)和闭包(closure);

5、提供thread类型和结构化的协程(coroutine)机制,在此基础上可方便实现协作式多任务;

6、运行期能编译字符串形式的程序文本并载入虚拟机执行;

7、通过元表(metatable)和元方法(metamethod)提供动态元机制(dynamic meta-mechanism),从而允许程序运行时根据需要改变或扩充语法设施的内定语义;

8、能方便地利用表和动态元机制实现基于原型(prototype-based)的面向对象模型;

9、从5.1版开始提供了完善的模块机制,从而更好地支持开发大型的应用程序;

Lua的语法类似PASCAL和Modula但更加简洁,所有的语法产生式规则(EBNF)不过才60几个。熟悉C和PASCAL的程序员一般 只需半个小时便可将其完全掌握。而在语义上Lua则与Scheme极为相似,她们完全共享上述的1、3、4、6点特性, Scheme的continuation与协程也基本相同只是自由度更高。最引人注目的是,两种语言都只提供唯一一种数据结构:Lua的表和Scheme 的列表(list)。正因为如此,有人甚至称Lua为“只用表的Scheme”。 阅读全文…

分类: LUA, 转载 标签: