defmodule FunctionGenerator do
@doc false
defmacro new(env) do
for func <- [:to_tsquery, :phraseto_tsquery, :plainto_tsquery, :websearch_to_tsquery] do
quote do
@doc """
Creates a new Vectorex instance which can be used to build a full text search query
"""
def new(unquote(func), param) do
%unquote(env.module){params: [param], function: unquote(func)}
end
end
end
end
@doc false
defmacro new_subquery(env) do
quote do
@doc """
Creates a new Vectorex.Subquery instance
"""
def new(param) do
%unquote(env.module){params: [param]}
end
end
end
@doc false
defmacro operators(env) do
for operator <- [:not, :and, :or, :followed_by] do
quote do
@doc """
Adds a clause to the builder using #{unquote(operator)}
If the operator is supported by the text search control, the parameter is applied
to the builder. If not the parameter is ignored.
"""
@spec unquote(:"ts_#{operator}")(
vector :: unquote(env.module).t(),
params :: [String.t()] | String.t()
) :: unquote(env.module).t()
def unquote(:"ts_#{operator}")(%unquote(env.module){} = vector, params)
when is_list(params) do
Enum.reduce(params, vector, fn param, acc ->
unquote(:"ts_#{operator}")(acc, param)
end)
end
def unquote(:"ts_#{operator}")(%unquote(env.module){} = vector, param) do
append_param = fn ->
%{vector | params: [{unquote(operator), param} | vector.params]}
end
case param do
param = %Vectorex.Subquery{} ->
append_param.()
param when is_binary(param) ->
append_param.()
_ ->
vector
end
end
end
end
end
end