defmodule Rediscl.Query.Pipe do
@moduledoc """
Pipe query builder
"""
defstruct [
:set,
:get,
:mset,
:mget,
:del,
:lpush,
:rpush,
:lrange,
:lrem,
:lset,
:append,
:exists,
:setex,
:setnx,
:setrange,
:psetex,
:getrange,
:getset,
:strlen,
:incr,
:incrby,
:incrbyfloat,
:msetnx,
:decr,
:decrby,
:sadd,
:scard,
:sdiff,
:sdiffstore,
:sinter,
:sinterstore,
:sismember,
:smembers,
:smove,
:spop,
:srandmember,
:srem,
:sscan,
:sunion,
:sunionstore,
:zadd,
:zcard,
:zcount,
:zincrby,
:zinter,
:zinterstore,
:zlexcount,
:zrange,
:zrangebylex,
:zrangebyscore,
:zrank,
:zrem,
:zremrangebylex,
:zremrangebyrank,
:zremrangebyscore,
:zrevrange,
:zrevrangebylex,
:zrevrangebyscore,
:zrevrank,
:zscore,
:zunion,
:zunionstore,
:zscan
]
@pipes [
:set,
:get,
:mset,
:mget,
:del,
:lpush,
:rpush,
:lrange,
:lrem,
:lset,
:append,
:exists,
:setex,
:setnx,
:setrange,
:psetex,
:getrange,
:getset,
:strlen,
:incr,
:incrby,
:incrbyfloat,
:msetnx,
:decr,
:decrby,
:sadd,
:scard,
:sdiff,
:sdiffstore,
:sinter,
:sinterstore,
:sismember,
:smembers,
:smove,
:spop,
:srandmember,
:srem,
:sscan,
:sunion,
:sunionstore,
:zadd,
:zcard,
:zcount,
:zincrby,
:zinter,
:zinterstore,
:zlexcount,
:zrange,
:zrangebylex,
:zrangebyscore,
:zrank,
:zrem,
:zremrangebylex,
:zremrangebyrank,
:zremrangebyscore,
:zrevrange,
:zrevrangebylex,
:zrevrangebyscore,
:zrevrank,
:zscore,
:zunion,
:zunionstore,
:zscan
]
import Rediscl.Query.Api
defmacro begin(pipes \\ []) when is_list(pipes) do
build(pipes)
end
@doc ""
def build(pipes) when is_list(pipes) do
Enum.into(pipes, %{})
|> Enum.map(&build(&1))
end
def build({type, expr}) when type in @pipes do
build(type, expr)
end
def build(type, expr) when type == :exists and is_binary(expr) do
exists(expr)
end
def build(type, expr) when type == :append and is_list(expr) do
unless Enum.count(expr) == 2 and Enum.any?(expr, &typeof!(&1)),
do: raise(ArgumentError, "append given parameters not valid")
append(Enum.at(expr, 0), Enum.at(expr, 0))
end
def build(type, expr) when type == :set and is_list(expr) do
unless Enum.count(expr) == 2 and Enum.any?(expr, &typeof!(&1)),
do: raise(ArgumentError, "set given parameters not valid")
set(Enum.at(expr, 0), Enum.at(expr, 1))
end
def build(type, expr) when type == :setex and is_list(expr) do
unless Enum.count(expr) == 3 and typeof!(Enum.at(expr, 0)) and
is_integer(Enum.at(expr, 1)) and
(typeof!(Enum.at(expr, 2)) or is_integer(Enum.at(expr, 2))),
do: raise(ArgumentError, "setex given parameters not valid")
set_ex(Enum.at(expr, 0), Enum.at(expr, 1), Enum.at(expr, 2))
end
def build(type, expr) when type == :setnx and is_list(expr) do
unless Enum.count(expr) == 2 and typeof!(Enum.at(expr, 0)) and
(is_integer(Enum.at(expr, 1)) or typeof!(Enum.at(expr, 1))),
do: raise(ArgumentError, "setnx given parameters not valid")
set_nx(Enum.at(expr, 0), Enum.at(expr, 1))
end
def build(type, expr) when type == :setrange and is_list(expr) do
unless Enum.count(expr) == 3 and typeof!(Enum.at(expr, 0)) and
is_integer(Enum.at(expr, 1)) and typeof!(Enum.at(expr, 2)),
do: raise(ArgumentError, "setrange given parameters not valid")
set_range(Enum.at(expr, 0), Enum.at(expr, 1), Enum.at(expr, 2))
end
def build(type, expr) when type == :psetex and is_list(expr) do
unless Enum.count(expr) == 3 and typeof!(Enum.at(expr, 0)) and
is_integer(Enum.at(expr, 1)) and
(typeof!(Enum.at(expr, 2)) or is_integer(Enum.at(expr, 2))),
do: raise(ArgumentError, "psetex given parameters not valid")
pset_ex(Enum.at(expr, 0), Enum.at(expr, 1), Enum.at(expr, 2))
end
def build(type, expr) when type == :get and is_binary(expr) do
get(expr)
end
def build(type, expr) when type == :getrange and is_list(expr) do
unless Enum.count(expr) == 3 and typeof!(Enum.at(expr, 0)) and
Enum.any?(expr, &is_integer/1),
do: raise(ArgumentError, "getrange given parameters not valid")
get_range(Enum.at(expr, 0), Enum.at(expr, 1), Enum.at(expr, 2))
end
def build(type, expr) when type == :getset and is_list(expr) do
unless Enum.count(expr) == 2 and Enum.any?(expr, &typeof!/1),
do: raise(ArgumentError, "getset given parameters not valid")
get_set(Enum.at(expr, 0), Enum.at(expr, 1))
end
def build(type, expr) when type == :strlen and is_binary(expr) do
strlen(expr)
end
def build(type, expr) when type == :incr and is_binary(expr) do
incr(expr)
end
def build(type, expr) when type == :incrby and is_list(expr) do
unless Enum.count(expr) == 2 and typeof!(Enum.at(expr, 0)) and
is_integer(Enum.at(expr, 1)),
do: raise(ArgumentError, "incrby given parameters not valid")
incr_by(Enum.at(expr, 0), Enum.at(expr, 1))
end
def build(type, expr) when type == :incrbyfloat and is_list(expr) do
unless Enum.count(expr) == 2 and Enum.any?(expr, &typeof!/1),
do: raise(ArgumentError, "incrbyfloat given parameters not valid")
incr_by_float(Enum.at(expr, 0), Enum.at(expr, 1))
end
def build(type, expr) when type == :decr and is_binary(expr) do
decr(expr)
end
def build(type, expr) when type == :decrby and is_list(expr) do
unless Enum.count(expr) == 2 and typeof!(Enum.at(expr, 0)) and
is_integer(Enum.at(expr, 1)),
do: raise(ArgumentError, "decrby given parameters not valid")
decr_by(Enum.at(expr, 0), Enum.at(expr, 1))
end
def build(type, expr) when type == :mset and is_list(expr) do
unless Enum.count(expr) >= 2 and Enum.any?(expr, &typeof!(&1)),
do:
raise(
ArgumentError,
"mset given parameters must be greater than 2 " <>
"or given parameters not valid"
)
mset(expr)
end
def build(type, expr) when type == :msetnx and is_list(expr) do
mset_nx(expr)
end
def build(type, expr) when type == :mget do
unless Enum.count(expr) >= 2 and Enum.any?(expr, &typeof!(&1)),
do:
raise(
ArgumentError,
"mget given parameters must be greater than or equal to 1" <>
" or given parameters not valid"
)
mget(expr)
end
def build(type, expr)
when (type == :del and
is_list(expr)) or is_binary(expr) do
unless Enum.any?(expr, &typeof!(&1)),
do: raise(ArgumentError, "del given parameters not valid")
del(expr)
end
def build(type, expr) when type == :lpush and is_list(expr) do
unless Enum.count(expr) == 2 and typeof!(Enum.at(expr, 0)) and
is_list(Enum.at(expr, 1)) and
Enum.any?(Enum.at(expr, 1), &typeof!(&1)),
do:
raise(
ArgumentError,
"lpush given parameters must be greater than 2 or " <>
"values not list or values not valid type"
)
lpush(Enum.at(expr, 0), Enum.at(expr, 1))
end
def build(type, expr) when type == :rpush and is_list(expr) do
unless Enum.count(expr) == 2 and typeof!(Enum.at(expr, 0)) and
is_list(Enum.at(expr, 1)) and
Enum.any?(Enum.at(expr, 1), &typeof!(&1)),
do:
raise(
ArgumentError,
"rpush given parameters must be greater than 2 or " <>
"values not list or values not valid type"
)
rpush(Enum.at(expr, 0), Enum.at(expr, 1))
end
def build(type, expr) when type == :lset do
unless Enum.count(expr) === 3 and typeof!(Enum.at(expr, 0)) and
is_integer(Enum.at(expr, 1)) and typeof!(Enum.at(expr, 2)),
do:
raise(
ArgumentError,
"lset given parameters count equal to 3 or " <>
"values not valid type"
)
lset(Enum.at(expr, 0), Enum.at(expr, 1), Enum.at(expr, 2))
end
def build(type, expr) when type == :lrange do
unless Enum.count(expr) == 3 and typeof!(Enum.at(expr, 0)) and
is_integer(Enum.at(expr, 1)) and is_integer(String.to_integer(Enum.at(expr, 2))),
do:
raise(
ArgumentError,
"lrange given parameters count equal to 3 or " <>
" values not valid type"
)
lrange(Enum.at(expr, 0), Enum.at(expr, 1), Enum.at(expr, 2))
end
def build(type, expr) when type == :lrem do
unless Enum.count(expr) == 3 and typeof!(Enum.at(expr, 0)) and
is_integer(Enum.at(expr, 1)) and typeof!(Enum.at(expr, 2)),
do:
raise(
ArgumentError,
"lrem given parameters count equal to or " <>
"values not valid type"
)
lrem(Enum.at(expr, 0), Enum.at(expr, 1), Enum.at(expr, 2))
end
@doc false
defp typeof!(v) do
Rediscl.Typeable.typeof(v) == "string"
end
end