From 51ff7cded2f1a175199a9509830fce51a1e6a937 Mon Sep 17 00:00:00 2001 From: Joshua Yanovski Date: Mon, 20 Jul 2020 02:08:19 +0200 Subject: [PATCH] Fix corrupted character inventories by adding protection. This is a temporary bandaid until we move to our new schema, but it should at least allow people to log in with old characters. --- .../down.sql | 1 + .../up.sql | 39 +++++++++++++++++++ server/src/persistence/mod.rs | 3 ++ 3 files changed, 43 insertions(+) create mode 100644 server/src/migrations/2020-07-19-223917_update_item_stats/down.sql create mode 100644 server/src/migrations/2020-07-19-223917_update_item_stats/up.sql diff --git a/server/src/migrations/2020-07-19-223917_update_item_stats/down.sql b/server/src/migrations/2020-07-19-223917_update_item_stats/down.sql new file mode 100644 index 0000000000..291a97c5ce --- /dev/null +++ b/server/src/migrations/2020-07-19-223917_update_item_stats/down.sql @@ -0,0 +1 @@ +-- This file should undo anything in `up.sql` \ No newline at end of file diff --git a/server/src/migrations/2020-07-19-223917_update_item_stats/up.sql b/server/src/migrations/2020-07-19-223917_update_item_stats/up.sql new file mode 100644 index 0000000000..a747646b1d --- /dev/null +++ b/server/src/migrations/2020-07-19-223917_update_item_stats/up.sql @@ -0,0 +1,39 @@ +-- This migration updates all "stats" fields for each armour item in player inventory. +UPDATE + inventory +SET + items = json_replace( + -- Replace inventory slots. + items, + '$.slots', + ( + -- Replace each item in the inventory, by splitting the json into an array, applying our changes, + -- and then re-aggregating. + -- + -- NOTE: SQLite does not seem to provide a way to guarantee the order is the same after aggregation! + -- For now, it *does* seem to order by slots.key, but this doesn't seem to be guaranteed by anything. + -- For explicitness, we still include the ORDER BY, even though it seems to have no effect. + SELECT json_group_array( + json_replace( + slots.value, + '$.kind.Armor.stats', + CASE + -- ONLY replace item stats when the stats field currently lacks "protection" + -- (NOTE: This will also return true if the value is null, so if you are creating a nullable + -- JSON field please be careful before rerunning this migration!). + WHEN json_extract(slots.value, '$.kind.Armor.stats.protection') IS NULL + THEN + -- Replace armor stats with new armor + json('{ "protection": { "Normal": 1.0 } }') + ELSE + -- The protection stat was already added. + json_extract(slots.value, '$.kind.Armor.stats') + END + ) + ) + -- Extract all item slots + FROM json_each(json_extract(items, '$.slots')) AS slots + ORDER BY slots.key + ) + ) +; diff --git a/server/src/persistence/mod.rs b/server/src/persistence/mod.rs index 34c1d4377a..441d741c63 100644 --- a/server/src/persistence/mod.rs +++ b/server/src/persistence/mod.rs @@ -22,6 +22,9 @@ use tracing::warn; // See: https://docs.rs/diesel_migrations/1.4.0/diesel_migrations/macro.embed_migrations.html // This macro is called at build-time, and produces the necessary migration info // for the `embedded_migrations` call below. +// +// NOTE: Adding a useless comment to trigger the migrations being run. Delete +// when needed. embed_migrations!(); /// Runs any pending database migrations. This is executed during server startup