1<?php 2 3/** 4 * @author Donald Ball 5 */ 6class Doctrine_Ticket_966_TestCase extends Doctrine_UnitTestCase 7{ 8 9 public function prepareTables() 10 { 11 $this->tables = array('Semester', 'Course', 'Weekday', 'CourseWeekday'); 12 parent::prepareTables(); 13 } 14 15 public function prepareData() 16 { 17 $semester = new Semester(); 18 $semester['name'] = 'Semester'; 19 $semester->save(); 20 21 foreach (array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday') as $name) 22 { 23 $weekday = new Weekday(); 24 $weekday['name'] = $name; 25 $weekday->save(); 26 } 27 28 for ($i=0; $i<3; $i++) 29 { 30 $course = new Course(); 31 $course['name'] = 'Course ' . $i; 32 $course['Semester'] = $semester; 33 $course->save(); 34 for ($w = 3; $w <6; $w++) 35 { 36 $cw = new CourseWeekday(); 37 $cw['Course'] = $course; 38 $cw['weekday_id'] = $w; 39 $cw->save(); 40 } 41 } 42 } 43 44 public function testArrayHydration() 45 { 46 $query = Doctrine_Query::create() 47 ->from('Semester s') 48 ->leftJoin('s.Courses c') 49 ->leftJoin('c.Weekdays cw'); 50 51 $semesters = $query->execute(array(), Doctrine_Core::HYDRATE_ARRAY); 52 $semester = $semesters[0]; 53 54 $this->assertAllWeekdaysArePopulated($semester); 55 } 56 57 public function testObjectHydration() 58 { 59 $query = Doctrine_Query::create() 60 ->from('Semester s') 61 ->leftJoin('s.Courses c') 62 ->leftJoin('c.Weekdays cw'); 63 64 $semester = $query->execute()->getFirst(); 65 66 $weekdayOids = array(); 67 foreach ($semester->Courses as $course) { 68 foreach ($course->Weekdays as $weekday) { 69 if ( ! in_array($weekday->getOid(), $weekdayOids)) { 70 $weekdayOids[] = $weekday->getOid(); 71 } 72 $this->assertTrue(is_numeric($weekday->id)); 73 $this->assertTrue(is_string($weekday->name)); 74 } 75 } 76 // should be only 3 weekday objects in total 77 $this->assertEqual(3, count($weekdayOids)); 78 79 $queryCountBefore = $this->conn->count(); 80 $this->assertAllWeekdaysArePopulated($semester); 81 $this->assertEqual($queryCountBefore, $this->conn->count()); 82 } 83 84 public function testLazyObjectHydration() 85 { 86 // clear identity maps to make sure we're starting with a clean plate 87 $this->conn->getTable('Course')->clear(); 88 $this->conn->getTable('Weekday')->clear(); 89 $this->conn->getTable('Semester')->clear(); 90 $query = Doctrine_Query::create()->from('Semester s'); 91 92 $semester = $query->execute()->getFirst(); 93 $queryCountBefore = $this->conn->count(); 94 $this->assertAllWeekdaysArePopulated($semester); 95 // expecting 4 additional queries: 1 to fetch the courses for the only semester and 96 // 1 for each weekday collection for each of the three courses. 97 $this->assertEqual($queryCountBefore + 4, $this->conn->count()); 98 } 99 100 private function assertAllWeekdaysArePopulated($semester) 101 { 102 foreach ($semester['Courses'] as $course) 103 { 104 foreach ($course['Weekdays'] as $weekday) 105 { 106 $this->assertTrue(is_numeric($weekday['id'])); 107 $this->assertTrue(is_string($weekday['name'])); 108 } 109 } 110 } 111 112} 113 114class Semester extends Doctrine_Record 115{ 116 117 public function setTableDefinition() 118 { 119 $this->setTableName('semester'); 120 $this->hasColumn('id', 'integer', 4, array('primary'=>'true', 'autoincrement'=>'true')); 121 $this->hasColumn('name', 'string', 255, array('notnull' => true)); 122 } 123 124 public function setUp() 125 { 126 parent::setUp(); 127 $this->hasMany('Course as Courses', array('local'=>'id', 'foreign'=>'semester_id')); 128 } 129 130} 131 132class Weekday extends Doctrine_Record 133{ 134 135 public function setTableDefinition() 136 { 137 $this->setTableName('weekday'); 138 $this->hasColumn('id', 'integer', 4, array('primary' => true, 'autoincrement' => true)); 139 $this->hasColumn('name', 'string', 9, array('notnull' => true, 'unique' => true)); 140 } 141 142 public function setUp() 143 { 144 // need to make the many-many bidirectional in order for the lazy-loading test to work. 145 // lazy-loading the weekdays ($course['Weekdays']) doesnt work when the relation is 146 // set up unidirectional. this is true for all many-many relations. 147 $this->hasMany('Course as courses', 148 array('refClass'=>'CourseWeekday', 'local'=>'weekday_id', 'foreign'=>'course_id')); 149 } 150} 151 152class Course extends Doctrine_Record 153{ 154 155 public function setTableDefinition() 156 { 157 $this->setTableName('course'); 158 $this->hasColumn('id', 'integer', 4, array('primary'=>'true', 'autoincrement'=>'true')); 159 $this->hasColumn('semester_id', 'integer', 4, array('notnull'=>true)); 160 $this->hasColumn('name', 'string', 255, array('notnull' => true)); 161 } 162 163 public function setUp() 164 { 165 parent::setUp(); 166 $this->hasOne('Semester', array('local' => 'semester_id', 167 'foreign' => 'id', 168 'onDelete' => 'CASCADE')); 169 $this->hasMany('Weekday as Weekdays', 170 array('refClass'=>'CourseWeekday', 'local'=>'course_id', 'foreign'=>'weekday_id')); 171 } 172 173} 174 175class CourseWeekday extends Doctrine_Record 176{ 177 178 public function setTableDefinition() 179 { 180 $this->setTableName('course_weekday'); 181 # Poor form to have an id on a join table, but that's what we were doing 182 $this->hasColumn('id', 'integer', 4, array('primary' => true, 'autoincrement' => true)); 183 $this->hasColumn('course_id', 'integer', 4, array('notnull' => true)); 184 $this->hasColumn('weekday_id', 'integer', 4, array('notnull' => true)); 185 } 186 187 public function setUp() 188 { 189 parent::setUp(); 190 $this->hasOne('Course', array('local'=>'course_id', 'foreign'=>'id', 'onDelete'=>'CASCADE')); 191 $this->hasOne('Weekday', array('local'=>'weekday_id', 'foreign'=>'id', 'onDelete'=>'CASCADE')); 192 } 193 194} 195