isn/lib/isn.ex

92 lines
2.1 KiB
Elixir
Raw Normal View History

defmodule Isn do
alias Postgrex.TypeInfo
@behaviour Postgrex.Extension
@isn ~w(ean13 isbn13 ismn13 issn13 isbn ismn issn upc)
2015-05-27 17:33:15 +00:00
@moduledoc """
A Postgrex.Extension enabling the use of postgresql data types from the isn
extension.
Add this module as an extension when establishing your Postgrex connection:
Postgrex.Connection.start_link(
database: "isn_test",
extensions: [{Isn, {}}])
Then you can do Ecto.Migrations like this:
defmodule MyApp.Repo.Migrations.CreateBook do
use Ecto.Migration
def change do
create table(:books) do
add :isbn, :isbn13
# other fields
end
end
end
You can also define Ecto.Models using the matching custom Ecto.Types:
defmodule MyApp.Book do
use MyApp.Web, :model
schema "books" do
field :isbn, Isn.ISBN13
# other fields
end
end
"""
def init(parameters, _opts),
do: parameters
2015-10-03 19:45:47 +00:00
def matching(_),
do: Enum.zip(Stream.cycle([:type]), @isn)
def format(_),
do: :text
def encode(%TypeInfo{type: type}, binary, _types, _opts) when type in @isn,
do: binary
def decode(%TypeInfo{type: type}, binary, _types, _opts) when type in @isn,
do: binary
end
# Generate Ecto.Type modules for all supported data types in the `isn`
# postgresql module.
for module <- ~w(ISBN ISMN ISSN ISBN13 ISMN13 ISSN13 UPC EAN13) do
module_name = Module.concat([Isn, module])
ecto_type = module |> String.downcase |> String.to_atom
defmodule module_name do
@behaviour Ecto.Type
@moduledoc """
Definition for the Isn.#{module} module.
2015-05-27 17:33:15 +00:00
How to use this in an Ecto.Model
2015-05-27 17:33:15 +00:00
defmodule MyApp.Book do
use MyApp.Web, :model
2015-05-27 17:33:15 +00:00
schema "books" do
field :#{ecto_type}, Isn.#{module}
# other fields
end
end
"""
def type, do: unquote(ecto_type)
def cast(nil), do: :error
def cast(isn), do: {:ok, to_string(isn)}
def load(isn), do: {:ok, to_string(isn)}
def dump(isn), do: {:ok, to_string(isn)}
end
end