Changeset

9834:a657df70cc31

Merge 0.11->trunk
author Kim Alvefur <zash@zash.se>
date Wed, 27 Feb 2019 10:29:10 +0100 (2019-02-27)
parents 9831:43f81e85cec2 (current diff) 9833:86fe021f16a6 (diff)
children 9835:20bf5b47c1fb
files plugins/mod_storage_memory.lua
diffstat 2 files changed, 258 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_storage_memory.lua	Sun Feb 24 16:30:11 2019 +0100
+++ b/plugins/mod_storage_memory.lua	Wed Feb 27 10:29:10 2019 +0100
@@ -76,46 +76,66 @@
 	return key;
 end
 
-local function archive_iter (a, start, stop, step, limit, when_start, when_end, match_with)
-	local item, when, with;
-	local count = 0;
-	coroutine.yield(true); -- Ready
-	for i = start, stop, step do
-		item = a[i];
-		when, with = item.when, item.with;
-		if when >= when_start and when_end >= when and (not match_with or match_with == with) then
-			coroutine.yield(item.key, item.value(), when, with);
-			count = count + 1;
-			if limit and count >= limit then return end
+function archive_store:find(username, query)
+	local items = self.store[username or NULL];
+	if not items then
+		return function () end, 0;
+	end
+	local count = #items;
+	local i = 0;
+	if query then
+		items = array():append(items);
+		if query.key then
+			items:filter(function (item)
+				return item.key == query.key;
+			end);
+		end
+		if query.with then
+			items:filter(function (item)
+				return item.with == query.with;
+			end);
+		end
+		if query.start then
+			items:filter(function (item)
+				return item.when >= query.start;
+			end);
+		end
+		if query["end"] then
+			items:filter(function (item)
+				return item.when <= query["end"];
+			end);
+		end
+		count = #items;
+		if query.reverse then
+			items:reverse();
+			if query.before then
+				for j = 1, count do
+					if (items[j].key or tostring(j)) == query.before then
+						i = j;
+						break;
+					end
+				end
+			end
+		elseif query.after then
+			for j = 1, count do
+				if (items[j].key or tostring(j)) == query.after then
+					i = j;
+					break;
+				end
+			end
+		end
+		if query.limit and #items - i > query.limit then
+			items[i+query.limit+1] = nil;
 		end
 	end
+	return function ()
+		i = i + 1;
+		local item = items[i];
+		if not item then return; end
+		return item.key, item.value(), item.when, item.with;
+	end, count;
 end
 
