summaryrefslogtreecommitdiff
path: root/lib/pleroma/migration_helper/object_id.ex
blob: 3cc487523c1d8e2fbc486b03c9c21e9850fe4e83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.MigrationHelper.ObjectId do
  @moduledoc """
  Functions for migrating Object IDs.
  """
  alias Pleroma.Chat.MessageReference
  alias Pleroma.DataMigrationFailedId
  alias Pleroma.Delivery
  alias Pleroma.HashtagObject
  alias Pleroma.Object
  alias Pleroma.Repo

  import Ecto.Changeset
  import Ecto.Query

  @doc "Change an object's ID including all references."
  def change_id(%Object{id: old_id} = object, new_id) do
    Repo.transaction(fn ->
      update_object_fk(MessageReference, old_id, new_id)
      update_object_fk(Delivery, old_id, new_id)
      update_object_fk(HashtagObject, old_id, new_id)
      update_object_fk(DataMigrationFailedId, old_id, new_id, :record_id)

      Repo.update!(change(object, id: new_id))
    end)
  end

  defp update_object_fk(schema, old_id, new_id, field \\ :object_id) do
    binding = [{field, old_id}]

    schema
    |> where(^binding)
    |> Repo.update_all(set: [{field, new_id}])
  end

  @doc "Generate a FlakeId from a datetime."
  @spec flake_from_time(NaiveDateTime.t()) :: flake_id :: String.t()
  def flake_from_time(%NaiveDateTime{} = dt) do
    dt
    |> build_worker()
    |> FlakeId.Worker.gen_flake()
    |> FlakeId.to_string()
  end

  # Build a one-off FlakeId worker.
  defp build_worker(%NaiveDateTime{} = dt) do
    %FlakeId.Worker{
      node: FlakeId.Worker.worker_id(),
      time: get_timestamp(dt, :millisecond)
    }
  end

  # Convert a NaiveDateTime into a Unix timestamp.
  @epoch ~N[1970-01-01 00:00:00]
  defp get_timestamp(%NaiveDateTime{} = dt, unit) do
    NaiveDateTime.diff(dt, @epoch, unit)
  end
end