/usr/lib/prosody/modules/storage/sqlbasic.lib.lua is in prosody 0.9.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | -- Basic SQL driver
-- This driver stores data as simple key-values
local ser = require "util.serialization".serialize;
local envload = require "util.envload".envload;
local deser = function(data)
module:log("debug", "deser: %s", tostring(data));
if not data then return nil; end
local f = envload("return "..data, nil, {});
if not f then return nil; end
local s, d = pcall(f);
if not s then return nil; end
return d;
end;
local driver = {};
driver.__index = driver;
driver.item_table = "item";
driver.list_table = "list";
function driver:prepare(sql)
module:log("debug", "query: %s", sql);
local err;
if not self.sqlcache then self.sqlcache = {}; end
local r = self.sqlcache[sql];
if r then return r; end
r, err = self.connection:prepare(sql);
if not r then error("Unable to prepare SQL statement: "..err); end
self.sqlcache[sql] = r;
return r;
end
function driver:load(username, host, datastore)
local select = self:prepare("select data from "..self.item_table.." where username=? and host=? and datastore=?");
select:execute(username, host, datastore);
local row = select:fetch();
return row and deser(row[1]) or nil;
end
function driver:store(username, host, datastore, data)
if not data or next(data) == nil then
local delete = self:prepare("delete from "..self.item_table.." where username=? and host=? and datastore=?");
delete:execute(username, host, datastore);
return true;
else
local d = self:load(username, host, datastore);
if d then -- update
local update = self:prepare("update "..self.item_table.." set data=? where username=? and host=? and datastore=?");
return update:execute(ser(data), username, host, datastore);
else -- insert
local insert = self:prepare("insert into "..self.item_table.." values (?, ?, ?, ?)");
return insert:execute(username, host, datastore, ser(data));
end
end
end
function driver:list_append(username, host, datastore, data)
if not data then return; end
local insert = self:prepare("insert into "..self.list_table.." values (?, ?, ?, ?)");
return insert:execute(username, host, datastore, ser(data));
end
function driver:list_store(username, host, datastore, data)
-- remove existing data
local delete = self:prepare("delete from "..self.list_table.." where username=? and host=? and datastore=?");
delete:execute(username, host, datastore);
if data and next(data) ~= nil then
-- add data
for _, d in ipairs(data) do
self:list_append(username, host, datastore, ser(d));
end
end
return true;
end
function driver:list_load(username, host, datastore)
local select = self:prepare("select data from "..self.list_table.." where username=? and host=? and datastore=?");
select:execute(username, host, datastore);
local r = {};
for row in select:rows() do
table.insert(r, deser(row[1]));
end
return r;
end
local _M = {};
function _M.new(dbtype, dbname, ...)
local d = {};
setmetatable(d, driver);
local dbh = get_database(dbtype, dbname, ...);
--d:set_connection(dbh);
d.connection = dbh;
return d;
end
return _M;
|