zf

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

domain.ex (4823B)


      1 # Zenflows is designed to implement the Valueflows vocabulary,
      2 # written and maintained by srfsh <info@dyne.org>.
      3 # Copyright (C) 2021-2023 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.Person.Domain do
     19 @moduledoc "Domain logic of Persons."
     20 
     21 import Ecto.Query
     22 
     23 alias Ecto.{Changeset, Multi}
     24 alias Zenflows.DB.{Page, Repo, Schema}
     25 alias Zenflows.VF.{Person, Person.Query}
     26 
     27 @spec one(Ecto.Repo.t(), Schema.id() | map() | Keyword.t())
     28 	:: {:ok, Person.t()} | {:error, String.t()}
     29 def one(repo \\ Repo, _)
     30 def one(repo, id) when is_binary(id), do: one(repo, id: id)
     31 def one(repo, clauses) do
     32 	case repo.get_by(where(Person, type: :per), clauses) do
     33 		nil -> {:error, "not found"}
     34 		found -> {:ok, found}
     35 	end
     36 end
     37 
     38 @spec one!(Ecto.Repo.t(), Schema.id() | map() | Keyword.t()) :: Person.t()
     39 def one!(repo \\ Repo, id_or_clauses) do
     40 	{:ok, value} = one(repo, id_or_clauses)
     41 	value
     42 end
     43 
     44 @spec all(Page.t()) :: {:ok, [Person.t()]} | {:error, Changeset.t()}
     45 def all(page \\ Page.new()) do
     46 	with {:ok, q} <- Query.all(page) do
     47 		{:ok, Page.all(q, page)}
     48 	end
     49 end
     50 
     51 @spec all!(Page.t()) :: [Person.t()]
     52 def all!(page \\ Page.new()) do
     53 	{:ok, value} = all(page)
     54 	value
     55 end
     56 
     57 @spec exists?(Keyword.t()) :: boolean()
     58 def exists?(conds) do
     59 	where(Person, ^conds) |> where(type: :per) |> Repo.exists?()
     60 end
     61 
     62 @spec pubkey(Schema.id()) :: {:ok, nil | String.t()} | {:error, String.t()}
     63 def pubkey(id) do
     64 	where(Person, type: :per, id: ^id)
     65 	|> select([:eddsa_public_key]) |> Repo.one()
     66 	|> case do
     67 		nil -> {:error, "not found"}
     68 		%{eddsa_public_key: pkey} -> {:ok, pkey}
     69 	end
     70 end
     71 
     72 @spec create(Schema.params()) :: {:ok, Person.t()} | {:error, Changeset.t()}
     73 def create(params) do
     74 	key = multi_key()
     75 	Multi.new()
     76 	|> multi_insert(params)
     77 	|> Repo.transaction()
     78 	|> case do
     79 		{:ok, %{^key => value}} -> {:ok, value}
     80 		{:error, _, reason, _} -> {:error, reason}
     81 	end
     82 end
     83 
     84 @spec create!(Schema.params()) :: Person.t()
     85 def create!(params) do
     86 	{:ok, value} = create(params)
     87 	value
     88 end
     89 
     90 @spec update(Schema.id(), Schema.params())
     91 	:: {:ok, Person.t()} | {:error, String.t() | Changeset.t()}
     92 def update(id, params) do
     93 	key = multi_key()
     94 	Multi.new()
     95 	|> multi_update(id, params)
     96 	|> Repo.transaction()
     97 	|> case do
     98 		{:ok, %{^key => value}} -> {:ok, value}
     99 		{:error, _, reason, _} -> {:error, reason}
    100 	end
    101 end
    102 
    103 @spec update!(Schema.id(), Schema.params()) :: Person.t()
    104 def update!(id, params) do
    105 	{:ok, value} = __MODULE__.update(id, params)
    106 	value
    107 end
    108 
    109 @spec delete(Schema.id()) ::
    110 	{:ok, Person.t()} | {:error, String.t() | Changeset.t()}
    111 def delete(id) do
    112 	key = multi_key()
    113 	Multi.new()
    114 	|> multi_delete(id)
    115 	|> Repo.transaction()
    116 	|> case do
    117 		{:ok, %{^key => value}} -> {:ok, value}
    118 		{:error, _, reason, _} -> {:error, reason}
    119 	end
    120 end
    121 
    122 @spec claim(Schema.id()) ::
    123 	{:ok, Person.t()} | {:error, String.t() | Changeset.t()}
    124 def claim(id) do
    125 	Multi.new()
    126 	|> multi_one(id)
    127 	|> Multi.run(:claim_id, &Zenflows.DID.claim/2)
    128 	|> Repo.transaction()
    129 	|> case do
    130 		{:ok, %{claim_id: value}} -> {:ok, value}
    131 		{:error, _, reason, _} -> {:error, reason}
    132 	end
    133 end
    134 
    135 @spec delete!(Schema.id()) :: Person.t()
    136 def delete!(id) do
    137 	{:ok, value} = delete(id)
    138 	value
    139 end
    140 
    141 @spec preload(Person.t(), :images | :primary_location) :: Person.t()
    142 def preload(per, x) when x in ~w[images primary_location]a do
    143 	Repo.preload(per, x)
    144 end
    145 
    146 @spec multi_key() :: atom()
    147 def multi_key(), do: :person
    148 
    149 @spec multi_one(Multi.t(), term(), Schema.id()) :: Multi.t()
    150 def multi_one(m, key \\ multi_key(), id) do
    151 	Multi.run(m, key, fn repo, _ -> one(repo, id) end)
    152 end
    153 
    154 @spec multi_insert(Multi.t(), term(), Schema.params()) :: Multi.t()
    155 def multi_insert(m, key \\ multi_key(), params) do
    156 	Multi.insert(m, key, Person.changeset(params))
    157 end
    158 
    159 @spec multi_update(Multi.t(), term(), Schema.id(), Schema.params()) :: Multi.t()
    160 def multi_update(m, key \\ multi_key(), id, params) do
    161 	m
    162 	|> multi_one("#{key}.one", id)
    163 	|> Multi.update(key,
    164 		&Person.changeset(Map.fetch!(&1, "#{key}.one"), params))
    165 end
    166 
    167 @spec multi_delete(Multi.t(), term(), Schema.id()) :: Multi.t()
    168 def multi_delete(m, key \\ multi_key(), id) do
    169 	m
    170 	|> multi_one("#{key}.one", id)
    171 	|> Multi.delete(key, &Map.fetch!(&1, "#{key}.one"))
    172 end
    173 end