Make Reference call the NIF itself

This commit is contained in:
Carlos Martín Nieto
2014-08-03 02:08:44 +02:00
parent 808646a5ca
commit fffdb47032
4 changed files with 69 additions and 28 deletions

View File

@@ -4,44 +4,70 @@ defmodule Geef.Reference do
import Geef
alias Geef.Reference
record = Record.extract(:geef_reference, from: "src/geef_records.hrl")
keys = :lists.map(&elem(&1, 0), record)
vals = :lists.map(&{&1, [], nil}, keys)
pairs = :lists.zip(keys, vals)
defstruct keys
def to_record(%Geef.Reference{unquote_splicing(pairs)}) do
{:geef_reference, unquote_splicing(vals)}
end
def from_record({:geef_reference, unquote_splicing(vals)}) do
%Geef.Reference{unquote_splicing(pairs)}
end
defp maybe_ref({:ok, ref}), do: {:ok, Reference.from_record(ref)}
defp maybe_ref(err = {:error, _}), do: err
defstruct repo: nil, name: nil, type: nil, target: nil
def create(repo, name, target, force \\ :false) do
:geef_ref.create(repo, name, target, force) |> maybe_ref
# fixme: this needs to ask the repo itself
repo_handle = :geef_repo.handle(repo)
case :geef_nif.reference_create(repo_handle, name, :oid, target, force) do
:ok ->
{:ok, %Reference{repo: repo, name: name, type: :oid, target: target}}
error ->
error
end
end
def create!(repo, name, target, force \\ :false) do
create(repo, name, target, force) |> assert_ok
end
def create_symbolic(repo, name, target, force \\ :false) do
:geef_ref.create(repo, name, target, force) |> maybe_ref
# fixme: this needs to ask the repo itself
repo_handle = :geef_repo.handle(repo)
case :geef_nif.reference_create(repo_handle, name, :symbolic, target, force) do
:ok ->
{:ok, %Reference{repo: repo, name: name, type: :symbolic, target: target}}
error ->
error
end
end
def create_symbolic!(repo, name, target, force \\ :false) do
create(repo, name, target, force) |> assert_ok
create_symbolic(repo, name, target, force) |> assert_ok
end
def lookup(repo, name), do: :geef_ref.lookup(repo, name) |> maybe_ref
def lookup(repo, name) do
case :geef_repo.reference_lookup(repo, name) do
{:ok, type, target} ->
{:ok, %Reference{repo: repo, name: name, type: type, target: target}}
error ->
error
end
end
def lookup!(repo, name), do: lookup(repo, name) |> assert_ok
def resolve(ref = %Reference{}), do: :geef_ref.resolve(to_record(ref)) |> maybe_ref
# A direct referene is only ever going to be itself
def resolve(ref = %Reference{type: :oid}) do
{:ok, ref}
end
def resolve(%Reference{repo: repo, name: name}) do
case :geef_repo.reference_resolve(repo, name) do
{:ok, resolved_name, target} ->
{:ok, %Reference{repo: repo, name: resolved_name, type: :oid, target: target}}
error ->
error
end
end
def resolve!(ref = %Reference{}), do: resolve(ref) |> assert_ok
def dwim(repo, name), do: :geef_ref.dwim(repo, name) |> maybe_ref
def dwim(repo, name) do
case :geef_repo.reference_dwim(repo, name) do
{:ok, real_name, type, target} ->
{:ok, %Reference{repo: repo, name: real_name, type: type, target: target}}
error ->
error
end
end
def dwim!(repo, name), do: dwim(repo, name) |> assert_ok
def shorthand(%Reference{name: name}) do