lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I am currently working on making the Lua PostgreSQL interface more user friendly, more Lua-ish, and I would appreciate comments...

TL;DR:  I am (ab)using the __call metamethod to "explode" a result set into a nested Lua table structure, is that a good idea?

Consider the following database access, the result of which needs to be stored in a table structure at p.acct:

	local res = db:exec([[
	SELECT
		account as account_nr,
		act_account.name as account,
		act_account.aclass as class_nr,
		act_account.agroup as group_nr,
		act_account.asgroup as subgroup_nr,
		act_class.cname as class,
		act_group.gname as group,
		act_subgroup.sgname as subgroup
	FROM
		act_account
                -- details ommitted...
	]])
	pgassertTuples(res)
	p.aclass = ''

	p.acct = {}
	for n = 1, res:ntuples() do
		p.acct[n] = {
			account_nr = res:getvalue(n, 1),
			account = res:getvalue(n, 2),
			class_nr = res:getvalue(n, 3),
			group_nr = res:getvalue(n, 4),
			subgroup_nr = res:getvalue(n, 5),
			class = res:getvalue(n, 6),
			group = res:getvalue(n, 7),
			subgroup = res:getvalue(n, 8)
		}
	end

In a first step I added an interator "tuples" to the result set, so this code can be rewritten as

	p.acct = {}
	for tuple, row in  res:tuples() do
		p.acct[row] = {
			account_nr = tuple:getvalue(1),
			account = tuple:getvalue(2),
			class_nr = tuple:getvalue(3),
			group_nr = tuple:getvalue(4),
			subgroup_nr = tuple:getvalue(5),
			class = tuple:getvalue(6),
			group = tuple:getvalue(7),
			subgroup = tuple:getvalue(8)
		}
	end

The iterator sets a metatable on the returned tuple to define the __index metamethod for direct field access, so it can be further simplified:

	p.acct = {}
	for tuple, row in  res:tuples() do
		p.acct[row] = {
			account_nr = tuple.account_nr,
			account = tuple.account,
			class_nr = tuple.class_nr,
			group_nr = tuple.group_nr,
			subgroup_nr = tuple.subgroup_nr,
			class = tuple.class,
			group = tuple.group,
			subgroup = tuple.subgroup
		}
	end

In the last step I added the __call metamethod to result set, to create the nested table structure in one single call

	p.acct = res()

Is that to much of an abuse?  What I am loosing here is the information about SQL NULL values, but to determine that I can still use the older interface, if needed (or figure out a smarter way...)

- mb