defmodule MishkaInstaller.Plugin do alias MishkaInstaller.Database.PluginSchema alias MishkaInstaller.PluginState import Ecto.Query use MishkaDeveloperTools.DB.CRUD, module: PluginSchema, error_atom: :plugin, repo: MishkaInstaller.repo @type data_uuid() :: Ecto.UUID.t @type record_input() :: map() @type error_tag() :: :plugin @type repo_data() :: Ecto.Schema.t() @type repo_error() :: Ecto.Changeset.t() @behaviour MishkaDeveloperTools.DB.CRUD @doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_add, 1} def create(attrs) do crud_add(attrs) end @doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_add, 1} def create(attrs, allowed_fields) do crud_add(attrs, allowed_fields) end @doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_edit, 1} def edit(attrs) do crud_edit(attrs) end @doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_edit, 1} def edit(attrs, allowed_fields) do crud_edit(attrs, allowed_fields) end @doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_delete, 1} def delete(id) do crud_delete(id) end @doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_get_record, 1} def show_by_id(id) do crud_get_record(id) end @doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_get_by_field, 2} def show_by_name(name) do crud_get_by_field("name", name) end def add_or_edit_by_name(state) do case show_by_name("#{state.name}") do {:ok, :get_record_by_field, :plugin, repo_data} -> edit(state |> Map.merge(%{id: repo_data.id})) _ -> create(state) end end def plugins(event: event) do from(plg in PluginSchema, where: plg.event == ^event) |> fields() |> MishkaInstaller.repo.all() |> Enum.map(&struct(PluginState, &1)) end def plugins() do from(plg in PluginSchema) |> fields() |> MishkaInstaller.repo.all() |> Enum.map(&struct(PluginState, &1)) end defp fields(query) do from [plg] in query, order_by: [desc: plg.inserted_at, desc: plg.id], select: %{ name: plg.name, event: plg.event, priority: plg.priority, status: plg.status, depend_type: plg.depend_type, depends: plg.depends } end def delete_plugins(event) do stream = MishkaInstaller.repo.stream(from(plg in PluginSchema)) MishkaInstaller.repo.transaction(fn() -> stream |> Stream.filter(&(event in &1.depends)) |> Enum.to_list() end) |> case do {:ok, []} -> [] {:ok, list} -> list |> Task.async_stream(&MishkaInstaller.Hook.unregister(module: &1.name), max_concurrency: 20) |> Stream.run error -> IO.inspect(error) end end end