logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

base_migrator_state.ex (3231B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Migrators.Support.BaseMigratorState do
  5. @moduledoc """
  6. Base background migrator state functionality.
  7. """
  8. @callback data_migration() :: Pleroma.DataMigration.t()
  9. defmacro __using__(_opts) do
  10. quote do
  11. use Agent
  12. alias Pleroma.DataMigration
  13. @behaviour Pleroma.Migrators.Support.BaseMigratorState
  14. @reg_name {:global, __MODULE__}
  15. def start_link(_) do
  16. Agent.start_link(fn -> load_state_from_db() end, name: @reg_name)
  17. end
  18. def data_migration, do: raise("data_migration/0 is not implemented")
  19. defoverridable data_migration: 0
  20. defp load_state_from_db do
  21. data_migration = data_migration()
  22. data =
  23. if data_migration do
  24. Map.new(data_migration.data, fn {k, v} -> {String.to_atom(k), v} end)
  25. else
  26. %{}
  27. end
  28. %{
  29. data_migration_id: data_migration && data_migration.id,
  30. data: data
  31. }
  32. end
  33. def persist_to_db do
  34. %{data_migration_id: data_migration_id, data: data} = state()
  35. if data_migration_id do
  36. DataMigration.update_one_by_id(data_migration_id, data: data)
  37. else
  38. {:error, :nil_data_migration_id}
  39. end
  40. end
  41. def reset do
  42. %{data_migration_id: data_migration_id} = state()
  43. with false <- is_nil(data_migration_id),
  44. :ok <-
  45. DataMigration.update_one_by_id(data_migration_id,
  46. state: :pending,
  47. data: %{}
  48. ) do
  49. reinit()
  50. else
  51. true -> {:error, :nil_data_migration_id}
  52. e -> e
  53. end
  54. end
  55. def reinit do
  56. Agent.update(@reg_name, fn _state -> load_state_from_db() end)
  57. end
  58. def state do
  59. Agent.get(@reg_name, & &1)
  60. end
  61. def get_data_key(key, default \\ nil) do
  62. get_in(state(), [:data, key]) || default
  63. end
  64. def put_data_key(key, value) do
  65. _ = persist_non_data_change(key, value)
  66. Agent.update(@reg_name, fn state ->
  67. put_in(state, [:data, key], value)
  68. end)
  69. end
  70. def increment_data_key(key, increment \\ 1) do
  71. Agent.update(@reg_name, fn state ->
  72. initial_value = get_in(state, [:data, key]) || 0
  73. updated_value = initial_value + increment
  74. put_in(state, [:data, key], updated_value)
  75. end)
  76. end
  77. defp persist_non_data_change(:state, value) do
  78. with true <- get_data_key(:state) != value,
  79. true <- value in Pleroma.DataMigration.State.__valid_values__(),
  80. %{data_migration_id: data_migration_id} when not is_nil(data_migration_id) <-
  81. state() do
  82. DataMigration.update_one_by_id(data_migration_id, state: value)
  83. else
  84. false -> :ok
  85. _ -> {:error, :nil_data_migration_id}
  86. end
  87. end
  88. defp persist_non_data_change(_, _) do
  89. nil
  90. end
  91. def data_migration_id, do: Map.get(state(), :data_migration_id)
  92. end
  93. end
  94. end