From a1f58833c734187fc16becaee57846a43ab38ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Sun, 24 Nov 2024 17:02:16 +0100 Subject: [PATCH 01/11] list nodes by show with an underscore because --- lib/radiator/outline/node_repository.ex | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index fc12c84d..2732fce7 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -62,7 +62,7 @@ defmodule Radiator.Outline.NodeRepository do ## Examples - iex> list_nodes(123) + iex> list_nodes_by_episode(123) [%Node{}, ...] """ @@ -76,6 +76,25 @@ defmodule Radiator.Outline.NodeRepository do |> List.flatten() end + @doc """ + Returns the list of nodes for a show. + + ## Examples + + iex> _list_nodes_by_show(123) + [%Node{}, ...] + + """ + + def _list_nodes_by_show(show_id) do + Node + |> where([p], p.show_id == ^show_id) + |> Repo.all() + # |> Enum.group_by(& &1.parent_id) + # |> Enum.map(fn {_parent_id, children} -> Radiator.Outline.order_sibling_nodes(children) end) + |> List.flatten() + end + @doc """ Returns the the number of nodes for an episode From 73441d251d40c972b533ad9fc115b5c1964b2857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Wo=CC=88ginger?= Date: Sun, 24 Nov 2024 17:10:26 +0100 Subject: [PATCH 02/11] change datamodel for outliners - there is only one for a show - new virtual (that means not shown to the user) nodes are introduced (inbox, root nodes) --- lib/radiator/outline/node_repository.ex | 11 +++++++++++ lib/radiator/podcast.ex | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index 2732fce7..386a7e06 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -292,6 +292,17 @@ defmodule Radiator.Outline.NodeRepository do |> Repo.one() end + # @TODO needed? + def get_root_node_for_show(show_id) do + Node + |> where([p], p.show_id == ^show_id) + # |> where([p], is_nil(p.episode_id)) + # |> where([p], is_nil(p.parent_id)) + # |> where([p], is_nil(p.prev_id)) + |> where([p], p._type == :global_root) + |> Repo.one() + end + @doc """ Returns all direct child nodes of a given node. ## Examples diff --git a/lib/radiator/podcast.ex b/lib/radiator/podcast.ex index e840eaaa..96d5bcd8 100644 --- a/lib/radiator/podcast.ex +++ b/lib/radiator/podcast.ex @@ -380,6 +380,15 @@ defmodule Radiator.Podcast do order_by: [desc: e.number] end + @doc """ + Lists all episodes for a given show. + """ + def list_episodes_for_show(show_id) do + list_available_episodes_query() + |> where([e], e.show_id == ^show_id) + |> Repo.all() + end + @doc """ Returns the query for list of episodes including the (soft) deleted once. From a2210027350e9dcfbadf50c99c0a83772e63954a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Thu, 28 Nov 2024 22:36:54 +0100 Subject: [PATCH 03/11] fixup --- lib/radiator/outline/node_repository.ex | 24 ++++++++++++++++++++++++ lib/radiator/podcast.ex | 16 +++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index 386a7e06..d360a40f 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -26,6 +26,30 @@ defmodule Radiator.Outline.NodeRepository do |> Repo.insert() end + @doc """ + Creates the internal nodes for a show, this is the global root + and the global inbox. + """ + def create_nodes_for_show(show_id) do + # create a root node for a show + {:ok, show_root} = + NodeRepository.create_node(%{ + show_id: show_id, + parent_id: nil, + prev_id: nil, + _type: "global_root" + }) + + {:ok, global_inbox} = + NodeRepository.create_node(%{ + show_id: show_id, + parent_id: show_root.uuid, + prev_id: nil, + _type: "global_inbox" + }) + {show_root, global_inbox} + end + @doc """ Deletes a node from the repository. diff --git a/lib/radiator/podcast.ex b/lib/radiator/podcast.ex index 96d5bcd8..a8edd0f3 100644 --- a/lib/radiator/podcast.ex +++ b/lib/radiator/podcast.ex @@ -182,9 +182,19 @@ defmodule Radiator.Podcast do """ def create_show(attrs \\ %{}) do - %Show{} - |> Show.changeset(attrs) - |> Repo.insert() + # also need to create the nodes for the show + # start a transaction + result = Repo.transaction(fn -> + show = %Show{} + |> Show.changeset(attrs) + |> Repo.insert() + + {show_root, global_inbox} = NodeRepository.create_nodes_for_show(show.id) + + up + + end) + result end @doc """ From aa73f96004969ddef8ea3bed0b5e1ed229be65ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Thu, 28 Nov 2024 22:37:36 +0100 Subject: [PATCH 04/11] fixup - format --- lib/radiator/outline/node_repository.ex | 1 + lib/radiator/podcast.ex | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index d360a40f..51b4afff 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -47,6 +47,7 @@ defmodule Radiator.Outline.NodeRepository do prev_id: nil, _type: "global_inbox" }) + {show_root, global_inbox} end diff --git a/lib/radiator/podcast.ex b/lib/radiator/podcast.ex index a8edd0f3..c7af689c 100644 --- a/lib/radiator/podcast.ex +++ b/lib/radiator/podcast.ex @@ -184,16 +184,19 @@ defmodule Radiator.Podcast do def create_show(attrs \\ %{}) do # also need to create the nodes for the show # start a transaction - result = Repo.transaction(fn -> - show = %Show{} - |> Show.changeset(attrs) - |> Repo.insert() + result = + Repo.transaction(fn -> + show = + %Show{} + |> Show.changeset(attrs) + |> Repo.insert() - {show_root, global_inbox} = NodeRepository.create_nodes_for_show(show.id) + {show_root, global_inbox} = NodeRepository.create_nodes_for_show(show.id) - up + up + end) - end) + IO.inspect(result, label: "result") result end From da3226d499d485a7329895a385957eb6e3429720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Thu, 28 Nov 2024 22:43:09 +0100 Subject: [PATCH 05/11] fixup 2 - format --- lib/radiator/podcast.ex | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/radiator/podcast.ex b/lib/radiator/podcast.ex index c7af689c..7440270e 100644 --- a/lib/radiator/podcast.ex +++ b/lib/radiator/podcast.ex @@ -191,9 +191,7 @@ defmodule Radiator.Podcast do |> Show.changeset(attrs) |> Repo.insert() - {show_root, global_inbox} = NodeRepository.create_nodes_for_show(show.id) - - up + {_show_root, _global_inbox} = NodeRepository.create_nodes_for_show(show.id) end) IO.inspect(result, label: "result") From cd47ef2a3f64e9a9d35045368d5908da8161fe61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Thu, 28 Nov 2024 23:14:24 +0100 Subject: [PATCH 06/11] fixup 3 - tests --- lib/radiator/outline/node_repository.ex | 4 ++-- lib/radiator/podcast.ex | 24 +++++++++++------------ test/support/fixtures/podcast_fixtures.ex | 12 ++++++------ 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index 51b4afff..3c0c0ec4 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -33,7 +33,7 @@ defmodule Radiator.Outline.NodeRepository do def create_nodes_for_show(show_id) do # create a root node for a show {:ok, show_root} = - NodeRepository.create_node(%{ + create_node(%{ show_id: show_id, parent_id: nil, prev_id: nil, @@ -41,7 +41,7 @@ defmodule Radiator.Outline.NodeRepository do }) {:ok, global_inbox} = - NodeRepository.create_node(%{ + create_node(%{ show_id: show_id, parent_id: show_root.uuid, prev_id: nil, diff --git a/lib/radiator/podcast.ex b/lib/radiator/podcast.ex index 7440270e..f0acefc4 100644 --- a/lib/radiator/podcast.ex +++ b/lib/radiator/podcast.ex @@ -7,6 +7,7 @@ defmodule Radiator.Podcast do import Ecto.Query, warn: false alias Radiator.Repo + alias Radiator.Outline.NodeRepository alias Radiator.Podcast.{Episode, Network, Show, ShowHosts} @doc """ @@ -183,19 +184,16 @@ defmodule Radiator.Podcast do """ def create_show(attrs \\ %{}) do # also need to create the nodes for the show - # start a transaction - result = - Repo.transaction(fn -> - show = - %Show{} - |> Show.changeset(attrs) - |> Repo.insert() - - {_show_root, _global_inbox} = NodeRepository.create_nodes_for_show(show.id) - end) - - IO.inspect(result, label: "result") - result + # start a transaction = + Repo.transaction(fn -> + {:ok, show} = + %Show{} + |> Show.changeset(attrs) + |> Repo.insert() + + {_show_root, _global_inbox} = NodeRepository.create_nodes_for_show(show.id) + show + end) end @doc """ diff --git a/test/support/fixtures/podcast_fixtures.ex b/test/support/fixtures/podcast_fixtures.ex index 20666a54..b04ff1fe 100644 --- a/test/support/fixtures/podcast_fixtures.ex +++ b/test/support/fixtures/podcast_fixtures.ex @@ -23,7 +23,7 @@ defmodule Radiator.PodcastFixtures do Generate a show. """ def show_fixture(attrs \\ %{}, hosts \\ []) do - network = get_network(attrs) + network = extract_network(attrs) {:ok, show} = attrs @@ -40,7 +40,7 @@ defmodule Radiator.PodcastFixtures do Generate a episode. """ def episode_fixture(attrs \\ %{}) do - show = get_show(attrs) + show = extract_show(attrs) number = Podcast.get_next_episode_number(show.id) {:ok, episode} = @@ -55,9 +55,9 @@ defmodule Radiator.PodcastFixtures do episode end - defp get_network(%{network_id: id}), do: Podcast.get_network!(id) - defp get_network(_), do: network_fixture() + defp extract_network(%{network_id: id}), do: Podcast.get_network!(id) + defp extract_network(_), do: network_fixture() - defp get_show(%{show_id: id}), do: Podcast.get_show!(id) - defp get_show(_), do: show_fixture() + defp extract_show(%{show_id: id}), do: Podcast.get_show!(id) + defp extract_show(_), do: show_fixture() end From f83c0b0d9e8e2654bbe5e020b377ac3b5492a764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Fri, 29 Nov 2024 18:04:12 +0100 Subject: [PATCH 07/11] fixup: pass episode id to function. could end up in ambiguous results --- lib/radiator/outline.ex | 4 ++-- lib/radiator/outline/node_repository.ex | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/radiator/outline.ex b/lib/radiator/outline.ex index 81e8d5b4..e4b50190 100644 --- a/lib/radiator/outline.ex +++ b/lib/radiator/outline.ex @@ -482,10 +482,10 @@ defmodule Radiator.Outline do Repo.transaction(fn -> old_next_node = - NodeRepository.get_node_by_parent_and_prev(get_node_id(parent_node), node.uuid) + NodeRepository.get_node_by_parent_and_prev(get_node_id(parent_node), node.uuid, node.episode_id) new_next_node = - NodeRepository.get_node_by_parent_and_prev(new_parent_id, new_prev_id) + NodeRepository.get_node_by_parent_and_prev(new_parent_id, new_prev_id, node.episode_id) {:ok, node} = NodeRepository.move_node_if(node, new_parent_id, new_prev_id) diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index 3c0c0ec4..95854bd4 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -194,17 +194,20 @@ defmodule Radiator.Outline.NodeRepository do end @doc """ - Gets a single node defined by the given prev_id and parent_id. + Gets a single node defined by the given prev_id and parent_id and the + episode id. + Returns `nil` if the Node cannot be found. ## Examples - iex> get_node_by_parent_and_prev("5adf3b360fb0", "380d56cf") + iex> get_node_by_parent_and_prev("5adf3b360fb0", "380d56cf", 23) nil - iex> get_node_by_parent_and_prev("5e3f5a0422a4", "b78a976d") + iex> get_node_by_parent_and_prev("5e3f5a0422a4", "b78a976d", 23) %Node{uuid: "33b2a1dac9b1", parent_id: "5e3f5a0422a4", prev_id: "b78a976d"} """ - def get_node_by_parent_and_prev(parent_id, prev_id) do + def get_node_by_parent_and_prev(parent_id, prev_id, episode_id) do Node + |> where(episode_id: ^episode_id) |> where_prev_node_equals(prev_id) |> where_parent_node_equals(parent_id) |> Repo.one() From 7e431b24c33a42a2062402e49fe889d608228405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Wo=CC=88ginger?= Date: Tue, 3 Dec 2024 21:22:21 +0100 Subject: [PATCH 08/11] more fixups for datamodel --- lib/radiator/outline.ex | 6 +++- lib/radiator/outline/node_repository.ex | 45 ++++++++++++++++++++++++- lib/radiator/podcast.ex | 2 +- test/support/data_case.ex | 10 +++++- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/lib/radiator/outline.ex b/lib/radiator/outline.ex index e4b50190..ca25a48c 100644 --- a/lib/radiator/outline.ex +++ b/lib/radiator/outline.ex @@ -482,7 +482,11 @@ defmodule Radiator.Outline do Repo.transaction(fn -> old_next_node = - NodeRepository.get_node_by_parent_and_prev(get_node_id(parent_node), node.uuid, node.episode_id) + NodeRepository.get_node_by_parent_and_prev( + get_node_id(parent_node), + node.uuid, + node.episode_id + ) new_next_node = NodeRepository.get_node_by_parent_and_prev(new_parent_id, new_prev_id, node.episode_id) diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index 95854bd4..372dc50a 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -30,7 +30,7 @@ defmodule Radiator.Outline.NodeRepository do Creates the internal nodes for a show, this is the global root and the global inbox. """ - def create_nodes_for_show(show_id) do + def create_virtual_nodes_for_show(show_id) do # create a root node for a show {:ok, show_root} = create_node(%{ @@ -51,6 +51,49 @@ defmodule Radiator.Outline.NodeRepository do {show_root, global_inbox} end + @doc """ + Creates the internal nodes for an episode, this is the episode root + and the episode inbox. + """ + def create_virtual_nodes_for_episode(%{id: episode_id, show_id: show_id}) do + # create a root node for a show + {show_root, _global_inbox} = get_virtual_nodes_for_show(show_id) + + {:ok, episode_root} = + create_node(%{ + episode_id: episode_id, + show_id: show_id, + parent_id: show_root.uuid, + prev_id: nil, + _type: "episode_root" + }) + + {:ok, episode_inbox} = + create_node(%{ + episode_id: episode_id, + show_id: show_id, + parent_id: episode_root.uuid, + prev_id: nil, + _type: "episode_inbox" + }) + + {episode_root, episode_inbox} + end + + def get_virtual_nodes_for_show(show_id) do + [node_1, node_2] = + Node + |> where([p], p.show_id == ^show_id) + |> where([p], p._type in [:global_root, :global_inbox]) + |> Repo.all() + + if node_1._type == :global_root do + {node_1, node_2} + else + {node_2, node_1} + end + end + @doc """ Deletes a node from the repository. diff --git a/lib/radiator/podcast.ex b/lib/radiator/podcast.ex index f0acefc4..7ff4f7a6 100644 --- a/lib/radiator/podcast.ex +++ b/lib/radiator/podcast.ex @@ -191,7 +191,7 @@ defmodule Radiator.Podcast do |> Show.changeset(attrs) |> Repo.insert() - {_show_root, _global_inbox} = NodeRepository.create_nodes_for_show(show.id) + {_show_root, _global_inbox} = NodeRepository.create_virtual_nodes_for_show(show.id) show end) end diff --git a/test/support/data_case.ex b/test/support/data_case.ex index 208f87df..136ba872 100644 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -16,6 +16,7 @@ defmodule Radiator.DataCase do use ExUnit.CaseTemplate alias Ecto.Adapters.SQL.Sandbox + alias Radiator.Outline.NodeRepository alias Radiator.PodcastFixtures import Radiator.OutlineFixtures @@ -93,7 +94,10 @@ defmodule Radiator.DataCase do end def simple_node_fixture_hierachical(_) do - episode = PodcastFixtures.episode_fixture() + show = PodcastFixtures.show_fixture() + {_show_root, _global_inbox} = NodeRepository.create_virtual_nodes_for_show(show.id) + + episode = PodcastFixtures.episode_fixture(show_id: show.id) node_1 = node_fixture( @@ -120,8 +124,12 @@ defmodule Radiator.DataCase do end def complex_node_fixture(_) do + show = PodcastFixtures.show_fixture() + {_show_root, _global_inbox} = NodeRepository.create_virtual_nodes_for_show(show.id) episode = PodcastFixtures.episode_fixture() + {_show_root, _global_inbox} = NodeRepository.create_virtual_nodes_for_episode(episode) + parent_node = node_fixture( episode_id: episode.id, From d254b03fd7f5a03fd1a867109429b427f160ae1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Tue, 3 Dec 2024 22:11:27 +0100 Subject: [PATCH 09/11] more datamodel fixups, parent_id nil --- lib/radiator/outline.ex | 11 +++++++++-- lib/radiator/outline/node_repository.ex | 20 ++++++++++++++++++++ test/radiator/outline_test.exs | 17 +++++++++++++++++ test/support/data_case.ex | 4 ++-- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/lib/radiator/outline.ex b/lib/radiator/outline.ex index ca25a48c..794d9a45 100644 --- a/lib/radiator/outline.ex +++ b/lib/radiator/outline.ex @@ -78,9 +78,9 @@ defmodule Radiator.Outline do # if no previous node is given, the new node will be inserted as the first child of the parent node def insert_node(%{"show_id" => _show_id} = attrs) do Repo.transaction(fn -> - prev_id = attrs["prev_id"] - parent_id = attrs["parent_id"] episode_id = attrs["episode_id"] + prev_id = attrs["prev_id"] + parent_id = convert_parent_id_to_intern(attrs["parent_id"], episode_id) prev_node = NodeRepository.get_node_if(prev_id) parent_node = find_parent_node(prev_node, parent_id) @@ -108,6 +108,13 @@ defmodule Radiator.Outline do end) end + defp convert_parent_id_to_intern(nil, episode_id) do + {episode_root, _} = NodeRepository.get_virtual_nodes_for_episode(episode_id) + episode_root.uuid + end + + defp convert_parent_id_to_intern(parent_id, _episode_id), do: parent_id + def insert_node(%{"episode_id" => episode_id} = attrs) do %Episode{show_id: show_id} = Podcast.get_episode!(episode_id) diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index 372dc50a..306993bf 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -80,6 +80,9 @@ defmodule Radiator.Outline.NodeRepository do {episode_root, episode_inbox} end + @doc """ + TODO add documentation + """ def get_virtual_nodes_for_show(show_id) do [node_1, node_2] = Node @@ -94,6 +97,23 @@ defmodule Radiator.Outline.NodeRepository do end end + @doc """ + TODO add documentation + """ + def get_virtual_nodes_for_episode(episode_id) do + [node_1, node_2] = + Node + |> where([p], p.episode_id == ^episode_id) + |> where([p], p._type in [:episode_root, :episode_inbox]) + |> Repo.all() + + if node_1._type == :episode_root do + {node_1, node_2} + else + {node_2, node_1} + end + end + @doc """ Deletes a node from the repository. diff --git a/test/radiator/outline_test.exs b/test/radiator/outline_test.exs index f779068f..46873173 100644 --- a/test/radiator/outline_test.exs +++ b/test/radiator/outline_test.exs @@ -264,6 +264,23 @@ defmodule Radiator.OutlineTest do assert NodeRepository.get_node!(nested_node_2.uuid).prev_id == nested_node_1.uuid end + test "when parent node is nil it will be set to the episode root", %{ + parent_node: parent_node + } do + node_attrs = %{"parent_id" => nil, "episode_id" => parent_node.episode_id} + {:ok, %{node: new_node}} = Outline.insert_node(node_attrs) + # do not test result since it will be altered + # but fetching if from the repo with low level functions will return the true value + {episode_root, _} = NodeRepository.get_virtual_nodes_for_episode(parent_node.episode_id) + assert NodeRepository.get_node!(new_node.uuid).parent_id == episode_root.uuid + end + + test "when parent node is not given it will be set to the episode root", %{ + parent_node: parent_node + } do + + end + test "without a parent node the inserted node will be put at the top", %{ parent_node: parent_node } do diff --git a/test/support/data_case.ex b/test/support/data_case.ex index 136ba872..b3b1b409 100644 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -128,13 +128,13 @@ defmodule Radiator.DataCase do {_show_root, _global_inbox} = NodeRepository.create_virtual_nodes_for_show(show.id) episode = PodcastFixtures.episode_fixture() - {_show_root, _global_inbox} = NodeRepository.create_virtual_nodes_for_episode(episode) + {episode_root, _eposide_inbox} = NodeRepository.create_virtual_nodes_for_episode(episode) parent_node = node_fixture( episode_id: episode.id, show_id: episode.show_id, - parent_id: nil, + parent_id: episode_root.uuid, prev_id: nil, content: "root of all evil" ) From f157e935c1f627cbc1731a4518ce205fb6d3488a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Tue, 3 Dec 2024 23:03:42 +0100 Subject: [PATCH 10/11] WIP: add root nodes as virtual attributes to show and enhance the query to fetch these nodes with the show --- lib/radiator/podcast.ex | 41 ++++++++++++++++++++++++++++++++++++ lib/radiator/podcast/show.ex | 3 ++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/radiator/podcast.ex b/lib/radiator/podcast.ex index 7ff4f7a6..f1895394 100644 --- a/lib/radiator/podcast.ex +++ b/lib/radiator/podcast.ex @@ -170,6 +170,47 @@ defmodule Radiator.Podcast do |> Repo.preload(preload) end + @doc """ + Gets a single show and preloads its virtual nodes (root and inbox) in a single query. + Sets the virtual attributes root_node_id and inbox_node_id. + + ## Examples + + iex> get_show(123) + %Show{root_node_id: "uuid-1", inbox_node_id: "uuid-2"} + + iex> get_show(456) + nil + + """ + def get_show(id, preload: preload) do + Show + |> join(:inner, [s], n in Node, + on: n.show_id == s.id and n._type in [:global_root, :global_inbox]) + |> where([s, _], s.id == ^id) + |> select([s, n], %{ + show: s, + nodes: n + }) + |> Repo.all() + # |> Repo.preload(preload) # FIXME + |> case do + [] -> + nil + nodes_and_show -> + show = hd(nodes_and_show).show + {root_id, inbox_id} = nodes_and_show + |> Enum.map(& &1.nodes) + |> Enum.reduce({nil, nil}, fn node, {root, inbox} -> + case node._type do + :global_root -> {node.uuid, inbox} + :global_inbox -> {root, node.uuid} + end + end) + %{show | root_node_id: root_id, inbox_node_id: inbox_id} + end + end + @doc """ Creates a show. diff --git a/lib/radiator/podcast/show.ex b/lib/radiator/podcast/show.ex index 1bd5fe3c..747e2b94 100644 --- a/lib/radiator/podcast/show.ex +++ b/lib/radiator/podcast/show.ex @@ -12,9 +12,10 @@ defmodule Radiator.Podcast.Show do schema "shows" do field :title, :string field :description, :string + field :root_node_id, :binary_id, virtual: true + field :inbox_node_id, :binary_id, virtual: true belongs_to :network, Network - has_many(:episodes, Episode) has_many(:outline_nodes, Node) many_to_many(:hosts, User, join_through: "show_hosts") From 40e2e464b7d4fa18785f378f9093e406469c3e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20W=C3=B6ginger?= Date: Fri, 6 Dec 2024 17:54:35 +0100 Subject: [PATCH 11/11] WIP: stop working at this point. Restart on working on a container unaware outliner --- lib/radiator/outline.ex | 20 +++++++++++++------- lib/radiator/outline/node_repository.ex | 3 ++- lib/radiator/podcast.ex | 2 +- lib/radiator/podcast/episode.ex | 2 ++ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/radiator/outline.ex b/lib/radiator/outline.ex index 794d9a45..cc092b45 100644 --- a/lib/radiator/outline.ex +++ b/lib/radiator/outline.ex @@ -108,13 +108,6 @@ defmodule Radiator.Outline do end) end - defp convert_parent_id_to_intern(nil, episode_id) do - {episode_root, _} = NodeRepository.get_virtual_nodes_for_episode(episode_id) - episode_root.uuid - end - - defp convert_parent_id_to_intern(parent_id, _episode_id), do: parent_id - def insert_node(%{"episode_id" => episode_id} = attrs) do %Episode{show_id: show_id} = Podcast.get_episode!(episode_id) @@ -123,6 +116,13 @@ defmodule Radiator.Outline do |> insert_node() end + defp convert_parent_id_to_intern(nil, episode_id) do + {episode_root, _} = NodeRepository.get_virtual_nodes_for_episode(episode_id) + episode_root.uuid + end + + defp convert_parent_id_to_intern(parent_id, _episode_id), do: parent_id + @doc """ Intends a node given by its id (by using the tab key). @@ -248,6 +248,12 @@ defmodule Radiator.Outline do {:error, :parent_and_prev_not_consistent} end + def move_node(node_id, prev_id: new_prev_id, parent_id: nil) do + node = NodeRepository.get_node(node_id) + intern_parent = convert_parent_id_to_intern(nil, node.episode_id) + move_node(node_id, prev_id: new_prev_id, parent_id: intern_parent) + end + def move_node(node_id, prev_id: new_prev_id, parent_id: new_parent_id) do case NodeRepository.get_node(node_id) do nil -> diff --git a/lib/radiator/outline/node_repository.ex b/lib/radiator/outline/node_repository.ex index 306993bf..94049c40 100644 --- a/lib/radiator/outline/node_repository.ex +++ b/lib/radiator/outline/node_repository.ex @@ -81,7 +81,8 @@ defmodule Radiator.Outline.NodeRepository do end @doc """ - TODO add documentation + returns the virtual nodes of a show + TODO: perhaps these should be stored in the show itself? """ def get_virtual_nodes_for_show(show_id) do [node_1, node_2] = diff --git a/lib/radiator/podcast.ex b/lib/radiator/podcast.ex index f1895394..28f6a344 100644 --- a/lib/radiator/podcast.ex +++ b/lib/radiator/podcast.ex @@ -193,7 +193,7 @@ defmodule Radiator.Podcast do nodes: n }) |> Repo.all() - # |> Repo.preload(preload) # FIXME + |> Repo.preload(preload) # FIXME |> case do [] -> nil diff --git a/lib/radiator/podcast/episode.ex b/lib/radiator/podcast/episode.ex index 845d6c58..ea6a6176 100644 --- a/lib/radiator/podcast/episode.ex +++ b/lib/radiator/podcast/episode.ex @@ -16,6 +16,8 @@ defmodule Radiator.Podcast.Episode do field :slug, :string field :is_deleted, :boolean, default: false field :deleted_at, :utc_datetime + field :root_node_id, :binary_id, virtual: true + field :inbox_node_id, :binary_id, virtual: true belongs_to :show, Show