Author: Tobias Schlitt Date: 2006-10-09 20:03:08 +0200 (Mon, 09 Oct 2006) New Revision: 3665
Log: - Added Many-To-One relation class. - Implemented select for this relation. - Fixed SQL for test database. Added: trunk/PersistentObject/src/exceptions/related_object_not_found.php trunk/PersistentObject/src/relations/many_to_one.php trunk/PersistentObject/tests/many_to_one_relation_test.php Modified: trunk/PersistentObject/src/exceptions/relation_not_found.php trunk/PersistentObject/src/interfaces/definition_manager.php trunk/PersistentObject/src/persistent_autoload.php trunk/PersistentObject/src/persistent_session.php trunk/PersistentObject/tests/data/relation_test.sql trunk/PersistentObject/tests/data/relation_test_employer.php trunk/PersistentObject/tests/data/relationtestperson.php trunk/PersistentObject/tests/suite.php Added: trunk/PersistentObject/src/exceptions/related_object_not_found.php =================================================================== --- trunk/PersistentObject/src/exceptions/related_object_not_found.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/src/exceptions/related_object_not_found.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -0,0 +1,33 @@ +<?php +/** + * File containing the ezcPersistentRelatedObjectNotFoundException class + * + * @package PersistentObject + * @version //autogen// + * @copyright Copyright (C) 2005, 2006 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ + +/** + * Exception thrown, if the given relation class Äould not be found. + * + * @package PersistentObject + * @version //autogen// + */ +class ezcPersistentRelatedObjectNotFoundException extends ezcPersistentObjectException +{ + + /** + * Constructs a new ezcPersistentRelatedObjectNotFoundException for the class $class + * which does not have a relation for $relatedClass. + * + * @param string $class + * @param string $relatedClass + * @return void + */ + public function __construct( $object, $relatedClass ) + { + parent::__construct( "No related object found with class <{$relatedClass}> for object of class <" . get_class( $object ) . ">." ); + } +} +?> Property changes on: trunk/PersistentObject/src/exceptions/related_object_not_found.php ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/PersistentObject/src/exceptions/relation_not_found.php =================================================================== --- trunk/PersistentObject/src/exceptions/relation_not_found.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/src/exceptions/relation_not_found.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -1,17 +1,16 @@ <?php /** - * File containing the ezcPersistentObjectException class + * File containing the ezcPersistentRelationNotFoundException class * * @package PersistentObject * @version //autogen// * @copyright Copyright (C) 2005, 2006 eZ systems as. All rights reserved. * @license http://ez.no/licenses/new_bsd New BSD License */ + /** - * General exception class for the PersistentObject package. + * Exception thrown, if the given relation class Äould not be found. * - * All exceptions in the persistent object package are derived from this exception. - * * @package PersistentObject * @version //autogen// */ Modified: trunk/PersistentObject/src/interfaces/definition_manager.php =================================================================== --- trunk/PersistentObject/src/interfaces/definition_manager.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/src/interfaces/definition_manager.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -47,7 +47,7 @@ } if ( isset( $def->idProperty ) ) { - $def->columns[$def->idProperty->columnName] = $def->idProperty->propertyName; + $def->columns[$def->idProperty->columnName] = $def->idProperty; } return $def; } Modified: trunk/PersistentObject/src/persistent_autoload.php =================================================================== --- trunk/PersistentObject/src/persistent_autoload.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/src/persistent_autoload.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -14,6 +14,7 @@ 'ezcPersistentSingleTableMap' => 'PersistentObject/structs/single_table_map.php', 'ezcPersistentRelation' => 'PersistentObject/interfaces/relation.php', 'ezcPersistentOneToManyRelation' => 'PersistentObject/relations/one_to_many.php', + 'ezcPersistentManyToOneRelation' => 'PersistentObject/relations/many_to_one.php', 'ezcPersistentDefinitionManager' => 'PersistentObject/interfaces/definition_manager.php', 'ezcPersistentMultiManager' => 'PersistentObject/managers/multi_manager.php', 'ezcPersistentCodeManager' => 'PersistentObject/managers/code_manager.php', @@ -22,6 +23,7 @@ 'ezcPersistentSessionNotFoundException' => 'PersistentObject/exceptions/session_not_found.php', 'ezcPersistentDefinitionNotFoundException' => 'PersistentObject/exceptions/definition_not_found.php', 'ezcPersistentRelationNotFoundException' => 'PersistentObject/exceptions/relation_not_found.php', + 'ezcPersistentRelatedObjectNotFoundException' => 'PersistentObject/exceptions/related_object_not_found.php', 'ezcPersistentObjectNotPersistentException' => 'PersistentObject/exceptions/not_persistent.php', 'ezcPersistentObjectAlreadyPersistentException' => 'PersistentObject/exceptions/already_persistent.php', 'ezcPersistentQueryException' => 'PersistentObject/exceptions/query_exception.php', Modified: trunk/PersistentObject/src/persistent_session.php =================================================================== --- trunk/PersistentObject/src/persistent_session.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/src/persistent_session.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -333,20 +333,85 @@ /** * Returns the related objects of a given class for an object. * This method returns the related objects of type $relatedClass for the - * object $object. + * object $object. This method (in contrast to [EMAIL PROTECTED] getRelatedObject()}) + * always returns an array of result objects, no matter if only 1 object + * was found (e.g. [EMAIL PROTECTED] ezcPersistentManyToOneRelation}). * * Example: * <code> * $person = $session->load( "Person", 1 ); * $relatedAddresses = $session->getRelatedObjects( $person, "Address" ); + * echo "Number of addresses found: " . count( $relatedAddresses ); * </code> + * + * Relations that should preferably be used with this method are: + * - [EMAIL PROTECTED] ezcPersistentOneToManyRelation} + * - [EMAIL PROTECTED] ezcPersistentManyToManyRelation} * * @param mixed $object The object to fetch related objects for. * @param mixed $relatedClass The class of the related objects to fetch. - * @return array(int=>$relatedClass) + * @return array(int=>object) + * + * @throws ezcPersistentRelationNotFoundException + * if the given $object does not have a relation to $relatedClass. */ public function getRelatedObjects( $object, $relatedClass ) { + $query = $this->createRelationQuery( $object, $relatedClass ); + return $this->find( $query, $relatedClass ); + } + + /** + * Returns the related object of a given class for an object. + * This method returns the related object of type $relatedClass for the + * object $object. This method (in contrast to [EMAIL PROTECTED] getRelatedObjects()}) + * always a single result object, no matter if more objects could be found + * (e.g. [EMAIL PROTECTED] ezcPersistentOneToManyRelation}). + * + * Example: + * <code> + * $person = $session->load( "Person", 1 ); + * $relatedAddress = $session->getRelatedObject( $person, "Address" ); + * echo "Address of this person: " . $relatedAddress->__toString(); + * </code> + * + * Relations that should preferably be used with this method are: + * - {ezcPersistentManyToOneRelation} + * - {ezcPersistentOneToOneRelation} + * + * @param object $object The object to fetch related objects for. + * @param string $relatedClass The class of the related objects to fetch. + * @return object + * + * @throws ezcPersistentRelationNotFoundException + * if the given $object does not have a relation to $relatedClass. + */ + public function getRelatedObject( $object, $relatedClass ) + { + $query = $this->createRelatedQuery( $object, $relatedClass ); + // This method only needs to return 1 object + $query->limit( 1 ); + $resArr = $this->find( $query, $relatedClass ); + if ( sizeof( $resArr ) < 1 ) + { + throw new ezcPersistentRelatedObjectNotFound( $object, $relatedClass ); + } + return $resArr[0]; + } + + /** + * Returns the base query for retrieving related objects. + * See [EMAIL PROTECTED] getRelatedObject()} and [EMAIL PROTECTED] getRelatedObjects()}. + * + * @param object $object + * @param string $relatedClass + * @return ezcDbSelectQuery + * + * @throws ezcPersistentRelationNotFoundException + * if the given $object does not have a relation to $relatedClass. + */ + private function createRelationQuery( $object, $relatedClass ) + { $def = $this->definitionManager->fetchDefinition( ( $class = get_class( $object ) ) ); if ( !isset( $def->relations[$relatedClass] ) ) { @@ -360,20 +425,23 @@ switch ( get_class( $relation ) ) { case "ezcPersistentOneToManyRelation": + case "ezcPersistentManyToOneRelation": + case "ezcPersistentOneToOneRelation": foreach ( $relation->columnMap as $map ) { $query->where( $query->expr->eq( $this->database->quoteIdentifier( "{$map->destinationColumn}" ), - $query->bindValue( $object->{$def->columns[$map->sourceColumn]} ) + $query->bindValue( $object->{$def->columns[$map->sourceColumn]->propertyName} ) ) ); } break; + case "ezcPersistentManyToManyRelation": default: throw new Exception( "Still in development phase, " . get_class( $relation ) . " not implemented, yet." ); } - return $this->find( $query, $relatedClass ); + return $query; } /* Added: trunk/PersistentObject/src/relations/many_to_one.php =================================================================== --- trunk/PersistentObject/src/relations/many_to_one.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/src/relations/many_to_one.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -0,0 +1,136 @@ +<?php +/** + * File containing the ezcPersistentManyToOneRelation. + * + * @package PersistentObject + * @version //autogentag// + * @copyright Copyright (C) 2005 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ + +/** + * Relation class to reflect a many-to-one table relation (m:1). + * + * @property bool $cascade + * Wether to cascade delete action from the source table to the + * destination table. + * + * @package PersistentObject + * @version //autogen// + * @copyright Copyright (C) 2005 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ +class ezcPersistentManyToOneRelation extends ezcPersistentRelation +{ + + private $properties = array( + "cascade" => false, + ); + + /** + * Validates an [EMAIL PROTECTED] ezcPersistentRelation::$columnMap} property. + * Checks is the given array represents a valid $columnMap property. Column + * maps for this kind of relation may only contain instances of + * [EMAIL PROTECTED] ezcPersistentSingleTableMap} and have to at least contain 1 + * instance. + * + * @param array $columnMap The column map to check. + * + * @throws ezcBaseValueException On an invalid column map. + */ + protected function validateColumnMap( array $columnMap ) + { + if ( sizeof( $columnMap ) < 1 ) + { + throw new ezcBaseValueException( + "colmunMap", + $columnMap, + "array(ezcPersistentSingleTableMap) > 0 elements" + ); + } + foreach ( $columnMap as $relation ) + { + if ( !( $relation instanceof ezcPersistentSingleTableMap ) ) + { + throw new ezcBaseValueException( + "columnMap", + $columnMap, + "array(ezcPersistentSingleTableMap) > 0 elements" + ); + } + } + } + + /** + * Property read access. + * + * @param string $key Name of the property. + * @return mixed Value of the property or null. + * + * @throws ezcBasePropertyNotFoundException + * If the the desired property is not found. + * @ignore + */ + public function __get( $propertyName ) + { + switch ( $propertyName ) + { + case "cascade": + return $this->properties[$propertyName]; + default: + return parent::__get( $propertyName ); + } + + } + + /** + * Property write access. + * + * @param string $key Name of the property. + * @param mixed $val The value for the property. + * + * @throws ezcBasePropertyNotFoundException + * If a the value for the property options is not an instance of + * @throws ezcBaseValueException + * If a the value for a property is out of range. + * @ignore + */ + public function __set( $propertyName, $propertyValue ) + { + switch ( $propertyName ) + { + case "cascade": + if ( !is_bool( $propertyValue ) ) + { + throw new ezcBaseValueException( + $propertyName, + $propertyValue, + "bool" + ); + } + $this->properties[$propertyName] = $propertyValue; + break; + default: + parent::__set( $propertyName, $propertyValue ); + break; + } + } + + /** + * Property isset access. + * + * @param string $key Name of the property. + * @return bool True is the property is set, otherwise false. + * @ignore + */ + public function __isset( $propertyName ) + { + if ( array_key_exists( $propertyName, $this->properties ) ) + { + return true; + } + return parent::__isset( ( $propertyName ) ); + } +} + +?> Property changes on: trunk/PersistentObject/src/relations/many_to_one.php ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/PersistentObject/tests/data/relation_test.sql =================================================================== --- trunk/PersistentObject/tests/data/relation_test.sql 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/tests/data/relation_test.sql 2006-10-09 18:03:08 UTC (rev 3665) @@ -23,7 +23,7 @@ `city` varchar(100) NOT NULL, `type` varchar(10) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -- Dumping data for table `PO_addresses` @@ -44,7 +44,7 @@ `id` tinyint(4) NOT NULL auto_increment, `name` varchar(100) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; -- -- Dumping data for table `PO_employers` @@ -65,7 +65,7 @@ `surename` varchar(100) NOT NULL, `employer` tinyint(4) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; -- -- Dumping data for table `PO_persons` Modified: trunk/PersistentObject/tests/data/relation_test_employer.php =================================================================== --- trunk/PersistentObject/tests/data/relation_test_employer.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/tests/data/relation_test_employer.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -24,6 +24,16 @@ "name" => $this->firstname, ); } + + public static function __set_state( array $state ) + { + $employer = new RelationTestEmployer(); + foreach ( $state as $key => $value ) + { + $employer->$key = $value; + } + return $employer; + } } ?> Modified: trunk/PersistentObject/tests/data/relationtestperson.php =================================================================== --- trunk/PersistentObject/tests/data/relationtestperson.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/tests/data/relationtestperson.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -25,6 +25,12 @@ $def->properties['employer']->propertyName = 'employer'; $def->properties['employer']->propertyType = ezcPersistentObjectProperty::PHP_TYPE_INT; +$def->relations["RelationTestEmployer"] = new ezcPersistentManyToOneRelation( "persons", "employers" ); +$def->relations["RelationTestEmployer"]->reverse = true; +$def->relations["RelationTestEmployer"]->columnMap = array( + new ezcPersistentSingleTableMap( "employer", "id" ), +); + return $def; ?> Added: trunk/PersistentObject/tests/many_to_one_relation_test.php =================================================================== --- trunk/PersistentObject/tests/many_to_one_relation_test.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/tests/many_to_one_relation_test.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -0,0 +1,81 @@ +<?php +/** + * @copyright Copyright (C) 2005, 2006 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + * @version //autogentag// + * @filesource + * @package PersistentObject + * @subpackage Tests + */ + +require_once dirname( __FILE__ ) . "/data/relation_test_employer.php"; +require_once dirname( __FILE__ ) . "/data/relation_test_person.php"; + +/** + * Tests ezcPersistentManyToOneRelation class. + * + * @package PersistentObject + * @subpackage Tests + */ +class ezcPersistentManyToOneRelationTest extends ezcTestCase +{ + + private $session; + + public static function suite() + { + return new PHPUnit_Framework_TestSuite( "ezcPersistentManyToOneRelationTest" ); + } + + public function setup() + { + RelationTestPerson::setupTables(); + RelationTestPerson::insertData(); + $this->session = new ezcPersistentSession( + ezcDbInstance::get(), + new ezcPersistentCodeManager( dirname( __FILE__ ) . "/data/" ) + ); + } + + public function teardown() + { + RelationTestEmployer::cleanup(); + } + + public function testGetRelatedObjectsEmployer1() + { + $employer = $this->session->load( "RelationTestPerson", 1 ); + $res = array ( + 0 => + RelationTestEmployer::__set_state(array( + 'id' => '2', + 'name' => 'Oldschool Web 1.x company', + )), + ); + + $this->assertEquals( + $res, + $this->session->getRelatedObjects( $employer, "RelationTestEmployer" ), + "Related RelationTestPerson objects not fetched correctly." + ); + } + + public function testGetRelatedObjectsEmployer2() + { + $employer = $this->session->load( "RelationTestPerson", 2 ); + $res = array ( + 0 => RelationTestEmployer::__set_state(array( + 'id' => '1', + 'name' => 'Great Web 2.0 company', + )), + ); + + $this->assertEquals( + $res, + $this->session->getRelatedObjects( $employer, "RelationTestEmployer" ), + "Related RelationTestPerson objects not fetched correctly." + ); + } +} + +?> Property changes on: trunk/PersistentObject/tests/many_to_one_relation_test.php ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/PersistentObject/tests/suite.php =================================================================== --- trunk/PersistentObject/tests/suite.php 2006-10-09 11:59:39 UTC (rev 3664) +++ trunk/PersistentObject/tests/suite.php 2006-10-09 18:03:08 UTC (rev 3665) @@ -18,6 +18,7 @@ require_once( 'manual_generator_test.php' ); require_once( 'persistent_session_instance_test.php' ); require_once( 'one_to_many_relation_test.php' ); +require_once( 'many_to_one_relation_test.php' ); /** * @package PersistentObject @@ -37,6 +38,7 @@ $this->addTest( ezcPersistentManualGeneratorTest::suite() ); $this->addTest( ezcPersistentSessionInstanceTest::suite() ); $this->addTest( ezcPersistentOneToManyRelationTest::suite() ); + $this->addTest( ezcPersistentManyToOneRelationTest::suite() ); } public static function suite() -- svn-components mailing list svn-components@lists.ez.no http://lists.ez.no/mailman/listinfo/svn-components