Skip to content

Commit a5779c3

Browse files
committed
feat: query descendants of a query
1 parent 3c132f7 commit a5779c3

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

lib/query/descendants.ex

+17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ defmodule Hierarch.Query.Descendants 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], fragment("? @> ?", a.__ltrees__, field(t, ^path_column)))
26+
end
1027
def query(%schema{} = struct, opts \\ []) do
1128
with_self = Keyword.get(opts, :with_self, false)
1229

test/hierarch/descendants_test.exs

+27
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,31 @@ defmodule Hierarch.DescendantsTest do
5959
assert_match descendants, [astronomy, astrophysics, cosmology]
6060
end
6161
end
62+
63+
describe "query/1" do
64+
import Ecto.Query
65+
66+
test "returns their descendants", catelogs do
67+
science = Map.get(catelogs, "Top.Science")
68+
hobbies = Map.get(catelogs, "Top.Hobbies")
69+
70+
astronomy = Map.get(catelogs, "Top.Science.Astronomy")
71+
astrophysics = Map.get(catelogs, "Top.Science.Astronomy.Astrophysics")
72+
cosmology = Map.get(catelogs, "Top.Science.Astronomy.Cosmology")
73+
74+
amateurs_astronomy = Map.get(catelogs, "Top.Hobbies.Amateurs_Astronomy")
75+
76+
query = from(
77+
c in Catelog,
78+
where: c.id in ^[science.id, hobbies.id]
79+
)
80+
81+
descendants =
82+
query
83+
|> Hierarch.Query.Descendants.query()
84+
|> Repo.all
85+
86+
assert_match descendants, [astronomy, astrophysics, cosmology, amateurs_astronomy]
87+
end
88+
end
6289
end

0 commit comments

Comments
 (0)