Changeset 11031
- Timestamp:
- 08/21/08 23:56:53 (3 months ago)
- Files:
-
- plugins/DbFinderPlugin/README (modified) (1 diff)
- plugins/DbFinderPlugin/lib/sfDoctrineFinder.php (modified) (16 diffs)
- plugins/DbFinderPlugin/lib/sfModelFinder.php (modified) (1 diff)
- plugins/DbFinderPlugin/lib/sfPropelFinder.php (modified) (1 diff)
- plugins/DbFinderPlugin/test/unit/sfDoctrineFinderInternalsTest.php (modified) (1 diff)
- plugins/DbFinderPlugin/test/unit/sfDoctrineFinderRelationsTest.php (modified) (2 diffs)
- plugins/DbFinderPlugin/test/unit/sfDoctrineFinderTest.php (modified) (1 diff)
- plugins/DbFinderPlugin/test/unit/sfPropelFinderRelationsTest.php (modified) (2 diffs)
- plugins/DbFinderPlugin/test/unit/sfPropelFinderTest.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/DbFinderPlugin/README
r10845 r11031 573 573 --------- 574 574 575 ### 2008-08-13 | Trunk 576 575 ### 2008-08-21 | Trunk 576 577 * francois: Implemented `sfDoctrineFinder::join()` 577 578 * francois: Added `getQueryObject()` to the list of default methods 578 * francois: Implemented `sfDoctrine ::orderBy()`579 * francois: Implemented `sfDoctrineFinder::orderBy()` 579 580 * francois: Moved magic `__call()` to the parent `sfModelFinder` class 580 581 * francois: Implemented `sfDoctrineFinder::relatedTo()` (and fixed a bug in the `sfPropelFinder::relatedTo()` implementation) plugins/DbFinderPlugin/lib/sfDoctrineFinder.php
r10901 r11031 41 41 public function setClass($class, $alias = '') 42 42 { 43 $this->addAlias($class, $alias); 43 if($alias) 44 { 45 $this->addAlias($class, $alias); 46 } 44 47 $this->class = $class; 45 48 $this->alias = $alias; … … 70 73 } 71 74 72 public function getQuery() 73 { 74 return $this->buildQuery(); 75 } 76 77 public function buildquery() 78 { 75 public function buildQuery() 76 { 77 // Temporarily disabling the the subquery algorithm (enabled again in cleanup()). 78 // Read more at http://www.phpdoctrine.org/documentation/manual/0_11/?one-page#dql-doctrine-query-language:limit-and-offset-clauses:the-limit-subquery-algorithm 79 $this->object->getTable()->setAttribute(Doctrine::ATTR_QUERY_LIMIT, Doctrine::LIMIT_ROWS); 80 81 // Add columns 82 $this->query->select($this->getAlias($this->class).'.*'); 83 // TODO: add with() classes columns 84 85 // Add conditions 79 86 if($this->queryPattern) 80 87 { … … 94 101 public function getQueryObject() 95 102 { 96 return $this-> getQuery();103 return $this->buildQuery(); 97 104 } 98 105 … … 135 142 * @param mixed $connection Optional connection object 136 143 * 137 * @return sf PropelFinder a finder object144 * @return sfDoctrineFinder a finder object 138 145 * @throws Exception If the data is neither a classname nor an array 139 146 */ … … 148 155 return self::fromCollection($from); 149 156 } 150 throw new Exception('sf PropelFinder::from() only accepts a model object classname or an array of model objects');157 throw new Exception('sfDoctrineFinder::from() only accepts a model object classname or an array of model objects'); 151 158 } 152 159 … … 157 164 * @param string $class Model classname on which the search will be done 158 165 * 159 * @return sf PropelFinder a finder object166 * @return sfDoctrineFinder a finder object 160 167 */ 161 168 public static function fromArray($array, $class, $pkName) … … 332 339 public function count($distinct = false) 333 340 { 334 $res = $this-> getQuery()->count();341 $res = $this->buildQuery()->count(); 335 342 $this->cleanup(); 336 343 … … 351 358 $this->query->limit($limit); 352 359 } 353 $res = $this-> getQuery()->execute();360 $res = $this->buildQuery()->execute(); 354 361 $this->cleanup(); 355 362 … … 511 518 if($forceIndividualDeletes) 512 519 { 513 $objects = $this-> getQuery()->delete()->execute();520 $objects = $this->buildQuery()->delete()->execute(); 514 521 $nbDeleted = 0; 515 522 foreach($objects as $object) … … 521 528 else 522 529 { 523 if (!$this-> getQuery()->contains('where'))530 if (!$this->buildQuery()->contains('where')) 524 531 { 525 532 // Empty queries don't return the number of deleted rows … … 571 578 protected function cleanup() 572 579 { 580 // Re-enabling the the subquery algorithm. 581 $this->object->getTable()->setAttribute(Doctrine::ATTR_QUERY_LIMIT, Doctrine::LIMIT_RECORDS); 582 573 583 if($this->reinit) 574 584 { … … 1021 1031 case 3: 1022 1032 // $articleFinder->join('Article.CategoryId', 'Category.Id', 'RIGHT JOIN') 1033 // This is mostly for compatibility with Propel 1034 $relation = $this->findRelationFromColumns($args[0], $args[1]); 1023 1035 $operator = trim(str_replace('join', '', strtolower($args[2]))); 1036 $relatedClass = $relation->getTable()->getClassnameToReturn(); 1037 $alias = ''; 1024 1038 break; 1025 1039 } 1026 1040 $method = $operator . 'Join'; 1027 1041 $startClass = $this->getAlias($relation->offsetGet('localTable')->getClassnameToReturn()); 1028 if($isTrueAlias) 1029 { 1030 $this->addAlias($startClass.'.'.$relation->getAlias(), $alias); 1042 $relationClass = $relation->getTable()->getClassnameToReturn(); 1043 $this->query->$method($startClass.'.'.$relation->getAlias().' '.$alias); 1044 1045 if($relationClass == $relatedClass) 1046 { 1047 $this->addAlias($relationClass, $alias); 1031 1048 } 1032 1049 else 1033 1050 { 1034 $this->addAlias($relation->getClass(), $startClass.'.'.$relation->getAlias()); 1051 // $relatedClass is in fact the relation name, not the foreign class name 1052 $this->addAlias($relatedClass, $alias); 1035 1053 } 1036 1054 … … 1101 1119 } 1102 1120 1121 public function findRelationFromColumns($col1, $col2) 1122 { 1123 list($leftClass, $leftColumn, $leftAlias) = $this->getColName($col1, $class = null, $detail = true, $autoAddJoin = false); 1124 list($rightClass, $rightColumn, $rightAlias) = $this->getColName($col2, $class = null, $detail = true, $autoAddJoin = false); 1125 1126 foreach($this->relatedTables as $table) 1127 { 1128 foreach ($table->getRelations() as $key => $relation) 1129 { 1130 if ($relation->getClass() == $rightClass && $relation->getForeign() == $rightColumn && 1131 $relation->offsetGet('localTable')->getClassnameToReturn() == $leftClass && $relation->getLocal() == $leftColumn) 1132 { 1133 $this->relatedTables[]= Doctrine::getTable($rightClass); 1134 $this->relations[$rightClass] = $relation; 1135 1136 return $relation; 1137 } 1138 if ($relation->getClass() == $leftClass && $relation->getForeign() == $leftColumn && 1139 $relation->offsetGet('localTable')->getClassnameToReturn() == $rightClass && $relation->getLocal() == $rightColumn) 1140 { 1141 $this->relatedTables[]= Doctrine::getTable($leftClass); 1142 $this->relations[$leftClass] = $relation; 1143 1144 return $relation; 1145 } 1146 1147 } 1148 } 1149 1150 throw new Exception(sprintf('Cannot determine relation between %s and %s', $col1, $col2)); 1151 } 1152 1103 1153 /** 1104 1154 * Behavior-like supplementary getter for supplementary columns added by way of withColumn() … … 1146 1196 } 1147 1197 1148 protected function getColName($phpName, $class = null, $ autoAddJoin = true)1198 protected function getColName($phpName, $class = null, $detail = false, $autoAddJoin = true) 1149 1199 { 1150 1200 if(strpos($phpName, '.') !== false) … … 1165 1215 if(!$class) 1166 1216 { 1167 // TODO: guess class1168 1217 $class = $this->getClass(); 1169 1218 } … … 1189 1238 } 1190 1239 1191 return $alias . '.' . self::underscore($phpName); 1240 $colName = $alias . '.' . self::underscore($phpName); 1241 1242 return $detail ? array($class, self::underscore($phpName), $alias) : $alias . '.' . self::underscore($phpName); 1243 } 1244 1245 public function debug() 1246 { 1247 echo "** Debugging Doctrine Query\n"; 1248 $this->limit(1); 1249 echo " " . $this->getQueryObject()->getDQL()."\n"; 1250 $this->findOne(); 1251 echo " " . $this->getLatestQuery()."\n"; 1192 1252 } 1193 1253 } plugins/DbFinderPlugin/lib/sfModelFinder.php
r10901 r11031 218 218 { 219 219 // If the connection is a PDO instance, PHP throws an exception when serializing a finder object 220 // So we must pl y well with it220 // So we must play well with it 221 221 $attributes = get_object_vars($this); 222 222 unset($attributes['connection']); plugins/DbFinderPlugin/lib/sfPropelFinder.php
r10901 r11031 1317 1317 break; 1318 1318 } 1319 $operator = trim(str_replace('JOIN', '', strtoupper($operator))) . ' JOIN'; 1319 1320 $this->criteria->addJoin($column1, $column2, $operator); 1320 1321 plugins/DbFinderPlugin/test/unit/sfDoctrineFinderInternalsTest.php
r10901 r11031 66 66 class myFinder extends sfDoctrineFinder 67 67 { 68 public function getColName($phpName, $class = null, $ autoAddJoin = false)68 public function getColName($phpName, $class = null, $detail = false, $autoAddJoin = false) 69 69 { 70 return parent::getColName($phpName, $class, $ autoAddJoin);70 return parent::getColName($phpName, $class, $detail, $autoAddJoin); 71 71 } 72 72 } plugins/DbFinderPlugin/test/unit/sfDoctrineFinderRelationsTest.php
r10901 r11031 120 120 $databaseManager->initialize(); 121 121 122 $t = new lime_test( 15, new lime_output_color());122 $t = new lime_test(34, new lime_output_color()); 123 123 124 124 $t->diag('findRelation()'); … … 219 219 $t->is($article->getTitle(), 'bbbbb', 'join() allows to join to another table (one-to-many)'); 220 220 221 $nbArticles = sfDoctrineFinder::from('DArticle')->join('Category')->where('Category.Name', 'cat1')->count(); 222 $t->is($nbArticles, 2, 'join() accepts relation names instead of related class names'); 223 $nbArticles = sfDoctrineFinder::from('DArticle')->join('DCategory a')->where('a.Name', 'cat1')->count(); 224 $t->is($nbArticles, 2, 'join() accepts class aliases'); 225 $nbArticles = sfDoctrineFinder::from('DArticle')->join('Category a')->where('a.Name', 'cat1')->count(); 226 $t->is($nbArticles, 2, 'join() accepts relation aliases'); 227 228 $finder = sfDoctrineFinder::from('DArticle')->join('DCategory'); 229 $finder->count(); 230 $t->ok(stripos($finder->getLatestQuery(), 'inner join') !== false, 'join($table) defaults to an inner join'); 231 $finder = sfDoctrineFinder::from('DArticle')->join('DCategory', 'left join'); 232 $finder->count(); 233 $t->ok(stripos($finder->getLatestQuery(), 'left join') !== false, 'join($table, $type) accepts a join type as second parameter (like "left join")'); 234 $finder = sfDoctrineFinder::from('DArticle')->join('DCategory', Criteria::LEFT_JOIN); 235 $finder->count(); 236 $t->ok(stripos($finder->getLatestQuery(), 'left join') !== false, 'join($table, $type) accepts a join type as second parameter (like "Criteria::LEFT_JOIN")'); 237 $finder = sfDoctrineFinder::from('DArticle')->join('DCategory', 'left'); 238 $finder->count(); 239 $t->ok(stripos($finder->getLatestQuery(), 'left join') !== false, 'join($table, $type) accepts a join type as second parameter (like "left")'); 240 241 $finder = sfDoctrineFinder::from('DArticle')->join('DArticle.CategoryId', 'DCategory.Id', 'inner')->where('Category.Name', 'cat1'); 242 $t->is($nbArticles, 2, 'join($start, $end, $type) allows to join based on the two members of the relationship'); 243 sfDoctrineFinder::from('DArticle')->join('DCategory.Id', 'DArticle.CategoryId', 'inner')->where('Category.Name', 'cat1'); 244 $t->is($nbArticles, 2, 'join($end, $start, $type) allows to join based on the two members of the relationship'); 245 246 Doctrine_Query::create()->delete()->from('DArticle')->execute(); 247 Doctrine_Query::create()->delete()->from('DComment')->execute(); 248 Doctrine_Query::create()->delete()->from('DAuthor')->execute(); 249 $article1 = new DArticle(); 250 $article1->setTitle('aaaaa'); 251 $article1->setCategory($category1); 252 $article1->save(); 253 $author1 = new DAuthor(); 254 $author1->setName('John'); 255 $author1->save(); 256 $comment = new DComment(); 257 $comment->setContent('foo'); 258 $comment->setArticleId($article1->getId()); 259 $comment->setAuthor($author1); 260 $comment->save(); 261 $article = sfDoctrineFinder::from('DArticle')->join('DComment')->join('DAuthor')->where('DAuthor.Name', 'John')->findOne(); 262 $t->is($article->getTitle(), 'aaaaa', 'you can chain several join() statements'); 263 $article = sfDoctrineFinder::from('DArticle')->join('DComment')->where('DAuthor.Name', 'John')->findOne(); 264 $t->is($article->getTitle(), 'aaaaa', 'join() can be omitted if column names are explicit'); 265 $article = sfDoctrineFinder::from('DArticle')->joinDComment()->joinDAuthor()->where('DAuthor.Name', 'John')->findOne(); 266 $t->is($article->getTitle(), 'aaaaa', 'joinXXX() does a join according to the XXX column name'); 267 268 $comment = sfDoctrineFinder::from('DComment')->join('DArticle')->join('DAuthor')->where('DAuthor.Name', 'John')->findOne(); 269 $t->is($comment->getContent(), 'foo', 'you can add several join() statements'); 270 $t->is($comment->getArticle()->getTitle(), 'aaaaa', 'you can add several join() statements'); 271 $t->is($comment->getAuthor()->getName(), 'John', 'you can add several join() statements'); 272 273 $t->diag('leftJoin(), rightJoin(), innerJoin()'); 274 275 $finder = sfDoctrineFinder::from('DArticle')->leftJoin('DComment'); 276 $t->is($finder->getQueryObject()->getDQL(), 'SELECT d.* FROM DArticle d LEFT JOIN d.DComment d1', 'leftJoin($table) ends up in a left join'); 277 //$finder = sfDoctrineFinder::from('DArticle')->innerJoin('DComment'); 278 $t->skip('rightJoin($table) ends up in a right join'); 279 $finder = sfDoctrineFinder::from('DArticle')->innerJoin('DComment'); 280 $t->is($finder->getQueryObject()->getDQL(), 'SELECT d.* FROM DArticle d INNER JOIN d.DComment d1', 'innerJoin($table) ends up in an inner join'); 281 282 $finder = sfDoctrineFinder::from('DArticle')->leftJoin('DArticle.Id', 'DComment.ArticleId'); 283 $t->is($finder->getQueryObject()->getDQL(), 'SELECT d.* FROM DArticle d LEFT JOIN d.DComment ', 'leftJoin($start, $end) creates left join'); 284 285 $t->diag('with()'); 286 287 Doctrine_Query::create()->delete()->from('DArticle')->execute(); 288 Doctrine_Query::create()->delete()->from('DCategory')->execute(); 289 $category1 = new DCategory(); 290 $category1->setName('cat1'); 291 $category1->save(); 292 $article1 = new DArticle(); 293 $article1->setTitle('aaaaa'); 294 $article1->setCategory($category1); 295 $article1->save(); 296 $finder = sfDoctrineFinder::from('DArticle'); 297 $article = $finder->findOne(); 298 $sql = $finder->getLatestQuery(); 299 $category = $article->getCategory(); 300 //$t->isnt($finder->getLatestQuery(), $sql, 'Calling a getter on a related object issues a new query'); plugins/DbFinderPlugin/test/unit/sfDoctrineFinderTest.php
r10845 r11031 78 78 79 79 $finder = sfDoctrineFinder::from('DArticle')->where('Title', 'foo'); 80 $t->isa_ok($finder->getQuery (), 'Doctrine_Query', 'getQuery() returns the query object as composed by the finder');80 $t->isa_ok($finder->getQueryObject(), 'Doctrine_Query', 'getQueryObject() returns the query object as composed by the finder'); 81 81 $finder->findOne(); 82 82 $t->is($finder->getLatestQuery(), 'SELECT d.id AS d__id, d.title AS d__title, d.category_id AS d__category_id FROM d_article d WHERE d.title = \'foo\' LIMIT 1', 'getLatestQuery() returns the latest SQL query'); plugins/DbFinderPlugin/test/unit/sfPropelFinderRelationsTest.php
r10812 r11031 77 77 $databaseManager->initialize(); 78 78 79 $t = new lime_test(8 3, new lime_output_color());79 $t = new lime_test(85, new lime_output_color()); 80 80 81 81 $t->diag('findRelation()'); … … 167 167 $joins = $finder->getCriteria()->getJoins(); 168 168 $join = array_pop($joins); 169 $t->is($join->getJoinType(), 'LEFT JOIN', 'join($table, $type) creates a typed join'); 169 $t->is($join->getJoinType(), 'LEFT JOIN', 'join($table, $type) creates a typed join (with $type like Criteria::LEFT_JOIN)'); 170 171 $finder = sfPropelFinder::from('Article')->join('Comment', 'left join'); 172 $joins = $finder->getCriteria()->getJoins(); 173 $join = array_pop($joins); 174 $t->is($join->getJoinType(), 'LEFT JOIN', 'join($table, $type) creates a typed join (with $type like "left join")'); 175 176 $finder = sfPropelFinder::from('Article')->join('Comment', 'left'); 177 $joins = $finder->getCriteria()->getJoins(); 178 $join = array_pop($joins); 179 $t->is($join->getJoinType(), 'LEFT JOIN', 'join($table, $type) creates a typed join (with $type like "left")'); 180 170 181 $t->is($join->getLeftColumnName(), 'ID', 'join($table, $type) guesses the left column name'); 171 182 $t->is($join->getLeftTableName(), 'article', 'join($table, $type) guesses the left table name'); plugins/DbFinderPlugin/test/unit/sfPropelFinderTest.php
r10845 r11031 69 69 70 70 $finder = sfPropelFinder::from('Article')->where('Title', 'foo'); 71 $t->isa_ok($finder->get Criteria(), 'Criteria', 'getCriteria() returns the criteria as composed by the finder');71 $t->isa_ok($finder->getQueryObject(), 'Criteria', 'getQueryObject() returns the criteria as composed by the finder'); 72 72 $finder->findOne(); 73 73 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID FROM article WHERE article.TITLE=\'foo\' LIMIT 1', 'getLatestQuery() returns the latest SQL query');