Skip to content

Instantly share code, notes, and snippets.

@talentdeficit
Created July 4, 2017 03:38
Show Gist options
  • Save talentdeficit/f9811be8a8acb495beb65092e24098cc to your computer and use it in GitHub Desktop.
Save talentdeficit/f9811be8a8acb495beb65092e24098cc to your computer and use it in GitHub Desktop.
defmodule Filter do
require Ecto.Query
@max_id 2147483647
@max_clock 9223372036854775807
@max_limit 1000
defstruct valid?: true, query: nil, limit: 1000, errors: []
def filter(%Filter{} = s, { "key", key }) do
filter(s, { "key.eq", key })
end
def filter(%Filter{} = s, { "key.eq", key }) do
case s.valid? do
true -> %{ s | query: Query.dynamic([t], t.key == ^key and ^s.query) }
false -> s
end
end
def filter(%Filter{} = s, { "key.in", keys }) do
keys = keys |> String.split(",")
case s.valid? do
true -> %{ s | query: Query.dynamic([t], t.key in ^keys and ^s.query) }
false -> s
end
end
## identical to `clock.eq`
def filter(%Filter{} = s, { "clock", clock }) do
filter(s, { "clock.eq", clock })
end
def filter(%Filter{} = s, { "clock.eq", clock }) do
try do
clock |> Filter.verify_clock
case s.valid? do
true -> %{ s | query: Query.dynamic([t], t.clock == ^clock and ^s.query) }
false -> s
end
rescue _ in [ ArgumentError ] ->
msg = "is not a valid clock"
error = [ { :clock, { msg, [] } } ]
%{ s | valid?: false, errors: s.errors ++ error }
end
end
def filter(%Filter{} = s, { "clock.gt", clock }) do
try do
clock |> Filter.verify_clock
case s.valid? do
true -> %{ s | query: Query.dynamic([t], t.clock > ^clock and ^s.query) }
false -> s
end
rescue _ in [ ArgumentError ] ->
msg = "is not a valid clock"
error = [ { :clock, { msg, [] } } ]
%{ s | valid?: false, errors: s.errors ++ error }
end
end
def filter(%Filter{} = s, { "clock.gte", clock }) do
try do
clock |> Filter.verify_clock
case s.valid? do
true -> %{ s | query: Query.dynamic([t], t.clock >= ^clock and ^s.query) }
false -> s
end
rescue _ in [ ArgumentError ] ->
msg = "is not a valid clock"
error = [ { :clock, { msg, [] } } ]
%{ s | valid?: false, errors: s.errors ++ error }
end
end
def filter(%Filter{} = s, { "clock.lt", clock }) do
try do
clock |> Filter.verify_clock
case s.valid? do
true -> %{ s | query: Query.dynamic([t], t.clock < ^clock and ^s.query) }
false -> s
end
rescue _ in [ ArgumentError ] ->
msg = "is not a valid clock"
error = [ { :clock, { msg, [] } } ]
%{ s | valid?: false, errors: s.errors ++ error }
end
end
def filter(%Filter{} = s, { "clock.lte", clock }) do
try do
clock |> Filter.verify_clock
case s.valid? do
true -> %{ s | query: Query.dynamic([t], t.clock <= ^clock and ^s.query) }
false -> s
end
rescue _ in [ ArgumentError ] ->
msg = "is not a valid clock"
error = [ { :clock, { msg, [] } } ]
%{ s | valid?: false, errors: s.errors ++ error }
end
end
def filter(%Filter{} = s, { "limit", limit }) do
try do
limit |> Filter.verify_limit
case s.valid? do
true -> %{ s | limit: limit }
false -> s
end
rescue _ in [ ArgumentError ] ->
msg = "is not a valid limit"
error = [ { :limit, { msg, [] } } ]
%{ s | valid?: false, errors: s.errors ++ error }
end
end
def verify_id(id) when id > 0 and id <= @max_id, do: id
def verify_id(_), do: raise ArgumentError
def verify_clock(clock) when clock > 0 and clock <= @max_clock, do: clock
def verify_clock(_), do: raise ArgumentError
def verify_limit(limit) when limit > 0 and limit <= @max_limit, do: limit
def verify_id(_), do: raise ArgumentError
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment