defmodule MishkaInstaller.Plugin do
@moduledoc """
This module is for communication with `Plugins` table and has essential functions such as
adding, editing, deleting, and displaying.
This module is related to module `MishkaInstaller.Database.PluginSchema`.
"""
alias MishkaInstaller.Database.PluginSchema
alias MishkaInstaller.PluginState
import Ecto.Query
use MishkaDeveloperTools.DB.CRUD,
module: PluginSchema,
error_atom: :plugin,
repo: MishkaInstaller.repo()
@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
@doc """
This is an aggregation function that includes editing or adding by name of plugin.
"""
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
@doc """
Show plugins by event name or all the plugin.
"""
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
@doc """
Delete all the plugins of an event by an event name.
"""
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