This component exposes methods for manipulating in-database trees based on the nested set model. All you need to do is ensure your table has a numeric primary key (the 'id' field), numeric left/right fields (the 'lpos' and 'rpos' fields, and a sortable field for ordering (the 'sort' field), if you want to use the sortChildren and/or sortSiblings methods. The names of the actual fields (along with the datasource and table name) are passed as arguments to the init method, and all are optional.
While the nested set model theoretically allows for multiple 'root' nodes, this implementation doesn't support that. There must be a single root node that all other nodes are descendants of. While parts of the code will work with multiple top-level nodes, many methods will fail, and none are indended to be used with a multi-root tree.
It must be mentioned that there is no guarentee that the left/right positions maintained by this object will remain fully compressed. It is entirely possible that spaces will develop.
Method Summary | |
public treemanager |
init(string dsn, string table, [string sortField="name"], [string lposField="lpos"], [string rposField="rpos"], [string idField="id"])
I initialize this treemanager object, and return myself. |
public string |
getChildIds(numeric id)
I return a list of IDs for the child nodes of the specified node. |
public struct |
getFirstChild(numeric id)
I return a struct with id, lpos, and rpos of the specified node's first child. |
public struct |
getNextSibling(numeric id)
Returns a struct with the id, lpos, and rpos of the specified node's next sibling. |
public struct |
getNode(numeric id)
Returns a struct with the id, lpos, and rpos of the specified node |
public query |
getNodeList([string columnList="*"])
I return a recordset containing the full list of nodes, using the specified columnList, with the addition of a 'depth' column, which contains the depth of each node in the tree. |
package struct |
getParent(numeric id)
Returns a struct with the id, lpos, and rpos of the specified node's parent. |
public struct |
getPreviousSibling(numeric id)
Returns a struct with the id, lpos, and rpos of the specified node's previous sibling. |
public void |
initializeHierarchy(numeric id)
I initialize the tree hierarchy with the specified node as the root. |
public void |
injectIntoHierarchy(numeric id, numeric parentID)
I inject a node into the hierarchy. In terms of the database, I take a record that doesn't currently belong to the tree and add it into the tree, using the specified node as it's parent. Newly added nodes will always end up as the last child of the parent. |
public void |
makeChildOfNode(numeric id, numeric parentId)
I nest an node under another node. If the new parent node is a descendant of the node being moved, an exception is raised. |
public void |
moveDown(numeric id)
I move a node down one slot. In other words, swap it with it's next sibling. If the node doesn't have a next sibling, nothing happens. |
private void |
moveSubtree(numeric id, numeric destPos)
Thid moves the specified node to a new place in the tree. |
public void |
moveToBottom(numeric id)
I move a node to the bottom of the sibling list. If the node doesn't have siblings or is already at the bottom, nothing happens. |
public void |
moveToTop(numeric id)
I move a node to the top of the sibling list. If the node doesn't have siblings or is already at the top, nothing happens. |
public void |
moveUp(numeric id)
I move a node up one slot. In other words, swap it with it's previous sibling. If the node doesn't have a previous sibling, nothing happens. |
public void |
nestObject(numeric id)
I nest an object under it's previous sibling. If the node doesn't have a previous sibling, nothing happens. |
public void |
removeFromHierarchy(numeric id)
I remove the specified node from the tree hierarchy. Note that the record will continue to exist in the database, it just won't be linked into the hierarchy |
private void |
shift(numeric startPos, numeric delta)
I move all positions greater than a certain position a certain distance. This is typically used to make or close hole in the hierarchy when moving subtrees around. |
private void |
shiftRange(numeric startPos, numeric endPos, numeric delta)
I move a range of positions a certain distance. Usually used for moving a subtree into/out of a hole in the hierarchy created with the shift method. |
public void |
sortChildren(numeric parentID, [boolean descending="false"])
I sort the children of the specified node according to the configured sort field, using the id field as backup to ensure a stable sort. The sort method used will be most performant when the nodes are already close to sorted (under the assumption that if you want the nodes sorted, you'll resort them after every operation that might have disturbed their ordering, and so rarely have more than a node or two to reorder). |
public void |
sortSiblings(numeric id, [boolean descending="false"])
I sort the node and it's siblings according to the configured sort field, using the id field as backup to ensure a stable sort. This method is currently implemented as nothing more than a call to sortChildren passing the id of the specified node's parent. That means that you can't sort the root level of the hierarchy, which should be expected, since a tree never has more than one node at it's root. |
public void |
unnestObject(numeric id)
I unnest an object (make it a sibling of it's parent). If the node doesn't have a parent, nothing happens. |
Method Detail |
public string getChildIds(numeric id)
numeric id
- The node to find the children of.public struct getFirstChild(numeric id)
numeric id
- The id of the node to find the first child of.IllegalStateException.NoChildrenException
public struct getNextSibling(numeric id)
numeric id
- The id of the node to find the next sibling of.IllegalStateException.NoNextSiblingException
public struct getNode(numeric id)
numeric id
- The id of the node to get info about.IllegalStateException.NoSuchNodeException
public query getNodeList([string columnList="*"])
[string columnList="*"]
- The list of columns to select for the recordset. This value
will be injected directly into the SQL, so it must be sanitized
before passing. Since the string is injected into the SELECT
clause of the statement, you cannot perform joins, but you can
use subqueries. The statement you're injecting into is a single
table SELECT on the unaliased table name, and ordered by the
lpos column.package struct getParent(numeric id)
numeric id
- The id of the node to find the parent of.IllegalStateException.NoParentException
public struct getPreviousSibling(numeric id)
numeric id
- The id of the node to find the next previous of.IllegalStateException.NoPreviousSiblingException
public treemanager init(string dsn, string table, [string sortField="name"], [string lposField="lpos"], [string rposField="rpos"], [string idField="id"])
string dsn
- The datasource to access the database though.string table
- The database table that the tree objects are stored in.[string sortField="name"]
- The field that should control sorting operations. This
field needn't be unique, it will always be backed up with the
'id' field to ensure a stable result.[string lposField="lpos"]
- The field that stores the left number of nodes.[string rposField="rpos"]
- The field that stores the right number of nodes.[string idField="id"]
- The field that stores the unique id of a node.public void initializeHierarchy(numeric id)
numeric id
- The id of the node to start as the root of the hierarchy.public void injectIntoHierarchy(numeric id, numeric parentID)
numeric id
- The id of the record to inject.numeric parentID
- The id of the node the new node should be a child of.public void makeChildOfNode(numeric id, numeric parentId)
numeric id
- The node to nest.numeric parentId
- The node's new parent node.IllegalStateException.InvalidNestingRequest
public void moveDown(numeric id)
numeric id
- The id of the node to move down.private void moveSubtree(numeric id, numeric destPos)
numeric id
- The node to move.numeric destPos
- The new lpos for the node. Note that this is not necessarily
the lpos the node will keep, because after the move the nodes may
be recompressed and the lpos shifted.public void moveToBottom(numeric id)
numeric id
- The id of the node to move to the bottom.public void moveToTop(numeric id)
numeric id
- The id of the node to move to the top.public void moveUp(numeric id)
numeric id
- The id of the node to move up.public void nestObject(numeric id)
numeric id
- The node to nest.public void removeFromHierarchy(numeric id)
numeric id
- The id of the node to remove.private void shift(numeric startPos, numeric delta)
numeric startPos
- The lowest position to move.numeric delta
- The distance to move (may be negative).private void shiftRange(numeric startPos, numeric endPos, numeric delta)
numeric startPos
- The starting position of the range.numeric endPos
- The ending position of the range.numeric delta
- The distance to move.public void sortChildren(numeric parentID, [boolean descending="false"])
numeric parentID
- The id of the node whose children need sorting[boolean descending="false"]
- Whether the sorting should be descending (reversed) orderpublic void sortSiblings(numeric id, [boolean descending="false"])
numeric id
- The id of one of the sibling nodes that need sorting[boolean descending="false"]
- Whether the sorting should be descending (reversed) orderpublic void unnestObject(numeric id)
numeric id
- The node to unnest.