-function archive_store:find(username, query)
-	local a = self.store[username or NULL] or {};
-	local start, stop, step = 1, #a, 1;
-	local qstart, qend, qwith = -math.huge, math.huge;
-	local limit;
-	if query then
-		module:log("debug", "query included")
-		if query.reverse then
-			start, stop, step = stop, start, -1;
-			if query.before then
-				start = a[query.before];
-			end
-		elseif query.after then
-			start = a[query.after];
-		end
-		limit = query.limit;
-		qstart = query.start or qstart;
-		qend = query["end"] or qend;
-		qwith = query.with;
-	end
-	if not start then return nil, "invalid-key"; end
-	local iter = coroutine.wrap(archive_iter);
-	iter(a, start, stop, step, limit, qstart, qend, qwith);
-	return iter;
-end
 
 function archive_store:delete(username, query)
 	if not query or next(query) == nil then
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/scansion/pubsub_multi_items.scs	Wed Feb 27 10:29:10 2019 +0100
@@ -0,0 +1,202 @@
+# Pubsub: Requesting multiple specific items from a node (#1322)
+
+[Client] Alice
+	jid: admin@localhost
+	password: password
+
+---------
+
+Alice connects
+
+Alice sends:
+	<presence xmlns:stream="http://etherx.jabber.org/streams" id=":7IoqYcT3191rfk_dZGo2"/>
+
+Alice receives:
+	<presence xmlns:stream="http://etherx.jabber.org/streams" from="${Alice's full JID}" id=":7IoqYcT3191rfk_dZGo2"/>
+
+Alice sends:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="pubsub.localhost" id=":m0SM8Hn5JxP9BJJ_X4Mz" type="set">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <create node="e96caf12-264f-4e5a-988e-00ae191771b6"/>
+	  </pubsub>
+	</iq>
+
+Alice receives:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="${Alice's full JID}" from="pubsub.localhost" type="result" id=":m0SM8Hn5JxP9BJJ_X4Mz"/>
+
+Alice sends:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="pubsub.localhost" id=":gwZgEQmzAHcQz-FZOxi-" type="get">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
+	    <configure node="e96caf12-264f-4e5a-988e-00ae191771b6"/>
+	  </pubsub>
+	</iq>
+
+Alice receives:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="${Alice's full JID}" from="pubsub.localhost" type="result" id=":gwZgEQmzAHcQz-FZOxi-">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
+	    <configure node="e96caf12-264f-4e5a-988e-00ae191771b6">
+	      <x xmlns="jabber:x:data" type="form">
+		<field var="FORM_TYPE" type="hidden">
+		  <value>http://jabber.org/protocol/pubsub#node_config</value>
+		</field>
+		<field var="pubsub#title" label="Title" type="text-single"/>
+		<field var="pubsub#description" label="Description" type="text-single"/>
+		<field var="pubsub#type" label="The type of node data, usually specified by the namespace of the payload (if any)" type="text-single"/>
+		<field var="pubsub#max_items" label="Max # of items to persist" type="text-single">
+		  <validate xmlns="http://jabber.org/protocol/xdata-validate" datatype="xs:integer"/>
+		  <value>20</value>
+		</field>
+		<field var="pubsub#persist_items" label="Persist items to storage" type="boolean">
+		  <value>0</value>
+		</field>
+		<field var="pubsub#access_model" label="Specify the subscriber model" type="list-single">
+		  <option label="authorize">
+		    <value>authorize</value>
+		  </option>
+		  <option label="open">
+		    <value>open</value>
+		  </option>
+		  <option label="presence">
+		    <value>presence</value>
+		  </option>
+		  <option label="roster">
+		    <value>roster</value>
+		  </option>
+		  <option label="whitelist">
+		    <value>whitelist</value>
+		  </option>
+		  <value>open</value>
+		</field>
+		<field var="pubsub#publish_model" label="Specify the publisher model" type="list-single">
+		  <option label="publishers">
+		    <value>publishers</value>
+		  </option>
+		  <option label="subscribers">
+		    <value>subscribers</value>
+		  </option>
+		  <option label="open">
+		    <value>open</value>
+		  </option>
+		  <value>publishers</value>
+		</field>
+		<field var="pubsub#deliver_notifications" label="Whether to deliver event notifications" type="boolean">
+		  <value>1</value>
+		</field>
+		<field var="pubsub#deliver_payloads" label="Whether to deliver payloads with event notifications" type="boolean">
+		  <value>1</value>
+		</field>
+		<field var="pubsub#notification_type" label="Specify the delivery style for notifications" type="list-single">
+		  <option label="Messages of type normal">
+		    <value>normal</value>
+		  </option>
+		  <option label="Messages of type headline">
+		    <value>headline</value>
+		  </option>
+		  <value>headline</value>
+		</field>
+		<field var="pubsub#notify_delete" label="Whether to notify subscribers when the node is deleted" type="boolean">
+		  <value>1</value>
+		</field>
+		<field var="pubsub#notify_retract" label="Whether to notify subscribers when items are removed from the node" type="boolean">
+		  <value>1</value>
+		</field>
+	      </x>
+	    </configure>
+	  </pubsub>
+	</iq>
+
+Alice sends:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="pubsub.localhost" id=":pfWBQ2MNIq8ieul57Qp7" type="set">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <publish node="e96caf12-264f-4e5a-988e-00ae191771b6">
+	      <item id="20e9eb9e-8acb-436e-a486-40e80400faf1">
+		<foo xmlns="https://zombofant.net/xmlns/aioxmpp#test">foo</foo>
+	      </item>
+	    </publish>
+	  </pubsub>
+	</iq>
+
+Alice receives:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="${Alice's full JID}" from="pubsub.localhost" type="result" id=":pfWBQ2MNIq8ieul57Qp7">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <publish node="e96caf12-264f-4e5a-988e-00ae191771b6">
+	      <item id="20e9eb9e-8acb-436e-a486-40e80400faf1"/>
+	    </publish>
+	  </pubsub>
+	</iq>
+
+Alice sends:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="pubsub.localhost" id=":Q5TLT6nsW0HHdkDgrPPe" type="set">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <publish node="e96caf12-264f-4e5a-988e-00ae191771b6">
+	      <item id="4b94623d-1127-41c0-ac47-e283fd890557">
+		<foo xmlns="https://zombofant.net/xmlns/aioxmpp#test">bar</foo>
+	      </item>
+	    </publish>
+	  </pubsub>
+	</iq>
+
+Alice receives:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="${Alice's full JID}" from="pubsub.localhost" type="result" id=":Q5TLT6nsW0HHdkDgrPPe">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <publish node="e96caf12-264f-4e5a-988e-00ae191771b6">
+	      <item id="4b94623d-1127-41c0-ac47-e283fd890557"/>
+	    </publish>
+	  </pubsub>
+	</iq>
+
+Alice sends:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="pubsub.localhost" id=":3nvB2E20p1iuM6lOPaP6" type="get">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <items node="e96caf12-264f-4e5a-988e-00ae191771b6">
+	      <item id="20e9eb9e-8acb-436e-a486-40e80400faf1"/>
+	      <item id="4b94623d-1127-41c0-ac47-e283fd890557"/>
+	    </items>
+	  </pubsub>
+	</iq>
+
+Alice receives:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="${Alice's full JID}" from="pubsub.localhost" type="result" id=":3nvB2E20p1iuM6lOPaP6">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <items node="e96caf12-264f-4e5a-988e-00ae191771b6">
+	      <item xmlns="http://jabber.org/protocol/pubsub" id="20e9eb9e-8acb-436e-a486-40e80400faf1">
+		<foo xmlns="https://zombofant.net/xmlns/aioxmpp#test">foo</foo>
+	      </item>
+	      <item xmlns="http://jabber.org/protocol/pubsub" id="4b94623d-1127-41c0-ac47-e283fd890557">
+		<foo xmlns="https://zombofant.net/xmlns/aioxmpp#test">bar</foo>
+	      </item>
+	    </items>
+	  </pubsub>
+	</iq>
+
+Alice sends:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="pubsub.localhost" id=":XQdyK54iyOKiJvUoX9t_" type="get">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <items node="e96caf12-264f-4e5a-988e-00ae191771b6"/>
+	  </pubsub>
+	</iq>
+
+Alice receives:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="${Alice's full JID}" from="pubsub.localhost" type="result" id=":XQdyK54iyOKiJvUoX9t_">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub">
+	    <items node="e96caf12-264f-4e5a-988e-00ae191771b6">
+	      <item xmlns="http://jabber.org/protocol/pubsub" id="20e9eb9e-8acb-436e-a486-40e80400faf1">
+		<foo xmlns="https://zombofant.net/xmlns/aioxmpp#test">foo</foo>
+	      </item>
+	      <item xmlns="http://jabber.org/protocol/pubsub" id="4b94623d-1127-41c0-ac47-e283fd890557">
+		<foo xmlns="https://zombofant.net/xmlns/aioxmpp#test">bar</foo>
+	      </item>
+	    </items>
+	  </pubsub>
+	</iq>
+
+Alice sends:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="pubsub.localhost" id=":ySGQOz5tnyWT82idwJZP" type="set">
+	  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
+	    <delete node="e96caf12-264f-4e5a-988e-00ae191771b6"/>
+	  </pubsub>
+	</iq>
+
+Alice receives:
+	<iq xmlns:stream="http://etherx.jabber.org/streams" to="${Alice's full JID}" from="pubsub.localhost" type="result" id=":ySGQOz5tnyWT82idwJZP"/>
+