diff options
Diffstat (limited to 'plugins/storage')
-rw-r--r-- | plugins/storage/ejabberd_init.lib.lua | 252 | ||||
-rw-r--r-- | plugins/storage/ejabberdstore.lib.lua | 190 | ||||
-rw-r--r-- | plugins/storage/mod_xep0227.lua | 4 | ||||
-rw-r--r-- | plugins/storage/sqlbasic.lib.lua | 97 | ||||
-rw-r--r-- | plugins/storage/xmlparse.lib.lua | 56 |
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;
|