Changeset 10344
- Timestamp:
- 07/17/08 17:49:59 (5 years ago)
- Files:
-
- plugins/sfPropelFinderPlugin/README (modified) (1 diff)
- plugins/sfPropelFinderPlugin/lib/DbFinder.php (modified) (4 diffs)
- plugins/sfPropelFinderPlugin/lib/DbFinderUtils.php (added)
- plugins/sfPropelFinderPlugin/lib/sfDoctrineFinder.php (modified) (4 diffs)
- plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php (modified) (4 diffs)
- plugins/sfPropelFinderPlugin/lib/sfPropelFinderUtils.php (modified) (1 diff)
- plugins/sfPropelFinderPlugin/test/unit/DbFinderTest.php (added)
- plugins/sfPropelFinderPlugin/test/unit/sfDoctrineFinderTest.php (modified) (2 diffs)
- plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderTest.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/sfPropelFinderPlugin/README
r10342 r10344 603 603 === 2008-07-17 | Trunk === 604 604 605 * francois: Implemented `sfDoctrineFinder::findBy()`, `findOneBy()`, `findPk()`, and initialized `where()` 605 606 * francois: Added preliminary support for table aliases (`from('Article a')`) in Doctrine and Propel finders 606 607 * francois: Implemented `sfDoctrineFinder::findOne()`, `findFirst()`, `findLast()` and `orderBy()` plugins/sfPropelFinderPlugin/lib/DbFinder.php
r10342 r10344 49 49 public static function fromClass($class) 50 50 { 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) 53 61 { 54 62 $finder = new sfPropelFinder($class); 55 63 } 56 else if($ classinstanceof Doctrine_Record)64 else if($tmp instanceof Doctrine_Record) 57 65 { 58 66 $finder = new sfDoctrineFinder($class); … … 130 138 else 131 139 { 132 $pkName = $column->get FullyQualifiedName();140 $pkName = $column->getPhpName(); 133 141 } 134 142 } … … 152 160 } 153 161 } 154 155 162 156 163 return self::fromArray($pks, $class, $pkName); … … 168 175 { 169 176 $finder = self::fromClass($class); 170 $finder-> add($pkName, 'in', $array);177 $finder->where($pkName, ' in ', $array); 171 178 172 179 return $finder; plugins/sfPropelFinderPlugin/lib/sfDoctrineFinder.php
r10342 r10344 95 95 } 96 96 97 /**98 * Class initializer99 *100 * @param string $from Doctrine classname on which the search will be done101 * @return sfDoctrineFinder a finder object102 */103 public static function fromClass($class)104 {105 $me = __CLASS__;106 $finder = new $me($class);107 108 return $finder;109 }110 111 112 97 // Finder Executers 113 98 … … 163 148 public function findBy($columnName, $value, $limit = null, $con = null, $reinitCriteria = false) 164 149 { 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); 166 154 } 167 155 168 156 public function findOneBy($columnName, $value, $con = null, $reinitCriteria = false) 169 157 { 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); 171 162 } 172 163 173 164 public function findPk($pk, $con = null) 174 165 { 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 } 176 200 } 177 201 … … 239 263 240 264 /** 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')) 241 274 * 242 275 * @param string $columnName PHPName of the column bearing the condition … … 249 282 public function where() 250 283 { 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 } 254 312 } 255 313 plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php
r10342 r10344 133 133 134 134 return $this; 135 }136 137 // Finder Initializers138 139 /**140 * Mixed initializer141 * Accepts either a string (Propel class) or an array of Propel objects142 *143 * @param mixed $from The data to initialize the finder with144 * @return sfPropelFinder a finder object145 * @throws Exception If the data is neither a classname nor an array146 */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 initializer162 *163 * @param string $from Propel classname on which the search will be done164 * @return sfPropelFinder a finder object165 */166 public static function fromClass($class)167 {168 $me = __CLASS__;169 $finder = new $me($class);170 171 return $finder;172 }173 174 /**175 * Collection initializer176 *177 * @param array $from Array of Propel objects of the same class178 * @param string $class Optional classname of the desired objects179 * @param string $class Optional column name of the primary key180 *181 * @return sfPropelFinder a finder object182 * @throws Exception If the array is empty, contains not Propel objects or composite objects183 */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 else200 {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 else221 {222 $pkName = $column->getFullyQualifiedName();223 }224 }225 }226 227 return self::fromArray($pks, $class, $pkName);228 }229 230 /**231 * Array initializer232 *233 * @param array $array Array of Primary keys234 * @param string $class Propel classname on which the search will be done235 *236 * @return sfPropelFinder a finder object237 */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;244 135 } 245 136 … … 742 633 $namedCondition = null; 743 634 } 744 list($value, $comparison) = sfPropelFinderUtils::getValueAndComparisonFromArguments($arguments);635 list($value, $comparison) = DbFinderUtils::getValueAndComparisonFromArguments($arguments); 745 636 $this->addCondition('And', $column, $value, $comparison, $namedCondition); 746 637 … … 759 650 $columnName = array_shift($arguments); 760 651 $column = $this->getColName($columnName); 761 list($value, $comparison) = sfPropelFinderUtils::getValueAndComparisonFromArguments($arguments);652 list($value, $comparison) = DbFinderUtils::getValueAndComparisonFromArguments($arguments); 762 653 $this->addCondition('And', $column, $value, $comparison); 763 654 … … 785 676 $columnName = array_shift($arguments); 786 677 $column = $this->getColName($columnName); 787 list($value, $comparison) = sfPropelFinderUtils::getValueAndComparisonFromArguments($arguments);678 list($value, $comparison) = DbFinderUtils::getValueAndComparisonFromArguments($arguments); 788 679 $this->addCondition('Or', $column, $value, $comparison); 789 680 plugins/sfPropelFinderPlugin/lib/sfPropelFinderUtils.php
r10132 r10344 45 45 } 46 46 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 74 47 public static function getPeerClassFromClass($class) 75 48 { plugins/sfPropelFinderPlugin/test/unit/sfDoctrineFinderTest.php
r10341 r10344 64 64 Doctrine_Query::create()->delete()->from('DArticle')->execute(); 65 65 66 $t = new lime_test( 18, new lime_output_color());66 $t = new lime_test(36, new lime_output_color()); 67 67 68 68 $t->diag('find()'); … … 156 156 $t->isa_ok($article, 'DArticle', 'findLast() returns a single object'); 157 157 $t->is($article->getTitle(), 'foo2', 'findLast() returns the last object matching the conditions'); 158 159 $t->diag('findBy() and findOneBy()'); 160 161 Doctrine_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'); 177 foreach ($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'); 190 foreach ($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 203 Doctrine_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 233 Doctrine_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(); 243 try 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 } 248 catch(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 65 65 ArticlePeer::doDeleteAll(); 66 66 67 $t = new lime_test(11 5, new lime_output_color());67 $t = new lime_test(116, new lime_output_color()); 68 68 69 69 $t->diag('find()'); … … 156 156 $t->is($article->getTitle(), 'foo2', 'findLast() returns the last object matching the conditions'); 157 157 158 $t->diag('findBy() and findOneBy ');158 $t->diag('findBy() and findOneBy()'); 159 159 160 160 ArticlePeer::doDeleteAll(); … … 411 411 $articles = sfPropelFinder::from('Article')->where('Title', 'is not null', null)->find(); 412 412 $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'); 413 415 try 414 416 {