Development

Changeset 10780

You must first sign up to be able to contribute.

Changeset 10780

Show
Ignore:
Timestamp:
08/11/08 16:26:01 (3 months ago)
Author:
francois
Message:

sfPropelFinderPlugin Implemented sfDoctrine::combine()

Files:

Legend:

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

    r10779 r10780  
    533533### 2008-08-11 | Trunk 
    534534 
     535* francois: Implemented `sfDoctrine::combine()` 
    535536* francois: Implemented `sfDoctrineFinder::orWhere()` 
    536537* francois: [BC Break] Removed `_and()` (synonym for `where()`) and renamed `_or()` to `orWhere()` 
  • plugins/sfPropelFinderPlugin/lib/sfDoctrineFinder.php

    r10779 r10780  
    2121    $queryPattern  = '', 
    2222    $queryArgs     = array(), 
     23    $namedPatterns = array(), 
     24    $namedArgs     = array(), 
    2325    $argNumber     = 0, 
    2426    $queryListener = null, 
     
    440442      for ($i=0; $i < $count; $i++) 
    441443      {  
    442         $this->addCondition($pkColumns[$i], '=', $pk[$i]); 
     444        $this->addCondition('and', $pkColumns[$i], '=', $pk[$i]); 
    443445      } 
    444446      return $this->findOne(); 
     
    449451      if(is_array($pk)) 
    450452      { 
    451         $this->addCondition($pkColumns[0], ' IN ', $pk); 
     453        $this->addCondition('and', $pkColumns[0], ' IN ', $pk); 
    452454        return $this->find(); 
    453455      } 
    454456      else 
    455457      { 
    456         $this->addCondition($pkColumns[0], '=', $pk); 
     458        $this->addCondition('and', $pkColumns[0], '=', $pk); 
    457459        return $this->findOne(); 
    458460      } 
     
    684686    } 
    685687    list($value, $comparison) = self::getValueAndComparisonFromArguments($arguments); 
    686     $this->addCondition($column, $comparison, $value); 
    687      
    688     return $this; 
    689   } 
    690    
    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     } 
    697     if($comparison == ' IN ') 
    698     { 
    699       if($operator == 'or') 
    700       { 
    701         throw new Exception('sfDoctrineFinder cannot OR a condition with an IN'); 
    702       } 
    703       $this->query->whereIn($column, $value); 
    704     } 
    705     else 
    706     { 
    707       // The operator of the first condition is ignored 
    708       $operator = $this->queryPattern ? $operator : ''; 
    709       if(is_null($value)) 
    710       { 
    711         $this->queryPattern .= sprintf(' %s %s %s', $operator, $column, $comparison); 
    712       } 
    713       else 
    714       { 
    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     } 
     688    $this->addCondition('and', $column, $comparison, $value, $namedCondition); 
     689     
     690    return $this; 
    721691  } 
    722692 
     
    736706    $column = $this->getColName($columnName); 
    737707    list($value, $comparison) = self::getValueAndComparisonFromArguments($arguments); 
    738     $this->addCondition($column, $comparison, $value, 'or'); 
     708    $this->addCondition('or', $column, $comparison, $value); 
    739709     
    740710    return $this; 
    741711  } 
    742712 
     713  protected function addCondition($cond = 'and', $column, $comparison, $value, $namedCondition = null) 
     714  { 
     715    if($comparison == ' NOT IN ') 
     716    { 
     717      throw new Exception('sfDoctrineFinder cannot add a condition with a NOT IN'); 
     718    } 
     719    if($comparison == ' IN ') 
     720    { 
     721      if($cond == 'or') 
     722      { 
     723        throw new Exception('sfDoctrineFinder cannot OR a condition with an IN'); 
     724      } 
     725      $this->query->whereIn($column, $value); 
     726    } 
     727    else 
     728    { 
     729      if($namedCondition) 
     730      { 
     731        if(is_null($value)) 
     732        { 
     733          $this->namedPatterns[$namedCondition] = sprintf('%s %s', $column, $comparison); 
     734        } 
     735        else 
     736        { 
     737          $argName = ':param'.$this->argNumber; 
     738          $this->argNumber++; 
     739          $this->namedPatterns[$namedCondition] = sprintf('%s %s %s', $column, $comparison, $argName); 
     740          $this->namedArgs[$namedCondition][$argName] = $value; 
     741        } 
     742      } 
     743      else 
     744      { 
     745        // The operator of the first condition is ignored 
     746        $cond = $this->queryPattern ? $cond : ''; 
     747        if(is_null($value)) 
     748        { 
     749          $this->queryPattern .= sprintf(' %s %s %s', $cond, $column, $comparison); 
     750        } 
     751        else 
     752        { 
     753          $argName = ':param'.$this->argNumber; 
     754          $this->argNumber++; 
     755          $this->queryPattern .= sprintf(' %s %s %s %s', $cond, $column, $comparison, $argName); 
     756          $this->queryArgs[$argName] = $value; 
     757        } 
     758      } 
     759    } 
     760  } 
     761   
    743762  /** 
    744763   * Combine named conditions into the main query or into a new named condition 
     
    754773  public function combine($conditions, $operator = 'and', $namedCondition = null) 
    755774  { 
    756     throw new Exception('This method is not yet implemented'); 
     775    $addMethod = 'add'.ucfirst(strtolower(trim($operator))); 
     776    if(!is_array($conditions)) 
     777    { 
     778      $conditions = array($conditions); 
     779    } 
     780     
     781    $pattern = '('; 
     782    $args = array(); 
     783    $isFirst = true; 
     784    foreach($conditions as $condition) 
     785    { 
     786      if(!$isFirst) 
     787      { 
     788        $pattern .= ' ' . $operator . ' '; 
     789      } 
     790      $pattern .= $this->namedPatterns[$condition]; 
     791      $args = array_merge($args, $this->namedArgs[$condition]); 
     792      unset($this->namedPatterns[$condition]); 
     793      unset($this->namedArgs[$condition]); 
     794      $isFirst = false; 
     795    } 
     796    $pattern .= ')'; 
     797     
     798    if($namedCondition) 
     799    { 
     800      $this->namedPatterns[$namedCondition] = $pattern; 
     801      $this->namedArgs[$namedCondition] = $args; 
     802    } 
     803    else 
     804    { 
     805      $this->query->addWhere($pattern, $args); 
     806    } 
    757807     
    758808    return $this; 
  • plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php

    r10779 r10780  
    1313{ 
    1414  protected  
    15     $class        = null, 
    16     $peerClass    = null, 
    17     $object       = null, 
    18     $databaseMap  = null, 
    19     $connection   = null, 
    20     $criteria     = null, 
    21     $reinit       = true, 
    22     $latestQuery  = '', 
    23     $criterions   = array(), 
    24     $withClasses  = array(), 
    25     $withColumns  = array(), 
    26     $culture      = null; 
     15    $class           = null, 
     16    $peerClass       = null, 
     17    $object          = null, 
     18    $databaseMap     = null, 
     19    $connection      = null, 
     20    $criteria        = null, 
     21    $reinit          = true, 
     22    $latestQuery     = '', 
     23    $criterions      = array(), 
     24    $namedCriterions = array(), 
     25    $withClasses     = array(), 
     26    $withColumns     = array(), 
     27    $culture         = null; 
    2728   
    2829  public function getClass() 
     
    10221023  { 
    10231024    $addMethod = 'add'.ucfirst(strtolower(trim($operator))); 
    1024     if(!is_Array($conditions)) 
     1025    if(!is_array($conditions)) 
    10251026    { 
    10261027      $conditions = array($conditions); 
  • plugins/sfPropelFinderPlugin/test/unit/sfDoctrineFinderTest.php

    r10779 r10780  
    7373Doctrine_Query::create()->delete()->from('DArticle')->execute(); 
    7474 
    75 $t = new lime_test(84, new lime_output_color()); 
     75$t = new lime_test(92, new lime_output_color()); 
    7676 
    7777$t->diag('find()'); 
     
    560560$t->skip('orWhere() works on a simple jointure'); 
    561561$t->skip('orWhere() works on a multiple jointure'); 
     562 
     563$t->diag('combine()'); 
     564 
     565$columns    = "d.id AS d__id, d.title AS d__title, d.category_id AS d__category_id"; 
     566$baseSelect = "SELECT $columns FROM d_article d WHERE "; 
     567 
     568$finder = sfDoctrineFinder::from('DArticle')-> 
     569  where('Title', '=', 'foo', 'cond1')-> 
     570  where('Title', '=', 'bar'); 
     571$finder->find(); 
     572$t->is( 
     573  $finder->getLatestQuery(), 
     574  $baseSelect . "d.title = 'bar'", 
     575  'where() called with a named condition does not affect the SQL until it is combined' 
     576); 
     577 
     578$finder = sfDoctrineFinder::from('DArticle')-> 
     579  where('Title', '=', 'foo', 'cond1')-> 
     580  where('Title', '=', 'bar', 'cond2')-> 
     581  combine(array('cond1', 'cond2'), 'or'); 
     582$finder->find(); 
     583$t->is( 
     584  $finder->getLatestQuery(), 
     585  $baseSelect . "(d.title = 'foo' OR d.title = 'bar')", 
     586  'combine() combines conditions into the main query' 
     587); 
     588 
     589$finder = sfDoctrineFinder::from('DArticle')-> 
     590  where('Title', '=', 'foo', 'cond1')-> 
     591  where('Title', '=', 'bar', 'cond2')-> 
     592  combine(array('cond1', 'cond2'), 'and'); 
     593$finder->find(); 
     594$t->is( 
     595  $finder->getLatestQuery(), 
     596  $baseSelect . "(d.title = 'foo' AND d.title = 'bar')", 
     597  'combine() combines conditions into the main criteria' 
     598); 
     599 
     600$finder = sfDoctrineFinder::from('DArticle')-> 
     601  where('Title', '=', 'foo', 'cond1')-> 
     602  where('Title', '=', 'bar', 'cond2')-> 
     603  where('Title', '=', 'foobar')-> 
     604  combine(array('cond1', 'cond2'), 'or'); 
     605$finder->find(); 
     606$t->is( 
     607  $finder->getLatestQuery(), 
     608  $baseSelect . "(d.title = 'foo' OR d.title = 'bar') AND d.title = 'foobar'", 
     609  'combine() clauses live well with the usual conditions' 
     610); 
     611 
     612$finder = sfDoctrineFinder::from('DArticle')-> 
     613  where('Title', '=', 'foo', 'cond1')-> 
     614  where('Title', '=', 'bar', 'cond2')-> 
     615  combine(array('cond1', 'cond2'), 'or')-> 
     616  where('Title', '=', 'foobar'); 
     617$finder->find(); 
     618$t->is( 
     619  $finder->getLatestQuery(), 
     620  $baseSelect . "(d.title = 'foo' OR d.title = 'bar') AND d.title = 'foobar'", 
     621  'combine() clauses live well with the usual conditions and appear ordered as they were called' 
     622); 
     623 
     624$finder = sfDoctrineFinder::from('DArticle')-> 
     625  where('Title', '=', 'foo', 'cond1')-> 
     626  where('Title', '=', 'bar', 'cond2')-> 
     627  where('Title', '=', 'foobar', 'cond3')-> 
     628  combine(array('cond1', 'cond2'), 'or', 'cond4')-> 
     629  combine(array('cond4', 'cond3'), 'and'); 
     630$finder->find(); 
     631$t->is( 
     632  $finder->getLatestQuery(), 
     633  $baseSelect . "((d.title = 'foo' OR d.title = 'bar') AND d.title = 'foobar')", 
     634  'combine() can return a named condition' 
     635); 
     636 
     637$finder = sfDoctrineFinder::from('DArticle')-> 
     638  where('Title', '=', 'foo', 'cond1')-> 
     639  where('Title', '=', 'bar', 'cond2')-> 
     640  where('Title', '=', 'foobar', 'cond3')-> 
     641  where('Title', '=', 'boofar', 'cond4')-> 
     642  combine(array('cond1', 'cond2'), 'or', 'cond6')-> 
     643  combine(array('cond3', 'cond4'), 'or', 'cond7')-> 
     644  combine(array('cond6', 'cond7'), 'and'); 
     645$finder->find(); 
     646$t->is( 
     647  $finder->getLatestQuery(), 
     648  $baseSelect . "((d.title = 'foo' OR d.title = 'bar') AND (d.title = 'foobar' OR d.title = 'boofar'))", 
     649  'combine() allows for imbricated conditions' 
     650); 
     651 
     652$finder = sfDoctrineFinder::from('DArticle')-> 
     653  where('Title', '=', 'foo', 'cond1')-> 
     654  where('Title', '=', 'bar', 'cond2')-> 
     655  where('Title', '=', 'foobar', 'cond3')-> 
     656  combine(array('cond1', 'cond2', 'cond3'), 'or'); 
     657$finder->find(); 
     658$t->is( 
     659  $finder->getLatestQuery(), 
     660  $baseSelect . "(d.title = 'foo' OR d.title = 'bar' OR d.title = 'foobar')", 
     661  'combine() can combine more than two conditions' 
     662);