Skip to content

Commit c45cb44

Browse files
committed
feat: query ancestors of a query
1 parent 3515af3 commit c45cb44

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

lib/query/ancestors.ex

+19
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,25 @@ defmodule Hierarch.Query.Ancestors 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: %{__uuid__: fragment("regexp_split_to_table(replace(ltree2text(?), '_', '-'), '\\.')", field(t, ^path_column))}
18+
19+
uuids_array_query =
20+
from t in subquery(uuids_query),
21+
where: not is_nil(t.__uuid__),
22+
or_where: t.__uuid__ != ^"",
23+
select: %{__uuids__: fragment("array_agg(cast(? as uuid))", t.__uuid__)}
24+
25+
schema
26+
|> join(:cross, [], a in subquery(uuids_array_query))
27+
|> where([t, a], field(t, ^pk_column) in a.__uuids__)
28+
end
1029
def query(%schema{} = struct, opts \\ []) do
1130
with_self = Keyword.get(opts, :with_self, false)
1231

test/hierarch/ancestors_test.exs

+25
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,29 @@ defmodule Hierarch.AncestorsTest do
5454
assert ancestors == [top]
5555
end
5656
end
57+
58+
describe "ancestors/1" do
59+
import Ecto.Query
60+
61+
test "returns ancestors of a query", catelogs do
62+
science = Map.get(catelogs, "Top.Science")
63+
hobbies = Map.get(catelogs, "Top.Hobbies")
64+
pictures = Map.get(catelogs, "Top.Collections.Pictures")
65+
66+
top = Map.get(catelogs, "Top")
67+
collections = Map.get(catelogs, "Top.Collections")
68+
69+
query = from(
70+
c in Catelog,
71+
where: c.id in ^[science.id, hobbies.id, pictures.id]
72+
)
73+
74+
descendants =
75+
query
76+
|> Hierarch.Query.Ancestors.query()
77+
|> Repo.all
78+
79+
assert_match descendants, [top, collections]
80+
end
81+
end
5782
end

0 commit comments

Comments
 (0)