aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2020-05-11 21:56:19 +0200
committerKim Alvefur <zash@zash.se>2020-05-11 21:56:19 +0200
commitb9bb7cca20ac53685a13fd096a74abd1ae5eb3d3 (patch)
treed3c52660aea85e97cb676dad5994bc6613834fd2
parentc3058505713cfbad76812f7797d52cc32e626fea (diff)
downloadprosody-b9bb7cca20ac53685a13fd096a74abd1ae5eb3d3.tar.gz
prosody-b9bb7cca20ac53685a13fd096a74abd1ae5eb3d3.zip
mod_storage_internal: Implement key-value API
-rw-r--r--plugins/mod_storage_internal.lua40
-rw-r--r--spec/core_storagemanager_spec.lua15
2 files changed, 55 insertions, 0 deletions
diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua
index c8b902cf..586ea10f 100644
--- a/plugins/mod_storage_internal.lua
+++ b/plugins/mod_storage_internal.lua
@@ -208,6 +208,46 @@ function archive:find(username, query)
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
diff --git a/spec/core_storagemanager_spec.lua b/spec/core_storagemanager_spec.lua
index 29ab014f..96ccceb6 100644
--- a/spec/core_storagemanager_spec.lua
+++ b/spec/core_storagemanager_spec.lua
@@ -439,6 +439,21 @@ describe("storagemanager", function ()
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