# SPDX-License-Identifier: Apache-2.0
defmodule BitcrowdEcto.Schema do
@moduledoc """
An opinionated set of defaults for Ecto schemas.
* Uses `Ecto.Schema` and imports `Ecto.Changeset` and `BitcrowdEcto.Changeset`
* Configures an autogenerated PK of type `binary_id`
* Configures FKs to be of type `binary_id`
* Sets timestamp type to `utc_datetime_usec`
* Defines a type `t` as a struct of the schema module.
* Defines an `id` type
## Usage
defmodule MyApp.MySchema do
use BitcrowdEcto.Schema
end
Or if you table lives in a different Postgres schema:
defmodule MyApp.MySchema do
use BitcrowdEcto.Schema, prefix: "foo"
end
"""
@moduledoc since: "0.1.0"
defmacro __using__(opts) do
schema_prefix =
if prefix = Keyword.get(opts, :prefix) do
quote do
@schema_prefix unquote(prefix)
end
end
quote do
use Ecto.Schema
import Ecto.Changeset
import BitcrowdEcto.Changeset
unquote(schema_prefix)
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
@timestamps_opts [type: :utc_datetime_usec]
@type t :: %__MODULE__{}
@type id :: binary
end
end
@doc """
Safely converts a string into an enum member atom. Returns nil if conversion is not posssible.
## Example
iex> to_enum_member(TestEnumSchema, :some_enum, "foo")
:foo
"""
@doc since: "0.9.0"
@spec to_enum_member(schema :: module, field :: atom, value :: any) :: term | nil
def to_enum_member(schema, field, value) when is_atom(value) do
to_enum_member(schema, field, to_string(value))
end
def to_enum_member(schema, field, value) do
schema
|> Ecto.Enum.mappings(field)
|> Enum.find_value(fn {member, member_mapping} ->
if value == member_mapping, do: member
end)
end
@doc """
Safely converts a string into an enum member atom. Raises if conversion is not possible.
"""
@doc since: "0.9.0"
@spec to_enum_member!(schema :: module, field :: atom, value :: any) :: term | no_return
def to_enum_member!(schema, field, value) do
to_enum_member(schema, field, value) ||
raise ArgumentError, """
#{inspect(value)} is not a member of enum #{inspect(field)} of schema #{inspect(schema)}!
"""
end
end