defmodule UltraPlug.Repository do @moduledoc """ Accesses the configured repo. TODO: Document configuration TODO: Document options """ import Plug.Conn @repo Application.get_env(:ultra_plug, :repo) def init(opts) do {assign_to, [{action, source}]} = Keyword.pop(opts, :assign_to) assign_to = assign_to || detect_assign_to(source, action == :all) {action, source, assign_to} end defp detect_assign_to(source, plural?) do if Kernel.function_exported?(source, :__schema__, 1) do schema_name(source, plural?) else source end end defp schema_name(source, true) do source |> apply(:__schema__, [:source]) |> String.to_atom end defp schema_name(source, false) do source |> to_string |> Mix.Phoenix.inflect |> Keyword.get(:singular) |> String.to_atom end def call(conn, opts \\ []) def call(conn = %{assigns: %{error: _}}, _) do conn end def call(conn, {:all, source, assign_to}) do result = apply(@repo, :all, [source]) assign(conn, assign_to, result) end def call(conn, {:delete!, source, assign_to}) do result = apply(@repo, :delete!, [conn.assigns[source]]) assign(conn, assign_to, result) end def call(conn, {:get!, source, assign_to}) do result = apply(@repo, :get!, [source, conn.params["id"]]) assign(conn, assign_to, result) end def call(conn, {:insert, source, assign_to}) do case apply(@repo, :insert, [conn.assigns[source]]) do {:error, error} -> assign(conn, :error, error) {:ok, result} -> assign(conn, assign_to, result) end end def call(conn, {:insert!, source, assign_to}) do result = apply(@repo, :insert!, [conn.assigns[source]]) assign(conn, assign_to, result) end def call(conn, {:update, source, assign_to}) do case apply(@repo, :update, [conn.assigns[source]]) do {:error, error} -> assign(conn, :error, error) {:ok, result} -> assign(conn, assign_to, result) end end def call(conn, opts) when is_list(opts) do call(conn, init(opts)) end end