zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

commit 6cab0f95671aa73744c4e43305177b22cbb0b580
parent 0839e3b9e4e0022cdf2d4e31f64bf26a2758b11e
Author: srfsh <dev@srf.sh>
Date:   Fri, 23 Sep 2022 16:58:11 +0300

Zenflows.VF.Proposal.{Domain,Filter}: add filtering

They're a bit rough and unstructured, but it'll work fine for now.

Diffstat:
Msrc/zenflows/vf/proposal/domain.ex | 10++++++----
Asrc/zenflows/vf/proposal/filter.ex | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/zenflows/vf/proposal/type.ex | 6++++++
3 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/src/zenflows/vf/proposal/domain.ex b/src/zenflows/vf/proposal/domain.ex @@ -20,7 +20,7 @@ defmodule Zenflows.VF.Proposal.Domain do alias Ecto.Multi alias Zenflows.DB.{Paging, Repo} -alias Zenflows.VF.Proposal +alias Zenflows.VF.{Proposal, Proposal.Filter} @typep repo() :: Ecto.Repo.t() @typep chgset() :: Ecto.Changeset.t() @@ -38,9 +38,11 @@ def one(repo, clauses) do end end -@spec all(Paging.params()) :: Paging.result() -def all(params) do - Paging.page(Proposal, params) +@spec all(Paging.params()) :: Filter.error() | Paging.result() +def all(params \\ %{}) do + with {:ok, q} <- Filter.filter(params[:filter] || %{}) do + Paging.page(q, params) + end end @spec create(params()) :: {:ok, Proposal.t()} | {:error, chgset()} diff --git a/src/zenflows/vf/proposal/filter.ex b/src/zenflows/vf/proposal/filter.ex @@ -0,0 +1,78 @@ +# Zenflows is designed to implement the Valueflows vocabulary, +# written and maintained by srfsh <info@dyne.org>. +# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +defmodule Zenflows.VF.Proposal.Filter do +@moduledoc "Filtering logic of Proposals." + +use Zenflows.DB.Schema + +import Ecto.Query + +alias Ecto.Query +alias Zenflows.DB.{Filter, ID} +alias Zenflows.VF.{Proposal, Validate} + +@type error() :: Filter.error() + +@spec filter(Filter.params()) :: Filter.result() +def filter(params) do + case chgset(params) do + %{valid?: true, changes: c} -> + {:ok, Enum.reduce(c, Proposal, &f(&2, &1))} + %{valid?: false} = cset -> + {:error, cset} + end +end + +@spec f(Query.t(), {atom(), term()}) :: Query.t() +defp f(q, {:primary_intents_resource_inventoried_as_conforms_to, v}) do + q = if has_named_binding?(q, :pi), + do: q, + else: join(q, :inner, [x], pi in assoc(x, :primary_intents), as: :pi) + q = if has_named_binding?(q, :r), + do: q, + else: join(q, :inner, [pi: pi], r in assoc(pi, :resource_inventoried_as), as: :r) + where(q, [r: r], r.conforms_to_id in ^v) +end +defp f(q, {:primary_intents_resource_inventoried_as_primary_accountable, v}) do + q = if has_named_binding?(q, :pi), + do: q, + else: join(q, :inner, [x], pi in assoc(x, :primary_intents), as: :pi) + q = if has_named_binding?(q, :r), + do: q, + else: join(q, :inner, [pi: pi], r in assoc(pi, :resource_inventoried_as), as: :r) + where(q, [r: r], r.primary_accountable_id in ^v) +end + +embedded_schema do + field :primary_intents_resource_inventoried_as_conforms_to, {:array, ID} + field :primary_intents_resource_inventoried_as_primary_accountable, {:array, ID} +end + +@cast ~w[ + primary_intents_resource_inventoried_as_conforms_to + primary_intents_resource_inventoried_as_primary_accountable +]a + +@spec chgset(params()) :: Changeset.t() +defp chgset(params) do + %__MODULE__{} + |> Changeset.cast(params, @cast) + |> Validate.class(:primary_intents_resource_inventoried_as_conforms_to) + |> Validate.class(:primary_intents_resource_inventoried_as_primary_accountable) +end +end diff --git a/src/zenflows/vf/proposal/type.ex b/src/zenflows/vf/proposal/type.ex @@ -130,6 +130,11 @@ object :proposal_connection do field :edges, non_null(list_of(non_null(:proposal_edge))) end +input_object :proposal_filter_params do + field :primary_intents_resource_inventoried_as_conforms_to, list_of(non_null(:id)) + field :primary_intents_resource_inventoried_as_primary_accountable, list_of(non_null(:id)) +end + object :query_proposal do field :proposal, :proposal do arg :id, non_null(:id) @@ -142,6 +147,7 @@ object :query_proposal do arg :after, :id arg :last, :integer arg :before, :id + arg :filter, :proposal_filter_params resolve &Resolv.proposals/2 end