# Pleroma: A lightweight social networking server # Copyright © 2017-2021 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Migrators.HashtagsTableMigrator.State do use Agent alias Pleroma.DataMigration defdelegate data_migration(), to: Pleroma.Migrators.HashtagsTableMigrator @reg_name {:global, __MODULE__} def start_link(_) do Agent.start_link(fn -> load_state_from_db() end, name: @reg_name) end defp load_state_from_db do data_migration = data_migration() data = if data_migration do Map.new(data_migration.data, fn {k, v} -> {String.to_atom(k), v} end) else %{} end %{ data_migration_id: data_migration && data_migration.id, data: data } end def persist_to_db do %{data_migration_id: data_migration_id, data: data} = state() if data_migration_id do DataMigration.update_one_by_id(data_migration_id, data: data) else {:error, :nil_data_migration_id} end end def reset do %{data_migration_id: data_migration_id} = state() with false <- is_nil(data_migration_id), :ok <- DataMigration.update_one_by_id(data_migration_id, state: :pending, data: %{} ) do reinit() else true -> {:error, :nil_data_migration_id} e -> e end end def reinit do Agent.update(@reg_name, fn _state -> load_state_from_db() end) end def state do Agent.get(@reg_name, & &1) end def get_data_key(key, default \\ nil) do get_in(state(), [:data, key]) || default end def put_data_key(key, value) do _ = persist_non_data_change(key, value) Agent.update(@reg_name, fn state -> put_in(state, [:data, key], value) end) end def increment_data_key(key, increment \\ 1) do Agent.update(@reg_name, fn state -> initial_value = get_in(state, [:data, key]) || 0 updated_value = initial_value + increment put_in(state, [:data, key], updated_value) end) end defp persist_non_data_change(:state, value) do with true <- get_data_key(:state) != value, true <- value in Pleroma.DataMigration.State.__valid_values__(), %{data_migration_id: data_migration_id} when not is_nil(data_migration_id) <- state() do DataMigration.update_one_by_id(data_migration_id, state: value) else false -> :ok _ -> {:error, :nil_data_migration_id} end end defp persist_non_data_change(_, _) do nil end def data_migration_id, do: Map.get(state(), :data_migration_id) end