Development

Changeset 10344

You must first sign up to be able to contribute.

Changeset 10344

Show
Ignore:
Timestamp:
07/17/08 17:49:59 (5 years ago)
Author:
francois
Message:

sfPropelFinderPlugin Implemented sfDoctrineFinder::findBy(), findOneBy(), findPk(), and initialized where()

Files:

Legend:

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

    r10342 r10344  
    603603=== 2008-07-17 | Trunk === 
    604604 
     605 * francois: Implemented `sfDoctrineFinder::findBy()`, `findOneBy()`, `findPk()`, and initialized `where()` 
    605606 * francois: Added preliminary support for table aliases (`from('Article a')`) in Doctrine and Propel finders 
    606607 * francois: Implemented `sfDoctrineFinder::findOne()`, `findFirst()`, `findLast()` and `orderBy()` 
  • plugins/sfPropelFinderPlugin/lib/DbFinder.php

    r10342 r10344  
    4949  public static function fromClass($class) 
    5050  { 
    51     $tmp = new $class; 
    52     if($class instanceof BaseObject) 
     51    if(strpos($class, ' ') !== false) 
     52    { 
     53      list($realClass, $alias) = explode(' ', $class); 
     54    } 
     55    else 
     56    { 
     57      $realClass = $class; 
     58    } 
     59    $tmp = new $realClass; 
     60    if($tmp instanceof BaseObject) 
    5361    { 
    5462      $finder = new sfPropelFinder($class); 
    5563    } 
    56     else if($class instanceof Doctrine_Record) 
     64    else if($tmp instanceof Doctrine_Record) 
    5765    { 
    5866      $finder = new sfDoctrineFinder($class); 
     
    130138          else 
    131139          { 
    132             $pkName = $column->getFullyQualifiedName(); 
     140            $pkName = $column->getPhpName(); 
    133141          } 
    134142        } 
     
    152160      } 
    153161    } 
    154  
    155162     
    156163    return self::fromArray($pks, $class, $pkName); 
     
    168175  { 
    169176    $finder = self::fromClass($class); 
    170     $finder->add($pkName, 'in', $array); 
     177    $finder->where($pkName, ' in ', $array); 
    171178     
    172179    return $finder; 
  • plugins/sfPropelFinderPlugin/lib/sfDoctrineFinder.php

    r10342 r10344  
    9595  } 
    9696   
    97   /** 
    98    * Class initializer 
    99    * 
    100    * @param string $from Doctrine classname on which the search will be done 
    101    * @return sfDoctrineFinder a finder object 
    102    */ 
    103   public static function fromClass($class) 
    104   { 
    105     $me = __CLASS__; 
    106     $finder = new $me($class); 
    107      
    108     return $finder; 
    109   } 
    110    
    111    
    11297  // Finder Executers 
    11398   
     
    163148  public function findBy($columnName, $value, $limit = null, $con = null, $reinitCriteria = false) 
    164149  { 
    165     throw new Exception('This method is not yet implemented'); 
     150    $column = $this->getColName($columnName); 
     151    $this->where($column, '=', $value); 
     152     
     153    return $this->find($limit, $con, $reinitCriteria); 
    166154  } 
    167155 
    168156  public function findOneBy($columnName, $value, $con = null, $reinitCriteria = false) 
    169157  { 
    170     throw new Exception('This method is not yet implemented'); 
     158    $column = $this->getColName($columnName); 
     159    $this->where($column, '=', $value); 
     160     
     161    return $this->findOne($con, $reinitCriteria); 
    171162  } 
    172163   
    173164  public function findPk($pk, $con = null) 
    174165  { 
    175     throw new Exception('This method is not yet implemented'); 
     166    $pkColumns = $this->getObject()->getTable()->getIdentifierColumnNames(); 
     167    if(($count = count($pkColumns)) > 1) 
     168    { 
     169      // composite primary key 
     170      if(!is_array($pk)) 
     171      { 
     172        throw new Exception(sprintf('Class %s has a composite primary key and expects %s parameters to retrieve a record by pk', $this->class, join(', ', $pkColumns))); 
     173      }  
     174      else if (is_array($count[0])) 
     175      { 
     176        // array of arrays 
     177        // sorry the finder can't do that on objects with composte primary keys 
     178        throw new Exception('Impossible to find a list of Pks on an objects with composite primary keys'); 
     179      } 
     180      for ($i=0; $i < $count; $i++) 
     181      {  
     182        $this->addCondition($pkColumns[$i], '=', $pk[$i]); 
     183      } 
     184      return $this->findOne(); 
     185    } 
     186    else 
     187    { 
     188      // simple primary kay 
     189      if(is_array($pk)) 
     190      { 
     191        $this->addCondition($pkColumns[0], 'in', $pk); 
     192        return $this->find(); 
     193      } 
     194      else 
     195      { 
     196        $this->addCondition($pkColumns[0], '=', $pk); 
     197        return $this->findOne(); 
     198      } 
     199    } 
    176200  } 
    177201   
     
    239263   
    240264  /** 
     265   * Finder Fluid Interface for Doctrine_Query::addWhere() 
     266   * Infers $column, $value, $comparison from $columnName and some optional arguments 
     267   * Examples: 
     268   *   $articleFinder->where('IsPublished') 
     269   *    => $query->addWhere('a.is_published = ?', array(true)) 
     270   *   $articleFinder->where('CommentId', 3) 
     271   *    => $query->addwhere('a.comment_id = ?', array(3)) 
     272   *   $articleFinder->where('Title', 'like', '%foo') 
     273   *    => $query->addWhere('a.title LIKE ?', array('%foo')) 
    241274   * 
    242275   * @param      string  $columnName PHPName of the column bearing the condition 
     
    249282  public function where() 
    250283  { 
    251     throw new Exception('This method is not yet implemented'); 
    252      
    253     return $this; 
     284    $arguments = func_get_args(); 
     285    $columnName = array_shift($arguments); 
     286    $column = $this->getColName($columnName); 
     287    if(isset($arguments[2])) 
     288    { 
     289      $namedCondition = $arguments[2]; 
     290      unset($arguments[2]); 
     291    } 
     292    else 
     293    { 
     294      $namedCondition = null; 
     295    } 
     296    list($value, $comparison) = DbFinderUtils::getValueAndComparisonFromArguments($arguments); 
     297    $this->addCondition($column, $comparison, $value); 
     298     
     299    return $this; 
     300  } 
     301   
     302  protected function addCondition($column, $comparison, $value) 
     303  { 
     304    if($comparison == 'in') 
     305    { 
     306      $this->query->whereIn($column, $value); 
     307    } 
     308    else 
     309    { 
     310      $this->query->addWhere(sprintf('%s %s ?', $column, $comparison), is_array($value) ? $value : array($value)); 
     311    } 
    254312  } 
    255313 
  • plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php

    r10342 r10344  
    133133     
    134134    return $this; 
    135   } 
    136    
    137   // Finder Initializers 
    138    
    139   /** 
    140    * Mixed initializer 
    141    * Accepts either a string (Propel class) or an array of Propel objects 
    142    * 
    143    * @param mixed $from The data to initialize the finder with 
    144    * @return sfPropelFinder a finder object 
    145    * @throws Exception If the data is neither a classname nor an array 
    146    */ 
    147   public static function from($from) 
    148   { 
    149     if (is_string($from)) 
    150     { 
    151       return self::fromClass($from); 
    152     } 
    153     if (is_array($from)) 
    154     { 
    155       return self::fromCollection($from); 
    156     } 
    157     throw new Exception('sfPropelFinder::from() only accepts a Propel object classname or an array of Propel objects'); 
    158   } 
    159  
    160   /** 
    161    * Class initializer 
    162    * 
    163    * @param string $from Propel classname on which the search will be done 
    164    * @return sfPropelFinder a finder object 
    165    */ 
    166   public static function fromClass($class) 
    167   { 
    168     $me = __CLASS__; 
    169     $finder = new $me($class); 
    170      
    171     return $finder; 
    172   } 
    173    
    174   /** 
    175    * Collection initializer 
    176    * 
    177    * @param array $from Array of Propel objects of the same class 
    178    * @param string $class Optional classname of the desired objects 
    179    * @param string $class Optional column name of the primary key 
    180    * 
    181    * @return sfPropelFinder a finder object 
    182    * @throws Exception If the array is empty, contains not Propel objects or composite objects 
    183    */ 
    184   public static function fromCollection($collection, $class = '', $pkName = '') 
    185   { 
    186     $pks = array(); 
    187     foreach($collection as $object) 
    188     { 
    189       if($class != get_class($object)) 
    190       { 
    191         if($class) 
    192         { 
    193           throw new Exception('A sfPropelFinder can only be initialized from an array of objects of a single class'); 
    194         } 
    195         if($object instanceof BaseObject) 
    196         { 
    197           $class = get_class($object); 
    198         } 
    199         else 
    200         { 
    201           throw new Exception('A sfPropelFinder can only be initialized from an array of Propel objects'); 
    202         } 
    203       } 
    204       $pks []= $object->getPrimaryKey(); 
    205     } 
    206     if(!$class) 
    207     { 
    208       throw new Exception('A sfPropelFinder cannot be initialized with an empty array'); 
    209     } 
    210      
    211     $tempObject = new $class(); 
    212     foreach ($tempObject->getPeer()->getTableMap()->getColumns() as $column) 
    213     { 
    214       if($column->isPrimaryKey()) 
    215       { 
    216         if($pkName) 
    217         { 
    218           throw new Exception('A sfPropelFinder cannot be initialized from an array of objects with several foreign keys'); 
    219         } 
    220         else 
    221         { 
    222           $pkName = $column->getFullyQualifiedName(); 
    223         } 
    224       } 
    225     } 
    226      
    227     return self::fromArray($pks, $class, $pkName); 
    228   } 
    229    
    230   /** 
    231    * Array initializer 
    232    * 
    233    * @param array $array Array of Primary keys 
    234    * @param string $class Propel classname on which the search will be done 
    235    * 
    236    * @return sfPropelFinder a finder object 
    237    */ 
    238   public static function fromArray($array, $class, $pkName) 
    239   { 
    240     $finder = self::fromClass($class); 
    241     $finder->add($pkName, $array, Criteria::IN); 
    242      
    243     return $finder; 
    244135  } 
    245136   
     
    742633      $namedCondition = null; 
    743634    } 
    744     list($value, $comparison) = sfPropelFinderUtils::getValueAndComparisonFromArguments($arguments); 
     635    list($value, $comparison) = DbFinderUtils::getValueAndComparisonFromArguments($arguments); 
    745636    $this->addCondition('And', $column, $value, $comparison, $namedCondition); 
    746637     
     
    759650    $columnName = array_shift($arguments); 
    760651    $column = $this->getColName($columnName); 
    761     list($value, $comparison) = sfPropelFinderUtils::getValueAndComparisonFromArguments($arguments); 
     652    list($value, $comparison) = DbFinderUtils::getValueAndComparisonFromArguments($arguments); 
    762653    $this->addCondition('And', $column, $value, $comparison); 
    763654     
     
    785676    $columnName = array_shift($arguments); 
    786677    $column = $this->getColName($columnName); 
    787     list($value, $comparison) = sfPropelFinderUtils::getValueAndComparisonFromArguments($arguments); 
     678    list($value, $comparison) = DbFinderUtils::getValueAndComparisonFromArguments($arguments); 
    788679    $this->addCondition('Or', $column, $value, $comparison); 
    789680     
  • plugins/sfPropelFinderPlugin/lib/sfPropelFinderUtils.php

    r10132 r10344  
    4545  } 
    4646   
    47   public static function getValueAndComparisonFromArguments($arguments = array()) 
    48   { 
    49     $comparison = Criteria::EQUAL; 
    50     switch (count($arguments)) 
    51     { 
    52       case 0: 
    53         $value = true; 
    54         break; 
    55       case 1: 
    56         $value = array_shift($arguments); 
    57         break; 
    58       case 2: 
    59         $comparison = array_shift($arguments); 
    60         $comparisonUp = trim(strtoupper($comparison)); 
    61         if(in_array($comparisonUp, array('LIKE', 'NOT LIKE', 'ILIKE', 'NOT ILIKE', 'IN', 'NOT IN', 'IS NULL', 'IS NOT NULL'))) 
    62         { 
    63           $comparison = ' '.$comparisonUp.' '; 
    64         } 
    65         $value = array_shift($arguments); 
    66         break; 
    67       default: 
    68         throw new Exception('sfPropelFinder::whereXXX() can only be called with one or two arguments'); 
    69     } 
    70  
    71     return array($value, $comparison); 
    72   } 
    73    
    7447  public static function getPeerClassFromClass($class) 
    7548  { 
  • plugins/sfPropelFinderPlugin/test/unit/sfDoctrineFinderTest.php

    r10341 r10344  
    6464Doctrine_Query::create()->delete()->from('DArticle')->execute(); 
    6565 
    66 $t = new lime_test(18, new lime_output_color()); 
     66$t = new lime_test(36, new lime_output_color()); 
    6767 
    6868$t->diag('find()'); 
     
    156156$t->isa_ok($article, 'DArticle', 'findLast() returns a single object'); 
    157157$t->is($article->getTitle(), 'foo2', 'findLast() returns the last object matching the conditions'); 
     158 
     159$t->diag('findBy() and findOneBy()'); 
     160 
     161Doctrine_Query::create()->delete()->from('DArticle')->execute(); 
     162 
     163$article1 = new DArticle(); 
     164$article1->setTitle('foo'); 
     165$article1->save(); 
     166 
     167$article2 = new DArticle(); 
     168$article2->setTitle('foo2'); 
     169$article2->save(); 
     170 
     171$article3 = new DArticle(); 
     172$article3->setTitle('foo'); 
     173$article3->save(); 
     174 
     175$articles = sfDoctrineFinder::from('DArticle')->findBy('Title', 'foo'); 
     176$t->is(count($articles), 2, 'findBy() adds a condition on a given column'); 
     177foreach ($articles as $article) 
     178{ 
     179  $t->is($article->getTitle(), 'foo', 'findBy() adds a condition on a given column'); 
     180} 
     181 
     182$articles = sfDoctrineFinder::from('DArticle')->findBy('Title', 'foo', 1); 
     183$t->is(count($articles), 1, 'findBy() accepts a limit parameter'); 
     184 
     185$article = sfDoctrineFinder::from('DArticle')->findOneBy('Title', 'foo2'); 
     186$t->is($article->getTitle(), 'foo2', 'findOneBy() adds a condition on a given column'); 
     187 
     188$articles = sfDoctrineFinder::from('DArticle')->findByTitle('foo'); 
     189$t->is(count($articles), 2, 'findByXXX() adds a condition on a given column'); 
     190foreach ($articles as $article) 
     191{ 
     192  $t->is($article->getTitle(), 'foo', 'findByXXX() adds a condition on a given column'); 
     193} 
     194 
     195$articles = sfDoctrineFinder::from('DArticle')->findByTitle('foo', 1); 
     196$t->is(count($articles), 1, 'findByXXX() accepts a limit parameter'); 
     197 
     198$article = sfDoctrineFinder::from('DArticle')->findOneByTitle('foo2'); 
     199$t->is($article->getTitle(), 'foo2', 'findOneByXXX() adds a condition on a given column'); 
     200 
     201$t->diag('findPk()'); 
     202 
     203Doctrine_Query::create()->delete()->from('DArticle')->execute(); 
     204 
     205$article1 = new DArticle(); 
     206$article1->setTitle('foo'); 
     207$article1->save(); 
     208 
     209$article2 = new DArticle(); 
     210$article2->setTitle('foo2'); 
     211$article2->save(); 
     212 
     213$article3 = new DArticle(); 
     214$article3->setTitle('foo3'); 
     215$article3->save(); 
     216 
     217$finder = new sfDoctrineFinder('DArticle'); 
     218$article = $finder->findPk($article2->getId()); 
     219$t->is($article->getTitle(), 'foo2', 'findPk() returns the object with the primary key matching the argument'); 
     220$t->ok(!is_array($article), 'findPk() returns a single object when passed a single primary key'); 
     221$finder = new sfDoctrineFinder('DArticle'); 
     222$article = $finder->findPk(76543787654); 
     223$t->is($article, null, 'findPk() returns null if the primary key is not found'); 
     224$finder = new sfDoctrineFinder('DArticle'); 
     225$articles = $finder->findPk(array($article2->getId(), $article1->getId())); 
     226$t->isa_ok($articles, 'Doctrine_Collection', 'findPk() returns a collection of objects when passed an array of primary keys'); 
     227$t->is(count($articles), 2, 'findPk() returns the objects with the primary keys matching the arguments'); 
     228 
     229$t->skip('findPk() is compatible with with()'); 
     230//$article = $finder->with('Category')->findPk($article2->getId()); 
     231//$t->cmp_ok(strpos($finder->getLatestQuery(), 'SELECT article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM article, category'), '===', 0, 'findPk() is compatible with with()'); 
     232 
     233Doctrine_Query::create()->delete()->from('DArticle')->execute(); 
     234 
     235$article1 = new DArticle(); 
     236$article1->setTitle('foo'); 
     237$article1->save(); 
     238$articlei18n1 = new DArticleI18n(); 
     239$articlei18n1->setCulture('fr'); 
     240$articlei18n1->setContent('Bar'); 
     241$articlei18n1->setId($article1->getId()); 
     242$articlei18n1->save(); 
     243try 
     244{ 
     245  $articleI18n = sfDoctrineFinder::from('DArticleI18n')->findPk($articlei18n1->getId()); 
     246  $t->fail('findPk() expects an array of values for objects with composite primary keys'); 
     247} 
     248catch(Exception $e) 
     249{ 
     250  $t->pass('findPk() expects an array of values for objects with composite primary keys'); 
     251} 
     252$articleI18n = sfDoctrineFinder::from('DArticleI18n')->findPk(array($articlei18n1->getId(), $articlei18n1->getCulture())); 
     253$t->is_deeply($articleI18n->toArray(), $articlei18n1->toArray(), 'findPk() retrieves objects with composite primary keys based on an array of Pks'); 
  • plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderTest.php

    r10342 r10344  
    6565ArticlePeer::doDeleteAll(); 
    6666 
    67 $t = new lime_test(115, new lime_output_color()); 
     67$t = new lime_test(116, new lime_output_color()); 
    6868 
    6969$t->diag('find()'); 
     
    156156$t->is($article->getTitle(), 'foo2', 'findLast() returns the last object matching the conditions'); 
    157157 
    158 $t->diag('findBy() and findOneBy'); 
     158$t->diag('findBy() and findOneBy()'); 
    159159 
    160160ArticlePeer::doDeleteAll(); 
     
    411411$articles = sfPropelFinder::from('Article')->where('Title', 'is not null', null)->find(); 
    412412$t->is(count($articles), 3, 'where() accepts a text comparator and is permissive on syntax'); 
     413$articles = sfPropelFinder::from('Article')->where('Title', ' in ', array('abc', 'def'))->find(); 
     414$t->is(count($articles), 2, 'where() accepts a "in" comparator'); 
    413415try 
    414416{