From 0f0d32d335c2fb6bba59e5a6043412ad6d61e74a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 1 Feb 2021 12:47:05 +0100 Subject: mod_storage_sql: Implement map-like API for archives Used by mod_http_file_share, muc moderation, etc. Tests tweaked because they failed on stanza internals that happen becasue of re-serialization. Namespaces differ since inheritance is implicit when building but explicit after parsing. --- plugins/mod_storage_sql.lua | 47 +++++++++++++++++++++++++++++++++++++++ spec/core_storagemanager_spec.lua | 4 ++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 91b73eb4..6bd094e5 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -482,6 +482,53 @@ function archive_store:find(username, query) end, total; end +function archive_store:get(username, key) + local iter, err = self:find(username, { key = key }) + if not iter then return iter, err; end + for _, stanza, when, with in iter do + return stanza, when, with; + end + return nil, "item-not-found"; +end + +function archive_store:set(username, key, new_value, new_when, new_with) + local user,store = username,self.store; + local ok, result = engine:transaction(function () + + local update_query = [[ + UPDATE "prosodyarchive" + SET %s + WHERE %s + ]]; + local args = { host, user or "", store, key }; + local setf = {}; + local where = { "\"host\" = ?", "\"user\" = ?", "\"store\" = ?", "\"key\" = ?"}; + + if new_value then + table.insert(setf, '"type" = ?') + table.insert(setf, '"value" = ?') + local t, value = serialize(new_value); + table.insert(args, 1, t); + table.insert(args, 2, value); + end + + if new_when then + table.insert(setf, 1, '"when" = ?') + table.insert(args, 1, new_when); + end + + if new_with then + table.insert(setf, 1, '"with" = ?') + table.insert(args, 1, new_with); + end + + update_query = update_query:format(t_concat(setf, ", "), t_concat(where, " AND ")); + return engine:update(update_query, unpack(args)); + end); + if not ok then return ok, result; end + return result:affected() == 1; +end + function archive_store:summary(username, query) query = query or {}; local user,store = username,self.store; diff --git a/spec/core_storagemanager_spec.lua b/spec/core_storagemanager_spec.lua index cf9429c1..7f86255f 100644 --- a/spec/core_storagemanager_spec.lua +++ b/spec/core_storagemanager_spec.lua @@ -556,7 +556,7 @@ describe("storagemanager", function () local id = archive:append("mapuser", nil, test_stanza, test_time, "contact@example.com"); do local stanza_roundtrip, when, with = archive:get("mapuser", id); - assert.same(test_stanza, stanza_roundtrip, "same stanza is returned"); + assert.same(tostring(test_stanza), tostring(stanza_roundtrip), "same stanza is returned"); assert.equal(test_time, when, "same 'when' is returned"); assert.equal("contact@example.com", with, "same 'with' is returned"); end @@ -568,7 +568,7 @@ describe("storagemanager", function () do local replaced, when, with = archive:get("mapuser", id); - assert.same(replacement_stanza, replaced, "replaced stanza is returned"); + assert.same(tostring(replacement_stanza), tostring(replaced), "replaced stanza is returned"); assert.equal(test_time+1, when, "modified 'when' is returned"); assert.equal("contact@example.com", with, "original 'with' is returned"); end -- cgit v1.2.3