zf

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

filter.ex (7021B)


      1 # Zenflows is designed to implement the Valueflows vocabulary,
      2 # written and maintained by srfsh <info@dyne.org>.
      3 # Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>.
      4 #
      5 # This program is free software: you can redistribute it and/or modify
      6 # it under the terms of the GNU Affero General Public License as published by
      7 # the Free Software Foundation, either version 3 of the License, or
      8 # (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU Affero General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU Affero General Public License
     16 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
     17 
     18 defmodule Zenflows.VF.Proposal.Filter do
     19 @moduledoc false
     20 
     21 import Ecto.Query
     22 
     23 alias Ecto.{Changeset, Queryable}
     24 alias Zenflows.DB.{ID, Page, Schema, Validate}
     25 alias Zenflows.VF.Proposal
     26 
     27 @spec all(Page.t()) :: {:ok, Queryable.t()} | {:error, Changeset.t()}
     28 def all(%{filter: nil}), do: {:ok, Proposal}
     29 def all(%{filter: params}) do
     30 	with {:ok, filters} <- all_validate(params) do
     31 		{:ok, Enum.reduce(filters, Proposal, &all_f(&2, &1))}
     32 	end
     33 end
     34 
     35 @spec all_f(Queryable.t(), {atom(), term()}) :: Queryable.t()
     36 defp all_f(q, {:primary_intents_resource_inventoried_as_conforms_to, v}) do
     37 	q
     38 	|> join(:primary_intents_resource_inventoried_as)
     39 	|> where([primary_intents_resource_inventoried_as: r], r.conforms_to_id in ^v)
     40 end
     41 defp all_f(q, {:or_primary_intents_resource_inventoried_as_conforms_to, v}) do
     42 	q
     43 	|> join(:primary_intents_resource_inventoried_as)
     44 	|> or_where([primary_intents_resource_inventoried_as: r], r.conforms_to_id in ^v)
     45 end
     46 defp all_f(q, {:primary_intents_resource_inventoried_as_primary_accountable, v}) do
     47 	q
     48 	|> join(:primary_intents_resource_inventoried_as)
     49 	|> where([primary_intents_resource_inventoried_as: r], r.primary_accountable_id in ^v)
     50 end
     51 defp all_f(q, {:or_primary_intents_resource_inventoried_as_primary_accountable, v}) do
     52 	q
     53 	|> join(:primary_intents_resource_inventoried_as)
     54 	|> or_where([primary_intents_resource_inventoried_as: r], r.primary_accountable_id in ^v)
     55 end
     56 defp all_f(q, {:primary_intents_resource_inventoried_as_classified_as, v}) do
     57 	q
     58 	|> join(:primary_intents_resource_inventoried_as)
     59 	|> where([primary_intents_resource_inventoried_as: r], fragment("? @> ?", r.classified_as, ^v))
     60 end
     61 defp all_f(q, {:or_primary_intents_resource_inventoried_as_classified_as, v}) do
     62 	q
     63 	|> join(:primary_intents_resource_inventoried_as)
     64 	|> or_where([primary_intents_resource_inventoried_as: r], fragment("? @> ?", r.classified_as, ^v))
     65 end
     66 defp all_f(q, {:primary_intents_resource_inventoried_as_name, v}) do
     67 	q
     68 	|> join(:primary_intents_resource_inventoried_as)
     69 	|> where([primary_intents_resource_inventoried_as: r], ilike(r.name, ^"%#{v}%"))
     70 end
     71 defp all_f(q, {:or_primary_intents_resource_inventoried_as_name, v}) do
     72 	q
     73 	|> join(:primary_intents_resource_inventoried_as)
     74 	|> or_where([primary_intents_resource_inventoried_as: r], ilike(r.name, ^v))
     75 end
     76 defp all_f(q, {:primary_intents_resource_inventoried_as_id, v}) do
     77 	q
     78 	|> join(:primary_intents_resource_inventoried_as)
     79 	|> where([primary_intents_resource_inventoried_as: r], r.id in ^v)
     80 end
     81 defp all_f(q, {:or_primary_intents_resource_inventoried_as_id, v}) do
     82 	q
     83 	|> join(:primary_intents_resource_inventoried_as)
     84 	|> or_where([primary_intents_resource_inventoried_as: r], r.id in ^v)
     85 end
     86 
     87 # join primary_intents
     88 @spec join(Queryable.t(), atom()) :: Queryable.t()
     89 defp join(q, :primary_intents) do
     90 	if has_named_binding?(q, :primary_intents),
     91 		do: q,
     92 		else: join(q, :inner, [x], pi in assoc(x, :primary_intents), as: :primary_intents)
     93 end
     94 # join resource_inventoried_as through primary_intents above
     95 defp join(q, :primary_intents_resource_inventoried_as) do
     96 	q = join(q, :primary_intents)
     97 	if has_named_binding?(q, :primary_intents_resource_inventoried_as),
     98 		do: q,
     99 		else: join(q, :inner, [primary_intents: pi], r in assoc(pi, :resource_inventoried_as),
    100 			as: :primary_intents_resource_inventoried_as)
    101 end
    102 
    103 @spec all_validate(Schema.params())
    104 	:: {:ok, Changeset.data()} | {:error, Changeset.t()}
    105 defp all_validate(params) do
    106 	{%{}, %{
    107 		primary_intents_resource_inventoried_as_conforms_to: {:array, ID},
    108 		or_primary_intents_resource_inventoried_as_conforms_to: {:array, ID},
    109 		primary_intents_resource_inventoried_as_primary_accountable: {:array, ID},
    110 		or_primary_intents_resource_inventoried_as_primary_accountable: {:array, ID},
    111 		primary_intents_resource_inventoried_as_classified_as: {:array, :string},
    112 		or_primary_intents_resource_inventoried_as_classified_as: {:array, :string},
    113 		primary_intents_resource_inventoried_as_name: :string,
    114 		or_primary_intents_resource_inventoried_as_name: :string,
    115 		primary_intents_resource_inventoried_as_id: {:array, ID},
    116 		or_primary_intents_resource_inventoried_as_id: {:array, ID},
    117 	}}
    118 	|> Changeset.cast(params, ~w[
    119 		primary_intents_resource_inventoried_as_conforms_to
    120 		or_primary_intents_resource_inventoried_as_conforms_to
    121 		primary_intents_resource_inventoried_as_primary_accountable
    122 		or_primary_intents_resource_inventoried_as_primary_accountable
    123 		primary_intents_resource_inventoried_as_classified_as
    124 		or_primary_intents_resource_inventoried_as_classified_as
    125 		primary_intents_resource_inventoried_as_name
    126 		or_primary_intents_resource_inventoried_as_name
    127 		primary_intents_resource_inventoried_as_id
    128 		or_primary_intents_resource_inventoried_as_id
    129 	]a)
    130 	|> Validate.class(:primary_intents_resource_inventoried_as_conforms_to)
    131 	|> Validate.class(:or_primary_intents_resource_inventoried_as_conforms_to)
    132 	|> Validate.class(:primary_intents_resource_inventoried_as_primary_accountable)
    133 	|> Validate.class(:or_primary_intents_resource_inventoried_as_primary_accountable)
    134 	|> Validate.class(:primary_intents_resource_inventoried_as_classified_as)
    135 	|> Validate.class(:or_primary_intents_resource_inventoried_as_classified_as)
    136 	|> Validate.name(:primary_intents_resource_inventoried_as_name)
    137 	|> Validate.name(:or_primary_intents_resource_inventoried_as_name)
    138 	|> Validate.exist_nand([:primary_intents_resource_inventoried_as_conforms_to,
    139 		:or_primary_intents_resource_inventoried_as_conforms_to])
    140 	|> Validate.exist_nand([:primary_intents_resource_inventoried_as_primary_accountable,
    141 		:or_primary_intents_resource_inventoried_as_primary_accountable])
    142 	|> Validate.exist_nand([:primary_intents_resource_inventoried_as_classified_as,
    143 		:or_primary_intents_resource_inventoried_as_classified_as])
    144 	|> Validate.exist_nand([:primary_intents_resource_inventoried_as_name,
    145 		:or_primary_intents_resource_inventoried_as_name])
    146 	|> Validate.exist_nand([:primary_intents_resource_inventoried_as_id,
    147 		:or_primary_intents_resource_inventoried_as_id])
    148 	|> Validate.escape_like(:primary_intents_resource_inventoried_as_name)
    149 	|> Validate.escape_like(:or_primary_intents_resource_inventoried)
    150 	|> Changeset.apply_action(nil)
    151 end
    152 end