You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
338 lines
8.2 KiB
338 lines
8.2 KiB
defmodule DecentralisedBookIndex.Metadata.Book do
|
|
use Ash.Resource,
|
|
otp_app: :decentralised_book_index,
|
|
domain: DecentralisedBookIndex.Metadata,
|
|
data_layer: AshPostgres.DataLayer,
|
|
extensions: [AshJsonApi.Resource]
|
|
|
|
require Ash.Query
|
|
alias DecentralisedBookIndex.Metadata
|
|
|
|
json_api do
|
|
type "book"
|
|
end
|
|
|
|
postgres do
|
|
table "books"
|
|
repo DecentralisedBookIndex.Repo
|
|
end
|
|
|
|
actions do
|
|
defaults [:read, :destroy]
|
|
|
|
create :create do
|
|
primary? true
|
|
|
|
accept [
|
|
:title,
|
|
:description,
|
|
:format,
|
|
:language,
|
|
:page_count,
|
|
:published,
|
|
:publisher_id,
|
|
:cover_image_url,
|
|
:book_editions_registry_id
|
|
]
|
|
|
|
argument :bids, {:array, :map}
|
|
argument :author_roles, {:array, :map}
|
|
|
|
change fn changeset, _ ->
|
|
registry_id = Ash.Changeset.get_attribute(changeset, :book_editions_registry_id)
|
|
|
|
if registry_id == nil do
|
|
{:ok, registry} = DecentralisedBookIndex.Metadata.create_book_editions_registry()
|
|
|
|
Ash.Changeset.force_change_attribute(changeset, :book_editions_registry_id, registry.id)
|
|
else
|
|
changeset
|
|
end
|
|
end
|
|
|
|
change manage_relationship(:bids, type: :direct_control, order_is_key: :order)
|
|
change manage_relationship(:author_roles, type: :direct_control, order_is_key: :order)
|
|
end
|
|
|
|
create :sync_create do
|
|
accept [
|
|
:id,
|
|
:title,
|
|
:description,
|
|
:format,
|
|
:language,
|
|
:page_count,
|
|
:published,
|
|
:publisher_id,
|
|
:cover_image_url,
|
|
:book_editions_registry_id,
|
|
:inserted_at,
|
|
:updated_at,
|
|
:dbi_server_id
|
|
]
|
|
|
|
argument :bids, {:array, :map}
|
|
argument :author_roles, {:array, :map}
|
|
|
|
change fn changeset, _ ->
|
|
registry_id = Ash.Changeset.get_attribute(changeset, :book_editions_registry_id)
|
|
|
|
if registry_id == nil do
|
|
{:ok, registry} = DecentralisedBookIndex.Metadata.create_book_editions_registry()
|
|
|
|
Ash.Changeset.force_change_attribute(changeset, :book_editions_registry_id, registry.id)
|
|
else
|
|
changeset
|
|
end
|
|
end
|
|
|
|
change manage_relationship(:bids, type: :direct_control, order_is_key: :order)
|
|
change manage_relationship(:author_roles, type: :direct_control, order_is_key: :order)
|
|
end
|
|
|
|
create :add_book_to_related_editions_registry do
|
|
accept [
|
|
:title,
|
|
:description,
|
|
:format,
|
|
:language,
|
|
:page_count,
|
|
:published,
|
|
:publisher_id,
|
|
:cover_image_url
|
|
]
|
|
|
|
argument :related_book_id, :uuid do
|
|
allow_nil? false
|
|
end
|
|
|
|
argument :bids, {:array, :map}
|
|
argument :author_roles, {:array, :map}
|
|
|
|
change fn changeset, context ->
|
|
related_book_id = changeset.arguments.related_book_id
|
|
|
|
if related_book_id == nil do
|
|
Ash.Changeset.add_error(changeset, :related_book_id, "Related book is empty")
|
|
else
|
|
{:ok, related_book} = DecentralisedBookIndex.Metadata.get_book_by_id(related_book_id)
|
|
|
|
Ash.Changeset.force_change_attribute(
|
|
changeset,
|
|
:book_editions_registry_id,
|
|
related_book.book_editions_registry_id
|
|
)
|
|
end
|
|
end
|
|
|
|
change manage_relationship(:bids, type: :direct_control, order_is_key: :order)
|
|
change manage_relationship(:author_roles, type: :direct_control, order_is_key: :order)
|
|
end
|
|
|
|
read :by_id do
|
|
argument :id, :uuid, allow_nil?: false
|
|
get? true
|
|
filter expr(id == ^arg(:id))
|
|
end
|
|
|
|
read :by_bid do
|
|
argument :type, :string, allow_nil?: false
|
|
argument :bid, :string, allow_nil?: false
|
|
get? true
|
|
filter expr(exists(bids, type == ^arg(:type) and bid == ^arg(:bid)))
|
|
end
|
|
|
|
read :get_alternative_editions do
|
|
argument :book, :struct, allow_nil?: false
|
|
|
|
prepare fn query, context ->
|
|
book = query.arguments.book
|
|
|
|
DecentralisedBookIndex.Metadata.Book
|
|
|> Ash.Query.filter(
|
|
book_editions_registry_id == ^book.book_editions_registry_id and
|
|
id != ^book.id
|
|
)
|
|
end
|
|
end
|
|
|
|
read :get_author_books do
|
|
argument :author, :struct, allow_nil?: false
|
|
|
|
prepare fn query, context ->
|
|
author = query.arguments.author
|
|
|
|
{:ok, author_ids} = Metadata.get_author_ids(author)
|
|
|
|
Metadata.Book
|
|
|> Ash.Query.filter(expr(exists(author_roles, author_id in ^author_ids)))
|
|
end
|
|
end
|
|
|
|
read :search do
|
|
argument :query, :ci_string do
|
|
constraints allow_empty?: true
|
|
default ""
|
|
end
|
|
|
|
filter expr(contains(title, ^arg(:query)))
|
|
|
|
pagination offset?: true, default_limit: 10
|
|
end
|
|
|
|
read :search_by_bid do
|
|
argument :type, :string, allow_nil?: false
|
|
argument :bid, :string, allow_nil?: false
|
|
|
|
filter expr(exists(bids, type == ^arg(:type) and contains(bid, ^arg(:bid))))
|
|
|
|
pagination offset?: true, default_limit: 10
|
|
end
|
|
|
|
update :update do
|
|
primary? true
|
|
require_atomic? false
|
|
|
|
accept [
|
|
:title,
|
|
:description,
|
|
:format,
|
|
:language,
|
|
:page_count,
|
|
:published,
|
|
:publisher_id,
|
|
:cover_image_url,
|
|
:book_editions_registry_id
|
|
]
|
|
|
|
argument :bids, {:array, :map}
|
|
argument :author_roles, {:array, :map}
|
|
|
|
change fn changeset, _ ->
|
|
registry_id = Ash.Changeset.get_attribute(changeset, :book_editions_registry_id)
|
|
|
|
if registry_id == nil do
|
|
{:ok, registry} = DecentralisedBookIndex.Metadata.create_book_editions_registry()
|
|
|
|
Ash.Changeset.force_change_attribute(changeset, :book_editions_registry_id, registry.id)
|
|
else
|
|
changeset
|
|
end
|
|
end
|
|
|
|
change manage_relationship(:bids, type: :direct_control, order_is_key: :order)
|
|
change manage_relationship(:author_roles, type: :direct_control, order_is_key: :order)
|
|
end
|
|
|
|
update :sync do
|
|
require_atomic? false
|
|
|
|
accept [
|
|
:id,
|
|
:title,
|
|
:description,
|
|
:format,
|
|
:language,
|
|
:page_count,
|
|
:published,
|
|
:publisher_id,
|
|
:cover_image_url,
|
|
:book_editions_registry_id,
|
|
:inserted_at,
|
|
:updated_at,
|
|
:dbi_server_id
|
|
]
|
|
|
|
argument :bids, {:array, :map}
|
|
argument :author_roles, {:array, :map}
|
|
|
|
change fn changeset, _ ->
|
|
registry_id = Ash.Changeset.get_attribute(changeset, :book_editions_registry_id)
|
|
|
|
if registry_id == nil do
|
|
{:ok, registry} = DecentralisedBookIndex.Metadata.create_book_editions_registry()
|
|
|
|
Ash.Changeset.force_change_attribute(changeset, :book_editions_registry_id, registry.id)
|
|
else
|
|
changeset
|
|
end
|
|
end
|
|
|
|
change manage_relationship(:bids, type: :direct_control, order_is_key: :order)
|
|
change manage_relationship(:author_roles, type: :direct_control, order_is_key: :order)
|
|
end
|
|
|
|
update :assign_cover_image do
|
|
accept [:cover_image_url]
|
|
end
|
|
end
|
|
|
|
attributes do
|
|
uuid_primary_key :id, writable?: true
|
|
|
|
attribute :title, :string do
|
|
allow_nil? false
|
|
public? true
|
|
end
|
|
|
|
attribute :description, :string do
|
|
allow_nil? false
|
|
public? true
|
|
end
|
|
|
|
attribute :published, :date do
|
|
allow_nil? false
|
|
public? true
|
|
end
|
|
|
|
attribute :language, :string do
|
|
allow_nil? false
|
|
public? true
|
|
end
|
|
|
|
attribute :format, :string do
|
|
allow_nil? false
|
|
public? true
|
|
end
|
|
|
|
attribute :page_count, :integer do
|
|
allow_nil? false
|
|
public? true
|
|
end
|
|
|
|
attribute :cover_image_url, :string do
|
|
allow_nil? true
|
|
public? true
|
|
end
|
|
|
|
timestamps() do
|
|
writable? true
|
|
public? true
|
|
end
|
|
end
|
|
|
|
validations do
|
|
validate numericality(:page_count, greater_than: 0)
|
|
end
|
|
|
|
relationships do
|
|
belongs_to :dbi_server, Metadata.DBIServer
|
|
|
|
belongs_to :book_editions_registry, Metadata.BookEditionsRegistry
|
|
|
|
belongs_to :publisher, Metadata.Publisher do
|
|
public? true
|
|
end
|
|
|
|
has_many :author_roles, Metadata.AuthorRole do
|
|
sort order: :asc
|
|
public? true
|
|
end
|
|
|
|
has_many :bids, Metadata.BookId do
|
|
sort order: :asc
|
|
public? true
|
|
end
|
|
end
|
|
end
|