Index

Version 7 (Petr Mourek, 07/28/2010 02:40 pm)

1 2 Roman Mackovčák
h1. Nested set plugin for Grails
2 3 Roman Mackovčák
3 3 Roman Mackovčák
h2. What is Nested set?
4 3 Roman Mackovčák
5 3 Roman Mackovčák
A nested set model is a way of organising hierarchical data in a relational database, "see Wikipedia":http://en.wikipedia.org/wiki/Nested_set_model.
6 3 Roman Mackovčák
7 3 Roman Mackovčák
h2. Installation instructions
8 3 Roman Mackovčák
9 7 Petr Mourek
Download the attachment:grails-nested-set-0.3.zip and run 
10 3 Roman Mackovčák
11 3 Roman Mackovčák
<pre><code class="java">
12 3 Roman Mackovčák
grails install-plugin /path/to/the/plugin.zip
13 3 Roman Mackovčák
</code></pre>
14 3 Roman Mackovčák
15 3 Roman Mackovčák
16 3 Roman Mackovčák
h2. Essentials
17 3 Roman Mackovčák
18 3 Roman Mackovčák
The NestedSet plugin injects the functionality of a nested set to any domain class. It is as simple as declaring a static variable.
19 3 Roman Mackovčák
20 3 Roman Mackovčák
<pre><code class="java">
21 3 Roman Mackovčák
class Employee {
22 3 Roman Mackovčák
	String firstName
23 3 Roman Mackovčák
	String lastName
24 3 Roman Mackovčák
	
25 3 Roman Mackovčák
	static nestedSet = true
26 3 Roman Mackovčák
}
27 3 Roman Mackovčák
</code></pre>
28 3 Roman Mackovčák
29 5 Roman Mackovčák
Moreover, it does not interfere with the domain at all. The whole structure is stored in a domain class named NestedSet, in a separate table.
30 3 Roman Mackovčák
31 5 Roman Mackovčák
It is possible to create a Nested set from any of your domain classes. Nevertheless, the tree structures can contain only classes with common ancestor. This ancestor have to be marked as a nested set.
32 3 Roman Mackovčák
33 3 Roman Mackovčák
The following example will create 2 tree structures: Employee and Location.
34 3 Roman Mackovčák
35 3 Roman Mackovčák
<pre><code class="java">
36 3 Roman Mackovčák
class Employee {
37 3 Roman Mackovčák
	String firstName
38 3 Roman Mackovčák
	String lastName
39 3 Roman Mackovčák
	
40 3 Roman Mackovčák
	static nestedSet = true
41 3 Roman Mackovčák
}
42 3 Roman Mackovčák
43 3 Roman Mackovčák
class Location{
44 3 Roman Mackovčák
	String name
45 3 Roman Mackovčák
	static nestedSet = true
46 3 Roman Mackovčák
}
47 3 Roman Mackovčák
48 3 Roman Mackovčák
class Continent extends Location{}
49 3 Roman Mackovčák
50 3 Roman Mackovčák
class State extends Location{}
51 3 Roman Mackovčák
52 3 Roman Mackovčák
class City extends Location{}
53 3 Roman Mackovčák
</code></pre>
54 3 Roman Mackovčák
55 3 Roman Mackovčák
The Location tree structure can contain any of the descendants - Continent, State, City.
56 3 Roman Mackovčák
57 3 Roman Mackovčák
The methods of the NestedSet are described in the following example.
58 3 Roman Mackovčák
59 3 Roman Mackovčák
h2. Example
60 3 Roman Mackovčák
61 3 Roman Mackovčák
<pre><code class="java">
62 3 Roman Mackovčák
class Employee {
63 3 Roman Mackovčák
	String firstName
64 3 Roman Mackovčák
	String lastName
65 3 Roman Mackovčák
	
66 3 Roman Mackovčák
	static nestedSet = true
67 3 Roman Mackovčák
	
68 3 Roman Mackovčák
	/** 
69 3 Roman Mackovčák
	*	Returns the direct manager of the employee
70 3 Roman Mackovčák
	**/
71 3 Roman Mackovčák
	def manager() {
72 3 Roman Mackovčák
		nestedSetGetParent()
73 3 Roman Mackovčák
	}
74 3 Roman Mackovčák
	
75 3 Roman Mackovčák
	/**
76 3 Roman Mackovčák
	*	Returns all managers of the employee
77 3 Roman Mackovčák
	**/
78 3 Roman Mackovčák
	def managers() {
79 3 Roman Mackovčák
		nestedSetGetAncestors()
80 3 Roman Mackovčák
	}
81 3 Roman Mackovčák
	
82 3 Roman Mackovčák
	/**
83 3 Roman Mackovčák
	*	Returns direct subordinates of the employee
84 3 Roman Mackovčák
	**/
85 3 Roman Mackovčák
	def directSubordinates() {
86 3 Roman Mackovčák
		nestedSetGetChildren()
87 3 Roman Mackovčák
	}
88 3 Roman Mackovčák
	
89 3 Roman Mackovčák
	/**
90 3 Roman Mackovčák
	*	Returns direct subordinates of the employee and their subordinates
91 3 Roman Mackovčák
	**/
92 3 Roman Mackovčák
	def allSubordinates() {
93 3 Roman Mackovčák
		nestedSetGetDescendants()
94 3 Roman Mackovčák
	}
95 3 Roman Mackovčák
	
96 3 Roman Mackovčák
	/**
97 3 Roman Mackovčák
	*	Returns the top managers (having no manager)
98 3 Roman Mackovčák
	**/
99 3 Roman Mackovčák
	static def topManagers() {
100 3 Roman Mackovčák
		nestedSetGetRoots()
101 3 Roman Mackovčák
	}
102 3 Roman Mackovčák
	
103 3 Roman Mackovčák
	/**
104 3 Roman Mackovčák
	*	Promote employee to be the top manager
105 3 Roman Mackovčák
	**/
106 3 Roman Mackovčák
	def makeTopManager() {
107 3 Roman Mackovčák
		nestedSetMakeRoot()
108 3 Roman Mackovčák
	}
109 3 Roman Mackovčák
	
110 3 Roman Mackovčák
	/**
111 3 Roman Mackovčák
	*	Remove the employee and all subordinates from hierarchy
112 3 Roman Mackovčák
	**/
113 3 Roman Mackovčák
	def outsourceDepartment() {
114 3 Roman Mackovčák
		nestedSetRemove()
115 3 Roman Mackovčák
	}
116 3 Roman Mackovčák
	
117 3 Roman Mackovčák
	/**
118 3 Roman Mackovčák
	*	Adds a new subordinate
119 3 Roman Mackovčák
	**/
120 3 Roman Mackovčák
	def addSubordinate(so) {
121 3 Roman Mackovčák
		nestedSetAddChild(so)
122 3 Roman Mackovčák
	}
123 3 Roman Mackovčák
	
124 3 Roman Mackovčák
	/**
125 3 Roman Mackovčák
	*	Move the whole department under different manager
126 3 Roman Mackovčák
	**/
127 3 Roman Mackovčák
	def reorganize(newManager){
128 3 Roman Mackovčák
		nestedSetMoveTo(newManager)
129 3 Roman Mackovčák
	}
130 3 Roman Mackovčák
	
131 3 Roman Mackovčák
	String toString() {
132 3 Roman Mackovčák
		"$firstName $lastName"
133 3 Roman Mackovčák
	}
134 3 Roman Mackovčák
}
135 3 Roman Mackovčák
}
136 3 Roman Mackovčák
</code></pre>
137 3 Roman Mackovčák
138 3 Roman Mackovčák
h2. Limitations
139 3 Roman Mackovčák
140 3 Roman Mackovčák
* If DB set to update, it does not create the appropriate indexes.... Human:Hibernate 0:1
141 3 Roman Mackovčák
* It works well for "slowly changing" (static) hierarchical structures. The dynamic ones should be stored using different structure.