defmodule Kaffy.ResourceCallbacks do @moduledoc false alias Kaffy.Utils def create_callbacks(conn, resource, changes) do changeset = Kaffy.ResourceAdmin.create_changeset(resource, changes) repo = Kaffy.Utils.repo() repo.transaction(fn -> result = with {:ok, changeset} <- before_insert(conn, resource, changeset), {:ok, changeset} <- before_save(conn, resource, changeset), {:ok, entry} <- exec_insert(conn, resource, changeset), {:ok, entry} <- after_save(conn, resource, entry), do: after_insert(conn, resource, entry) case result do {:ok, entry} -> entry {:error, changeset} -> repo.rollback(changeset) {:error, entry, error} -> repo.rollback({entry, error}) end end) end defp exec_insert(conn, resource, changeset) do with {:ok, entry} <- insert(conn, resource, changeset) do {:ok, entry} else {:error, :not_found} -> Kaffy.Utils.repo().insert(changeset) unexpected_error -> {:error, unexpected_error} end end def update_callbacks(conn, resource, entry, changes) do changeset = Kaffy.ResourceAdmin.update_changeset(resource, entry, changes) repo = Kaffy.Utils.repo() repo.transaction(fn -> result = with {:ok, changeset} <- before_update(conn, resource, changeset), {:ok, changeset} <- before_save(conn, resource, changeset), {:ok, entry} <- exec_update(conn, resource, changeset), {:ok, entry} <- after_save(conn, resource, entry), do: after_update(conn, resource, entry) case result do {:ok, entry} -> entry {:error, changeset} -> repo.rollback(changeset) {:error, entry, error} -> repo.rollback({entry, error}) end end) end defp exec_update(conn, resource, changeset) do with {:ok, entry} <- update(conn, resource, changeset) do {:ok, entry} else {:error, :not_found} -> Kaffy.Utils.repo().update(changeset) unexpected_error -> {:error, unexpected_error} end end def delete_callbacks(conn, resource, entry) do repo = Kaffy.Utils.repo() repo.transaction(fn -> result = with {:ok, changeset} <- before_delete(conn, resource, entry), {:ok, entry} <- exec_delete(conn, resource, changeset), do: after_delete(conn, resource, entry) case result do {:ok, entry} -> entry {:error, changeset} -> repo.rollback(changeset) {:error, entry, error} -> repo.rollback({entry, error}) end end) end defp before_insert(conn, resource, changeset) do Utils.get_assigned_value_or_default( resource, :before_insert, {:ok, changeset}, [conn, changeset], false ) end defp insert(conn, resource, changeset) do Utils.get_assigned_value_or_default( resource, :insert, {:error, :not_found}, [conn, changeset], false ) end defp after_insert(conn, resource, entry) do Utils.get_assigned_value_or_default( resource, :after_insert, {:ok, entry}, [conn, entry], false ) end defp before_update(conn, resource, changeset) do Utils.get_assigned_value_or_default( resource, :before_update, {:ok, changeset}, [conn, changeset], false ) end defp before_save(conn, resource, changeset) do Utils.get_assigned_value_or_default( resource, :before_save, {:ok, changeset}, [conn, changeset], false ) end defp after_save(conn, resource, entry) do Utils.get_assigned_value_or_default(resource, :after_save, {:ok, entry}, [conn, entry], false) end defp update(conn, resource, changeset) do Utils.get_assigned_value_or_default( resource, :update, {:error, :not_found}, [conn, changeset], false ) end defp after_update(conn, resource, entry) do Utils.get_assigned_value_or_default( resource, :after_update, {:ok, entry}, [conn, entry], false ) end defp exec_delete(conn, resource, changeset) do with {:ok, entry} <- delete(conn, resource, changeset) do {:ok, entry} else {:error, :not_found} -> Kaffy.Utils.repo().delete(changeset) unexpected_error -> {:error, unexpected_error} end end defp before_delete(conn, resource, entry) do changeset = Kaffy.ResourceAdmin.update_changeset(resource, entry, %{}) Utils.get_assigned_value_or_default( resource, :before_delete, {:ok, changeset}, [conn, changeset], false ) end defp delete(conn, resource, changeset) do Utils.get_assigned_value_or_default( resource, :delete, {:error, :not_found}, [conn, changeset], false ) end defp after_delete(conn, resource, entry) do # changeset = Kaffy.ResourceAdmin.update_changeset(resource, entry, %{}) Utils.get_assigned_value_or_default( resource, :after_delete, {:ok, entry}, [conn, entry], false ) end end