Changeset 10785
- Timestamp:
- 08/11/08 18:41:08 (3 months ago)
- Files:
-
- plugins/sfPropelFinderPlugin/README (modified) (6 diffs)
- plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php (modified) (3 diffs)
- plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderRelationsTest.php (modified) (11 diffs)
- plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderTest.php (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/sfPropelFinderPlugin/README
r10780 r10785 178 178 // No need to tell the finder which columns to use for the join, just the related Class 179 179 // After all, the columns of the FK are already defined in the schema. 180 // Note that the default join() call results in a SQL INNER JOIN clause 181 // This is somewhat different from the Propel default, which issues a WHERE clause, but the result is the same 180 182 181 183 // If subsequent conditions use explicit column names, … … 192 194 findOne(); 193 195 194 // Or if you want a special type of join (left, right , inner)195 $article = DbFinder::from('Article')-> 196 innerJoin('Comment')->196 // Or if you want a special type of join (left, right) 197 $article = DbFinder::from('Article')-> 198 leftJoin('Comment')-> 197 199 where('Comment.Content', 'You rock!')-> 198 200 findOne(); … … 200 202 // Or both 201 203 $article = DbFinder::from('Article')-> 202 innerJoin('Article.Id', 'Comment.ArticleId')->204 leftJoin('Article.Id', 'Comment.ArticleId')-> 203 205 where('Comment.Content', 'You rock!')-> 204 206 findOne(); … … 286 288 Just as Propel offers generated `doSelectJoinXXX()` methods, `DbFinder` allows you to hydrate related objects in a single query - you just have to call the `with()` method to specify which objects the main object should be hydrated with. 287 289 288 $comment = DbFinder::from('Comment')->with('Article')-> 290 $comment = DbFinder::from('Comment')-> 291 with('Article')-> 289 292 join('Article')-> 290 293 where('Article.Title', 'Hello, world')-> … … 419 422 420 423 ### Updating objects 421 422 424 423 425 $article1 = new Article; … … 533 535 ### 2008-08-11 | Trunk 534 536 537 * francois: `sfPropelFinder::join()` now defaults to an `INNER JOIN` instead of a `WHERE` statement (will facilitate compatibility with Doctrine) 535 538 * francois: Implemented `sfDoctrine::combine()` 536 539 * francois: Implemented `sfDoctrineFinder::orWhere()` plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php
r10780 r10785 1099 1099 { 1100 1100 $this->addCondition('and', $c->getFullyQualifiedName(), $object->getByName($c->getRelatedName(), BasePeer::TYPE_COLNAME), Criteria::EQUAL); 1101 break; 1101 1102 } 1102 1103 } … … 1220 1221 * Infers $column1, $column2 and $operator from $relatedClass and some optional arguments 1221 1222 * Uses the Propel column maps, based on the schema, to guess the related columns 1223 * Beware that the default JOIN operator is INNER JOIN, while Criteria defaults to WHERE 1222 1224 * Examples: 1223 1225 * $articleFinder->join('Comment') 1224 * => $c->addJoin(ArticlePeer::ID, CommentPeer::ARTICLE_ID )1226 * => $c->addJoin(ArticlePeer::ID, CommentPeer::ARTICLE_ID, Criteria::INNER_JOIN) 1225 1227 * $articleFinder->join('Category', 'RIGHT JOIN') 1226 1228 * => $c->addJoin(ArticlePeer::CATEGORY_ID, CategoryPeer::ID, Criteria::RIGHT_JOIN) … … 1249 1251 list($column1, $column2) = $this->getRelation($relatedClass); 1250 1252 $this->addRelation(sfPropelFinderUtils::getPeerClassFromClass($relatedClass), $alias); 1251 $operator = isset($args[1]) ? $args[1] : null;1253 $operator = isset($args[1]) ? $args[1] : Criteria::INNER_JOIN; 1252 1254 break; 1253 1255 case 3: plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderRelationsTest.php
r10655 r10785 77 77 $databaseManager->initialize(); 78 78 79 $t = new lime_test(8 2, new lime_output_color());79 $t = new lime_test(83, new lime_output_color()); 80 80 81 81 $t->diag('findRelation()'); … … 158 158 $joins = $finder->getCriteria()->getJoins(); 159 159 $join = array_pop($joins); 160 $t->is($join->getJoinType(), null, 'join() ends up in a simplejoin');160 $t->is($join->getJoinType(), Criteria::INNER_JOIN, 'join() ends up in an inner join'); 161 161 $t->is($join->getLeftColumnName(), 'ID', 'join($table) guesses the left column name'); 162 162 $t->is($join->getLeftTableName(), 'article', 'join($table) guesses the left table name'); … … 295 295 $article1->setCategory($category1); 296 296 $article1->save(); 297 $sql = 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM article , category WHERE article.CATEGORY_ID=category.IDLIMIT 1';297 $sql = 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM article INNER JOIN category ON (article.CATEGORY_ID=category.ID) LIMIT 1'; 298 298 $finder = sfPropelFinder::from('Article')->join('Category')->with('Category'); 299 299 $article = $finder->findOne(); … … 308 308 $t->is($article->getCategory()->getName(), 'cat1', 'fetching objects with a with() returns the correct related object'); 309 309 $t->is(Propel::getConnection()->getLastExecutedQuery(), $sql, 'with() called without a join() hydrates the related classes and avoids subsequent queries'); 310 311 $finder = sfPropelFinder::from('Article')->leftJoin('Category')->with('Category'); 312 $article = $finder->findOne(); 313 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM article LEFT JOIN category ON (article.CATEGORY_ID=category.ID) LIMIT 1', 'calling a particular join() before with() changes the join clause'); 310 314 311 315 ArticlePeer::doDeleteAll(); … … 326 330 $finder = sfPropelFinder::from('Comment')->with('Article')->with('Author'); 327 331 $comment = $finder->findOne(); 328 $sql = 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.ID, article.TITLE, article.CATEGORY_ID, author.ID, author.NAME FROM comment , article, author WHERE comment.ARTICLE_ID=article.ID AND comment.AUTHOR_ID=author.IDLIMIT 1';332 $sql = 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.ID, article.TITLE, article.CATEGORY_ID, author.ID, author.NAME FROM comment INNER JOIN article ON (comment.ARTICLE_ID=article.ID) INNER JOIN author ON (comment.AUTHOR_ID=author.ID) LIMIT 1'; 329 333 $t->is($finder->getLatestQuery(), $sql, 'you can call with() several times to hydrate more than one related object'); 330 334 $t->is($comment->getContent(), 'foo', 'you can call with() several times to hydrate more than one related object'); … … 333 337 $t->is(Propel::getConnection()->getLastExecutedQuery(), $sql, 'with() called several tims hydrates the related classes and avoids subsequent queries'); 334 338 339 $sql = 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.ID, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM comment INNER JOIN article ON (comment.ARTICLE_ID=article.ID) INNER JOIN category ON (article.CATEGORY_ID=category.ID) LIMIT 1'; 335 340 $finder = sfPropelFinder::from('Comment')->with('Article')->with('Category'); 336 341 $comment = $finder->findOne(); 337 $t->is($finder->getLatestQuery(), 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.ID, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM comment, article, category WHERE comment.ARTICLE_ID=article.ID AND article.CATEGORY_ID=category.ID LIMIT 1', 'with() can even hydrate related objects via a related object');342 $t->is($finder->getLatestQuery(), $sql, 'with() can even hydrate related objects via a related object'); 338 343 339 344 $finder = sfPropelFinder::from('Comment')->with('Article', 'Category'); 340 345 $comment = $finder->findOne(); 341 $t->is($finder->getLatestQuery(), 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.ID, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM comment, article, category WHERE comment.ARTICLE_ID=article.ID AND article.CATEGORY_ID=category.ID LIMIT 1', 'with() accepts several arguments, so you don\'t need to call it several times');346 $t->is($finder->getLatestQuery(), $sql, 'with() accepts several arguments, so you don\'t need to call it several times'); 342 347 343 348 $t->diag('withI18n()'); … … 353 358 $article1->save(); 354 359 360 $baseSQL = 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, article_i18n.CONTENT, article_i18n.ID, article_i18n.CULTURE FROM article INNER JOIN article_i18n ON (article.ID=article_i18n.ID) '; 355 361 sfContext::getInstance()->getUser()->setCulture('en'); 356 362 $finder = sfPropelFinder::from('Article')->withI18n(); 357 363 $article = $finder->findOne(); 358 364 $query = $finder->getLatestQuery(); 359 $t->is($query, 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, article_i18n.CONTENT, article_i18n.ID, article_i18n.CULTURE FROM article, article_i18n WHERE article_i18n.CULTURE=\'en\' AND article.ID=article_i18n.IDLIMIT 1', 'withI18n() hydrates the related I18n object with a culture taken from the user object');365 $t->is($query, $baseSQL . 'WHERE article_i18n.CULTURE=\'en\' LIMIT 1', 'withI18n() hydrates the related I18n object with a culture taken from the user object'); 360 366 $t->is($article->getContent(), 'english content', 'withI18n() considers the current user culture for hydration'); 361 367 $t->is(Propel::getConnection()->getLastExecutedQuery(), $query, 'withI18n() hydrates the i18n object so that no further query is necessary'); … … 365 371 $article = $finder->findOne(); 366 372 367 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, article_i18n.CONTENT, article_i18n.ID, article_i18n.CULTURE FROM article, article_i18n WHERE article_i18n.CULTURE=\'fr\' AND article.ID=article_i18n.IDLIMIT 1', 'withI18n() hydrates the related I18n object with a culture taken from the user object');373 $t->is($finder->getLatestQuery(), $baseSQL . 'WHERE article_i18n.CULTURE=\'fr\' LIMIT 1', 'withI18n() hydrates the related I18n object with a culture taken from the user object'); 368 374 $t->is($article->getContent(), 'contenu français', 'withI18n() considers the current user culture for hydration'); 369 375 … … 377 383 $finder = sfPropelFinder::from('Article')->with('I18n'); 378 384 $article = $finder->findOne(); 379 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, article_i18n.CONTENT, article_i18n.ID, article_i18n.CULTURE FROM article, article_i18n WHERE article_i18n.CULTURE=\'en\' AND article.ID=article_i18n.IDLIMIT 1', 'with(\'I18n\') is a synonym for withI18n()');385 $t->is($finder->getLatestQuery(), $baseSQL . 'WHERE article_i18n.CULTURE=\'en\' LIMIT 1', 'with(\'I18n\') is a synonym for withI18n()'); 380 386 $finder = sfPropelFinder::from('Article')->with('i18n'); 381 387 $article = $finder->findOne(); 382 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, article_i18n.CONTENT, article_i18n.ID, article_i18n.CULTURE FROM article, article_i18n WHERE article_i18n.CULTURE=\'en\' AND article.ID=article_i18n.IDLIMIT 1', 'with(\'i18n\') is a synonym for withI18n()');388 $t->is($finder->getLatestQuery(), $baseSQL . 'WHERE article_i18n.CULTURE=\'en\' LIMIT 1', 'with(\'i18n\') is a synonym for withI18n()'); 383 389 384 390 $t->diag('withColumn()'); … … 405 411 $comment = $finder->findOne(); 406 412 $t->is($comment->getColumn('Article.Title'), 'bbbbb', 'Additional columns added with withColumn() are stored in the object and can be retrieved with getColumn()'); 407 $t->is($finder->getLatestQuery(), 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.TITLE AS "Article.Title" FROM comment , article WHERE comment.ARTICLE_ID=article.IDLIMIT 1', 'Columns added with withColumn() can contain a dot (and are then escaped with double quotes in SQL)');413 $t->is($finder->getLatestQuery(), 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.TITLE AS "Article.Title" FROM comment INNER JOIN article ON (comment.ARTICLE_ID=article.ID) LIMIT 1', 'Columns added with withColumn() can contain a dot (and are then escaped with double quotes in SQL)'); 408 414 409 415 $comment = sfPropelFinder::from('Comment')-> … … 465 471 orderBy('NbComments'); 466 472 $article = $finder->findOne(); 467 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, COUNT(comment.ID) AS NbComments FROM article , comment WHERE article.ID=comment.ARTICLE_IDGROUP BY article.ID ORDER BY NbComments ASC LIMIT 1', 'Columns added with withColumn() can be used for sorting');473 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, COUNT(comment.ID) AS NbComments FROM article INNER JOIN comment ON (article.ID=comment.ARTICLE_ID) GROUP BY article.ID ORDER BY NbComments ASC LIMIT 1', 'Columns added with withColumn() can be used for sorting'); 468 474 469 475 $t->diag('sfPropelFinder::with() issues with object finders classes'); plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderTest.php
r10779 r10785 226 226 227 227 $article = $finder->with('Category')->findPk($article2->getId()); 228 $t->cmp_ok(strpos($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM article ,category'), '===', 0, 'findPk() is compatible with with()');228 $t->cmp_ok(strpos($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM article INNER JOIN category'), '===', 0, 'findPk() is compatible with with()'); 229 229 230 230 ArticlePeer::doDeleteAll(); … … 523 523 $t->is( 524 524 $finder->getLatestQuery(), 525 "SELECT $columns FROM article , category WHERE (category.NAME='foo' OR category.NAME='bar') AND article.CATEGORY_ID=category.ID",525 "SELECT $columns FROM article INNER JOIN category ON (article.CATEGORY_ID=category.ID) WHERE (category.NAME='foo' OR category.NAME='bar')", 526 526 'orWhere() works on a simple jointure' 527 527 ); … … 535 535 $t->is( 536 536 $finder->getLatestQuery(), 537 "SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID FROM comment , article, author WHERE (article.TITLE='foo' OR author.NAME='bar') AND comment.ARTICLE_ID=article.ID AND comment.AUTHOR_ID=author.ID",537 "SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID FROM comment INNER JOIN article ON (comment.ARTICLE_ID=article.ID) INNER JOIN author ON (comment.AUTHOR_ID=author.ID) WHERE (article.TITLE='foo' OR author.NAME='bar')", 538 538 'orWhere() works on a multiple jointure' 539 539 ); … … 774 774 withColumn('COUNT(comment.ID)', 'NbComments'); 775 775 $article = $finder->findOne(); 776 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, COUNT(comment.ID) AS NbComments FROM article , comment WHERE article.ID=comment.ARTICLE_IDGROUP BY article.ID LIMIT 1', 'groupBy() accepts a column name and issues a GROUP BY clause');776 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, COUNT(comment.ID) AS NbComments FROM article INNER JOIN comment ON (article.ID=comment.ARTICLE_ID) GROUP BY article.ID LIMIT 1', 'groupBy() accepts a column name and issues a GROUP BY clause'); 777 777 778 778 $finder = sfPropelFinder::from('Article')-> … … 782 782 withColumn('COUNT(comment.ID)', 'NbComments'); 783 783 $article = $finder->findOne(); 784 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, article.ID AS foo, COUNT(comment.ID) AS NbComments FROM article , comment WHERE article.ID=comment.ARTICLE_IDGROUP BY foo LIMIT 1', 'groupBy() accepts a column alias and issues a GROUP BY clause');784 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, article.ID AS foo, COUNT(comment.ID) AS NbComments FROM article INNER JOIN comment ON (article.ID=comment.ARTICLE_ID) GROUP BY foo LIMIT 1', 'groupBy() accepts a column alias and issues a GROUP BY clause'); 785 785 786 786 $finder = sfPropelFinder::from('Article')-> … … 789 789 withColumn('COUNT(comment.ID)', 'NbComments'); 790 790 $article = $finder->findOne(); 791 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, COUNT(comment.ID) AS NbComments FROM article , comment WHERE article.ID=comment.ARTICLE_IDGROUP BY article.ID LIMIT 1', 'groupByXXX() accepts a column name and issues a GROUP BY clause');791 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, COUNT(comment.ID) AS NbComments FROM article INNER JOIN comment ON (article.ID=comment.ARTICLE_ID) GROUP BY article.ID LIMIT 1', 'groupByXXX() accepts a column name and issues a GROUP BY clause'); 792 792 793 793 $t->diag('groupByClass()'); … … 815 815 withColumn('COUNT(comment.ID)', 'NbComments'); 816 816 $article = $finder->findOne(); 817 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, COUNT(comment.ID) AS NbComments FROM article , comment WHERE article.ID=comment.ARTICLE_IDGROUP BY article.ID,article.TITLE,article.CATEGORY_ID LIMIT 1', 'groupByClass() accepts a model class name and issues a GROUP BY clause on all columns');817 $t->is($finder->getLatestQuery(), 'SELECT article.ID, article.TITLE, article.CATEGORY_ID, COUNT(comment.ID) AS NbComments FROM article INNER JOIN comment ON (article.ID=comment.ARTICLE_ID) GROUP BY article.ID,article.TITLE,article.CATEGORY_ID LIMIT 1', 'groupByClass() accepts a model class name and issues a GROUP BY clause on all columns'); 818 818 819 819 $t->diag('set()');