util.pubsub: Add support for limiting number of items to retrieve
authorKim Alvefur <zash@zash.se>
Sun, 05 Sep 2021 16:21:10 +0200
changeset 11771 5610f7c5b261
parent 11770 6ad335cd43f9
child 11772 aa6ab07544c2
util.pubsub: Add support for limiting number of items to retrieve Hopefully this will eventually be upgraded to RSM, which is why the argument is called 'resultspec' and is a table.
spec/util_pubsub_spec.lua
util/pubsub.lua
--- a/spec/util_pubsub_spec.lua	Wed Sep 01 19:05:24 2021 +0200
+++ b/spec/util_pubsub_spec.lua	Sun Sep 05 16:21:10 2021 +0200
@@ -528,4 +528,61 @@
 		end);
 
 	end)
+
+	describe("max_items", function ()
+		it("works", function ()
+			local service = pubsub.new { };
+
+			local ok = service:create("node", true)
+			assert.truthy(ok);
+
+			for i = 1, 20 do
+				assert.truthy(service:publish("node", true, "item"..tostring(i), "data"..tostring(i)));
+			end
+
+			do
+				local ok, items = service:get_items("node", true, nil, { max = 3 });
+				assert.truthy(ok, items);
+				assert.equal(3, #items);
+				assert.same({
+						"item20",
+						"item19",
+						"item18",
+						item20 = "data20",
+						item19 = "data19",
+						item18 = "data18",
+					}, items, "items should be ordered by oldest first");
+			end
+
+			do
+				local ok, items = service:get_items("node", true, nil, { max = 10 });
+				assert.truthy(ok, items);
+				assert.equal(10, #items);
+				assert.same({
+						"item20",
+						"item19",
+						"item18",
+						"item17",
+						"item16",
+						"item15",
+						"item14",
+						"item13",
+						"item12",
+						"item11",
+						item20 = "data20",
+						item19 = "data19",
+						item18 = "data18",
+						item17 = "data17",
+						item16 = "data16",
+						item15 = "data15",
+						item14 = "data14",
+						item13 = "data13",
+						item12 = "data12",
+						item11 = "data11",
+					}, items, "items should be ordered by oldest first");
+			end
+
+		end);
+
+	end)
 end);
--- a/util/pubsub.lua	Wed Sep 01 19:05:24 2021 +0200
+++ b/util/pubsub.lua	Sun Sep 05 16:21:10 2021 +0200
@@ -642,7 +642,7 @@
 	return true
 end
 
-function service:get_items(node, actor, ids) --> (true, { id, [id] = node }) or (false, err)
+function service:get_items(node, actor, ids, resultspec) --> (true, { id, [id] = node }) or (false, err)
 	-- Access checking
 	if not self:may(node, actor, "get_items") then
 		return false, "forbidden";
@@ -660,18 +660,23 @@
 		ids = { ids };
 	end
 	local data = {};
+	local limit = resultspec and resultspec.max;
 	if ids then
 		for _, key in ipairs(ids) do
 			local value = self.data[node]:get(key);
 			if value then
 				data[#data+1] = key;
 				data[key] = value;
+				-- Limits and ids seem like a problematic combination.
+				if limit and #data >= limit then break end
 			end
 		end
 	else
 		for key, value in self.data[node]:items() do
 			data[#data+1] = key;
 			data[key] = value;
+			if limit and #data >= limit then break
+			end
 		end
 	end
 	return true, data;