-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from circles-learning-labs/add_multiranges
Add support for multirange types
- Loading branch information
Showing
11 changed files
with
231 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
defmodule PgMultiranges do | ||
@moduledoc """ | ||
PgMultiranges provides a simple wrapper around `Postgrex.Multirange`. | ||
The behaviour is an extension of `PgRanges`, with each multi type implemented | ||
as a list of the base type. For example, `PgRanges.Int4Multirange` takes a list of | ||
`PgRanges.Int4Range` structs as its constructor argument. | ||
""" | ||
|
||
@callback new([map()]) :: any | ||
@callback new([{any, any, any}]) :: any | ||
@callback from_postgrex(any) :: any | ||
@callback to_postgrex(any) :: any | ||
|
||
@optional_callbacks [ | ||
new: 1, | ||
from_postgrex: 1, | ||
to_postgrex: 1 | ||
] | ||
|
||
@doc false | ||
|
||
defmacro __using__(opts) do | ||
subtype = opts[:subtype] | ||
|
||
if subtype == nil do | ||
raise ArgumentError, "#{inspect(__MODULE__)} must be used with the :subtype option" | ||
end | ||
|
||
subtype_opts = Keyword.drop(opts, [:subtype]) | ||
|
||
quote location: :keep, bind_quoted: [subtype: subtype, opts: subtype_opts] do | ||
alias Postgrex.Multirange | ||
|
||
use Ecto.Type | ||
@behaviour PgMultiranges | ||
@before_compile PgRanges | ||
|
||
@type t :: %__MODULE__{ranges: [unquote(subtype).t()]} | ||
|
||
defstruct [:ranges] | ||
|
||
@spec new([map()]) :: __MODULE__.t() | ||
def new(ranges, opts \\ []) do | ||
fields = Enum.map(ranges, &unquote(subtype).new(&1.lower, &1.upper, opts)) | ||
struct!(__MODULE__, %{ranges: fields}) | ||
end | ||
|
||
@doc false | ||
@spec from_postgrex(Multirange.t()) :: __MODULE__.t() | ||
def from_postgrex(%Multirange{ranges: ranges}), | ||
do: struct!(__MODULE__, %{ranges: Enum.map(ranges, &unquote(subtype).from_postgrex/1)}) | ||
|
||
@doc false | ||
@spec to_postgrex(__MODULE__.t()) :: Multirange.t() | ||
def to_postgrex(%__MODULE__{ranges: ranges}), | ||
do: struct!(Multirange, %{ranges: Enum.map(ranges, &unquote(subtype).to_postgrex/1)}) | ||
|
||
@doc false | ||
def cast(nil), do: {:ok, nil} | ||
def cast(%Multirange{} = range), do: {:ok, from_postgrex(range)} | ||
def cast(%__MODULE__{} = range), do: {:ok, range} | ||
def cast(_), do: :error | ||
|
||
@doc false | ||
def load(nil), do: {:ok, nil} | ||
def load(%Multirange{} = range), do: {:ok, from_postgrex(range)} | ||
def load(_), do: :error | ||
|
||
@doc false | ||
def dump(nil), do: {:ok, nil} | ||
def dump(%__MODULE__{} = range), do: {:ok, to_postgrex(range)} | ||
def dump(_), do: :error | ||
|
||
@doc false | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
defmodule PgRanges.DateMultirange do | ||
use PgMultiranges, subtype: PgRanges.DateRange | ||
|
||
@impl true | ||
@spec type() :: :datemultirange | ||
def type, do: :datemultirange | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
defmodule PgRanges.Int4Multirange do | ||
use PgMultiranges, subtype: PgRanges.Int4Range | ||
|
||
@impl true | ||
@spec type() :: :int4multirange | ||
def type, do: :int4multirange | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
defmodule PgRanges.Int8Multirange do | ||
use PgMultiranges, subtype: PgRanges.Int8Range | ||
|
||
@impl true | ||
@spec type() :: :int8multirange | ||
def type, do: :int8multirange | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
defmodule PgRanges.NumMultirange do | ||
use PgMultiranges, subtype: PgRanges.NumRange | ||
|
||
@impl true | ||
@spec type() :: :nummultirange | ||
def type, do: :nummultirange | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
defmodule PgRanges.TsMultirange do | ||
use PgMultiranges, subtype: PgRanges.TsRange | ||
|
||
@impl true | ||
@spec type() :: :tsmultirange | ||
def type, do: :tsmultirange | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
defmodule PgRanges.TstzMultirange do | ||
use PgMultiranges, subtype: PgRanges.TstzRange | ||
|
||
@impl true | ||
@spec type() :: :tstzmultirange | ||
def type, do: :tstzmultirange | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters