ezcTreeDbExternalTableDataStore can be used in two different modes. In the
first you specify a database field that is matched against the node's ID, and
another field that is used for the "data" property belonging to a node. The next
example illustrates this:
1. <?php
2. require_once 'tutorial_autoload.php';
3.
4. $dbh = ezcDbFactory::create( 'sqlite://:memory:' );
5. $dbh->exec( <<<ENDSQL
6. CREATE TABLE nested_set (
7. 'id' varchar(255) NOT NULL,
8. 'parent_id' varchar(255),
9. 'lft' integer NOT NULL,
10. 'rgt' integer NOT NULL
11. );
12. CREATE UNIQUE INDEX 'nested_set_pri' on 'nested_set' ( 'id' );
13. CREATE INDEX 'nested_set_left' on 'nested_set' ( 'lft' );
14. CREATE INDEX 'nested_set_right' on 'nested_set' ( 'rgt' );
15.
16. CREATE TABLE data (
17. 'node_id' varchar(255) NOT NULL,
18. 'data_field' varchar(255) NOT NULL
19. );
20. CREATE UNIQUE INDEX 'data_pri' on 'data' ( 'node_id' );
21. ENDSQL
22. );
23.
24. $store = new ezcTreeDbExternalTableDataStore( $dbh, 'data', 'node_id', 'data_field' );
25. $tree = new ezcTreeDbNestedSet( $dbh, 'nested_set', $store );
26.
27. $tree->setRootNode( $rootNode = $tree->createNode( 'Elements', 'Elements' ) );
28. $rootNode->addChild( $nonMetal = $tree->createNode( 'NonMetals', 'Non-Metals' ) );
29. $rootNode->addChild( $nobleGasses = $tree->createNode( 'NobleGasses', 'Noble Gasses' ) );
30. $nonMetal->addChild( $tree->createNode( 'H', 'Hydrogen' ) );
31.
32. echo $tree->fetchNodeById( 'H' )->data, "\n";
33. ?>
In this example, lines 4 to 22 set up the database and database tables. Refer
to the specific database back-end's documentation for full information on
what the different tables should look like. In this case,
for the data store we only create two fields: node_id and
data_field. We can see this back in line 24, where we instantiate the store
object. We specify the database object, the name of the data table ('data'),
the field that is matched against the node ID ('node_id') and which field to
use for data ('data_field'). In lines 27 to 30 we then insert some sample nodes
and line 32 demonstrates the retrieval of data.
In the second mode, we do not specify a field to fetch data from:
1. <?php
2. require_once 'tutorial_autoload.php';
3.
4. // Setup the database tables
5. $dbh = ezcDbFactory::create( 'sqlite://:memory:' );
6. $dbh->exec( <<<ENDSQL
7. CREATE TABLE nested_set (
8. 'id' varchar(255) NOT NULL,
9. 'parent_id' varchar(255),
10. 'lft' integer NOT NULL,
11. 'rgt' integer NOT NULL
12. );
13. CREATE UNIQUE INDEX 'nested_set_pri' on 'nested_set' ( 'id' );
14. CREATE INDEX 'nested_set_left' on 'nested_set' ( 'lft' );
15. CREATE INDEX 'nested_set_right' on 'nested_set' ( 'rgt' );
16.
17. CREATE TABLE data (
18. 'node_id' varchar(255) NOT NULL,
19. 'melting_temp_k' float,
20. 'boiling_temp_k' float
21. );
22. CREATE UNIQUE INDEX 'data_pri' on 'data' ( 'node_id' );
23. ENDSQL
24. );
25.
26. // Setup the store and tree
27. $store = new ezcTreeDbExternalTableDataStore( $dbh, 'data', 'node_id' );
28. $tree = new ezcTreeDbNestedSet( $dbh, 'nested_set', $store );
29.
30. // Insert data
31. $tree->setRootNode( $root = $tree->createNode( 'Metals', array() ) );
32. $root->addChild( $tree->createNode( 'Fe', array( 'melting_temp_K' => 1811, 'boiling_temp_K' => 3134 ) ) );
33.
34. // Fetch data
35. var_dump( $tree->fetchNodeById( 'Fe' )->data );
36. ?>
Differences when compared with the previous example include the data table definition in lines
17 to 21. Instead of defining a specific data field to use, there are now
multiple fields ('melting_temp_k' and 'boiling_temp_k'). The instantiation of
the data store in line 27 now misses the fourth argument as well. The data that
is specified when creating a node now consists of an array describing all the
fields in the database table, except for the 'node_id' as that one is implicit.
When fetching the data the whole table record is returned, minus the 'node_id'
field.
The ezcTreePersistentObjectDataStore brings multiple data fields even further
and extends the Tree to use persistent objects as data for the tree nodes.
1. <?php
2. require_once 'tutorial_autoload.php';
3.
4. // Setup the database tables
5. $dbh = ezcDbFactory::create( 'sqlite://:memory:' );
6. $dbh->exec( <<<ENDSQL
7. CREATE TABLE nested_set (
8. 'id' varchar(255) NOT NULL,
9. 'parent_id' varchar(255),
10. 'lft' integer NOT NULL,
11. 'rgt' integer NOT NULL
12. );
13. CREATE UNIQUE INDEX 'nested_set_pri' on 'nested_set' ( 'id' );
14. CREATE INDEX 'nested_set_left' on 'nested_set' ( 'lft' );
15. CREATE INDEX 'nested_set_right' on 'nested_set' ( 'rgt' );
16.
17. CREATE TABLE data (
18. 'node_id' varchar(255) NOT NULL,
19. 'melting_temp_k' float,
20. 'boiling_temp_k' float
21. );
22. CREATE UNIQUE INDEX 'data_pri' on 'data' ( 'node_id' );
23. ENDSQL
24. );
25.
26. // Create the example Persistent Object definition files and stub classes
27. $dbSchema = ezcDbSchema::createFromDb( $dbh );
28. $writer1 = new ezcDbSchemaPersistentWriter( true );
29. $writer2 = new ezcDbSchemaPersistentClassWriter( true );
30. $writer1->saveToFile( 'files/po_defs', $dbSchema );
31. $writer2->saveToFile( 'files/classes', $dbSchema );
32. require 'files/classes/data.php';
33.
34. // Setup the store and tree
35. $session = new ezcPersistentSession( $dbh, new ezcPersistentCodeManager( "files/po_defs" ) );
36. $store = new ezcTreePersistentObjectDataStore( $session, 'data', 'node_id' );
37. $tree = new ezcTreeDbNestedSet( $dbh, 'nested_set', $store );
38.
39. // Insert data
40. $metal = new data();
41. $tree->setRootNode( $root = $tree->createNode( 'Metals', $metal ) );
42. $iron = new data();
43. $iron->setState( array( 'melting_temp_k' => 1811, 'boiling_temp_k' => 3134 ) );
44. $root->addChild( $tree->createNode( 'Fe', $iron ) );
45.
46. // Fetch data
47. $fe = $tree->fetchNodeById( 'Fe' )->data;
48. var_dump( $fe );
49. ?>
The database tables are set up just like the previous example in lines 5 to 24.
Lines 26 to 32 then continue to use the DatabaseSchema component to write
persistent definition files and class stubs. The store is set up in lines 35 and
36. ezcTreePersistentObjectDataStore uses ezcPersistentSession as the
first argument and then the object's class and object's ID property as second
and third arguments. Unlike the previous example, you should specify the class
and property names of the persistent objects that you are storing - not
the table name and ID field. Lines 39 to 48 then show how data is inserted into
the tree, and how it is retrieved. You will most likely have to tune the
classes that are generated for you in a real life situation, as the generated
classes (line 29 and 31) only have private properties and the getState() and
setState() methods that persistent objects are required to have. Refer
to the PersistentObject documentation for more information.