@@ -93,46 +93,41 @@ defmodule NestedSets do
9393 { :ok , ns_node ( ) } | { :error , term ( ) | Ecto.Changeset . t ( ) }
9494 def make_root ( repo , node ) do
9595 cfg = config ( node )
96- schema = node . __struct__
9796
9897 repo . transact ( fn ->
99- if cfg . tree == false do
100- exists? =
101- repo . exists? ( from n in schema , where: field ( n , ^ cfg . lft ) == 1 )
102-
103- if exists? do
104- repo . rollback ( :root_already_exists )
105- end
98+ with :ok <- validate_single_root ( repo , node , cfg ) ,
99+ { :ok , inserted } <- insert_root_node ( repo , node , cfg ) do
100+ { :ok , maybe_set_tree_id ( repo , inserted , cfg ) }
106101 end
102+ end )
103+ end
107104
108- changeset =
109- node
110- |> Ecto.Changeset . change ( % {
111- cfg . lft => 1 ,
112- cfg . rgt => 2 ,
113- cfg . depth => 0
114- } )
115-
116- { :ok , inserted } = repo . insert ( changeset )
117-
118- # set tree_id when multi-tree mode enabled, TODO: improve
119- final_node =
120- if cfg . tree != false do
121- pk = get_primary_key ( inserted )
122-
123- { 1 , _ } =
124- repo . update_all (
125- from ( n in schema , where: n . id == ^ pk ) ,
126- set: [ { cfg . tree , pk } ]
127- )
128-
129- repo . get! ( schema , pk )
130- else
131- inserted
132- end
105+ defp validate_single_root ( _repo , _node , % { tree: tree } ) when tree != false , do: :ok
133106
134- { :ok , final_node }
135- end )
107+ defp validate_single_root ( repo , node , cfg ) do
108+ 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
110+ end
111+
112+ defp insert_root_node ( repo , node , cfg ) do
113+ node
114+ |> Ecto.Changeset . change ( % { cfg . lft => 1 , cfg . rgt => 2 , cfg . depth => 0 } )
115+ |> repo . insert ( )
116+ end
117+
118+ defp maybe_set_tree_id ( _repo , node , % { tree: false } ) , do: node
119+
120+ defp maybe_set_tree_id ( repo , node , cfg ) do
121+ schema = node . __struct__
122+ pk = get_primary_key ( node )
123+
124+ { 1 , _ } =
125+ repo . update_all (
126+ from ( n in schema , where: n . id == ^ pk ) ,
127+ set: [ { cfg . tree , pk } ]
128+ )
129+
130+ repo . get! ( schema , pk )
136131 end
137132
138133 @ doc """
@@ -221,43 +216,45 @@ defmodule NestedSets do
221216 """
222217 @ spec delete_node ( Ecto.Repo . t ( ) , ns_node ( ) ) :: { :ok , ns_node ( ) } | { :error , term ( ) }
223218 def delete_node ( repo , node ) do
224- cfg = config ( node )
225-
226219 if root? ( node ) do
227220 { :error , :cannot_delete_root }
228221 else
229- schema = node . __struct__
230-
231- repo . transact ( fn ->
232- refreshed = repo . reload! ( node )
233- lft = Map . get ( refreshed , cfg . lft )
234- rgt = Map . get ( refreshed , cfg . rgt )
235-
236- deleted = repo . delete! ( refreshed )
237-
238- # if it has children, shift them up/left to fill the parent's shell
239- if rgt - lft > 1 do
240- query =
241- from ( n in schema ,
242- where: field ( n , ^ cfg . lft ) > ^ lft and field ( n , ^ cfg . rgt ) < ^ rgt
243- )
244- |> apply_tree_condition ( refreshed , cfg )
245-
246- repo . update_all ( query ,
247- inc: [
248- { cfg . lft , - 1 } ,
249- { cfg . rgt , - 1 } ,
250- { cfg . depth , - 1 }
251- ]
222+ do_delete_node ( repo , node )
223+ end
224+ end
225+
226+ defp do_delete_node ( repo , node ) do
227+ cfg = config ( node )
228+
229+ repo . transact ( fn ->
230+ refreshed = repo . reload! ( node )
231+ lft = Map . get ( refreshed , cfg . lft )
232+ rgt = Map . get ( refreshed , cfg . rgt )
233+
234+ deleted = repo . delete! ( refreshed )
235+
236+ # if it has children, shift them up/left to fill the parent's shell
237+ if rgt - lft > 1 do
238+ query =
239+ from ( n in node . __struct__ ,
240+ where: field ( n , ^ cfg . lft ) > ^ lft and field ( n , ^ cfg . rgt ) < ^ rgt
252241 )
253- end
242+ |> apply_tree_condition ( refreshed , cfg )
243+
244+ repo . update_all ( query ,
245+ inc: [
246+ { cfg . lft , - 1 } ,
247+ { cfg . rgt , - 1 } ,
248+ { cfg . depth , - 1 }
249+ ]
250+ )
251+ end
254252
255- # close the gap (width of 2 for the single node deleted)
256- shift_left_right ( repo , refreshed , rgt + 1 , - 2 , cfg )
253+ # close the gap (width of 2 for the single node deleted)
254+ shift_left_right ( repo , refreshed , rgt + 1 , - 2 , cfg )
257255
258- { :ok , deleted }
259- end )
260- end
256+ { :ok , deleted }
257+ end )
261258 end
262259
263260 @ doc """
0 commit comments