mod_storage_sql: Implement map-like API for archives
authorKim Alvefur <zash@zash.se>
Mon, 01 Feb 2021 12:47:05 +0100
changeset 11358 10fba62332c5
parent 11357 367e6beaf8ab
child 11359 89efa3f2966b
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
spec/core_storagemanager_spec.lua
--- a/plugins/mod_storage_sql.lua	Mon Feb 01 12:17:56 2021 +0100
+++ b/plugins/mod_storage_sql.lua	Mon Feb 01 12:47:05 2021 +0100
@@ -482,6 +482,53 @@
 	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;
--- a/spec/core_storagemanager_spec.lua	Mon Feb 01 12:17:56 2021 +0100
+++ b/spec/core_storagemanager_spec.lua	Mon Feb 01 12:47:05 2021 +0100
@@ -556,7 +556,7 @@
 					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 @@
 
 					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