Changeset

8213:e1272aeef31c

mod_pubsub: Add item persistence using mod_storage_*’s archive store.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sat, 15 Apr 2017 01:21:55 +0100
parents 8212:66173e4b355a
children 8214:da8bc600902a
files plugins/mod_pubsub/mod_pubsub.lua plugins/mod_pubsub/pubsub.lib.lua
diffstat 2 files changed, 80 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_pubsub/mod_pubsub.lua	Sun Apr 02 19:08:54 2017 +0100
+++ b/plugins/mod_pubsub/mod_pubsub.lua	Sat Apr 15 01:21:55 2017 +0100
@@ -21,6 +21,8 @@
 module:add_identity("pubsub", "service", pubsub_disco_name);
 module:add_feature("http://jabber.org/protocol/pubsub");
 
+local archive = module:open_store("pubsub", "archive");
+
 function handle_pubsub_iq(event)
 	local origin, stanza = event.origin, event.stanza;
 	local pubsub_tag = stanza.tags[1];
@@ -36,6 +38,10 @@
 	end
 end
 
+local function simple_itemstore(config, node)
+	return lib_pubsub.simple_itemstore(archive, config, node, expose_publisher);
+end
+
 function simple_broadcast(kind, node, jids, item, actor)
 	if item then
 		item = st.clone(item);
@@ -224,6 +230,7 @@
 		autocreate_on_publish = autocreate_on_publish;
 		autocreate_on_subscribe = autocreate_on_subscribe;
 
+		itemstore = simple_itemstore;
 		broadcaster = simple_broadcast;
 		get_affiliation = get_affiliation;
 
--- a/plugins/mod_pubsub/pubsub.lib.lua	Sun Apr 02 19:08:54 2017 +0100
+++ b/plugins/mod_pubsub/pubsub.lib.lua	Sat Apr 15 01:21:55 2017 +0100
@@ -1,4 +1,5 @@
 local t_unpack = table.unpack or unpack; -- luacheck: ignore 113
+local time_now = os.time;
 
 local st = require "util.stanza";
 local uuid_generate = require "util.uuid".generate;
@@ -316,4 +317,76 @@
 	return true;
 end
 
+local function create_encapsulating_item(id, payload, publisher, expose_publisher)
+	local item = st.stanza("item", { id = id }, xmlns_pubsub);
+	item:add_child(payload);
+	if expose_publisher then
+		item.attr.publisher = publisher;
+	end
+	return item;
+end
+
+local function simple_itemstore(archive, config, node, expose_publisher)
+	module:log("debug", "Creation of itemstore for node %s with config %s", node, config);
+	local get_set = {};
+	function get_set:items()
+		local store = self.store;
+		local data, err = archive:find(node);
+		if not data then
+			module:log("error", "Unable to get items: %s", err);
+			return true;
+		end
+		module:log("debug", "Listed items %s from store %s", data, store);
+		return function()
+			local id, payload, when, publisher = data();
+			if id == nil then
+				return;
+			end
+			local item = create_encapsulating_item(id, payload, publisher, expose_publisher);
+			return id, item;
+		end;
+	end
+	function get_set:get(key)
+		local store = self.store;
+		local data, err = archive:find(node, {
+			key = key;
+		});
+		if not data then
+			module:log("error", "Unable to get item: %s", err);
+			return nil, err;
+		end
+		-- Workaround for buggy SQL drivers which require iterating until we get a nil.
+		local id, payload, when, publisher;
+		for a, b, c, d in data() do
+			id, payload, when, publisher = a, b, c, d;
+		end
+		module:log("debug", "Get item %s (published at %s by %s) from store %s", id, when, publisher, store);
+		if id == nil then
+			return nil;
+		end
+		return create_encapsulating_item(id, payload, publisher, expose_publisher);
+	end
+	function get_set:set(key, value)
+		local store = self.store;
+		module:log("debug", "Set item %s to %s for %s in store %s", key, value, node, store);
+		local data, err;
+		if value ~= nil then
+			local publisher = value.attr.publisher;
+			local payload = value.tags[1];
+			data, err = archive:append(node, key, payload, time_now(), publisher);
+		else
+			data, err = archive:delete(node, {
+				key = key;
+			});
+		end
+		if not data then
+			module:log("error", "Unable to set item: %s", err);
+			return nil, err;
+		end
+		return true;
+	end
+	return setmetatable(get_set, archive);
+end
+_M.simple_itemstore = simple_itemstore;
+
 return _M;