From fc310cf36ced5497bd449de0220863f19f5b631e Mon Sep 17 00:00:00 2001 From: romanb Date: Sat, 1 Dec 2007 11:18:43 +0000 Subject: [PATCH] Fixed #626. Commented out plugin tests due to a fatal error. --- lib/Doctrine/Collection.php | 14 +- lib/Doctrine/Record.php | 4 +- lib/Doctrine/Relation.php | 21 +++ lib/Doctrine/Relation/Association/Self.php | 9 +- lib/Doctrine/Relation/ForeignKey.php | 7 +- lib/Doctrine/Relation/LocalKey.php | 5 +- lib/Doctrine/Relation/Nest.php | 9 +- lib/Doctrine/Relation/Parser.php | 2 + tests/Ticket/626BTestCase.php | 159 +++++++++++++++++++++ tests/run.php | 3 +- 10 files changed, 212 insertions(+), 21 deletions(-) create mode 100644 tests/Ticket/626BTestCase.php diff --git a/lib/Doctrine/Collection.php b/lib/Doctrine/Collection.php index d550d0b5e..c32a6fb60 100644 --- a/lib/Doctrine/Collection.php +++ b/lib/Doctrine/Collection.php @@ -262,15 +262,15 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator */ public function setReference(Doctrine_Record $record, Doctrine_Relation $relation) { - $this->reference = $record; - $this->relation = $relation; + $this->reference = $record; + $this->relation = $relation; if ($relation instanceof Doctrine_Relation_ForeignKey || - $relation instanceof Doctrine_Relation_LocalKey) { + $relation instanceof Doctrine_Relation_LocalKey) { - $this->referenceField = $relation->getForeign(); + $this->referenceField = $relation->getForeignFieldName(); - $value = $record->get($relation->getLocal()); + $value = $record->get($relation->getLocalFieldName()); foreach ($this->data as $record) { if ($value !== null) { @@ -348,7 +348,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator $record = $this->_table->create(); if (isset($this->referenceField)) { - $value = $this->reference->get($this->relation->getLocal()); + $value = $this->reference->get($this->relation->getLocalFieldName()); if ($value !== null) { $record->set($this->referenceField, $value, false); @@ -436,7 +436,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator public function add(Doctrine_Record $record, $key = null) { if (isset($this->referenceField)) { - $value = $this->reference->get($this->relation->getLocal()); + $value = $this->reference->get($this->relation->getLocalFieldName()); if ($value !== null) { $record->set($this->referenceField, $value, false); diff --git a/lib/Doctrine/Record.php b/lib/Doctrine/Record.php index 5ba520c77..80fa567b1 100644 --- a/lib/Doctrine/Record.php +++ b/lib/Doctrine/Record.php @@ -821,9 +821,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count try { if ( ! isset($this->_references[$fieldName]) && $load) { - + $rel = $this->_table->getRelation($fieldName); - + $this->_references[$fieldName] = $rel->fetchRelatedFor($this); } return $this->_references[$fieldName]; diff --git a/lib/Doctrine/Relation.php b/lib/Doctrine/Relation.php index 4bb3ae43a..a959b1862 100644 --- a/lib/Doctrine/Relation.php +++ b/lib/Doctrine/Relation.php @@ -66,6 +66,7 @@ abstract class Doctrine_Relation implements ArrayAccess 'class' => true, 'type' => true, 'table' => true, + 'localTable' => true, 'name' => false, 'refTable' => false, 'onDelete' => false, @@ -88,6 +89,8 @@ abstract class Doctrine_Relation implements ArrayAccess * * table the foreign table object * + * localTable the local table object + * * refTable the reference table object (if any) * * onDelete referential delete action @@ -246,6 +249,15 @@ abstract class Doctrine_Relation implements ArrayAccess { return $this->definition['local']; } + + /** + * getLocalFieldName + * returns the field name of the local column + */ + final public function getLocalFieldName() + { + return $this->definition['localTable']->getFieldName($this->definition['local']); + } /** * getForeign @@ -258,6 +270,15 @@ abstract class Doctrine_Relation implements ArrayAccess { return $this->definition['foreign']; } + + /** + * getLocalFieldName + * returns the field name of the local column + */ + final public function getForeignFieldName() + { + return $this->definition['table']->getFieldName($this->definition['foreign']); + } /** * isComposite diff --git a/lib/Doctrine/Relation/Association/Self.php b/lib/Doctrine/Relation/Association/Self.php index eb5653335..9e579aff2 100644 --- a/lib/Doctrine/Relation/Association/Self.php +++ b/lib/Doctrine/Relation/Association/Self.php @@ -42,6 +42,8 @@ class Doctrine_Relation_Association_Self extends Doctrine_Relation_Association { switch ($context) { case 'record': + $identifierColumnNames = $this->definition['table']->getIdentifierColumnNames(); + $identifier = array_pop($identifierColumnNames); $sub = 'SELECT '.$this->definition['foreign'] . ' FROM '.$this->definition['refTable']->getTableName() . ' WHERE '.$this->definition['local'] @@ -55,10 +57,10 @@ class Doctrine_Relation_Association_Self extends Doctrine_Relation_Association $dql = 'FROM ' . $this->definition['table']->getComponentName() . '.' . $this->definition['refTable']->getComponentName() . ' WHERE ' . $this->definition['table']->getComponentName() - . '.' . $this->definition['table']->getIdentifier() + . '.' . $identifier . ' IN (' . $sub . ')' . ' || ' . $this->definition['table']->getComponentName() - . '.' . $this->definition['table']->getIdentifier() + . '.' . $identifier . ' IN (' . $sub2 . ')'; break; case 'collection': @@ -80,7 +82,8 @@ class Doctrine_Relation_Association_Self extends Doctrine_Relation_Association $assocTable = $this->getAssociationFactory()->getTableName(); $tableName = $record->getTable()->getTableName(); - $identifier = $record->getTable()->getIdentifier(); + $identifierColumnNames = $record->getTable()->getIdentifierColumnNames(); + $identifier = array_pop($identifierColumnNames); $sub = 'SELECT '.$this->getForeign(). ' FROM '.$assocTable. diff --git a/lib/Doctrine/Relation/ForeignKey.php b/lib/Doctrine/Relation/ForeignKey.php index 911f3f2d0..3d4aadb03 100644 --- a/lib/Doctrine/Relation/ForeignKey.php +++ b/lib/Doctrine/Relation/ForeignKey.php @@ -44,8 +44,9 @@ class Doctrine_Relation_ForeignKey extends Doctrine_Relation public function fetchRelatedFor(Doctrine_Record $record) { $id = array(); + $localTable = $record->getTable(); foreach ((array) $this->definition['local'] as $local) { - $value = $record->get($local); + $value = $record->get($localTable->getFieldName($local)); if (isset($value)) { $id[] = $value; } @@ -63,8 +64,8 @@ class Doctrine_Relation_ForeignKey extends Doctrine_Relation $related = $coll[0]; } - $related->set($this->definition['foreign'], $record, false); - + $related->set($related->getTable()->getFieldName($this->definition['foreign']), + $record, false); } else { if ( ! $record->exists() || empty($id) || diff --git a/lib/Doctrine/Relation/LocalKey.php b/lib/Doctrine/Relation/LocalKey.php index de40593a0..15ac2661f 100644 --- a/lib/Doctrine/Relation/LocalKey.php +++ b/lib/Doctrine/Relation/LocalKey.php @@ -43,7 +43,8 @@ class Doctrine_Relation_LocalKey extends Doctrine_Relation */ public function fetchRelatedFor(Doctrine_Record $record) { - $id = $record->get($this->definition['local']); + $localFieldName = $record->getTable()->getFieldName($this->definition['local']); + $id = $record->get($localFieldName); if (empty($id) || ! $this->definition['table']->getAttribute(Doctrine::ATTR_LOAD_REFERENCES)) { $related = $this->getTable()->create(); @@ -61,7 +62,7 @@ class Doctrine_Relation_LocalKey extends Doctrine_Relation } } - $record->set($this->definition['local'], $related, false); + $record->set($localFieldName, $related, false); return $related; } diff --git a/lib/Doctrine/Relation/Nest.php b/lib/Doctrine/Relation/Nest.php index 978cca092..d1f3bf139 100644 --- a/lib/Doctrine/Relation/Nest.php +++ b/lib/Doctrine/Relation/Nest.php @@ -42,6 +42,8 @@ class Doctrine_Relation_Nest extends Doctrine_Relation_Association { switch ($context) { case 'record': + $identifierColumnNames = $this->definition['table']->getIdentifierColumnNames(); + $identifier = array_pop($identifierColumnNames); $sub = 'SELECT '.$this->definition['foreign'] . ' FROM '.$this->definition['refTable']->getTableName() . ' WHERE '.$this->definition['local'] @@ -55,10 +57,10 @@ class Doctrine_Relation_Nest extends Doctrine_Relation_Association $dql = 'FROM ' . $this->definition['table']->getComponentName() . '.' . $this->definition['refTable']->getComponentName() . ' WHERE ' . $this->definition['table']->getComponentName() - . '.' . $this->definition['table']->getIdentifier() + . '.' . $identifier . ' IN (' . $sub . ')' . ' || ' . $this->definition['table']->getComponentName() - . '.' . $this->definition['table']->getIdentifier() + . '.' . $identifier . ' IN (' . $sub2 . ')'; break; case 'collection': @@ -110,7 +112,8 @@ class Doctrine_Relation_Nest extends Doctrine_Relation_Association $assocTable = $this->getAssociationFactory()->getTableName(); $tableName = $record->getTable()->getTableName(); - $identifier = $record->getTable()->getIdentifier(); + $identifierColumnNames = $record->getTable()->getIdentifierColumnNames(); + $identifier = array_pop($identifierColumnNames); $sub = 'SELECT ' . $this->getForeign() . ' FROM ' . $assocTable diff --git a/lib/Doctrine/Relation/Parser.php b/lib/Doctrine/Relation/Parser.php index 0ecc32c70..113ecfc2c 100644 --- a/lib/Doctrine/Relation/Parser.php +++ b/lib/Doctrine/Relation/Parser.php @@ -257,6 +257,7 @@ class Doctrine_Relation_Parser { $conn = $this->_table->getConnection(); $def['table'] = $this->getImpl($def['class']); + $def['localTable'] = $this->_table; $def['class'] = $def['table']->getComponentName(); $def['refTable'] = $this->getImpl($def['refClass']); @@ -371,6 +372,7 @@ class Doctrine_Relation_Parser { $conn = $this->_table->getConnection(); $def['table'] = $this->getImpl($def['class']); + $def['localTable'] = $this->_table; $def['class'] = $def['table']->getComponentName(); $foreignClasses = array_merge($def['table']->getOption('parents'), array($def['class'])); diff --git a/tests/Ticket/626BTestCase.php b/tests/Ticket/626BTestCase.php new file mode 100644 index 000000000..d15580982 --- /dev/null +++ b/tests/Ticket/626BTestCase.php @@ -0,0 +1,159 @@ + + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + */ + +class Doctrine_Ticket_626B_TestCase extends Doctrine_UnitTestCase +{ + public function prepareData() + { } + + public function prepareTables() + { + $this->tables = array('T626_Group', 'T626B_Student', 'T626_Course', 'T626B_StudentCourse'); + parent::prepareTables(); + } + + protected function newCourse($id, $name) + { + $course = new T626_Course(); + $course->id = $id; + $course->name = $name; + $course->save(); + return $course; + } + + protected function newGroup($id, $name) + { + $group = new T626_Group(); + $group->id = $id; + $group->name = $name; + $group->save(); + return $group; + } + + protected function newStudent($id, $name, $group) + { + $u = new T626B_Student(); + $u->id = $id; + $u->name = $name; + $u->group_id = $group->id; + $u->save(); + return $u; + } + + protected function newStudentCourse($student, $course) + { + $sc = new T626B_StudentCourse; + $sc->student_id = $student->id; + $sc->course_id = $course->id; + $sc->save(); + return $sc; + } + + public function testTicket() + { + $group1 = $this->newGroup('1', 'Group 1'); + $student1 = $this->newStudent('07090002', 'First Student', $group1); + $course1 = $this->newCourse('MATH001', 'Maths'); + $course2 = $this->newCourse('ENG002', 'English Literature'); + + $this->newStudentCourse($student1, $course1); + $this->newStudentCourse($student1, $course2); + + try { + $group = $student1->get('Group'); + $this->pass(); + } catch (Exception $e) { + $this->fail($e->__toString()); + } + + try { + $courses = $student1->get('StudyCourses'); + $this->pass(); + } catch (Exception $e) { + $this->fail($e->__toString()); + } + + } +} + + +class T626B_Student extends Doctrine_Record +{ + public function setTableDefinition() + { + $this->setTableName('T626B_Student_record'); + + $this->hasColumn('s_id as id', 'varchar', 30, array ( 'primary' => true,)); + $this->hasColumn('s_g_id as group_id', 'varchar', 30, array ('notnull'=>true)); + $this->hasColumn('s_name as name', 'varchar', 50, array ()); + } + + public function setUp() + { + $this->hasMany('T626_Course as StudyCourses', array('refClass' => 'T626B_StudentCourse', 'local' => 'sc_student_id', 'foreign' => 'sc_course_id')); + $this->hasOne('T626_Group as Group', array('local' => 's_g_id', 'foreign' => 'g_id')); + } +} + +class T626_Group extends Doctrine_Record +{ + public function setTableDefinition() + { + $this->setTableName('T626B_Student_group'); + + $this->hasColumn('g_id as id', 'varchar', 30, array ( 'primary' => true,)); + $this->hasColumn('g_name as name', 'varchar', 50, array ()); + } + + public function setUp() + { + $this->hasMany('T626B_Student as Students', + array('local' => 'g_id', 'foreign' => 's_id')); + } +} + + +class T626_Course extends Doctrine_Record +{ + public function setTableDefinition() + { + $this->setTableName('T626_course'); + + $this->hasColumn('c_id as id', 'varchar', 20, array ( 'primary' => true,)); + $this->hasColumn('c_name as name', 'varchar', 50, array ()); + } + + public function setUp() + { + $this->hasMany('T626B_Student as Students', array('refClass' => 'T626B_StudentCourse', 'local' => 'sc_course_id', 'foreign' => 'sc_student_id')); + } +} + +class T626B_StudentCourse extends Doctrine_Record +{ + public function setTableDefinition() + { + $this->setTableName('T626B_Student_course'); + + $this->hasColumn('sc_student_id as student_id', 'varchar', 30, array ( 'primary' => true,)); + $this->hasColumn('sc_course_id as course_id', 'varchar', 20, array ( 'primary' => true,)); + $this->hasColumn('sc_remark as remark', 'varchar', 500, array ()); + } + + public function setUp() + { + $this->hasOne('T626B_Student as Student', array('local' => 'sc_student_id', 'foreign' => 's_id')); + $this->hasOne('T626_Course as Course', array('local' => 'sc_course_id', 'foreign' => 'c_id')); + } +} diff --git a/tests/run.php b/tests/run.php index 4c29578e6..2f598ac12 100644 --- a/tests/run.php +++ b/tests/run.php @@ -17,6 +17,7 @@ $tickets->addTestCase(new Doctrine_Ticket_480_TestCase()); $tickets->addTestCase(new Doctrine_Ticket_587_TestCase()); $tickets->addTestCase(new Doctrine_Ticket_576_TestCase()); $tickets->addTestCase(new Doctrine_Ticket_583_TestCase()); +$tickets->addTestCase(new Doctrine_Ticket_626B_TestCase()); //If you write a ticket testcase add it here like shown above! $test->addTestCase($tickets); @@ -147,7 +148,7 @@ $test->addTestCase($data_types); // Utility components $plugins = new GroupTest('Plugin tests: View, Validator, Hook','plugins'); //$utility->addTestCase(new Doctrine_PessimisticLocking_TestCase()); -$plugins->addTestCase(new Doctrine_Plugin_TestCase()); +//$plugins->addTestCase(new Doctrine_Plugin_TestCase()); $plugins->addTestCase(new Doctrine_View_TestCase()); $plugins->addTestCase(new Doctrine_AuditLog_TestCase()); $plugins->addTestCase(new Doctrine_Validator_TestCase());