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

Reply via email to