defmodule MishkaInstaller.Dependency do
@moduledoc """
This module can hold your dependencies' information in database
> Do not use these functions directly, because we do not update JSON file in this module, some functions were prepared in DepHandler module for you.
"""
alias MishkaInstaller.Database.DependencySchema
alias MishkaInstaller.Installer.DepHandler
import Ecto.Query
use MishkaDeveloperTools.DB.CRUD,
module: DependencySchema,
error_atom: :dependency,
repo: MishkaInstaller.repo()
@behaviour MishkaDeveloperTools.DB.CRUD
@doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_add, 1}
def create(attrs) do
crud_add(attrs)
|> notify_subscribers(:dependency)
end
@doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_add, 1}
def create(attrs, allowed_fields) do
crud_add(attrs, allowed_fields)
|> notify_subscribers(:dependency)
end
@doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_edit, 1}
def edit(attrs) do
crud_edit(attrs)
|> notify_subscribers(:dependency)
end
@doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_edit, 1}
def edit(attrs, allowed_fields) do
crud_edit(attrs, allowed_fields)
|> notify_subscribers(:dependency)
end
@doc delegate_to: {MishkaDeveloperTools.DB.CRUD, :crud_delete, 1}
def delete(id) do
crud_delete(id)
|> notify_subscribers(:dependency)
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(app) do
crud_get_by_field("app", app)
end
def update_app_version(id, data) do
crud_edit(
Map.merge(convert_map_from_atom_to_string(data), %{
"id" => id,
"dependency_type" => "force_update"
})
)
end
@spec create_or_update(map()) :: tuple()
def create_or_update(data) do
case show_by_name(data.app) do
{:error, :get_record_by_field, :dependency} ->
create(data)
{:ok, :get_record_by_field, :dependency, record_info} ->
if Version.compare(data.version, record_info.version) == :gt do
update_app_version(record_info.id, data)
else
{:error, :update_app_version, :older_version}
end
end
end
def dependencies() do
from(dep in DependencySchema)
|> fields()
|> MishkaInstaller.repo().all()
end
def dependencies(:struct) do
dependencies()
|> Enum.map(&struct(DepHandler, &1))
end
@spec change_dependency_type_with_app(String.t(), String.t()) ::
{:ok, :change_dependency_type_with_app, map()}
| {:error, :change_dependency_type_with_app, :dependency, atom() | map()}
def change_dependency_type_with_app(app, dependency_type) do
with {:ok, :get_record_by_field, :dependency, record_info} <-
MishkaInstaller.Dependency.show_by_name(app),
{:ok, :edit, :dependency, repo_data} <-
MishkaInstaller.Dependency.edit(%{
"id" => record_info.id,
"dependency_type" => dependency_type
}) do
{:ok, :change_dependency_type_with_app, repo_data}
else
{:error, :get_record_by_field, :dependency} ->
{:error, :change_dependency_type_with_app, :dependency, :not_found}
{:error, :edit, action, :dependency} when action in [:uuid, :get_record_by_id] ->
{:error, :change_dependency_type_with_app, :dependency, :not_found}
{:error, :edit, :dependency, repo_error} ->
{:error, :change_dependency_type_with_app, :dependency, repo_error}
end
end
defp fields(query) do
from([dep] in query,
order_by: [desc: dep.inserted_at, desc: dep.id],
select: %{
app: dep.app,
version: dep.version,
type: dep.type,
url: dep.url,
git_tag: dep.git_tag,
custom_command: dep.custom_command,
dependency_type: dep.dependency_type,
dependencies: dep.dependencies
}
)
end
def subscribe do
Phoenix.PubSub.subscribe(
MishkaInstaller.get_config(:pubsub) || MishkaInstaller.PubSub,
"dependency"
)
end
if Mix.env() == :test do
def notify_subscribers(params, _type_send), do: params
else
def notify_subscribers({:ok, action, :dependency, repo_data} = params, type_send) do
Phoenix.PubSub.broadcast(
MishkaInstaller.get_config(:pubsub) || MishkaInstaller.PubSub,
"dependency",
{:ok, type_send, action, repo_data}
)
params
end
def notify_subscribers(params, _), do: params
end
defp convert_map_from_atom_to_string(map) do
for {key, val} <- map, into: %{} do
{to_string(key), to_string(val)}
end
end
end