diff --git a/init.lua b/init.lua index 569df95..446e7fc 100644 --- a/init.lua +++ b/init.lua @@ -58,6 +58,7 @@ mail.migrate() if minetest.get_modpath("mtt") then dofile(MP .. "/mtt.lua") dofile(MP .. "/api.spec.lua") + dofile(MP .. "/migrate.spec.lua") dofile(MP .. "/util/uuid.spec.lua") dofile(MP .. "/util/normalize.spec.lua") end diff --git a/migrate.lua b/migrate.lua index 5fe0838..5378686 100644 --- a/migrate.lua +++ b/migrate.lua @@ -11,26 +11,24 @@ local function migrate_v1_to_v3() file:close() for name, oldmessages in pairs(oldmails) do + print("[mail,v1] + migrating player '" .. name .. "'") local entry = mail.get_storage_entry(name) for _, msg in ipairs(oldmessages) do - if msg.to then - table.insert(entry.inbox, { - id = mail.new_uuid(), - from = msg.sender or msg.from, - to = msg.to, - subject = msg.subject, - body = msg.body, - time = msg.time, - }) - end + table.insert(entry.inbox, { + id = mail.new_uuid(), + from = msg.sender or msg.from, + to = msg.to or name, + subject = msg.subject, + body = msg.body, + time = msg.time or os.time(), + }) end mail.set_storage_entry(name, entry) end -- rename file - print("[mail] migration done, renaming old mail.db") + print("[mail,v1] migration done, renaming old mail.db") os.rename(minetest.get_worldpath().."/mail.db", minetest.get_worldpath().."/mail.db.old") - mail.storage:set_int(STORAGE_VERSION_KEY, 3) end local function read_json_file(path) @@ -62,37 +60,39 @@ local function migrate_v2_to_v3() local saneplayername = string.gsub(playername, "[.|/]", "") local player_inbox = read_json_file(maildir .. "/" .. saneplayername .. ".json") + print("[mail,v2] + migrating player '" .. playername .. "'") for _, msg in ipairs(player_inbox) do - if msg.to then - table.insert(entry.inbox, { - id = mail.new_uuid(), - from = msg.sender or msg.from, - to = msg.to, - cc = msg.cc, - subject = msg.subject, - body = msg.body, - time = msg.time, - }) - end + table.insert(entry.inbox, { + id = mail.new_uuid(), + from = msg.sender or msg.from, + to = msg.to or playername, + cc = msg.cc, + subject = msg.subject, + body = msg.body, + time = msg.time or os.time(), + }) end mail.set_storage_entry(playername, entry) end - print("[mail] migration done") - mail.storage:set_int(STORAGE_VERSION_KEY, 3) + print("[mail,v2] migration done") end) end function mail.migrate() - local v1_file = io.open(minetest.get_worldpath().."/mail.db", "r") - if v1_file then - -- v1 to v3 - migrate_v1_to_v3() - end - + -- check for v2 storage first, v1-migration might have set the v3-flag already local version = mail.storage:get_int(STORAGE_VERSION_KEY) if version < 3 then -- v2 to v3 migrate_v2_to_v3() + mail.storage:set_int(STORAGE_VERSION_KEY, 3) + end + + -- check for v1 storage + local v1_file = io.open(minetest.get_worldpath().."/mail.db", "r") + if v1_file then + -- v1 to v3 + migrate_v1_to_v3() + mail.storage:set_int(STORAGE_VERSION_KEY, 3) end end \ No newline at end of file diff --git a/migrate.spec.lua b/migrate.spec.lua new file mode 100644 index 0000000..b98341b --- /dev/null +++ b/migrate.spec.lua @@ -0,0 +1,28 @@ + +mtt.register("migrate v1", function(callback) + local entry = mail.get_storage_entry("old_v1_player") + assert(entry) + assert(#entry.inbox == 1) + assert(entry.inbox[1].from == "singleplayer") + assert(entry.inbox[1].to == "old_v1_player") + assert(entry.inbox[1].subject == "test1") + assert(entry.inbox[1].body == "test2") + assert(entry.inbox[1].id) + assert(entry.inbox[1].time > 0) + + callback() +end) + +mtt.register("migrate v2", function(callback) + local entry = mail.get_storage_entry("old_v2_player") + assert(entry) + assert(#entry.inbox == 1) + assert(entry.inbox[1].from == "someone-else") + assert(entry.inbox[1].to == "old_v2_player") + assert(entry.inbox[1].subject == "test1") + assert(entry.inbox[1].body == "test2") + assert(entry.inbox[1].id) + assert(entry.inbox[1].time == 1678467148) + + callback() +end) \ No newline at end of file diff --git a/test/Dockerfile b/test/Dockerfile index 6324d80..9c1bd1b 100644 --- a/test/Dockerfile +++ b/test/Dockerfile @@ -1,6 +1,13 @@ ARG ENGINE_VERSION=5.5.0 FROM registry.gitlab.com/minetest/minetest/server:${ENGINE_VERSION} +# copy old v1 maildb for migration testing +COPY ./mail.db /root/.minetest/worlds/world/mail.db +# copy old v2 mail-dir and auth.sqlite for migration testing +COPY ./old_v2_player.json /root/.minetest/worlds/world/mails/ +COPY ./auth.sqlite /root/.minetest/worlds/world/auth.sqlite + + USER root RUN apk add git &&\ mkdir -p /root/.minetest/worlds/world/worldmods/ &&\ diff --git a/test/auth.sqlite b/test/auth.sqlite new file mode 100644 index 0000000..e6bac67 Binary files /dev/null and b/test/auth.sqlite differ diff --git a/test/mail.db b/test/mail.db new file mode 100644 index 0000000..3104acb --- /dev/null +++ b/test/mail.db @@ -0,0 +1 @@ +local _={};_[1]="singleplayer";return {old_v1_player={{unread=true,subject="test1",sender=_[1],body="test2"}},[_[1]]={}} \ No newline at end of file diff --git a/test/old_v2_player.json b/test/old_v2_player.json new file mode 100644 index 0000000..2bb859a --- /dev/null +++ b/test/old_v2_player.json @@ -0,0 +1 @@ +[{"body":"test2","sender":"someone-else","subject":"test1","time":1678467148,"unread":false}] \ No newline at end of file