diff --git a/runtime/lib/formatter/PropelFormatter.php b/runtime/lib/formatter/PropelFormatter.php index 9990a295c..0b452f4eb 100644 --- a/runtime/lib/formatter/PropelFormatter.php +++ b/runtime/lib/formatter/PropelFormatter.php @@ -169,12 +169,14 @@ protected function isWithOneToMany() */ protected function getWorkerObject($col, $class) { - if(isset($this->currentObjects[$col])) { - $this->currentObjects[$col]->clear(); + $key = $col . '_' . $class; + + if (isset($this->currentObjects[$key])) { + $this->currentObjects[$key]->clear(); } else { - $this->currentObjects[$col] = new $class(); + $this->currentObjects[$key] = new $class(); } - return $this->currentObjects[$col]; + return $this->currentObjects[$key]; } /** diff --git a/test/testsuite/runtime/formatter/PropelFormatterTest.php b/test/testsuite/runtime/formatter/PropelFormatterTest.php new file mode 100644 index 000000000..ad24819ea --- /dev/null +++ b/test/testsuite/runtime/formatter/PropelFormatterTest.php @@ -0,0 +1,65 @@ +getMockForAbstractClass('PropelFormatter'); + + $method = new ReflectionMethod('PropelFormatter', 'getWorkerObject'); + $method->setAccessible(true); + + $classNames = array( + 'Bookstore', + 'BookReader', + 'BookClubList', + ); + + $col = 0; + foreach ($classNames as $className) { + // getWorkerObject() should always return an instance of the requested class, regardless of the value of $col + $result = $method->invoke($formatter, $col, $className); + + $this->assertEquals($className, get_class($result), 'getWorkerObject did not return an instance of the requested class'); + } + } + + public function testGetWorkerObjectCachedInstance() + { + $formatter = $this->getMockForAbstractClass('PropelFormatter'); + + $method = new ReflectionMethod('PropelFormatter', 'getWorkerObject'); + $method->setAccessible(true); + + $className = 'Bookstore'; + $col = 0; + + $result1 = $method->invoke($formatter, $col, $className); + $result2 = $method->invoke($formatter, $col, $className); + + $this->assertEquals(spl_object_hash($result1), spl_object_hash($result2), 'getWorkerObject should return a cached instance of a class at the same col index'); + } +} diff --git a/test/testsuite/runtime/formatter/PropelOnDemandFormatterTest.php b/test/testsuite/runtime/formatter/PropelOnDemandFormatterTest.php index 08c8a75cf..4fb03be8d 100644 --- a/test/testsuite/runtime/formatter/PropelOnDemandFormatterTest.php +++ b/test/testsuite/runtime/formatter/PropelOnDemandFormatterTest.php @@ -148,4 +148,25 @@ public function testFormatOneManyResults() $this->assertTrue($book instanceof Book, 'PropelOnDemandFormatter::formatOne() returns a model object'); } + public function testFormatSingleTableInheritanceManyResults() + { + $con = Propel::getConnection(BookPeer::DATABASE_NAME); + BookstoreDataPopulator::populate($con); + + $stmt = $con->query('SELECT * FROM bookstore_employee'); + $formatter = new PropelOnDemandFormatter(); + $formatter->init(new ModelCriteria('bookstore', 'BookstoreEmployee')); + + $employees = $formatter->format($stmt); + + foreach ($employees as $employee) { + $row = array(); + $row[1] = $employee->getClassKey(); + + $omClass = BookstoreEmployeePeer::getOMClass($row, 0, false); + $actualClass = get_class($employee); + + $this->assertEquals($omClass, $actualClass, 'PropelOnDemandFormatter::format() should handle single table inheritance'); + } + } } diff --git a/test/tools/helpers/bookstore/BookstoreDataPopulator.php b/test/tools/helpers/bookstore/BookstoreDataPopulator.php index d21eb9a59..0b7d34ada 100644 --- a/test/tools/helpers/bookstore/BookstoreDataPopulator.php +++ b/test/tools/helpers/bookstore/BookstoreDataPopulator.php @@ -167,6 +167,11 @@ public static function populate($con = null) $bemp2->setSupervisor($bemp1); $bemp2->save($con); + $bemp3 = new BookstoreCashier(); + $bemp3->setName("Tim"); + $bemp3->setJobTitle("Cashier"); + $bemp3->save($con); + $role = new AcctAccessRole(); $role->setName("Admin");