Changeset 10779
- Timestamp:
- 08/11/08 15:57:28 (3 months ago)
- Files:
-
- plugins/sfPropelFinderPlugin/README (modified) (5 diffs)
- plugins/sfPropelFinderPlugin/lib/DbFinder.php (modified) (5 diffs)
- plugins/sfPropelFinderPlugin/lib/sfDoctrineFinder.php (modified) (10 diffs)
- plugins/sfPropelFinderPlugin/lib/sfDoctrineFinderListener.php (modified) (2 diffs)
- plugins/sfPropelFinderPlugin/lib/sfModelFinder.php (modified) (1 diff)
- plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php (modified) (6 diffs)
- plugins/sfPropelFinderPlugin/test/unit/sfDoctrineFinderTest.php (modified) (2 diffs)
- plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderTest.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/sfPropelFinderPlugin/README
r10772 r10779 81 81 where('PublishedAt', '<', time())-> 82 82 find(); 83 // Or even better, use the _and() and _or() methods for SQL-like code83 // For OR conditions, use orWhere() instead of where() 84 84 $articles = $articleFinder-> 85 85 where('Title', 'foo')-> 86 _and('PublishedAt', '<', time())->87 _or('Title', 'like', 'bar%')->86 where('PublishedAt', '<', time())-> 87 orWhere('Title', 'like', 'bar%')-> 88 88 find(); 89 89 … … 116 116 117 117 // everything chained together 118 $articles = DbFinder::from('Article')->where('Title', 'like', '%world')-> _and('IsPublished', true)->orderBy('CreatedAt')->find();118 $articles = DbFinder::from('Article')->where('Title', 'like', '%world')->where('IsPublished', true)->orderBy('CreatedAt')->find(); 119 119 // You can write it in several lines, too 120 120 $articles = DbFinder::from('Article')-> 121 121 where('Title', 'like', '%world')-> 122 _and('IsPublished', true)->122 where('IsPublished', true)-> 123 123 orderBy('CreatedAt')-> 124 124 find(); … … 237 237 ### Complex logic 238 238 239 // _and() and _or() only allow simple logical operations on a single condition239 // where() and _or() only allow simple logical operations on a single condition 240 240 // For more complex logic, you have to use combine() 241 241 // It expects an array of named conditions to be combined, and an operator … … 533 533 ### 2008-08-11 | Trunk 534 534 535 * francois: Implemented `sfDoctrineFinder::orWhere()` 536 * francois: [BC Break] Removed `_and()` (synonym for `where()`) and renamed `_or()` to `orWhere()` 537 * mrhyde: Fixed problem with `sfPropelFinder`, symfony cache, and Propel 1.3 535 538 * francois: Refactored `DbFinder` to allow agnostic finders on model objects to extend it, and to fix problem with lacking PHPDoc on `DbFinder` methods 536 539 * francois: Added abstract `sfModelFinder` class to keep all abstract methods out of `DbFinder` … … 558 561 ### 2008-07-07 | 0.3.0 Beta 559 562 560 * mrhyde: Fixed problem with `sfPropelFinder`, symfony cache, and Propel 1.3561 563 * francois: Added `sfPropelFinder::combine()` method to handle complex queries with And and Or 562 564 * francois: Added support for `with()` in `findPk()` (and documented the method) plugins/sfPropelFinderPlugin/lib/DbFinder.php
r10765 r10779 523 523 524 524 /** 525 * Finder Fluid Interface for AND in a WHERE526 * Infers $column, $value, $comparison from $columnName and some optional arguments527 *528 * @see where()529 * @return DbDinder the current finder object530 */531 public function _and()532 {533 call_user_func_array(array($this->adapter, '_and'), func_get_arg());534 535 return $this;536 }537 538 /**539 525 * Finder Fluid Interface for OR in a WHERE 540 526 * Infers $column, $value, $comparison from $columnName and some optional arguments 541 527 * Examples: 542 * $articleFinder-> _or('CommentId', 3)528 * $articleFinder->orWhere('CommentId', 3) 543 529 * => WHERE ... OR article.COMMENT_ID = 3 544 * $articleFinder-> _or('Title', 'like', '%foo')530 * $articleFinder->orWhere('Title', 'like', '%foo') 545 531 * => WHERE ... OR article.TITLE LIKE '%foo' 546 532 * … … 551 537 * @return DbFinder the current finder object 552 538 */ 553 public function _or()554 { 555 call_user_func_array(array($this->adapter, ' _or'), func_get_arg());539 public function orWhere() 540 { 541 call_user_func_array(array($this->adapter, 'orWhere'), func_get_arg()); 556 542 557 543 return $this; … … 735 721 return call_user_func_array(array($this, 'where'), $arguments); 736 722 } 723 if(strpos($name, 'orWhere') === 0) 724 { 725 array_unshift($arguments, substr($name, 7)); 726 return call_user_func_array(array($this, 'orWhere'), $arguments); 727 } 737 728 if(strpos($name, 'orderBy') === 0) 738 729 { … … 749 740 array_unshift($arguments, substr($name, 4)); 750 741 return call_user_func_array(array($this, 'join'), $arguments); 751 752 742 } 753 743 if(($pos = strpos($name, 'Join')) > 0) … … 757 747 return call_user_func_array(array($this, 'join'), $arguments); 758 748 } 759 if(strpos($name, '_and') === 0)760 {761 array_unshift($arguments, substr($name, 4));762 return call_user_func_array(array($this, '_and'), $arguments);763 }764 if(strpos($name, 'and') === 0)765 {766 array_unshift($arguments, substr($name, 3));767 return call_user_func_array(array($this, '_and'), $arguments);768 769 }770 if(strpos($name, '_or') === 0)771 {772 array_unshift($arguments, substr($name, 3));773 return call_user_func_array(array($this, '_or'), $arguments);774 775 }776 if(strpos($name, 'or') === 0)777 {778 array_unshift($arguments, substr($name, 2));779 return call_user_func_array(array($this, '_or'), $arguments);780 }781 749 if(strpos($name, 'findBy') === 0) 782 750 { plugins/sfPropelFinderPlugin/lib/sfDoctrineFinder.php
r10765 r10779 19 19 $reinit = true, 20 20 $query = null, 21 $queryPattern = '', 22 $queryArgs = array(), 23 $argNumber = 0, 21 24 $queryListener = null, 22 25 $withClasses = array(), … … 64 67 public function getQuery() 65 68 { 69 return $this->buildQuery(); 70 } 71 72 public function buildquery() 73 { 74 if($this->queryPattern) 75 { 76 $this->query->addWhere($this->queryPattern, $this->queryArgs); 77 $this->queryPattern = ''; 78 $this->queryArgs = array(); 79 } 80 66 81 return $this->query; 67 82 } … … 279 294 public function count($distinct = false) 280 295 { 281 $res = $this-> query->count();296 $res = $this->getQuery()->count(); 282 297 $this->cleanup(); 283 298 … … 298 313 $this->query->limit($limit); 299 314 } 300 $res = $this-> query->execute();315 $res = $this->getQuery()->execute(); 301 316 $this->cleanup(); 302 317 … … 458 473 if($forceIndividualDeletes) 459 474 { 460 $objects = $this-> query->delete()->execute();475 $objects = $this->getQuery()->delete()->execute(); 461 476 $nbDeleted = 0; 462 477 foreach($objects as $object) … … 468 483 else 469 484 { 470 if (!$this-> query->contains('where'))485 if (!$this->getQuery()->contains('where')) 471 486 { 472 487 // Empty queries don't return the number of deleted rows … … 674 689 } 675 690 676 protected function addCondition($column, $comparison, $value) 677 { 691 protected function addCondition($column, $comparison, $value, $operator = 'and') 692 { 693 if($comparison == ' NOT IN ') 694 { 695 throw new Exception('sfDoctrineFinder cannot add a condition with a NOT IN'); 696 } 678 697 if($comparison == ' IN ') 679 698 { 699 if($operator == 'or') 700 { 701 throw new Exception('sfDoctrineFinder cannot OR a condition with an IN'); 702 } 680 703 $this->query->whereIn($column, $value); 681 704 } 682 705 else 683 706 { 707 // The operator of the first condition is ignored 708 $operator = $this->queryPattern ? $operator : ''; 684 709 if(is_null($value)) 685 710 { 686 $this->query ->addWhere(sprintf('%s %s', $column, $comparison));711 $this->queryPattern .= sprintf(' %s %s %s', $operator, $column, $comparison); 687 712 } 688 713 else 689 714 { 690 $this->query->addWhere(sprintf('%s %s ?', $column, $comparison), is_array($value) ? $value : array($value)); 691 } 692 } 693 } 694 695 /** 696 * Infers $column, $value, $comparison from $columnName and some optional arguments 697 * 698 * @see where() 699 * @return sfDoctrineFinder the current finder object 700 */ 701 public function _and() 702 { 703 throw new Exception('This method is not yet implemented'); 704 705 return $this; 715 $argName = ':param'.$this->argNumber; 716 $this->argNumber++; 717 $this->queryPattern .= sprintf(' %s %s %s %s', $operator, $column, $comparison, $argName); 718 $this->queryArgs[$argName] = $value; 719 } 720 } 706 721 } 707 722 … … 715 730 * @return sfDoctrineFinder the current finder object 716 731 */ 717 public function _or() 718 { 719 throw new Exception('This method is not yet implemented'); 732 public function orWhere() 733 { 734 $arguments = func_get_args(); 735 $columnName = array_shift($arguments); 736 $column = $this->getColName($columnName); 737 list($value, $comparison) = self::getValueAndComparisonFromArguments($arguments); 738 $this->addCondition($column, $comparison, $value, 'or'); 720 739 721 740 return $this; … … 1001 1020 return call_user_func_array(array($this, 'where'), $arguments); 1002 1021 } 1022 if(strpos($name, 'orWhere') === 0) 1023 { 1024 array_unshift($arguments, substr($name, 7)); 1025 return call_user_func_array(array($this, 'orWhere'), $arguments); 1026 } 1003 1027 if(strpos($name, 'orderBy') === 0) 1004 1028 { … … 1015 1039 return call_user_func_array(array($this, 'join'), $arguments); 1016 1040 } 1017 if(strpos($name, '_and') === 0)1018 {1019 array_unshift($arguments, substr($name, 4));1020 return call_user_func_array(array($this, '_and'), $arguments);1021 }1022 if(strpos($name, 'and') === 0)1023 {1024 array_unshift($arguments, substr($name, 3));1025 return call_user_func_array(array($this, '_and'), $arguments);1026 1027 }1028 if(strpos($name, '_or') === 0)1029 {1030 array_unshift($arguments, substr($name, 3));1031 return call_user_func_array(array($this, '_or'), $arguments);1032 1033 }1034 if(strpos($name, 'or') === 0)1035 {1036 array_unshift($arguments, substr($name, 2));1037 return call_user_func_array(array($this, '_or'), $arguments);1038 }1039 1041 if(strpos($name, 'findBy') === 0) 1040 1042 { plugins/sfPropelFinderPlugin/lib/sfDoctrineFinderListener.php
r10655 r10779 34 34 public function preQuery(Doctrine_Event $event) 35 35 { 36 $this->queries []= $event->getQuery() .';';36 $this->queries []= $event->getQuery(); 37 37 } 38 38 … … 46 46 { 47 47 $query = $event->getQuery(); 48 $query = strtr($query, array('?' => "'%s'")); 49 $this->queries []= vsprintf($query, $event->getParams()).';'; 48 $params = $event->getParams(); 49 foreach($params as $key => $value) 50 { 51 $params[$key] = "'".$value."'"; 52 } 53 $this->queries []= strtr($query, $params); 50 54 } 51 55 plugins/sfPropelFinderPlugin/lib/sfModelFinder.php
r10772 r10779 81 81 abstract public function distinct(); 82 82 abstract public function where(); 83 abstract public function _and(); 84 abstract public function _or(); 83 abstract public function orWhere(); 85 84 abstract public function combine($conditions, $operator = 'and', $namedCondition = null); 86 85 abstract public function relatedTo($object); plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php
r10765 r10779 964 964 965 965 /** 966 * Finder Fluid Interface for Criteria::addAnd()967 * Infers $column, $value, $comparison from $columnName and some optional arguments968 *969 * @see where()970 * @return sfPropelFinder the current finder object971 */972 public function _and()973 {974 $arguments = func_get_args();975 $columnName = array_shift($arguments);976 $column = $this->getColName($columnName);977 list($value, $comparison) = self::getValueAndComparisonFromArguments($arguments);978 $this->addCondition('And', $column, $value, $comparison);979 980 return $this;981 }982 983 /**984 966 * Finder Fluid Interface for Criteria::addOr() 985 967 * Infers $column, $value, $comparison from $columnName and some optional arguments 986 968 * Examples: 987 * $articleFinder-> _or('CommentId', 3)969 * $articleFinder->orWhere('CommentId', 3) 988 970 * => $c->addOr(ArticlePeer::COMMENT_ID, 3) 989 * $articleFinder-> _or('Title', 'like', '%foo')971 * $articleFinder->orWhere('Title', 'like', '%foo') 990 972 * => $c->addOr(ArticlePeer::TITLE, '%foo', Criteria::LIKE) 991 973 * … … 996 978 * @return sfPropelFinder the current finder object 997 979 */ 998 public function _or()980 public function orWhere() 999 981 { 1000 982 $arguments = func_get_args(); … … 1070 1052 /** 1071 1053 * We want that the Finder fuild Interface works like: 1072 * PHP : whereA()-> _andB->_orC()->_orD()->_andE()1054 * PHP : whereA()->whereB->orWhereC()->orWhereD()->whereE() 1073 1055 * SQL : where A=? AND (B=? OR (C=? OR (D=? AND E=?))) 1074 1056 * So we have to add condition starting by the last one! … … 1489 1471 return call_user_func_array(array($this, 'where'), $arguments); 1490 1472 } 1473 if(strpos($name, 'orWhere') === 0) 1474 { 1475 array_unshift($arguments, substr($name, 7)); 1476 return call_user_func_array(array($this, 'orWhere'), $arguments); 1477 } 1491 1478 if(strpos($name, 'orderBy') === 0) 1492 1479 { … … 1503 1490 array_unshift($arguments, substr($name, 4)); 1504 1491 return call_user_func_array(array($this, 'join'), $arguments); 1505 1506 1492 } 1507 1493 if(($pos = strpos($name, 'Join')) > 0) … … 1511 1497 return call_user_func_array(array($this, 'join'), $arguments); 1512 1498 } 1513 if(strpos($name, '_and') === 0)1514 {1515 array_unshift($arguments, substr($name, 4));1516 return call_user_func_array(array($this, '_and'), $arguments);1517 }1518 if(strpos($name, 'and') === 0)1519 {1520 array_unshift($arguments, substr($name, 3));1521 return call_user_func_array(array($this, '_and'), $arguments);1522 1523 }1524 if(strpos($name, '_or') === 0)1525 {1526 array_unshift($arguments, substr($name, 3));1527 return call_user_func_array(array($this, '_or'), $arguments);1528 1529 }1530 if(strpos($name, 'or') === 0)1531 {1532 array_unshift($arguments, substr($name, 2));1533 return call_user_func_array(array($this, '_or'), $arguments);1534 }1535 1499 if(strpos($name, 'findBy') === 0) 1536 1500 { plugins/sfPropelFinderPlugin/test/unit/sfDoctrineFinderTest.php
r10755 r10779 73 73 Doctrine_Query::create()->delete()->from('DArticle')->execute(); 74 74 75 $t = new lime_test( 77, new lime_output_color());75 $t = new lime_test(84, new lime_output_color()); 76 76 77 77 $t->diag('find()'); … … 476 476 $articles = sfDoctrineFinder::from('DArticle')->whereTitle('like', '%bc')->find(); 477 477 $t->is(count($articles), 2, 'whereXXX() accepts a comparator as first argument when two arguments are given'); 478 479 $t->diag('orWhere()'); 480 481 $columns = "d.id AS d__id, d.title AS d__title, d.category_id AS d__category_id"; 482 $baseSelect = "SELECT $columns FROM d_article d WHERE "; 483 484 $finder = sfDoctrineFinder::from('DArticle')-> 485 where('Title', 'foo')-> 486 orWhere('Title', 'bar'); 487 $finder->find(); 488 $t->is( 489 $finder->getLatestQuery(), 490 $baseSelect . "(d.title = 'foo' OR d.title = 'bar')", 491 'orWhere() adds a SQL OR clause when called on a column where there is already a condition' 492 ); 493 494 $finder = sfDoctrineFinder::from('DArticle')-> 495 where('Title', 'foo')-> 496 orWhere('CategoryId', 1); 497 $finder->find(); 498 $t->is( 499 $finder->getLatestQuery(), 500 $baseSelect . "(d.title = 'foo' OR d.category_id = '1')", 501 'orWhere() adds a SQL OR clause when called on a column where there is no condition yet' 502 ); 503 504 $finder = sfDoctrineFinder::from('DArticle')-> 505 where('Title', 'foo')-> 506 where('Title', 'bar'); 507 $finder->find(); 508 $t->is( 509 $finder->getLatestQuery(), 510 $baseSelect . "(d.title = 'foo' AND d.title = 'bar')", 511 'where() adds a SQL AND clause when called on a column where there is already a condition' 512 ); 513 514 $finder = sfDoctrineFinder::from('DArticle')-> 515 where('Title', 'foo')-> 516 where('CategoryId', 1); 517 $finder->find(); 518 $t->is( 519 $finder->getLatestQuery(), 520 $baseSelect . "(d.title = 'foo' AND d.category_id = '1')", 521 'where() adds a SQL AND clause when called on a column where there is no condition yet' 522 ); 523 524 $finder = sfDoctrineFinder::from('DArticle')-> 525 where('CategoryId', 1)-> 526 where('Title', 'foo')-> 527 orWhere('Title', 'bar'); 528 $finder->find(); 529 $t->is( 530 $finder->getLatestQuery(), 531 $baseSelect . "(d.category_id = '1' AND (d.title = 'foo' OR d.title = 'bar'))", 532 'where() and orWhere() can be combined on the same finder' 533 ); 534 535 /* 536 $finder = sfDoctrineFinder::from('DArticle')-> 537 joinCategory()-> 538 where('Category.Name', 'foo')-> 539 orWhere('Category.Name', 'bar'); 540 $finder->find(); 541 $t->is( 542 $finder->getLatestQuery(), 543 "SELECT $columns FROM article, category WHERE (category.NAME='foo' OR category.NAME='bar') AND article.CATEGORY_ID=category.ID", 544 'orWhere() works on a simple jointure' 545 ); 546 547 $finder = sfDoctrineFinder::from('DComment')-> 548 joinArticle()-> 549 joinAuthor()-> 550 where('Article.Title', 'foo')-> 551 orWhere('Author.Name', 'bar'); 552 $finder->find(); 553 $t->is( 554 $finder->getLatestQuery(), 555 "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", 556 'orWhere() works on a multiple jointure' 557 ); 558 */ 559 560 $t->skip('orWhere() works on a simple jointure'); 561 $t->skip('orWhere() works on a multiple jointure'); plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderTest.php
r10774 r10779 460 460 $t->is(count($articles), 2, 'whereXXX() accepts a comparator as first argument when two arguments are given'); 461 461 462 $t->diag(' _and() and _or()');462 $t->diag('orWhere()'); 463 463 464 464 $columns = "article.ID, article.TITLE, article.CATEGORY_ID"; … … 467 467 $finder = sfPropelFinder::from('Article')-> 468 468 where('Title', 'foo')-> 469 _or('Title', 'bar');469 orWhere('Title', 'bar'); 470 470 $finder->find(); 471 471 $t->is( 472 472 $finder->getLatestQuery(), 473 473 $baseSelect . "(article.TITLE='foo' OR article.TITLE='bar')", 474 ' _or() adds a SQL OR clause when called on a column where there is already a condition'474 'orWhere() adds a SQL OR clause when called on a column where there is already a condition' 475 475 ); 476 476 477 477 $finder = sfPropelFinder::from('Article')-> 478 478 where('Title', 'foo')-> 479 _or('CategoryId', 1);479 orWhere('CategoryId', 1); 480 480 $finder->find(); 481 481 $t->is( 482 482 $finder->getLatestQuery(), 483 483 $baseSelect . "(article.TITLE='foo' OR article.CATEGORY_ID=1)", 484 ' _or() adds a SQL OR clause when called on a column where there is no condition yet'484 'orWhere() adds a SQL OR clause when called on a column where there is no condition yet' 485 485 ); 486 486 487 487 $finder = sfPropelFinder::from('Article')-> 488 488 where('Title', 'foo')-> 489 _and('Title', 'bar');489 where('Title', 'bar'); 490 490 $finder->find(); 491 491 $t->is( 492 492 $finder->getLatestQuery(), 493 493 $baseSelect . "(article.TITLE='foo' AND article.TITLE='bar')", 494 ' _and() adds a SQL AND clause when called on a column where there is already a condition'494 'where() adds a SQL AND clause when called on a column where there is already a condition' 495 495 ); 496 496 497 497 $finder = sfPropelFinder::from('Article')-> 498 498 where('Title', 'foo')-> 499 _and('CategoryId', 1);499 where('CategoryId', 1); 500 500 $finder->find(); 501 501 $t->is( 502 502 $finder->getLatestQuery(), 503 503 $baseSelect . "(article.TITLE='foo' AND article.CATEGORY_ID=1)", 504 ' _and() adds a SQL AND clause when called on a column where there is no condition yet'504 'where() adds a SQL AND clause when called on a column where there is no condition yet' 505 505 ); 506 506 507 507 $finder = sfPropelFinder::from('Article')-> 508 508 where('CategoryId', 1)-> 509 _and('Title', 'foo')->510 _or('Title', 'bar');509 where('Title', 'foo')-> 510 orWhere('Title', 'bar'); 511 511 $finder->find(); 512 512 $t->is( 513 513 $finder->getLatestQuery(), 514 514 $baseSelect . "(article.CATEGORY_ID=1 AND (article.TITLE='foo' OR article.TITLE='bar'))", 515 ' _and() and _or() can be combined on the same finder'515 'where() and orWhere() can be combined on the same finder' 516 516 ); 517 517 … … 519 519 joinCategory()-> 520 520 where('Category.Name', 'foo')-> 521 _or('Category.Name', 'bar');521 orWhere('Category.Name', 'bar'); 522 522 $finder->find(); 523 523 $t->is( 524 524 $finder->getLatestQuery(), 525 525 "SELECT $columns FROM article, category WHERE (category.NAME='foo' OR category.NAME='bar') AND article.CATEGORY_ID=category.ID", 526 ' _or() works on a simple jointure'526 'orWhere() works on a simple jointure' 527 527 ); 528 528 … … 531 531 joinAuthor()-> 532 532 where('Article.Title', 'foo')-> 533 _or('Author.Name', 'bar');533 orWhere('Author.Name', 'bar'); 534 534 $finder->find(); 535 535 $t->is( 536 536 $finder->getLatestQuery(), 537 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", 538 ' _or() works on a multiple jointure'538 'orWhere() works on a multiple jointure' 539 539 ); 540 540