Skuld.Effects.Port.Repo.Contract behaviour (skuld v0.23.0)
View SourcePort contract for common Ecto Repo operations.
Provides defport declarations for the standard write and read operations
from Ecto.Repo, so that domain code using Port for database access
doesn't need to redeclare these with identical boilerplate.
Write Operations
Write operations return {:ok, struct()} | {:error, Ecto.Changeset.t()}
and auto-generate bang variants (insert!, update!, delete!) that
unwrap the success value or dispatch Throw on error.
Bulk Operations
insert_all/3, update_all/3 and delete_all/2 follow Ecto's return
convention of {count, nil | list}. No bang variants are generated for
these.
Read Operations
Read operations follow Ecto's conventions: get/2, get_by/2, one/1
return nil on not-found; all/1 returns a list; exists?/1 returns
a boolean; aggregate/3 returns a term.
Bang read variants (get!/2, get_by!/2, one!/1) are provided as
separate port operations that mirror Ecto's raise-on-not-found semantics.
In the effectful context these dispatch Throw instead of raising.
Example
alias Skuld.Effects.Port.Repo
use Skuld.Syntax
defcomp create_user(attrs) do
changeset = User.changeset(%User{}, attrs)
user <- Repo.EffectPort.insert!(changeset)
return(user)
end
defcomp find_user(id) do
user <- Repo.EffectPort.get(User, id)
return(user)
end
Summary
Callbacks
@callback aggregate(queryable :: Ecto.Queryable.t(), aggregate :: atom(), field :: atom()) :: term()
@callback all(queryable :: Ecto.Queryable.t()) :: [struct()]
@callback delete(record :: struct()) :: {:ok, struct()} | {:error, Ecto.Changeset.t()}
@callback delete_all(queryable :: Ecto.Queryable.t(), opts :: keyword()) :: {non_neg_integer(), nil | list()}
@callback exists?(queryable :: Ecto.Queryable.t()) :: boolean()
@callback get(queryable :: Ecto.Queryable.t(), id :: term()) :: struct() | nil
@callback get!(queryable :: Ecto.Queryable.t(), id :: term()) :: struct()
@callback get_by(queryable :: Ecto.Queryable.t(), clauses :: keyword() | map()) :: struct() | nil
@callback get_by!(queryable :: Ecto.Queryable.t(), clauses :: keyword() | map()) :: struct()
@callback insert(changeset :: Ecto.Changeset.t()) :: {:ok, struct()} | {:error, Ecto.Changeset.t()}
@callback insert_all( source :: Ecto.Queryable.t() | binary(), entries :: [map() | keyword()], opts :: keyword() ) :: {non_neg_integer(), nil | list()}
@callback one(queryable :: Ecto.Queryable.t()) :: struct() | nil
@callback one!(queryable :: Ecto.Queryable.t()) :: struct()
@callback update(changeset :: Ecto.Changeset.t()) :: {:ok, struct()} | {:error, Ecto.Changeset.t()}
@callback update_all( queryable :: Ecto.Queryable.t(), updates :: keyword(), opts :: keyword() ) :: {non_neg_integer(), nil | list()}