Integration Lua to psql III
I finished patch that integrates Lua language to psql client https://github.com/okbob/lua-psql I wrote two examples. Second is a wrapping
VACUUM command. Target is a more readable
output in verbose mode. One bonus is printing progress - any second the pg_stat_progress_vacuum
is selected and result is printed.
function vacuum(args)
local options = {}
local tables = {}
if args == "help" then
print "\\lua vacuum {verbose=true}"
return
end
if args then
local transfx = load("return " .. args)
options = transfx()
end
local query =
[[SELECT quote_ident(n.nspname) AS nspname,
quote_ident(c.relname) AS relname
FROM pg_class c, pg_namespace n
WHERE n.oid = c.relnamespace
AND n.nspname <> 'information_schema'
AND n.nspname !~ '^pg_toast'
AND c.relkind IN ('r','s','n')]]
local rs, err = psql.exec(query)
local data = rs:fetch()
while data do
table.insert(tables, { nspname = data.nspname, relname = data.relname } )
data = rs:fetch()
end
rs:clear()
local n = 0
local mycon = psql.connect():clone()
rs, err = mycon:exec("select pg_backend_pid()");
local data = rs:fetch()
local pid = data.pg_backend_pid
for _, tbl in ipairs(tables) do
if options.verbose then
print(string.format("\27[7mVACUUM %s.%s \27[27m", tbl.nspname, tbl.relname))
mycon:sendquery("vacuum verbose " .. tbl.nspname .. "." .. tbl.relname)
mycon:sendquery("select pg_sleep(20)")
else
print(tbl.nspname .. "." .. tbl.relname)
mycon:sendquery("vacuum " .. tbl.nspname .. "." .. tbl.relname)
end
mycon:consumeinput()
isbusy = mycon:isbusy()
while isbusy do
n = n + 1
if mycon:resultwait(1) == 0 then
rs, err = psql.connect():exec(string.format("SELECT * FROM pg_stat_progress_vacuum WHERE pid = %d", pid))
if err then
error(err)
end
data = rs:fetch()
if data then
io.write(string.format("\rphase: %s, blks total: %d, blks scanned: %d, indexes total: %d, indexes processed: %d\27[0K", data.phase, data.heap_blks_total, data.heap_blks_scanned, data.indexes_total, data.indexes_processed))
else
io.write(string.format("\r\27[0K"))
end
io.flush()
rs:clear()
else
io.write(string.format("\r\27[0K"))
io.flush()
end
mycon:consumeinput()
isbusy = mycon:isbusy()
end
rs, err = mycon:getresult()
-- second getresult is used to force call PQgetResult, that should to return null
-- in this case, error is expected (not raised)
mycon:getresult()
if err then
print(err)
end
end
mycon:close()
end
Usage:
\luafile ~/vacuum.lua
\lua vacuum {verbose=true}

0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home