aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/storage
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/storage')
-rw-r--r--plugins/storage/ejabberd_init.lib.lua252
-rw-r--r--plugins/storage/ejabberdstore.lib.lua190
-rw-r--r--plugins/storage/mod_xep0227.lua4
-rw-r--r--plugins/storage/sqlbasic.lib.lua97
-rw-r--r--plugins/storage/xmlparse.lib.lua56
5 files changed, 2 insertions, 597 deletions
diff --git a/plugins/storage/ejabberd_init.lib.lua b/plugins/storage/ejabberd_init.lib.lua
deleted file mode 100644
index 91f8563b..00000000
--- a/plugins/storage/ejabberd_init.lib.lua
+++ /dev/null
@@ -1,252 +0,0 @@
-
-local t_concat = table.concat;
-local t_insert = table.insert;
-local pairs = pairs;
-local DBI = require "DBI";
-
-local sqlite = true;
-local q = {};
-
-local function set(key, val)
--- t_insert(q, "SET "..key.."="..val..";\n")
-end
-local function create_table(name, fields)
- t_insert(q, "CREATE TABLE ".."IF NOT EXISTS "..name.." (\n");
- for _, field in pairs(fields) do
- t_insert(q, "\t");
- field = t_concat(field, " ");
- if sqlite then
- if field:lower():match("^primary key *%(") then field = field:gsub("%(%d+%)", ""); end
- end
- t_insert(q, field);
- if _ ~= #fields then t_insert(q, ",\n"); end
- t_insert(q, "\n");
- end
- if sqlite then
- t_insert(q, ");\n");
- else
- t_insert(q, ") CHARACTER SET utf8;\n");
- end
-end
-local function create_index(name, index)
- --t_insert(q, "CREATE INDEX "..name.." ON "..index..";\n");
-end
-local function create_unique_index(name, index)
- --t_insert(q, "CREATE UNIQUE INDEX "..name.." ON "..index..";\n");
-end
-local function insert(target, value)
- t_insert(q, "INSERT INTO "..target.."\nVALUES "..value..";\n");
-end
-local function foreign_key(name, fkey, fname, fcol)
- t_insert(q, "ALTER TABLE `"..name.."` ADD FOREIGN KEY (`"..fkey.."`) REFERENCES `"..fname.."` (`"..fcol.."`) ON DELETE CASCADE;\n");
-end
-
-function build_query()
- q = {};
- set('table_type', 'InnoDB');
- create_table('hosts', {
- {'clusterid','integer','NOT','NULL'};
- {'host','varchar(250)','NOT','NULL','PRIMARY','KEY'};
- {'config','text','NOT','NULL'};
- });
- insert("hosts (clusterid, host, config)", "(1, 'localhost', '')");
- create_table('users', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'password','text','NOT','NULL'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host, username)'};
- });
- create_table('last', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'seconds','text','NOT','NULL'};
- {'state','text','NOT','NULL'};
- {'PRIMARY','KEY','(host, username)'};
- });
- create_table('rosterusers', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'jid','varchar(250)','NOT','NULL'};
- {'nick','text','NOT','NULL'};
- {'subscription','character(1)','NOT','NULL'};
- {'ask','character(1)','NOT','NULL'};
- {'askmessage','text','NOT','NULL'};
- {'server','character(1)','NOT','NULL'};
- {'subscribe','text','NOT','NULL'};
- {'type','text'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host(75), username(75), jid(75))'};
- });
- create_index('i_rosteru_username', 'rosterusers(username)');
- create_index('i_rosteru_jid', 'rosterusers(jid)');
- create_table('rostergroups', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'jid','varchar(250)','NOT','NULL'};
- {'grp','text','NOT','NULL'};
- {'PRIMARY','KEY','(host(75), username(75), jid(75))'};
- });
- --[[create_table('spool', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'xml','text','NOT','NULL'};
- {'seq','BIGINT','UNSIGNED','NOT','NULL','AUTO_INCREMENT','UNIQUE'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host, username, seq)'};
- });]]
- create_table('vcard', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'vcard','text','NOT','NULL'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host, username)'};
- });
- create_table('vcard_search', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'lusername','varchar(250)','NOT','NULL'};
- {'fn','text','NOT','NULL'};
- {'lfn','varchar(250)','NOT','NULL'};
- {'family','text','NOT','NULL'};
- {'lfamily','varchar(250)','NOT','NULL'};
- {'given','text','NOT','NULL'};
- {'lgiven','varchar(250)','NOT','NULL'};
- {'middle','text','NOT','NULL'};
- {'lmiddle','varchar(250)','NOT','NULL'};
- {'nickname','text','NOT','NULL'};
- {'lnickname','varchar(250)','NOT','NULL'};
- {'bday','text','NOT','NULL'};
- {'lbday','varchar(250)','NOT','NULL'};
- {'ctry','text','NOT','NULL'};
- {'lctry','varchar(250)','NOT','NULL'};
- {'locality','text','NOT','NULL'};
- {'llocality','varchar(250)','NOT','NULL'};
- {'email','text','NOT','NULL'};
- {'lemail','varchar(250)','NOT','NULL'};
- {'orgname','text','NOT','NULL'};
- {'lorgname','varchar(250)','NOT','NULL'};
- {'orgunit','text','NOT','NULL'};
- {'lorgunit','varchar(250)','NOT','NULL'};
- {'PRIMARY','KEY','(host, lusername)'};
- });
- create_index('i_vcard_search_lfn ', 'vcard_search(lfn)');
- create_index('i_vcard_search_lfamily ', 'vcard_search(lfamily)');
- create_index('i_vcard_search_lgiven ', 'vcard_search(lgiven)');
- create_index('i_vcard_search_lmiddle ', 'vcard_search(lmiddle)');
- create_index('i_vcard_search_lnickname', 'vcard_search(lnickname)');
- create_index('i_vcard_search_lbday ', 'vcard_search(lbday)');
- create_index('i_vcard_search_lctry ', 'vcard_search(lctry)');
- create_index('i_vcard_search_llocality', 'vcard_search(llocality)');
- create_index('i_vcard_search_lemail ', 'vcard_search(lemail)');
- create_index('i_vcard_search_lorgname ', 'vcard_search(lorgname)');
- create_index('i_vcard_search_lorgunit ', 'vcard_search(lorgunit)');
- create_table('privacy_default_list', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)'};
- {'name','varchar(250)','NOT','NULL'};
- {'PRIMARY','KEY','(host, username)'};
- });
- --[[create_table('privacy_list', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'name','varchar(250)','NOT','NULL'};
- {'id','BIGINT','UNSIGNED','NOT','NULL','AUTO_INCREMENT','UNIQUE'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host, username, name)'};
- });]]
- create_table('privacy_list_data', {
- {'id','bigint'};
- {'t','character(1)','NOT','NULL'};
- {'value','text','NOT','NULL'};
- {'action','character(1)','NOT','NULL'};
- {'ord','NUMERIC','NOT','NULL'};
- {'match_all','boolean','NOT','NULL'};
- {'match_iq','boolean','NOT','NULL'};
- {'match_message','boolean','NOT','NULL'};
- {'match_presence_in','boolean','NOT','NULL'};
- {'match_presence_out','boolean','NOT','NULL'};
- });
- create_table('private_storage', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'namespace','varchar(250)','NOT','NULL'};
- {'data','text','NOT','NULL'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host(75), username(75), namespace(75))'};
- });
- create_index('i_private_storage_username USING BTREE', 'private_storage(username)');
- create_table('roster_version', {
- {'username','varchar(250)','PRIMARY','KEY'};
- {'version','text','NOT','NULL'};
- });
- --[[create_table('pubsub_node', {
- {'host','text'};
- {'node','text'};
- {'parent','text'};
- {'type','text'};
- {'nodeid','bigint','auto_increment','primary','key'};
- });
- create_index('i_pubsub_node_parent', 'pubsub_node(parent(120))');
- create_unique_index('i_pubsub_node_tuple', 'pubsub_node(host(20), node(120))');
- create_table('pubsub_node_option', {
- {'nodeid','bigint'};
- {'name','text'};
- {'val','text'};
- });
- create_index('i_pubsub_node_option_nodeid', 'pubsub_node_option(nodeid)');
- foreign_key('pubsub_node_option', 'nodeid', 'pubsub_node', 'nodeid');
- create_table('pubsub_node_owner', {
- {'nodeid','bigint'};
- {'owner','text'};
- });
- create_index('i_pubsub_node_owner_nodeid', 'pubsub_node_owner(nodeid)');
- foreign_key('pubsub_node_owner', 'nodeid', 'pubsub_node', 'nodeid');
- create_table('pubsub_state', {
- {'nodeid','bigint'};
- {'jid','text'};
- {'affiliation','character(1)'};
- {'subscriptions','text'};
- {'stateid','bigint','auto_increment','primary','key'};
- });
- create_index('i_pubsub_state_jid', 'pubsub_state(jid(60))');
- create_unique_index('i_pubsub_state_tuple', 'pubsub_state(nodeid, jid(60))');
- foreign_key('pubsub_state', 'nodeid', 'pubsub_node', 'nodeid');
- create_table('pubsub_item', {
- {'nodeid','bigint'};
- {'itemid','text'};
- {'publisher','text'};
- {'creation','text'};
- {'modification','text'};
- {'payload','text'};
- });
- create_index('i_pubsub_item_itemid', 'pubsub_item(itemid(36))');
- create_unique_index('i_pubsub_item_tuple', 'pubsub_item(nodeid, itemid(36))');
- foreign_key('pubsub_item', 'nodeid', 'pubsub_node', 'nodeid');
- create_table('pubsub_subscription_opt', {
- {'subid','text'};
- {'opt_name','varchar(32)'};
- {'opt_value','text'};
- });
- create_unique_index('i_pubsub_subscription_opt', 'pubsub_subscription_opt(subid(32), opt_name(32))');]]
- return t_concat(q);
-end
-
-local function init(dbh)
- local q = build_query();
- for statement in q:gmatch("[^;]*;") do
- statement = statement:gsub("\n", ""):gsub("\t", " ");
- if sqlite then
- statement = statement:gsub("AUTO_INCREMENT", "AUTOINCREMENT");
- statement = statement:gsub("auto_increment", "autoincrement");
- end
- local result, err = DBI.Do(dbh, statement);
- if not result then
- print("X", result, err);
- print("Y", statement);
- end
- end
-end
-
-local _M = { init = init };
-return _M;
diff --git a/plugins/storage/ejabberdstore.lib.lua b/plugins/storage/ejabberdstore.lib.lua
deleted file mode 100644
index 7e8592a8..00000000
--- a/plugins/storage/ejabberdstore.lib.lua
+++ /dev/null
@@ -1,190 +0,0 @@
-
-local handlers = {};
-
-handlers.accounts = {
- get = function(self, user)
- local select = self:query("select password from users where username=?", user);
- local row = select and select:fetch();
- if row then return { password = row[1] }; end
- end;
- set = function(self, user, data)
- if data and data.password then
- return self:modify("update users set password=? where username=?", data.password, user)
- or self:modify("insert into users (username, password) values (?, ?)", user, data.password);
- else
- return self:modify("delete from users where username=?", user);
- end
- end;
-};
-handlers.vcard = {
- get = function(self, user)
- local select = self:query("select vcard from vcard where username=?", user);
- local row = select and select:fetch();
- if row then return parse_xml(row[1]); end
- end;
- set = function(self, user, data)
- if data then
- data = unparse_xml(data);
- return self:modify("update vcard set vcard=? where username=?", data, user)
- or self:modify("insert into vcard (username, vcard) values (?, ?)", user, data);
- else
- return self:modify("delete from vcard where username=?", user);
- end
- end;
-};
-handlers.private = {
- get = function(self, user)
- local select = self:query("select namespace,data from private_storage where username=?", user);
- if select then
- local data = {};
- for row in select:rows() do
- data[row[1]] = parse_xml(row[2]);
- end
- return data;
- end
- end;
- set = function(self, user, data)
- if data then
- self:modify("delete from private_storage where username=?", user);
- for namespace,text in pairs(data) do
- self:modify("insert into private_storage (username, namespace, data) values (?, ?, ?)", user, namespace, unparse_xml(text));
- end
- return true;
- else
- return self:modify("delete from private_storage where username=?", user);
- end
- end;
- -- TODO map_set, map_get
-};
-local subscription_map = { N = "none", B = "both", F = "from", T = "to" };
-local subscription_map_reverse = { none = "N", both = "B", from = "F", to = "T" };
-handlers.roster = {
- get = function(self, user)
- local select = self:query("select jid,nick,subscription,ask,server,subscribe,type from rosterusers where username=?", user);
- if select then
- local roster = { pending = {} };
- for row in select:rows() do
- local jid,nick,subscription,ask,server,subscribe,typ = unpack(row);
- local item = { groups = {} };
- if nick == "" then nick = nil; end
- item.nick = nick;
- item.subscription = subscription_map[subscription];
- if ask == "N" then ask = nil;
- elseif ask == "O" then ask = "subscribe"
- elseif ask == "I" then roster.pending[jid] = true; ask = nil;
- elseif ask == "B" then roster.pending[jid] = true; ask = "subscribe";
- else module:log("debug", "bad roster_item.ask: %s", ask); ask = nil; end
- item.ask = ask;
- roster[jid] = item;
- end
-
- select = self:query("select jid,grp from rostergroups where username=?", user);
- if select then
- for row in select:rows() do
- local jid,grp = unpack(rows);
- if roster[jid] then roster[jid].groups[grp] = true; end
- end
- end
- select = self:query("select version from roster_version where username=?", user);
- local row = select and select:fetch();
- if row then
- roster[false] = { version = row[1]; };
- end
- return roster;
- end
- end;
- set = function(self, user, data)
- if data and next(data) ~= nil then
- self:modify("delete from rosterusers where username=?", user);
- self:modify("delete from rostergroups where username=?", user);
- self:modify("delete from roster_version where username=?", user);
- local done = {};
- local pending = data.pending or {};
- for jid,item in pairs(data) do
- if jid and jid ~= "pending" then
- local subscription = subscription_map_reverse[item.subscription];
- local ask;
- if pending[jid] then
- if item.ask then ask = "B"; else ask = "I"; end
- else
- if item.ask then ask = "O"; else ask = "N"; end
- end
- local r = self:modify("insert into rosterusers (username,jid,nick,subscription,ask,askmessage,server,subscribe) values (?, ?, ?, ?, ?, '', '', '')", user, jid, item.nick or "", subscription, ask);
- if not r then module:log("debug", "--- :( %s", tostring(r)); end
- done[jid] = true;
- for group in pairs(item.groups) do
- self:modify("insert into rostergroups (username,jid,grp) values (?, ?, ?)", user, jid, group);
- end
- end
- end
- for jid in pairs(pending) do
- if not done[jid] then
- self:modify("insert into rosterusers (username,jid,nick,subscription,ask,askmessage,server,subscribe) values (?, ?, ?, ?, ?. ''. ''. '')", user, jid, "", "N", "I");
- end
- end
- local version = data[false] and data[false].version;
- if version then
- self:modify("insert into roster_version (username,version) values (?, ?)", user, version);
- end
- return true;
- else
- self:modify("delete from rosterusers where username=?", user);
- self:modify("delete from rostergroups where username=?", user);
- self:modify("delete from roster_version where username=?", user);
- end
- end;
-};
-
------------------------------
-local driver = {};
-driver.__index = driver;
-
-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.database:prepare(sql);
- if not r then error("Unable to prepare SQL statement: "..err); end
- self.sqlcache[sql] = r;
- return r;
-end
-
-function driver:query(sql, ...)
- local stmt = self:prepare(sql);
- if stmt:execute(...) then return stmt; end
-end
-function driver:modify(sql, ...)
- local stmt = self:query(sql, ...);
- if stmt and stmt:affected() > 0 then return stmt; end
-end
-
-function driver:open(host, datastore, typ)
- local cache_key = host.." "..datastore;
- if self.ds_cache[cache_key] then return self.ds_cache[cache_key]; end
- local instance = setmetatable({}, self);
- instance.host = host;
- instance.datastore = datastore;
- local handler = handlers[datastore];
- if not handler then return nil; end
- for key,val in pairs(handler) do
- instance[key] = val;
- end
- if instance.init then instance:init(); end
- self.ds_cache[cache_key] = instance;
- return instance;
-end
-
------------------------------
-local _M = {};
-
-function _M.new(dbtype, dbname, ...)
- local instance = setmetatable({}, driver);
- instance.__index = instance;
- instance.database = get_database(dbtype, dbname, ...);
- instance.ds_cache = {};
- return instance;
-end
-
-return _M;
diff --git a/plugins/storage/mod_xep0227.lua b/plugins/storage/mod_xep0227.lua
index b6d2e627..5d07a2ea 100644
--- a/plugins/storage/mod_xep0227.lua
+++ b/plugins/storage/mod_xep0227.lua
@@ -8,7 +8,7 @@ local os_remove = os.remove;
local io_open = io.open;
local st = require "util.stanza";
-local parse_xml_real = module:require("xmlparse");
+local parse_xml_real = require "util.xml".parse;
local function getXml(user, host)
local jid = user.."@"..host;
@@ -160,4 +160,4 @@ function driver:open(host, datastore, typ)
return instance;
end
-module:add_item("data-driver", driver);
+module:provides("storage", driver);
diff --git a/plugins/storage/sqlbasic.lib.lua b/plugins/storage/sqlbasic.lib.lua
deleted file mode 100644
index f1202287..00000000
--- a/plugins/storage/sqlbasic.lib.lua
+++ /dev/null
@@ -1,97 +0,0 @@
-
--- Basic SQL driver
--- This driver stores data as simple key-values
-
-local ser = require "util.serialization".serialize;
-local deser = function(data)
- module:log("debug", "deser: %s", tostring(data));
- if not data then return nil; end
- local f = loadstring("return "..data);
- if not f then return nil; end
- setfenv(f, {});
- 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;
diff --git a/plugins/storage/xmlparse.lib.lua b/plugins/storage/xmlparse.lib.lua
deleted file mode 100644
index 91063995..00000000
--- a/plugins/storage/xmlparse.lib.lua
+++ /dev/null
@@ -1,56 +0,0 @@
-
-local st = require "util.stanza";
-
--- XML parser
-local parse_xml = (function()
- local entity_map = setmetatable({
- ["amp"] = "&";
- ["gt"] = ">";
- ["lt"] = "<";
- ["apos"] = "'";
- ["quot"] = "\"";
- }, {__index = function(_, s)
- if s:sub(1,1) == "#" then
- if s:sub(2,2) == "x" then
- return string.char(tonumber(s:sub(3), 16));
- else
- return string.char(tonumber(s:sub(2)));
- end
- end
- end
- });
- local function xml_unescape(str)
- return (str:gsub("&(.-);", entity_map));
- end
- local function parse_tag(s)
- local name,sattr=(s):gmatch("([^%s]+)(.*)")();
- local attr = {};
- for a,b in (sattr):gmatch("([^=%s]+)=['\"]([^'\"]*)['\"]") do attr[a] = xml_unescape(b); end
- return name, attr;
- end
- return function(xml)
- local stanza = st.stanza("root");
- local regexp = "<([^>]*)>([^<]*)";
- for elem, text in xml:gmatch(regexp) do
- if elem:sub(1,1) == "!" or elem:sub(1,1) == "?" then -- neglect comments and processing-instructions
- elseif elem:sub(1,1) == "/" then -- end tag
- elem = elem:sub(2);
- stanza:up(); -- TODO check for start-end tag name match
- elseif elem:sub(-1,-1) == "/" then -- empty tag
- elem = elem:sub(1,-2);
- local name,attr = parse_tag(elem);
- stanza:tag(name, attr):up();
- else -- start tag
- local name,attr = parse_tag(elem);
- stanza:tag(name, attr);
- end
- if #text ~= 0 then -- text
- stanza:text(xml_unescape(text));
- end
- end
- return stanza.tags[1];
- end
-end)();
--- end of XML parser
-
-return parse_xml;