1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Migrators.Support.BaseMigratorState do
7 Base background migrator state functionality.
10 @callback data_migration() :: Pleroma.DataMigration.t()
12 defmacro __using__(_opts) do
16 alias Pleroma.DataMigration
18 @behaviour Pleroma.Migrators.Support.BaseMigratorState
19 @reg_name {:global, __MODULE__}
22 Agent.start_link(fn -> load_state_from_db() end, name: @reg_name)
25 def data_migration, do: raise("data_migration/0 is not implemented")
26 defoverridable data_migration: 0
28 defp load_state_from_db do
29 data_migration = data_migration()
33 Map.new(data_migration.data, fn {k, v} -> {String.to_atom(k), v} end)
39 data_migration_id: data_migration && data_migration.id,
45 %{data_migration_id: data_migration_id, data: data} = state()
47 if data_migration_id do
48 DataMigration.update_one_by_id(data_migration_id, data: data)
50 {:error, :nil_data_migration_id}
55 %{data_migration_id: data_migration_id} = state()
57 with false <- is_nil(data_migration_id),
59 DataMigration.update_one_by_id(data_migration_id,
65 true -> {:error, :nil_data_migration_id}
71 Agent.update(@reg_name, fn _state -> load_state_from_db() end)
75 Agent.get(@reg_name, & &1)
78 def get_data_key(key, default \\ nil) do
79 get_in(state(), [:data, key]) || default
82 def put_data_key(key, value) do
83 _ = persist_non_data_change(key, value)
85 Agent.update(@reg_name, fn state ->
86 put_in(state, [:data, key], value)
90 def increment_data_key(key, increment \\ 1) do
91 Agent.update(@reg_name, fn state ->
92 initial_value = get_in(state, [:data, key]) || 0
93 updated_value = initial_value + increment
94 put_in(state, [:data, key], updated_value)
98 defp persist_non_data_change(:state, value) do
99 with true <- get_data_key(:state) != value,
100 true <- value in Pleroma.DataMigration.State.__valid_values__(),
101 %{data_migration_id: data_migration_id} when not is_nil(data_migration_id) <-
103 DataMigration.update_one_by_id(data_migration_id, state: value)
106 _ -> {:error, :nil_data_migration_id}
110 defp persist_non_data_change(_, _) do
114 def data_migration_id, do: Map.get(state(), :data_migration_id)