Skip to content

Commit fd41c66

Browse files
committed
feat: query children of a query
1 parent a5779c3 commit fd41c66

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

lib/query/children.ex

+17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ defmodule Hierarch.Query.Children do
77
88
* `:with_self` - when true to include itself. Defaults to false.
99
"""
10+
def query(%{from: %{source: {_table_name, schema}}} = queryable) do
11+
path_column = schema.__hierarch__(:path_column)
12+
13+
[pk_column] = schema.__schema__(:primary_key)
14+
15+
uuids_query =
16+
from t in queryable,
17+
select: %{__ancestry__: fragment("text2ltree(replace(ltree2text(?), '-', '_')) || replace(text(?), '-', '_')", field(t, ^path_column), field(t, ^pk_column))}
18+
19+
uuids_array_query =
20+
from t in subquery(uuids_query),
21+
select: %{__ltrees__: fragment("array_agg(?)", t.__ancestry__)}
22+
23+
schema
24+
|> join(:cross, [], a in subquery(uuids_array_query))
25+
|> where([t, a], field(t, ^path_column) in a.__ltrees__)
26+
end
1027
def query(%schema{} = struct, opts \\ []) do
1128
with_self = Keyword.get(opts, :with_self, false)
1229

test/hierarch/children_test.exs

+25
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,29 @@ defmodule Hierarch.ChildrenTest do
5353
assert children == [astronomy]
5454
end
5555
end
56+
57+
describe "children/1" do
58+
import Ecto.Query
59+
60+
test "returns children of a query", catelogs do
61+
science = Map.get(catelogs, "Top.Science")
62+
hobbies = Map.get(catelogs, "Top.Hobbies")
63+
64+
astronomy = Map.get(catelogs, "Top.Science.Astronomy")
65+
66+
amateurs_astronomy = Map.get(catelogs, "Top.Hobbies.Amateurs_Astronomy")
67+
68+
query = from(
69+
c in Catelog,
70+
where: c.id in ^[science.id, hobbies.id]
71+
)
72+
73+
descendants =
74+
query
75+
|> Hierarch.Query.Children.query()
76+
|> Repo.all
77+
78+
assert_match descendants, [astronomy, amateurs_astronomy]
79+
end
80+
end
5681
end

0 commit comments

Comments
 (0)