Changeset

10837:f23363380599

mod_storage_internal: Implement key-value API
author Kim Alvefur <zash@zash.se>
date Mon, 11 May 2020 21:56:19 +0200
parents 10836:93019f3edd68
children 10838:f26f2ec33f1e
files plugins/mod_storage_internal.lua spec/core_storagemanager_spec.lua
diffstat 2 files changed, 55 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_storage_internal.lua	Mon May 11 21:41:02 2020 +0200
+++ b/plugins/mod_storage_internal.lua	Mon May 11 21:56:19 2020 +0200
@@ -208,6 +208,46 @@
 	end, count;
 end
 
+function archive:get(username, wanted_key)
+	local iter, err = self:find(username, { key = wanted_key })
+	if not iter then return iter, err; end
+	for key, stanza, when, with in iter do
+		if key == wanted_key then
+			return stanza, when, with;
+		end
+	end
+	return nil, "item-not-found";
+end
+
+function archive:set(username, key, new_value, new_when, new_with)
+	local items, err = datamanager.list_load(username, host, self.store);
+	if not items then
+		if err then
+			return items, err;
+		else
+			return nil, "item-not-found";
+		end
+	end
+
+	for i = 1, #items do
+		local old_item = items[i];
+		if old_item.key == key then
+			local item = st.preserialize(st.clone(new_value));
+
+			local when = new_when or item.when or datetime.parse(item.attr.stamp);
+			item.key = key;
+			item.when = when;
+			item.with = new_with or old_item.with;
+			item.attr.stamp = datetime.datetime(when);
+			item.attr.stamp_legacy = datetime.legacy(when);
+			items[i] = item;
+			return datamanager.list_store(username, host, self.store, items);
+		end
+	end
+
+	return nil, "item-not-found";
+end
+
 function archive:dates(username)
 	local items, err = datamanager.list_load(username, host, self.store);
 	if not items then return items, err; end
--- a/spec/core_storagemanager_spec.lua	Mon May 11 21:41:02 2020 +0200
+++ b/spec/core_storagemanager_spec.lua	Mon May 11 21:56:19 2020 +0200
@@ -439,6 +439,21 @@
 					assert.equal(2, count);
 					assert(archive:delete("user-issue1073"));
 				end);
+
+				it("can be treated as a map store", function ()
+					assert.falsy(archive:get("mapuser", "no-such-id"));
+					assert.falsy(archive:set("mapuser", "no-such-id", test_stanza));
+
+					local id = archive:append("mapuser", nil, test_stanza, test_time, "contact@example.com");
+					assert.same(test_stanza, archive:get("mapuser", id));
+
+					local replacement_stanza = st.stanza("test", { xmlns = "urn:example:foo" })
+						:tag("bar"):up()
+						:reset();
+					assert(archive:set("mapuser", id, replacement_stanza));
+					assert.same(replacement_stanza, archive:get("mapuser", id));
+				end);
+
 			end);
 		end);
 	end