Fix a migration wiping user info of users that don't have any mutes
authorrinpatch <rinpatch@sdf.org>
Fri, 18 Oct 2019 11:11:30 +0000 (14:11 +0300)
committerrinpatch <rinpatch@sdf.org>
Fri, 18 Oct 2019 11:11:30 +0000 (14:11 +0300)
And introduce safe_jsonb_set

lib/mix/tasks/pleroma/database.ex
lib/pleroma/object.ex
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/utils.ex
priv/repo/migrations/20190711042021_create_safe_jsonb_set.exs [new file with mode: 0644]
priv/repo/migrations/20190711042024_copy_muted_to_muted_notifications.exs

index bcc2052d6867283835eaa3405128c6c40dd166c2..ab7529e08fc6dd6ddcf1abd6fc3b4293d90c33c2 100644 (file)
@@ -54,7 +54,7 @@ defmodule Mix.Tasks.Pleroma.Database do
     Logger.info("Removing embedded objects")
 
     Repo.query!(
-      "update activities set data = jsonb_set(data, '{object}'::text[], data->'object'->'id') where data->'object'->>'id' is not null;",
+      "update activities set data = safe_jsonb_set(data, '{object}'::text[], data->'object'->'id') where data->'object'->>'id' is not null;",
       [],
       timeout: :infinity
     )
@@ -152,7 +152,7 @@ defmodule Mix.Tasks.Pleroma.Database do
         set: [
           data:
             fragment(
-              "jsonb_set(?, '{likes}', '[]'::jsonb, true)",
+              "safe_jsonb_set(?, '{likes}', '[]'::jsonb, true)",
               object.data
             )
         ]
index 3fa407931e3bd43d8fba928852232f75f2d09192..bf37b28a7ac38fd2dfd7e34d48487f1d4b9e3579 100644 (file)
@@ -181,7 +181,7 @@ defmodule Pleroma.Object do
         data:
           fragment(
             """
-            jsonb_set(?, '{repliesCount}',
+            safe_jsonb_set(?, '{repliesCount}',
               (coalesce((?->>'repliesCount')::int, 0) + 1)::varchar::jsonb, true)
             """,
             o.data,
@@ -204,7 +204,7 @@ defmodule Pleroma.Object do
         data:
           fragment(
             """
-            jsonb_set(?, '{repliesCount}',
+            safe_jsonb_set(?, '{repliesCount}',
               (greatest(0, (?->>'repliesCount')::int - 1))::varchar::jsonb, true)
             """,
             o.data,
index 617f160e0e547159237ff64bdb84e59368c64add..f0912fb100bfd7ee24d797deafbb6342842fb75a 100644 (file)
@@ -718,7 +718,7 @@ defmodule Pleroma.User do
       set: [
         info:
           fragment(
-            "jsonb_set(?, '{note_count}', ((?->>'note_count')::int + 1)::varchar::jsonb, true)",
+            "safe_jsonb_set(?, '{note_count}', ((?->>'note_count')::int + 1)::varchar::jsonb, true)",
             u.info,
             u.info
           )
@@ -739,7 +739,7 @@ defmodule Pleroma.User do
       set: [
         info:
           fragment(
-            "jsonb_set(?, '{note_count}', (greatest(0, (?->>'note_count')::int - 1))::varchar::jsonb, true)",
+            "safe_jsonb_set(?, '{note_count}', (greatest(0, (?->>'note_count')::int - 1))::varchar::jsonb, true)",
             u.info,
             u.info
           )
@@ -812,7 +812,7 @@ defmodule Pleroma.User do
         set: [
           info:
             fragment(
-              "jsonb_set(?, '{follower_count}', ?::varchar::jsonb, true)",
+              "safe_jsonb_set(?, '{follower_count}', ?::varchar::jsonb, true)",
               u.info,
               s.count
             )
index 39a532db34b16cbf0bcadda7bfc80637c2c4598f..f22cc2367cf7de15337cfff986ec85ae3e3ee098 100644 (file)
@@ -349,7 +349,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
     try do
       Ecto.Adapters.SQL.query!(
         Repo,
-        "UPDATE activities SET data = jsonb_set(data, '{state}', $1) WHERE data->>'type' = 'Follow' AND data->>'actor' = $2 AND data->>'object' = $3 AND data->>'state' = 'pending'",
+        "UPDATE activities SET data = safe_jsonb_set(data, '{state}', $1) WHERE data->>'type' = 'Follow' AND data->>'actor' = $2 AND data->>'object' = $3 AND data->>'state' = 'pending'",
         [state, actor, object]
       )
 
diff --git a/priv/repo/migrations/20190711042021_create_safe_jsonb_set.exs b/priv/repo/migrations/20190711042021_create_safe_jsonb_set.exs
new file mode 100644 (file)
index 0000000..d709614
--- /dev/null
@@ -0,0 +1,22 @@
+defmodule Pleroma.Repo.Migrations.CreateSafeJsonbSet do
+  use Ecto.Migration
+  alias Pleroma.User
+
+  def change do
+  execute("""
+  create or replace function safe_jsonb_set(target jsonb, path text[], new_value jsonb, create_missing boolean default true) returns jsonb as $$
+  declare
+    result jsonb;
+  begin
+    result := jsonb_set(target, path, coalesce(new_value, 'null'::jsonb), create_missing);
+    if result is NULL then
+      raise 'jsonb_set tried to wipe the object, please report this incindent to Pleroma bug tracker. https://git.pleroma.social/pleroma/pleroma/issues/new';
+      return target;
+    else
+      return result;
+    end if;
+  end;
+  $$ language plpgsql;
+  """)
+  end
+end
index b717cab2e8ec546c59b881d55c6781f0b9660ab8..a3c5b52deed44a234221bac695d037de2ac0b436 100644 (file)
@@ -3,6 +3,6 @@ defmodule Pleroma.Repo.Migrations.CopyMutedToMutedNotifications do
   alias Pleroma.User
 
   def change do
-  execute("update users set info = jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true")
+  execute("update users set info = safe_jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true")
   end
 end