Skip to content

Commit 1dd467a

Browse files
committed
api improvement, transact consistency
1 parent 3a3e399 commit 1dd467a

4 files changed

Lines changed: 66 additions & 65 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
# NestedSets
2+
# NestedSets for Ecto
33

44
![NestedSets](https://raw.githubusercontent.com/AlexGx/nested_sets/master/artwork/banner.png)
55

@@ -15,7 +15,7 @@
1515
</a>
1616
</p>
1717

18-
Battle-tested NestedSets behavior for Ecto that supports PostgreSQL, SQLite, and MySQL.
18+
Battle-tested NestedSets for Ecto that supports PostgreSQL, SQLite, and MySQL.
1919

2020
TODO: about Ecto 3.12+, add to doc `depth` is also a `level`
2121

lib/nested_sets.ex

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ defmodule NestedSets do
106106

107107
defp validate_single_root(repo, node, cfg) do
108108
exists? = repo.exists?(from n in node.__struct__, where: field(n, ^cfg.lft) == 1)
109-
if exists?, do: repo.rollback(:root_already_exists), else: :ok
109+
if exists?, do: {:error, :root_already_exists}, else: :ok
110110
end
111111

112112
defp insert_root_node(repo, node, cfg) do
@@ -303,13 +303,13 @@ defmodule NestedSets do
303303
@doc """
304304
Checks if node is a child/descendant of the potential parent.
305305
"""
306-
@spec child_of?(ns_node(), ns_node()) :: boolean()
307-
def child_of?(node, potential_parent) do
306+
@spec descendant_of?(ns_node(), ns_node()) :: boolean()
307+
def descendant_of?(node, potential_parent) do
308308
cfg = config(node)
309309

310310
if node.__struct__ != potential_parent.__struct__ do
311311
raise ArgumentError,
312-
"child_of?/2 expects both arguments to be structs of the same Schema, " <>
312+
"descendant_of?/2 expects both arguments to be structs of the same Schema, " <>
313313
"got #{inspect(node.__struct__)} and #{inspect(potential_parent.__struct__)}"
314314
end
315315

@@ -318,25 +318,25 @@ defmodule NestedSets do
318318
parent_lft = Map.get(potential_parent, cfg.lft)
319319
parent_rgt = Map.get(potential_parent, cfg.rgt)
320320

321-
is_descendant = node_lft > parent_lft && node_rgt < parent_rgt
321+
descendant? = node_lft > parent_lft && node_rgt < parent_rgt
322322

323-
if is_descendant && cfg.tree != false do
323+
if descendant? && cfg.tree != false do
324324
Map.get(node, cfg.tree) == Map.get(potential_parent, cfg.tree)
325325
else
326-
is_descendant
326+
descendant?
327327
end
328328
end
329329

330330
@doc """
331-
Checks if node is a direct child/descendant of the potential parent.
331+
Checks if node is a direct child of the potential parent.
332332
"""
333-
@spec direct_child_of?(ns_node(), ns_node()) :: boolean()
334-
def direct_child_of?(node, potential_parent) do
333+
@spec child_of?(ns_node(), ns_node()) :: boolean()
334+
def child_of?(node, potential_parent) do
335335
cfg = config(node)
336336

337337
if node.__struct__ != potential_parent.__struct__ do
338338
raise ArgumentError,
339-
"direct_child_of?/2 expects both arguments to be structs of the same Schema, " <>
339+
"child_of?/2 expects both arguments to be structs of the same Schema, " <>
340340
"got #{inspect(node.__struct__)} and #{inspect(potential_parent.__struct__)}"
341341
end
342342

@@ -352,11 +352,11 @@ defmodule NestedSets do
352352
parent_lft = Map.get(potential_parent, cfg.lft)
353353
parent_rgt = Map.get(potential_parent, cfg.rgt)
354354

355-
is_descendant? = node_lft > parent_lft && node_rgt < parent_rgt
355+
descendant? = node_lft > parent_lft && node_rgt < parent_rgt
356356

357-
has_correct_depth? = Map.get(node, cfg.depth) == Map.get(potential_parent, cfg.depth) + 1
357+
correct_depth? = Map.get(node, cfg.depth) == Map.get(potential_parent, cfg.depth) + 1
358358

359-
same_scope? && is_descendant? && has_correct_depth?
359+
same_scope? && descendant? && correct_depth?
360360
end
361361

362362
@doc """
@@ -644,7 +644,7 @@ defmodule NestedSets do
644644
get_primary_key(node) == get_primary_key(target) ->
645645
{:error, :cannot_move_to_itself}
646646

647-
child_of?(target, node) ->
647+
descendant_of?(target, node) ->
648648
{:error, :cannot_move_to_descendant}
649649

650650
position in [:before, :after] && root?(target) ->

lib/nested_sets/query.ex

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ defmodule NestedSets.Query do
2424

2525
import Ecto.Query
2626

27+
@type ns_node :: struct()
28+
2729
defp config(schema), do: NestedSets.config(schema)
2830

2931
defp get_schema(queryable) do
@@ -39,7 +41,7 @@ defmodule NestedSets.Query do
3941
## Options
4042
* `:depth` - limit to ancestors within N levels (optional)
4143
"""
42-
@spec ancestors(Ecto.Queryable.t(), struct(), keyword()) :: Ecto.Query.t() | nil
44+
@spec ancestors(Ecto.Queryable.t(), ns_node(), keyword()) :: Ecto.Query.t() | nil
4345
def ancestors(queryable, node, opts \\ []) do
4446
schema = get_schema(queryable)
4547
cfg = config(schema)
@@ -73,7 +75,7 @@ defmodule NestedSets.Query do
7375
@doc """
7476
Alias for `ancestors/3`.
7577
"""
76-
@spec parents(Ecto.Queryable.t(), struct(), keyword()) :: Ecto.Query.t() | nil
78+
@spec parents(Ecto.Queryable.t(), ns_node(), keyword()) :: Ecto.Query.t() | nil
7779
def parents(queryable, node, opts \\ []), do: ancestors(queryable, node, opts)
7880

7981
@doc """
@@ -82,7 +84,7 @@ defmodule NestedSets.Query do
8284
## Options
8385
* `:depth` - limit to descendants within N levels (optional)
8486
"""
85-
@spec descendants(Ecto.Queryable.t(), struct(), keyword()) :: Ecto.Query.t() | nil
87+
@spec descendants(Ecto.Queryable.t(), ns_node(), keyword()) :: Ecto.Query.t() | nil
8688
def descendants(queryable, node, opts \\ []) do
8789
schema = get_schema(queryable)
8890
cfg = config(schema)
@@ -116,7 +118,7 @@ defmodule NestedSets.Query do
116118
@doc """
117119
Alias for `descendants/3`.
118120
"""
119-
@spec children(Ecto.Queryable.t(), struct(), keyword()) :: Ecto.Query.t() | nil
121+
@spec children(Ecto.Queryable.t(), ns_node(), keyword()) :: Ecto.Query.t() | nil
120122
def children(queryable, node, opts \\ []), do: descendants(queryable, node, opts)
121123

122124
@doc """
@@ -128,7 +130,7 @@ defmodule NestedSets.Query do
128130
@doc """
129131
Finds all leaf nodes (nodes without children) under a node.
130132
"""
131-
@spec leaves(Ecto.Queryable.t(), struct()) :: Ecto.Query.t() | nil
133+
@spec leaves(Ecto.Queryable.t(), ns_node()) :: Ecto.Query.t() | nil
132134
def leaves(queryable, node) do
133135
schema = get_schema(queryable)
134136
cfg = config(schema)
@@ -150,7 +152,7 @@ defmodule NestedSets.Query do
150152
@doc """
151153
Finds the previous sibling of a node.
152154
"""
153-
@spec prev_sibling(Ecto.Queryable.t(), struct()) :: Ecto.Query.t() | nil
155+
@spec prev_sibling(Ecto.Queryable.t(), ns_node()) :: Ecto.Query.t() | nil
154156
def prev_sibling(queryable, node) do
155157
schema = get_schema(queryable)
156158
cfg = config(schema)
@@ -168,13 +170,13 @@ defmodule NestedSets.Query do
168170
@doc """
169171
Alias for `prev_sibling/2`.
170172
"""
171-
@spec prev(Ecto.Queryable.t(), struct()) :: Ecto.Query.t() | nil
173+
@spec prev(Ecto.Queryable.t(), ns_node()) :: Ecto.Query.t() | nil
172174
def prev(queryable, node), do: prev_sibling(queryable, node)
173175

174176
@doc """
175177
Finds the next sibling of a node.
176178
"""
177-
@spec next_sibling(Ecto.Queryable.t(), struct()) :: Ecto.Query.t() | nil
179+
@spec next_sibling(Ecto.Queryable.t(), ns_node()) :: Ecto.Query.t() | nil
178180
def next_sibling(queryable, node) do
179181
schema = get_schema(queryable)
180182
cfg = config(schema)
@@ -192,13 +194,13 @@ defmodule NestedSets.Query do
192194
@doc """
193195
Alias for `next_sibling/2`.
194196
"""
195-
@spec next(Ecto.Queryable.t(), struct()) :: Ecto.Query.t() | nil
197+
@spec next(Ecto.Queryable.t(), ns_node()) :: Ecto.Query.t() | nil
196198
def next(queryable, node), do: next_sibling(queryable, node)
197199

198200
@doc """
199201
Finds all siblings of a node (nodes with the same parent).
200202
"""
201-
@spec siblings(Ecto.Queryable.t(), struct()) :: Ecto.Query.t() | nil
203+
@spec siblings(Ecto.Queryable.t(), ns_node()) :: Ecto.Query.t() | nil
202204
def siblings(queryable, node) do
203205
schema = get_schema(queryable)
204206
cfg = config(schema)
@@ -245,7 +247,7 @@ defmodule NestedSets.Query do
245247
@doc """
246248
Finds the root node for a specific tree (when using tree).
247249
"""
248-
@spec root(Ecto.Queryable.t(), struct()) :: Ecto.Query.t() | nil
250+
@spec root(Ecto.Queryable.t(), ns_node()) :: Ecto.Query.t() | nil
249251
def root(queryable, node) do
250252
schema = get_schema(queryable)
251253
cfg = config(schema)
@@ -262,7 +264,7 @@ defmodule NestedSets.Query do
262264
@doc """
263265
Gets a node and all its descendants (the full subtree including the node itself).
264266
"""
265-
@spec subtree(Ecto.Queryable.t(), struct()) :: Ecto.Query.t() | nil
267+
@spec subtree(Ecto.Queryable.t(), ns_node()) :: Ecto.Query.t() | nil
266268
def subtree(queryable, node) do
267269
schema = get_schema(queryable)
268270
cfg = config(schema)
@@ -283,7 +285,7 @@ defmodule NestedSets.Query do
283285
@doc """
284286
Finds nodes at a specific depth level.
285287
"""
286-
@spec at_depth(Ecto.Queryable.t(), integer()) :: Ecto.Query.t()
288+
@spec at_depth(Ecto.Queryable.t(), non_neg_integer()) :: Ecto.Query.t()
287289
def at_depth(queryable, depth) do
288290
schema = get_schema(queryable)
289291
cfg = config(schema)
@@ -295,11 +297,10 @@ defmodule NestedSets.Query do
295297
end
296298

297299
@doc """
298-
@review: not only :integer
299300
Filters by a specific tree (when using tree).
300-
Accepts either a tree_id integer or a node struct.
301+
Accepts either a tree_id integer or a node.
301302
"""
302-
@spec in_tree(Ecto.Queryable.t(), integer() | struct()) :: Ecto.Query.t() | nil
303+
@spec in_tree(Ecto.Queryable.t(), pos_integer() | ns_node()) :: Ecto.Query.t() | nil
303304
def in_tree(queryable, tree_id) when is_integer(tree_id) do
304305
schema = get_schema(queryable)
305306
cfg = config(schema)

0 commit comments

Comments
 (0)