Author: dr
Date: Tue Jul 31 11:53:20 2007
New Revision: 5771
Log:
- Added documentation to the DB tree classes.
Modified:
trunk/Tree/src/backends/db.php
trunk/Tree/src/backends/db_parent_child.php
trunk/Tree/src/tree.php
Modified: trunk/Tree/src/backends/db.php
==============================================================================
--- trunk/Tree/src/backends/db.php [iso-8859-1] (original)
+++ trunk/Tree/src/backends/db.php [iso-8859-1] Tue Jul 31 11:53:20 2007
@@ -8,32 +8,63 @@
*/
/**
- * ezcTreeXml is an implementation of a tree backend that operates on
- * an XML file.
+ * ezcTreeDb contains common methods for the different database tree backends.
*
* @property-read ezcTreeXmlDataStore $store
+ * The data store that is used for retrieving/storing data.
+ * @property bool $prefetch
+ * Whether data pre-fetching is enabled.
+ * @property string $nodeClassName
+ * Which class is used as tree node - this class *must* inherit
+ * the ezcTreeNode class.
*
* @package Tree
* @version //autogentag//
- * @mainclass
*/
abstract class ezcTreeDb extends ezcTree
{
+ /**
+ * Contains the database connection handler
+ *
+ * @var ezcDbHandler
+ */
protected $dbh;
+ /**
+ * Contains the name of the table to retrieve the relational data from.
+ *
+ * @var string
+ */
protected $indexTableName;
/**
- * Constructs a new ezcTreeXml object
+ * Constructs a new ezcTreeDb object
+ *
+ * The different arguments to the constructor configure which database
+ * connection ($dbh) is used to access the database and the $indexTableName
+ * argument which table is used to retrieve the relation data from. The
+ * $store argument configure which data store is used with this tree.
+ *
+ * All database backends require the index table to atleast define the
+ * field 'id', which can either be a string or an integer field.
+ *
+ * @param ezcDbHandler $dbh
+ * @param string $indexTableName
+ * @param ezcTreeDbDataStore $store
*/
public function __construct( ezcDbHandler $dbh, $indexTableName,
ezcTreeDbDataStore $store )
{
- parent::__construct();
$this->dbh = $dbh;
$this->indexTableName = $indexTableName;
$this->properties['store'] = $store;
}
+ /**
+ * Returns whether the node with ID $id exists as tree node
+ *
+ * @param string $id
+ * @return bool
+ */
public function nodeExists( $id )
{
$db = $this->dbh;
Modified: trunk/Tree/src/backends/db_parent_child.php
==============================================================================
--- trunk/Tree/src/backends/db_parent_child.php [iso-8859-1] (original)
+++ trunk/Tree/src/backends/db_parent_child.php [iso-8859-1] Tue Jul 31
11:53:20 2007
@@ -8,10 +8,22 @@
*/
/**
- * ezcTreeXml is an implementation of a tree backend that operates on
- * an XML file.
+ * ezcTreeDbParentChild implements a tree backend which stores parent/child
+ * information in a simple table containing the node's ID and its parent's ID.
+ *
+ * The table that stores the index (configured using the $indexTableName
argument
+ * of the [EMAIL PROTECTED] __construct} method) should contain atleast two
fields. The
+ * first one 'id' will contain the node's ID, the second one 'parent_id' the ID
+ * of the node's parent. Both fields should be of the same database field type.
+ * Supported field types are either integer or a string type.
*
* @property-read ezcTreeXmlDataStore $store
+ * The data store that is used for retrieving/storing data.
+ * @property bool $prefetch
+ * Whether data pre-fetching is enabled.
+ * @property string $nodeClassName
+ * Which class is used as tree node - this class *must* inherit
+ * the ezcTreeNode class.
*
* @package Tree
* @version //autogentag//
@@ -19,11 +31,32 @@
*/
class ezcTreeDbParentChild extends ezcTreeDb
{
+ /**
+ * Creates a new ezcTreeDbParentChild object.
+ *
+ * The different arguments to the method configure which database
+ * connection ($dbh) is used to access the database and the $indexTableName
+ * argument which table is used to retrieve the relation data from. The
+ * $store argument configure which data store is used with this tree.
+ *
+ * It is up to the user to create the database table and make sure it is
+ * empty.
+ *
+ * @param ezcDbHandler $dbh
+ * @param string $indexTableName
+ * @param ezcTreeDbDataStore $store
+ */
public static function create( ezcDbHandler $dbh, $indexTableName,
ezcTreeDbDataStore $store )
{
return new ezcTreeDbParentChild( $dbh, $indexTableName, $store );
}
+ /**
+ * Returns the ID of parent of the node with ID $childId
+ *
+ * @param string $childId
+ * @return string
+ */
private function getParentId( $childId )
{
$db = $this->dbh;
@@ -39,6 +72,220 @@
return $row['parent_id'];
}
+
+ /**
+ * Runs SQL to get all the children of the node with ID $nodeId as a PDO
+ * result set
+ *
+ * @param string $nodeId
+ * @return PDOStatement
+ */
+ private function fetchChildRecords( $nodeId )
+ {
+ $db = $this->dbh;
+ $q = $db->createSelectQuery();
+
+ $q->select( 'id, parent_id' )
+ ->from( $db->quoteIdentifier( $this->indexTableName ) )
+ ->where( $q->expr->eq( 'parent_id', $q->bindValue( $nodeId ) ) );
+
+ $s = $q->prepare();
+ $s->execute();
+ return $s;
+ }
+
+ /**
+ * Adds the children nodes of the node with ID $nodeId to the
+ * ezcTreeNodeList $list.
+ *
+ * @param ezcTreeNodeList $list
+ * @param string $nodeId
+ */
+ private function addChildNodes( $list, $nodeId )
+ {
+ $className = $this->properties['nodeClassName'];
+ foreach ( $this->fetchChildRecords( $nodeId ) as $record )
+ {
+ $list->addNode( new $className( $this, $record['id'] ) );
+ $this->addChildNodes( $list, $record['id'] );
+ }
+ }
+
+ /**
+ * Returns all the children of the node with ID $id.
+ *
+ * @param string $id
+ * @return ezcTreeNodeList
+ */
+ public function fetchChildren( $id )
+ {
+ $className = $this->properties['nodeClassName'];
+ $list = new ezcTreeNodeList;
+ foreach ( $this->fetchChildRecords( $id ) as $record )
+ {
+ $list->addNode( new $className( $this, $record['id'] ) );
+ }
+ return $list;
+ }
+
+ /**
+ * Returns all the nodes in the path from the root node to the node with ID
+ * $id, including those two nodes.
+ *
+ * @param string $id
+ * @return ezcTreeNodeList
+ */
+ public function fetchPath( $id )
+ {
+ $className = $this->properties['nodeClassName'];
+ $list = new ezcTreeNodeList;
+ $list->addNode( new $className( $this, $id ) );
+
+ $id = $this->getParentId( $id );
+
+ while ( $id != null )
+ {
+ $list->addNode( new $className( $this, $id ) );
+ $id = $this->getParentId( $id );
+ }
+ return $list;
+ }
+
+ /**
+ * Alias for fetchSubtreeDepthFirst().
+ *
+ * @param string $id
+ * @return ezcTreeNodeList
+ */
+ public function fetchSubtree( $nodeId )
+ {
+ return $this->fetchSubtreeDepthFirst( $nodeId );
+ }
+
+ /**
+ * Returns the node with ID $id and all its children, sorted accoring to
+ * the `Breadth-first sorting`_ algorithm.
+ *
+ * @param string $id
+ * @return ezcTreeNodeList
+ */
+ public function fetchSubtreeBreadthFirst( $nodeId )
+ {
+ }
+
+ /**
+ * Returns the node with ID $id and all its children, sorted accoring to
+ * the `Depth-first sorting`_ algorithm.
+ *
+ * @param string $id
+ * @return ezcTreeNodeList
+ */
+ public function fetchSubtreeDepthFirst( $nodeId )
+ {
+ $className = $this->properties['nodeClassName'];
+ $list = new ezcTreeNodeList;
+ $list->addNode( new $className( $this, $nodeId ) );
+ $this->addChildNodes( $list, $nodeId );
+ return $list;
+ }
+
+ /**
+ * Returns the node with ID $id and all its children, sorted accoring to
+ * the `Topological sorting`_ algorithm.
+ *
+ * @param string $id
+ * @return ezcTreeNodeList
+ */
+ public function fetchSubtreeTopological( $nodeId )
+ {
+ }
+
+ /**
+ * Returns the number of direct children of the node with ID $id
+ *
+ * @param string $id
+ * @return int
+ */
+ public function getChildCount( $nodeId )
+ {
+ $db = $this->dbh;
+ $q = $db->createSelectQuery();
+
+ $q->select( 'count(id)' )
+ ->from( $db->quoteIdentifier( $this->indexTableName ) )
+ ->where( $q->expr->eq( 'parent_id', $q->bindValue( $nodeId ) ) );
+
+ $s = $q->prepare();
+ $s->execute();
+ return (int) $s->fetchColumn(0);
+ }
+
+ /**
+ * Adds the number of children with for the node with ID $nodeId nodes to
$count recursively.
+ *
+ * @param int &$count
+ * @param string $nodeId
+ */
+ private function countChildNodes( &$count, $nodeId )
+ {
+ foreach ( $this->fetchChildRecords( $nodeId ) as $record )
+ {
+ $count++;
+ $this->countChildNodes( $count, $record['id'] );
+ }
+ }
+
+ /**
+ * Returns the number of children of the node with ID $id, recursively
+ *
+ * @param string $id
+ * @return int
+ */
+ public function getChildCountRecursive( $id )
+ {
+ $count = 0;
+ $this->countChildNodes( $count, $id );
+ return $count;
+ }
+
+ /**
+ * Returns the distance from the root node to the node with ID $id
+ *
+ * @param string $id
+ * @return int
+ */
+ public function getPathLength( $id )
+ {
+ $id = $this->getParentId( $id );
+ $length = 0;
+
+ while ( $id !== null )
+ {
+ $id = $this->getParentId( $id );
+ $length++;
+ }
+ return $length;
+ }
+
+ /**
+ * Returns whether the node with ID $id has children
+ *
+ * @param string $id
+ * @return bool
+ */
+ public function hasChildNodes( $nodeId )
+ {
+ return $this->getChildCount( $nodeId ) > 0;
+ }
+
+ /**
+ * Returns whether the node with ID $childId is a direct child of the node
+ * with ID $parentId
+ *
+ * @param string $childId
+ * @param string $parentId
+ * @return bool
+ */
public function isChildOf( $childId, $parentId )
{
$id = $this->getParentId( $childId );
@@ -46,6 +293,14 @@
return $parentId === $id;
}
+ /**
+ * Returns whether the node with ID $childId is a direct or indirect child
+ * of the node with ID $parentId
+ *
+ * @param string $childId
+ * @param string $parentId
+ * @return bool
+ */
public function isDecendantOf( $childId, $parentId )
{
$parentId = (string) $parentId;
@@ -61,6 +316,14 @@
return false;
}
+ /**
+ * Returns whether the nodes with IDs $child1Id and $child2Id are siblings
+ * (ie, the share the same parent)
+ *
+ * @param string $child1Id
+ * @param string $child2Id
+ * @return bool
+ */
public function isSiblingOf( $child1Id, $child2Id )
{
$id1 = $this->getParentId( $child1Id );
@@ -68,128 +331,11 @@
return $id1 === $id2 && (string) $child1Id !== (string) $child2Id;
}
- private function fetchChildRecords( $nodeId )
- {
- $db = $this->dbh;
- $q = $db->createSelectQuery();
-
- $q->select( 'id, parent_id' )
- ->from( $db->quoteIdentifier( $this->indexTableName ) )
- ->where( $q->expr->eq( 'parent_id', $q->bindValue( $nodeId ) ) );
-
- $s = $q->prepare();
- $s->execute();
- return $s;
- }
-
- private function addChildNodes( $list, $nodeId )
- {
- $className = $this->properties['nodeClassName'];
- foreach ( $this->fetchChildRecords( $nodeId ) as $record )
- {
- $list->addNode( new $className( $this, $record['id'] ) );
- $this->addChildNodes( $list, $record['id'] );
- }
- }
-
- public function fetchChildren( $id )
- {
- $className = $this->properties['nodeClassName'];
- $list = new ezcTreeNodeList;
- foreach ( $this->fetchChildRecords( $id ) as $record )
- {
- $list->addNode( new $className( $this, $record['id'] ) );
- }
- return $list;
- }
-
- public function fetchPath( $id )
- {
- $className = $this->properties['nodeClassName'];
- $list = new ezcTreeNodeList;
- $list->addNode( new $className( $this, $id ) );
-
- $id = $this->getParentId( $id );
-
- while ( $id != null )
- {
- $list->addNode( new $className( $this, $id ) );
- $id = $this->getParentId( $id );
- }
- return $list;
- }
-
- public function fetchSubtree( $nodeId )
- {
- return $this->fetchSubtreeDepthFirst( $nodeId );
- }
-
- public function fetchSubtreeBreadthFirst( $nodeId )
- {
- }
-
- public function fetchSubtreeDepthFirst( $nodeId )
- {
- $className = $this->properties['nodeClassName'];
- $list = new ezcTreeNodeList;
- $list->addNode( new $className( $this, $nodeId ) );
- $this->addChildNodes( $list, $nodeId );
- return $list;
- }
-
- public function fetchSubtreeTopological( $nodeId )
- {
- }
-
- public function getChildCount( $nodeId )
- {
- $db = $this->dbh;
- $q = $db->createSelectQuery();
-
- $q->select( 'count(id)' )
- ->from( $db->quoteIdentifier( $this->indexTableName ) )
- ->where( $q->expr->eq( 'parent_id', $q->bindValue( $nodeId ) ) );
-
- $s = $q->prepare();
- $s->execute();
- return (int) $s->fetchColumn(0);
- }
-
- private function countChildNodes( &$count, $nodeId )
- {
- foreach ( $this->fetchChildRecords( $nodeId ) as $record )
- {
- $count++;
- $this->countChildNodes( $count, $record['id'] );
- }
- }
-
- public function getChildCountRecursive( $id )
- {
- $count = 0;
- $this->countChildNodes( $count, $id );
- return $count;
- }
-
- public function getPathLength( $id )
- {
- $id = $this->getParentId( $id );
- $length = 0;
-
- while ( $id !== null )
- {
- $id = $this->getParentId( $id );
- $length++;
- }
- return $length;
- }
-
- public function hasChildNodes( $nodeId )
- {
- return $this->getChildCount( $nodeId ) > 0;
- }
-
-
+ /**
+ * Sets a new node as root node, this wipes also out the whole tree
+ *
+ * @param ezcTreeNode $node
+ */
public function setRootNode( ezcTreeNode $node )
{
$db = $this->dbh;
@@ -209,6 +355,12 @@
$this->store->storeDataForNode( $node, $node->data );
}
+ /**
+ * Adds the node $childNode as child of the node with ID $parentId
+ *
+ * @param string $parentId
+ * @paran ezcTreeNode $childNode
+ */
public function addChild( $parentId, ezcTreeNode $childNode )
{
if ( $this->inTransaction )
@@ -229,6 +381,44 @@
$this->store->storeDataForNode( $childNode, $childNode->data );
}
+ private function deleteChildNodes( $nodeId )
+ {
+ $db = $this->dbh;
+ $q = $db->createDeleteQuery();
+
+ foreach ( $this->fetchChildRecords( $nodeId ) as $record )
+ {
+ $this->deleteChildNodes( $record['id'] );
+ }
+
+ $q->deleteFrom( $db->quoteIdentifier( $this->indexTableName ) )
+ ->where( $q->expr->eq( 'id', $q->bindValue( $nodeId ) ) );
+ $s = $q->prepare();
+ $s->execute();
+ }
+
+ /**
+ * Deletes the node with ID $id from the tree, including all its children
+ *
+ * @param string $id
+ */
+ public function delete( $id )
+ {
+ if ( $this->inTransaction )
+ {
+ $this->addTransactionItem( new ezcTreeTransactionItem(
ezcTreeTransactionItem::DELETE, null, $id ) );
+ return;
+ }
+
+ $this->deleteChildNodes( $id );
+ }
+
+ /**
+ * Moves the node with ID $id as child to the node with ID $targetParentId
+ *
+ * @param string $id
+ * @param string $targetParentId
+ */
public function move( $id, $targetParentId )
{
if ( $this->inTransaction )
@@ -248,33 +438,6 @@
$s->execute();
}
- protected function deleteChildNodes( $nodeId )
- {
- $db = $this->dbh;
- $q = $db->createDeleteQuery();
-
- foreach ( $this->fetchChildRecords( $nodeId ) as $record )
- {
- $this->deleteChildNodes( $record['id'] );
- }
-
- $q->deleteFrom( $db->quoteIdentifier( $this->indexTableName ) )
- ->where( $q->expr->eq( 'id', $q->bindValue( $nodeId ) ) );
- $s = $q->prepare();
- $s->execute();
- }
-
- public function delete( $id )
- {
- if ( $this->inTransaction )
- {
- $this->addTransactionItem( new ezcTreeTransactionItem(
ezcTreeTransactionItem::DELETE, null, $id ) );
- return;
- }
-
- $this->deleteChildNodes( $id );
- }
-
public function fixateTransaction()
{
}
Modified: trunk/Tree/src/tree.php
==============================================================================
--- trunk/Tree/src/tree.php [iso-8859-1] (original)
+++ trunk/Tree/src/tree.php [iso-8859-1] Tue Jul 31 11:53:20 2007
@@ -1,4 +1,27 @@
<?php
+/**
+ * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ * @version //autogentag//
+ * @filesource
+ * @package Tree
+ */
+
+/**
+ * ezcTree is an abstract class from which all the tree implementations
+ * inherit.
+ *
+ * @property-read ezcTreeXmlDataStore $store
+ * The data store that is used for retrieving/storing data.
+ * @property bool $prefetch
+ * Whether data pre-fetching is enabled.
+ * @property string $nodeClassName
+ * Which class is used as tree node - this class *must* inherit
+ * the ezcTreeNode class.
+ *
+ * @package Tree
+ * @version //autogentag//
+ */
abstract class ezcTree
{
/**
@@ -8,13 +31,26 @@
*/
protected $properties = array( 'prefetch' => false, 'nodeClassName' =>
'ezcTreeNode' );
+ /**
+ * Contains whether a transaction has been started.
+ *
+ * @var bool
+ */
protected $inTransaction = false;
+
+ /**
+ * Contains whether we are in a transaction commit stage.
+ *
+ * @var bool
+ */
protected $inTransactionCommit = false;
+
+ /**
+ * Contains a list of transaction items.
+ *
+ * @var array(ezcTreeTransactionItem)
+ */
private $transactionList = array();
-
- protected function __construct()
- {
- }
/**
* Returns the value of the property $name.
@@ -107,6 +143,14 @@
}
/**
+ * Returns whether the node with ID $id exists
+ *
+ * @param string $id
+ * @return bool
+ */
+ abstract public function nodeExists( $id );
+
+ /**
* Returns the node identified by the ID $id
*
* @param string $id
@@ -182,7 +226,6 @@
*/
abstract public function fetchSubtreeTopological( $id );
-
/**
* Returns the number of direct children of the node with ID $id
*
@@ -207,7 +250,6 @@
*/
abstract public function getPathLength( $id );
-
/**
* Returns whether the node with ID $id has children
*
@@ -215,7 +257,6 @@
* @return bool
*/
abstract public function hasChildNodes( $id );
-
/**
* Returns whether the node with ID $childId is a direct child of the node
@@ -247,15 +288,6 @@
*/
abstract public function isSiblingOf( $child1Id, $child2Id );
-
- /**
- * Returns whether the node with ID $id exists
- *
- * @param string $id
- * @return bool
- */
- abstract public function nodeExists( $id );
-
/**
* Sets a new node as root node, this wipes also out the whole tree
*
@@ -285,6 +317,7 @@
* @param string $targetParentId
*/
abstract public function move( $id, $targetParentId );
+
/**
* Starts an transaction in which all tree modifications are queued until
* the transaction is committed with the commit() method.
--
svn-components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/svn-components