[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Making the use of luapgsql more "Lua-ish"
- From: Marc Balmer <marc@...>
- Date: Wed, 23 Dec 2015 15:20:21 +0100
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