Packages

A version control system for RDF datasets.

Current section

Files

Jump to
ontogen lib ontogen.ex
Raw

lib/ontogen.ex

defmodule Ontogen do
use GenServer
alias Ontogen.{Service, Repository, ConfigError}
alias Ontogen.Operation.{Query, Command}
import Ontogen.Operation, only: [include_api: 1]
include_api Ontogen.Operations.BootCommand
include_api Ontogen.Operations.SetupCommand
include_api Ontogen.Operations.CleanCommand
include_api Ontogen.Operations.CommitCommand
include_api Ontogen.Operations.RevertCommand
include_api Ontogen.Operations.EffectiveChangesetQuery
include_api Ontogen.Operations.ChangesetQuery
include_api Ontogen.Operations.RevisionQuery
include_api Ontogen.Operations.HistoryQuery
include_api Ontogen.Operations.DatasetQuery
include_api Ontogen.Operations.RepositoryQuery
@allow_configless_mode Application.compile_env(:ontogen, :allow_configless_mode, false)
@env Application.compile_env(:ontogen, :env, Mix.env())
def env, do: @env
def ansi_enabled? do
Application.get_env(:ontogen, :ansi_enabled, true)
end
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end
def status, do: GenServer.call(__MODULE__, :status)
def service, do: GenServer.call(__MODULE__, :service)
def store, do: GenServer.call(__MODULE__, :store)
def dataset_info, do: GenServer.call(__MODULE__, :dataset_info)
def history_info, do: GenServer.call(__MODULE__, :history_info)
def head, do: GenServer.call(__MODULE__, :head)
def reload, do: GenServer.call(__MODULE__, :reload)
############################################################################
# Server (callbacks)
@impl true
def init(opts) do
{:ok, nil, {:continue, {:boot, opts}}}
end
@impl true
def handle_continue({:boot, opts}, _) do
case BootCommand.call(opts) do
{:ok, service} ->
{:noreply, service}
{:error, error} ->
if @allow_configless_mode do
{:noreply, {:error, error}}
else
{:stop, error}
end
end
end
@impl true
def handle_call(%BootCommand{} = operation, from, {:error, _}),
do: handle_call(operation, from, nil)
def handle_call(%BootCommand{} = operation, from, nil),
do: handle_call(operation, from, Ontogen.Config.service!())
def handle_call(%BootCommand{} = operation, _from, service) do
case BootCommand.call(operation, service) do
{:ok, service} -> {:reply, {:ok, service}, service}
{:error, _} = error -> {:reply, error, service}
end
end
def handle_call(:status, _from, {:error, error}),
do: {:reply, ConfigError.exception(reason: error), {:error, error}}
def handle_call(:status, _from, nil), do: {:reply, :unconfigured, nil}
def handle_call(:status, _from, service), do: {:reply, service.status, service}
def handle_call(_operation, _from, nil) do
{:reply, {:error, ConfigError.exception(reason: :missing)}, nil}
end
def handle_call(_operation, _from, {:error, error}) do
{:reply, {:error, ConfigError.exception(reason: error)}, {:error, error}}
end
def handle_call(:service, _from, service), do: {:reply, service, service}
def handle_call(:store, _from, service), do: {:reply, service.store, service}
def handle_call(:dataset_info, _from, service),
do: {:reply, service.repository.dataset, service}
def handle_call(:history_info, _from, service),
do: {:reply, service.repository.history, service}
def handle_call(%SetupCommand{} = operation, _from, %Service{status: :not_setup} = service) do
case SetupCommand.call(operation, service) do
{:ok, service} -> {:reply, {:ok, service}, service}
{:error, _} = error -> {:reply, error, service}
end
end
def handle_call(%SetupCommand{}, _from, service) do
{:reply, {:error, Repository.SetupError.exception(service: service, reason: :already_setup)},
service}
end
def handle_call(operation, _from, %{status: :not_setup} = service) do
{:reply, {:error, Repository.NotSetupError.exception(service: service, operation: operation)},
service}
end
def handle_call(:head, _from, service) do
{:reply, service.repository.head, service}
end
def handle_call(%operation{type: Query} = query, _from, service) do
case apply(operation, :call, [query, service]) do
{:ok, result} -> {:reply, {:ok, result}, service}
{:error, _} = error -> {:reply, error, service}
end
end
def handle_call(%operation{type: Command} = command, _from, service) do
case apply(operation, :call, [command, service]) do
{:ok, %Service{} = service} -> {:reply, :ok, service}
{:ok, %Service{} = service, result} -> {:reply, {:ok, result}, service}
{:error, _} = error -> {:reply, error, service}
end
end
end