commit 6cb36010f9aadfdf833131b4e6b0b7744d9e1d69
parent 1a5ce574399d1e862d80412ee88a9ef38ff96779
Author: sir fish <dev@srf.sh>
Date: Mon, 17 Oct 2022 14:16:20 +0000
Merge pull request #25 from dyne/srfsh/filter
Add resource name filters
Diffstat:
4 files changed, 59 insertions(+), 56 deletions(-)
diff --git a/src/zenflows/db/filter.ex b/src/zenflows/db/filter.ex
@@ -18,11 +18,32 @@
defmodule Zenflows.DB.Filter do
@moduledoc "Filtering helpers for Filter modules."
+alias Ecto.Changeset
+
@type params() :: %{atom() => term()}
-@type error() :: {:error, Ecto.Changeset.t()}
+@type error() :: {:error, Changeset.t()}
@type result() :: {:ok, Ecto.Query.t()} | error()
def escape_like(v) do
Regex.replace(~r/\\|%|_/, v, &"\\#{&1}")
end
+
+@doc """
+Changeset helper to check that `a` and `b` are not provided at the same time.
+"""
+@spec check_xor(Changeset.t(), atom(), atom()) :: Changeset.t()
+def check_xor(cset, a, b) do
+ x = Changeset.get_change(cset, a)
+ y = Changeset.get_change(cset, b)
+
+ if x && y do
+ msg = "can't provide both"
+
+ cset
+ |> Changeset.add_error(a, msg)
+ |> Changeset.add_error(b, msg)
+ else
+ cset
+ end
+end
end
diff --git a/src/zenflows/vf/person/filter.ex b/src/zenflows/vf/person/filter.ex
@@ -41,52 +41,31 @@ end
@spec f(Query.t(), {atom(), term()}) :: Query.t()
defp f(q, {:name, v}),
do: where(q, [x], ilike(x.name, ^"%#{Filter.escape_like(v)}%"))
+defp f(q, {:or_name, v}),
+ do: or_where(q, [x], ilike(x.name, ^"%#{Filter.escape_like(v)}%"))
defp f(q, {:user, v}),
do: where(q, [x], ilike(x.user, ^"%#{Filter.escape_like(v)}%"))
-defp f(q, {:user_or_name, v}) do
- v = "%#{Filter.escape_like(v)}%"
- where(q, [x], ilike(x.user, ^v) or ilike(x.name, ^v))
-end
+defp f(q, {:or_user, v}),
+ do: or_where(q, [x], ilike(x.user, ^"%#{Filter.escape_like(v)}%"))
embedded_schema do
field :name, :string
+ field :or_name, :string
field :user, :string
- field :user_or_name, :string
+ field :or_user, :string
end
+@cast ~w[name or_name user or_user]a
+
@spec chgset(params()) :: Changeset.t()
defp chgset(params) do
%__MODULE__{}
- |> Changeset.cast(params, ~w[name user user_or_name]a)
+ |> Changeset.cast(params, @cast)
|> Validate.name(:name)
+ |> Validate.name(:or_name)
|> Validate.name(:user)
- |> Validate.name(:user_or_name)
- |> user_or_name_mutex()
-end
-
-# Validate that `user_or_name` is mutually exclusive with either `user`
-# or `name`.
-@spec user_or_name_mutex(Changeset.t()) :: Changeset.t()
-defp user_or_name_mutex(cset) do
- name = Changeset.get_change(cset, :name)
- user = Changeset.get_change(cset, :user)
- user_or_name = Changeset.get_change(cset, :user_or_name)
-
- cond do
- user_or_name && user ->
- msg = "user-or-name and user can't be used together"
- cset
- |> Changeset.add_error(:user_or_name, msg)
- |> Changeset.add_error(:user, msg)
-
- user_or_name && name ->
- msg = "user-or-name and name can't be used together"
- cset
- |> Changeset.add_error(:user_or_name, msg)
- |> Changeset.add_error(:name, msg)
-
- true ->
- cset
- end
+ |> Validate.name(:or_user)
+ |> Filter.check_xor(:name, :or_name)
+ |> Filter.check_xor(:user, :or_user)
end
end
diff --git a/src/zenflows/vf/proposal/filter.ex b/src/zenflows/vf/proposal/filter.ex
@@ -67,7 +67,17 @@ end
defp f(q, {:or_primary_intents_resource_inventoried_as_classified_as, v}) do
q
|> join(:primary_intents_resource_inventoried_as)
- |> where([primary_intents_resource_inventoried_as: r], fragment("? @> ?", r.classified_as, ^v))
+ |> or_where([primary_intents_resource_inventoried_as: r], fragment("? @> ?", r.classified_as, ^v))
+end
+defp f(q, {:primary_intents_resource_inventoried_as_name, v}) do
+ q
+ |> join(:primary_intents_resource_inventoried_as)
+ |> where([primary_intents_resource_inventoried_as: r], ilike(r.name, ^"%#{Filter.escape_like(v)}%"))
+end
+defp f(q, {:or_primary_intents_resource_inventoried_as_name, v}) do
+ q
+ |> join(:primary_intents_resource_inventoried_as)
+ |> or_where([primary_intents_resource_inventoried_as: r], ilike(r.name, ^"%#{Filter.escape_like(v)}%"))
end
# join primary_intents
@@ -92,6 +102,8 @@ embedded_schema do
field :or_primary_intents_resource_inventoried_as_primary_accountable, {:array, ID}
field :primary_intents_resource_inventoried_as_classified_as, {:array, :string}
field :or_primary_intents_resource_inventoried_as_classified_as, {:array, :string}
+ field :primary_intents_resource_inventoried_as_name, :string
+ field :or_primary_intents_resource_inventoried_as_name, :string
end
@cast ~w[
@@ -101,6 +113,8 @@ end
or_primary_intents_resource_inventoried_as_primary_accountable
primary_intents_resource_inventoried_as_classified_as
or_primary_intents_resource_inventoried_as_classified_as
+ primary_intents_resource_inventoried_as_name
+ or_primary_intents_resource_inventoried_as_name
]a
@spec chgset(params()) :: Changeset.t()
@@ -113,28 +127,15 @@ defp chgset(params) do
|> Validate.class(:or_primary_intents_resource_inventoried_as_primary_accountable)
|> Validate.class(:primary_intents_resource_inventoried_as_classified_as)
|> Validate.class(:or_primary_intents_resource_inventoried_as_classified_as)
- |> check_xor(:primary_intents_resource_inventoried_as_conforms_to,
+ |> Validate.name(:primary_intents_resource_inventoried_name)
+ |> Validate.name(:or_primary_intents_resource_inventoried_name)
+ |> Filter.check_xor(:primary_intents_resource_inventoried_as_conforms_to,
:or_primary_intents_resource_inventoried_as_conforms_to)
- |> check_xor(:primary_intents_resource_inventoried_as_primary_accountable,
+ |> Filter.check_xor(:primary_intents_resource_inventoried_as_primary_accountable,
:or_primary_intents_resource_inventoried_as_primary_accountable)
- |> check_xor(:primary_intents_resource_inventoried_as_classified_as,
+ |> Filter.check_xor(:primary_intents_resource_inventoried_as_classified_as,
:or_primary_intents_resource_inventoried_as_classified_as)
-end
-
-# Check that `a` and `b` are not provided at the same time.
-@spec check_xor(Changeset.t(), atom(), atom()) :: Changeset.t()
-defp check_xor(cset, a, b) do
- x = Changeset.get_change(cset, a)
- y = Changeset.get_change(cset, b)
-
- if x && y do
- msg = "can't provide both"
-
- cset
- |> Changeset.add_error(a, msg)
- |> Changeset.add_error(b, msg)
- else
- cset
- end
+ |> Filter.check_xor(:primary_intents_resource_inventoried_as_name,
+ :or_primary_intents_resource_inventoried_as_name)
end
end
diff --git a/src/zenflows/vf/proposal/type.ex b/src/zenflows/vf/proposal/type.ex
@@ -137,6 +137,8 @@ input_object :proposal_filter_params do
field :or_primary_intents_resource_inventoried_as_primary_accountable, list_of(non_null(:id))
field :primary_intents_resource_inventoried_as_classified_as, list_of(non_null(:uri))
field :or_primary_intents_resource_inventoried_as_classified_as, list_of(non_null(:uri))
+ field :primary_intents_resource_inventoried_as_name, :string
+ field :or_primary_intents_resource_inventoried_as_name, :string
end
object :query_proposal do