Development

Changeset 8370

You must first sign up to be able to contribute.

Changeset 8370

Show
Ignore:
Timestamp:
04/09/08 12:10:14 (2 years ago)
Author:
francois
Message:

sfPropelFinderPlugin Fixed _and() and _or() so that they give expected results, rather than the buggy results of Propel s addAnd() and addOr() (based on a patch from jug) (refs #3287)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/sfPropelFinderPlugin/README

    r8168 r8370  
    226226}}} 
    227227 
    228 If you're not sure about what query is issued by the finder, you can always check the SQL code after executing a termination method (`find()`, `findOne()`, `findPk()`, `count()`, `delete()`) by calling the `getLatestQuery()` method. 
     228If you're not sure about what query is issued by the finder, you can always check the SQL code before executing a termination method by calling `getCriteria()->toString()`, or after executing a termination method by calling the `getLatestQuery()` method. 
    229229 
    230230{{{ 
     
    232232<?php 
    233233$finder = sfPropelFinder::from('Article')->where('Title', 'foo'); 
     234echo $finder->getCriteria()->toString(); 
     235// SELECT FROM article WHERE article.TITLE=? 
    234236$finder->findOne(); 
    235 $query = $finder->getLatestQuery(); 
     237echo $finder->getLatestQuery(); 
    236238// 'SELECT article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID FROM article WHERE article.TITLE=\'foo\' LIMIT 1' 
    237239}}} 
     
    244246 
    245247== Changelog == 
     248 
     249=== 2008-04-08 | Trunk === 
     250 
     251 * francois: Added support for magic `andXXX()` and `orXXX()` methods. 
     252 * jug: Fixed `_and()` and `_or()` so that they give expected results, rather than the buggy results of Propel's `addAnd()` and `addOr()` 
    246253 
    247254=== 2008-03-31 | 0.2.0 Beta === 
  • plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php

    r8212 r8370  
    1717  protected $relations = null; 
    1818  protected $latestQuery = ''; 
    19    
     19  protected $criterions = array(); 
     20 
    2021  public function __construct($class = '') 
    2122  { 
     
    4748    $this->relations[]= $peerClass; 
    4849    $this->peerClass = $peerClass; 
     50     
    4951    return $this; 
    5052  } 
     
    5254  public function getCriteria() 
    5355  { 
    54     return $this->criteria
     56    return $this->buildCriteria()
    5557  } 
    5658   
     
    5860  { 
    5961    $this->criteria = $criteria; 
     62    $this->criterions = array(); 
     63     
    6064    return $this; 
    6165  } 
    6266 
    6367  public function reinitCriteria() 
    64   { 
    65     $this->criteria = new Criteria(); 
    66     return $this; 
     68  {  
     69    return $this->setCriteria(new Criteria()); 
    6770  } 
    6871   
     
    103106  public function count($con = null, $reinitCriteria = true) 
    104107  { 
    105     $ret = call_user_func(array($this->getPeerClass(), 'doCount'), $this->criteria, $con); 
     108    $ret = call_user_func(array($this->getPeerClass(), 'doCount'), $this->getCriteria(), $con); 
    106109    $this->updateLatestQuery(); 
    107110    if($reinitCriteria) 
     
    119122      $this->criteria->setLimit($limit); 
    120123    } 
    121     $ret = call_user_func(array($this->getPeerClass(), 'doSelect'), $this->criteria, $con); 
     124    $ret = call_user_func(array($this->getPeerClass(), 'doSelect'), $this->getCriteria(), $con); 
    122125    $this->updateLatestQuery(); 
    123126    if($reinitCriteria) 
     
    131134  public function findOne($con = null, $reinitCriteria = true) 
    132135  { 
    133     $ret = call_user_func(array($this->getPeerClass(), 'doSelectOne'), $this->criteria, $con); 
     136    $ret = call_user_func(array($this->getPeerClass(), 'doSelectOne'), $this->getCriteria(), $con); 
    134137    $this->updateLatestQuery(); 
    135138    if($reinitCriteria) 
     
    158161  public function delete($con = null, $reinitCriteria = true) 
    159162  { 
    160     $deleteCriteria = clone $this->criteria
     163    $deleteCriteria = $this->getCriteria()
    161164    if($deleteCriteria->equals(new Criteria())) 
    162165    { 
     
    214217    }  
    215218    list($value, $comparison) = $this->getValueAndComparisonFromArguments($arguments); 
    216     $this->criteria->add($column, $value, $comparison); 
     219 
     220    $this->addCondition('and', $column, $value, $comparison ); 
    217221     
    218222    return $this; 
     
    240244    }  
    241245    list($value, $comparison) = $this->getValueAndComparisonFromArguments($arguments); 
    242     $this->criteria->addAnd($column, $value, $comparison); 
     246 
     247    $this->addCondition('and', $column, $value, $comparison); 
    243248     
    244249    return $this; 
     
    266271    }  
    267272    list($value, $comparison) = $this->getValueAndComparisonFromArguments($arguments); 
    268     $this->criteria->addOr($column, $value, $comparison); 
    269      
    270     return $this; 
     273    $this->addCondition('or', $column, $value, $comparison); 
     274     
     275    return $this; 
     276  } 
     277 
     278  /** 
     279   * Conditions have to be stocked before being really used 
     280   * cf. sfPropelFinder::buildCriteria() 
     281   */ 
     282  protected function addCondition($cond, $column, $value, $comparison) 
     283  { 
     284    $criterion = $this->criteria->getNewCriterion($column, $value, $comparison); 
     285    $criterion->func = "add".$cond; 
     286    $this->criterions []= $criterion; 
     287  } 
     288 
     289  /** 
     290   * We want that the Finder fuild Interface works like: 
     291   *   PHP : whereA()->_andB->_orC()->_orD()->_andE() 
     292   *   SQL : where A=? AND (B=? OR (C=? OR (D=? AND E=?))) 
     293   * So we have to add condition starting by the last one! 
     294   */ 
     295  protected function buildCriteria() 
     296  { 
     297    $criteria = clone $this->criteria; 
     298    $criterions = $this->criterions; 
     299 
     300    while ($criterion = array_pop($criterions)) 
     301    { 
     302      if ($c = count($criterions)) 
     303      { 
     304        call_user_func(array($criterions[$c-1], $criterion->func), $criterion); 
     305      } 
     306      else 
     307      { 
     308        call_user_func(array($criteria, $criterion->func), $criterion); 
     309      } 
     310    } 
     311     
     312    return $criteria; 
    271313  } 
    272314   
     
    453495      return $this->_and(substr($name, 4), $arguments); 
    454496    } 
     497    if(strpos($name, 'and') === 0) 
     498    { 
     499      return $this->_and(substr($name, 3), $arguments); 
     500    } 
    455501    if(strpos($name, '_or') === 0) 
    456502    { 
    457503      return $this->_or(substr($name, 3), $arguments); 
     504    } 
     505    if(strpos($name, 'or') === 0) 
     506    { 
     507      return $this->_or(substr($name, 2), $arguments); 
    458508    } 
    459509    if(method_exists($this->criteria, $name)) 
  • plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderTest.php

    r8168 r8370  
    6363ArticlePeer::doDeleteAll(); 
    6464 
    65 $t = new lime_test(70, new lime_output_color()); 
     65$t = new lime_test(77, new lime_output_color()); 
    6666 
    6767$t->diag('find()'); 
     
    283283$t->is(count($articles), 2, 'whereXXX() accepts a comparator as first argument when two arguments are given'); 
    284284 
     285$t->diag('_and() and _or()'); 
     286 
     287$columns    = "article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID"; 
     288$baseSelect = "SELECT $columns FROM article WHERE "; 
     289 
     290$finder = sfPropelFinder::from('Article')->whereTitle('foo')->_orTitle('bar'); 
     291$finder->find(); 
     292$t->is( 
     293  $finder->getLatestQuery(), 
     294  $baseSelect . "(article.TITLE='foo' OR article.TITLE='bar')", 
     295  '_or() adds a SQL OR clause when called on a column where there is already a condition' 
     296); 
     297 
     298$finder = sfPropelFinder::from('Article')->whereTitle('foo')->_orCategoryId(1); 
     299$finder->find(); 
     300$t->is( 
     301  $finder->getLatestQuery(), 
     302  $baseSelect . "(article.TITLE='foo' OR article.CATEGORY_ID=1)", 
     303  '_or() adds a SQL OR clause when called on a column where there is no condition yet' 
     304); 
     305 
     306$finder = sfPropelFinder::from('Article')->whereTitle('foo')->_andTitle('bar'); 
     307$finder->find(); 
     308$t->is( 
     309  $finder->getLatestQuery(), 
     310  $baseSelect . "(article.TITLE='foo' AND article.TITLE='bar')", 
     311  '_and() adds a SQL AND clause when called on a column where there is already a condition' 
     312); 
     313 
     314$finder = sfPropelFinder::from('Article')->whereTitle('foo')->_andCategoryId(1); 
     315$finder->find(); 
     316$t->is( 
     317  $finder->getLatestQuery(), 
     318  $baseSelect . "(article.TITLE='foo' AND article.CATEGORY_ID=1)", 
     319  '_and() adds a SQL AND clause when called on a column where there is no condition yet' 
     320); 
     321 
     322$finder = sfPropelFinder::from('Article')->whereCategoryId(1)->_andTitle('foo')->_orTitle('bar'); 
     323$finder->find(); 
     324$t->is( 
     325  $finder->getLatestQuery(), 
     326  $baseSelect . "(article.CATEGORY_ID=1 AND (article.TITLE='foo' OR article.TITLE='bar'))", 
     327  '_and() and _or() can be combined on the same finder' 
     328); 
     329 
     330$finder = sfPropelFinder::from('Article')->joinCategory()->where('Category_Name', 'foo')->_or('Category_Name', 'bar'); 
     331$finder->find(); 
     332$t->is( 
     333  $finder->getLatestQuery(), 
     334  "SELECT $columns FROM article, category WHERE (category.NAME='foo' OR category.NAME='bar') AND article.CATEGORY_ID=category.ID", 
     335  '_or() works on a simple jointure' 
     336); 
     337 
     338$finder = sfPropelFinder::from('Comment') 
     339  ->joinArticle() 
     340  ->joinAuthor() 
     341  ->where('Article_Title', 'foo') 
     342  ->_or('Author_Name', 'bar'); 
     343$finder->find(); 
     344$t->is( 
     345  $finder->getLatestQuery(), 
     346  "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", 
     347  '_or() works on a multiple jointure' 
     348); 
    285349 
    286350$t->diag('orderBy()'); 

The Sensio Labs Network

Since 1998, Sensio Labs has been promoting the Open-Source software movement by providing quality web application development, training, consulting.
Sensio Labs also supports several large Open-Source projects.