Ok, so few years have passed. Why it took so long? It simply didn’t took any time. I’ve got just a single question if this library is maintained. I said yes, but so far no issue, pull request or even a question was created.
Therefore I was just using this project for my personal purposes and slowly refactoring it when needed. I think the completely new code is much better now. The documentation should also be much cleaner. This is a first release on hex simply because I’m not pushing initial library code or first release candidates.
enumex have a new DSL. From now on you start with as simple code as possible and extend it by adding components. Therefore there is no convention forced to your enum module. You can use a component to integrate ecto or write your own easily.
defmodule MyApp.StaticEnums do
use Enumex.Static,
components: [
# Enumex.Static.Components.AbsinthePhase,
# Enumex.Static.Components.Constant,
# Enumex.Static.Components.EctoType,
# Enumex.Static.Components.Guards,
# Enumex.Static.Components.Index,
# Enumex.Static.Components.List,
# Enumex.Static.Components.Sort,
# Enumex.Static.Components.Typespecs
]
enum :my_enum, ~w[first second third]a
end
end
All compile-time state is written into ets storage which means there are no module attributes that you have to be aware of. That’s said some modules may use module attributes to integrate with other library. The simplest example here is Ecto.Schema integration (@primary_key and @schema_prefix).
What I like the most is a simple component system.
defmodule MyApp.MyComponent do
@moduledoc """
A component documentation
"""
use Enumex.Component
@doc """
A callback documentation
"""
@callback my_func :: :ok
comp [component: component_module] do
@behaviour component_module
@impl component_module
def my_func, do: :ok
end
end
You can start with a simple :string migration and end up with a PostgreSQL enumerated type or even work on runtime-determined values.
defmodule MyApp.DynamicEnums do
use Enumex.Dynamic,
components: [
# Enumex.Dynamic.Components.Context,
# Enumex.Dynamic.Components.Convert,
# Enumex.Dynamic.Components.EctoChangeset,
# Enumex.Dynamic.Components.EctoSchema,
# Enumex.Dynamic.Components.Typespecs
],
repo: MyApp.Repo
enum ModulePart, :enum_name do
# additional code like extra ecto schema fields
end
end
Now working with enums in Elixir, PostgreSQL or even SQLite is as simple as adding a component. ![]()
Anyone who depends on enumerated types can use Postgres adapter directly or Migration wrapper. With such features migrations are very easy to setup without a need to learn how to execute create type … sql. What’s best all migrations can be used safely on untrusted values. In my case I have used a test name as enum name. The adapter handles even the most weird cases. ![]()
defmodule ExampleMigration do
use Ecto.Migration
alias Enumex.Static.Adapters.Postgres
alias Enumex.Static.Migration
alias Enumex.Value
@first_value Value.new(ExampleEnum, :example, :firstt, 1)
@second_value Value.new(ExampleEnum, :example, :second, 2)
@third_value Value.new(ExampleEnum, :example, :third, 3)
def change do
Migration.create_enum(Postgres, [@first_value, @third_value])
Migration.rename_value(Postgres, @first_value, %{@first_value | id: :first})
# when rollback use `@first_value` as a default when dropping `:second` value from enumerated type
Migration.add_value(Postgres, @second_value, @first_value)
# when migrate use `@second_value` as a default when dropping `:third` value from enumerated type
Migration.drop_value(Postgres, @third_value, @second_value)
end
end






















