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 12:22:07 +0000 (15:22 +0300)
And introduce safe_jsonb_set

lib/mix/tasks/pleroma/database.ex
lib/pleroma/object.ex
lib/pleroma/user.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 cfd9eeada46ced0fd7a3449e59c45fe89f8aac82..8a827ca80fb0c14a1e92bbc8945b36fb57c880a5 100644 (file)
@@ -28,7 +28,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
     )
@@ -126,7 +126,7 @@ defmodule Mix.Tasks.Pleroma.Database do
         set: [
           data:
             fragment(
-              "jsonb_set(?, '{likes}', '[]'::jsonb, true)",
+              "safe_jsonb_set(?, '{likes}', '[]'::jsonb, true)",
               object.data
             )
         ]
index cdfbacb0e783c3610f3b9332696c77b929fa7c05..d9b41d710cebb6296a3b2d4cb41521feb2c27030 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 917bcf2ef0a99053b264670657886b6184b79d1a..d0d3e1f9aebfa8446990e7e566020c9af59c1a4a 100644 (file)
@@ -727,7 +727,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
           )
@@ -748,7 +748,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
           )
@@ -818,7 +818,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
             )
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..2f336a5
--- /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 bc4e828cc4a95253c9f7d962276ee0cd0d76a4cc..a5eec848b19b307e113f4874ea37f827c681ea94 100644 (file)
@@ -4,7 +4,7 @@ defmodule Pleroma.Repo.Migrations.CopyMutedToMutedNotifications do
 
   def change do
     execute(
-      "update users set info = jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true"
+      "update users set info = safe_jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true"
     )
   end
 end