PageRenderTime 62ms CodeModel.GetById 14ms app.highlight 39ms RepoModel.GetById 1ms app.codeStats 0ms

/propelorm/test/testsuite/generator/builder/om/QueryBuilderTest.php

https://bitbucket.org/franhb/propel
PHP | 1095 lines | 879 code | 185 blank | 31 comment | 3 complexity | c4dc1a8b69dfc4b1f6e3f483c868152e MD5 | raw file
   1<?php
   2
   3/**
   4 * This file is part of the Propel package.
   5 * For the full copyright and license information, please view the LICENSE
   6 * file that was distributed with this source code.
   7 *
   8 * @license    MIT License
   9 */
  10
  11require_once dirname(__FILE__) . '/../../../../tools/helpers/bookstore/BookstoreTestBase.php';
  12require_once dirname(__FILE__) . '/../../../../tools/helpers/bookstore/BookstoreDataPopulator.php';
  13
  14/**
  15 * Test class for QueryBuilder.
  16 *
  17 * @author     Franรงois Zaninotto
  18 * @version    $Id: QueryBuilderTest.php 1347 2009-12-03 21:06:36Z francois $
  19 * @package    generator.builder.om
  20 */
  21class QueryBuilderTest extends BookstoreTestBase
  22{
  23
  24    public function testExtends()
  25    {
  26        $q = new BookQuery();
  27        $this->assertTrue($q instanceof ModelCriteria, 'Model query extends ModelCriteria');
  28    }
  29
  30    public function testConstructor()
  31    {
  32        $query = new BookQuery();
  33        $this->assertEquals($query->getDbName(), 'bookstore', 'Constructor sets dabatase name');
  34        $this->assertEquals($query->getModelName(), 'Book', 'Constructor sets model name');
  35    }
  36
  37    public function testCreate()
  38    {
  39        $query = BookQuery::create();
  40        $this->assertTrue($query instanceof BookQuery, 'create() returns an object of its class');
  41        $this->assertEquals($query->getDbName(), 'bookstore', 'create() sets dabatase name');
  42        $this->assertEquals($query->getModelName(), 'Book', 'create() sets model name');
  43        $query = BookQuery::create('foo');
  44        $this->assertTrue($query instanceof BookQuery, 'create() returns an object of its class');
  45        $this->assertEquals($query->getDbName(), 'bookstore', 'create() sets dabatase name');
  46        $this->assertEquals($query->getModelName(), 'Book', 'create() sets model name');
  47        $this->assertEquals($query->getModelAlias(), 'foo', 'create() can set the model alias');
  48    }
  49
  50    public function testCreateCustom()
  51    {
  52        // see the myBookQuery class definition at the end of this file
  53        $query = myCustomBookQuery::create();
  54        $this->assertTrue($query instanceof myCustomBookQuery, 'create() returns an object of its class');
  55        $this->assertTrue($query instanceof BookQuery, 'create() returns an object of its class');
  56        $this->assertEquals($query->getDbName(), 'bookstore', 'create() sets dabatase name');
  57        $this->assertEquals($query->getModelName(), 'Book', 'create() sets model name');
  58        $query = myCustomBookQuery::create('foo');
  59        $this->assertTrue($query instanceof myCustomBookQuery, 'create() returns an object of its class');
  60        $this->assertEquals($query->getDbName(), 'bookstore', 'create() sets dabatase name');
  61        $this->assertEquals($query->getModelName(), 'Book', 'create() sets model name');
  62        $this->assertEquals($query->getModelAlias(), 'foo', 'create() can set the model alias');
  63    }
  64
  65    public function testBasePreSelect()
  66    {
  67        $method = new ReflectionMethod('Table2Query', 'basePreSelect');
  68        $this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePreSelect() by default');
  69
  70        $method = new ReflectionMethod('Table3Query', 'basePreSelect');
  71        $this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePreSelect() when a behavior is registered');
  72    }
  73
  74    public function testBasePreDelete()
  75    {
  76        $method = new ReflectionMethod('Table2Query', 'basePreDelete');
  77        $this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePreDelete() by default');
  78
  79        $method = new ReflectionMethod('Table3Query', 'basePreDelete');
  80        $this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePreDelete() when a behavior is registered');
  81    }
  82
  83    public function testBasePostDelete()
  84    {
  85        $method = new ReflectionMethod('Table2Query', 'basePostDelete');
  86        $this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePostDelete() by default');
  87
  88        $method = new ReflectionMethod('Table3Query', 'basePostDelete');
  89        $this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePostDelete() when a behavior is registered');
  90    }
  91
  92    public function testBasePreUpdate()
  93    {
  94        $method = new ReflectionMethod('Table2Query', 'basePreUpdate');
  95        $this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePreUpdate() by default');
  96
  97        $method = new ReflectionMethod('Table3Query', 'basePreUpdate');
  98        $this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePreUpdate() when a behavior is registered');
  99    }
 100
 101    public function testBasePostUpdate()
 102    {
 103        $method = new ReflectionMethod('Table2Query', 'basePostUpdate');
 104        $this->assertEquals('ModelCriteria', $method->getDeclaringClass()->getName(), 'BaseQuery does not override basePostUpdate() by default');
 105
 106        $method = new ReflectionMethod('Table3Query', 'basePostUpdate');
 107        $this->assertEquals('BaseTable3Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides basePostUpdate() when a behavior is registered');
 108    }
 109
 110    public function testQuery()
 111    {
 112        BookstoreDataPopulator::depopulate();
 113        BookstoreDataPopulator::populate();
 114
 115        $q = new BookQuery();
 116        $book = $q
 117            ->setModelAlias('b')
 118            ->where('b.Title like ?', 'Don%')
 119            ->orderBy('b.ISBN', 'desc')
 120            ->findOne();
 121        $this->assertTrue($book instanceof Book);
 122        $this->assertEquals('Don Juan', $book->getTitle());
 123    }
 124
 125    public function testFindPk()
 126    {
 127        $method = new ReflectionMethod('Table4Query', 'findPk');
 128        $this->assertEquals('BaseTable4Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides findPk()');
 129    }
 130
 131    public function testFindPkReturnsCorrectObjectForSimplePrimaryKey()
 132    {
 133        $b = new Book();
 134        $b->setTitle('bar');
 135        $b->save($this->con);
 136        $count = $this->con->getQueryCount();
 137
 138        BookPeer::clearInstancePool();
 139
 140        $book = BookQuery::create()->findPk($b->getId(), $this->con);
 141        $this->assertEquals($b, $book);
 142        $this->assertEquals($count+1, $this->con->getQueryCount(), 'findPk() issues a database query when instance is not in pool');
 143    }
 144
 145    public function testFindPkUsesInstancePoolingForSimplePrimaryKey()
 146    {
 147        $b = new Book();
 148        $b->setTitle('foo');
 149        $b->save($this->con);
 150        $count = $this->con->getQueryCount();
 151
 152        $book = BookQuery::create()->findPk($b->getId(), $this->con);
 153        $this->assertSame($b, $book);
 154        $this->assertEquals($count, $this->con->getQueryCount(), 'findPk() does not issue a database query when instance is in pool');
 155    }
 156
 157    public function testFindPkReturnsCorrectObjectForCompositePrimaryKey()
 158    {
 159        BookstoreDataPopulator::depopulate();
 160        BookstoreDataPopulator::populate();
 161
 162        // save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
 163        $c = new ModelCriteria('bookstore', 'Book');
 164        $books = $c->find();
 165        foreach ($books as $book) {
 166            $book->save();
 167        }
 168
 169        BookPeer::clearInstancePool();
 170
 171        // retrieve the test data
 172        $c = new ModelCriteria('bookstore', 'BookListRel');
 173        $bookListRelTest = $c->findOne();
 174        $pk = $bookListRelTest->getPrimaryKey();
 175
 176        $q = new BookListRelQuery();
 177        $bookListRel = $q->findPk($pk);
 178        $this->assertEquals($bookListRelTest, $bookListRel, 'BaseQuery overrides findPk() for composite primary keysto make it faster');
 179    }
 180
 181    public function testFindPkUsesFindPkSimpleOnEmptyQueries()
 182    {
 183        BookQuery::create()->findPk(123, $this->con);
 184        $expected = 'SELECT ID, TITLE, ISBN, PRICE, PUBLISHER_ID, AUTHOR_ID FROM book WHERE ID = 123';
 185        $this->assertEquals($expected, $this->con->getLastExecutedQuery());
 186    }
 187
 188    public function testFindPkSimpleAddsObjectToInstancePool()
 189    {
 190        $b = new Book();
 191        $b->setTitle('foo');
 192        $b->save($this->con);
 193        BookPeer::clearInstancePool();
 194
 195        BookQuery::create()->findPk($b->getId(), $this->con);
 196        $count = $this->con->getQueryCount();
 197
 198        $book = BookQuery::create()->findPk($b->getId(), $this->con);
 199        $this->assertEquals($b, $book);
 200        $this->assertEquals($count, $this->con->getQueryCount());
 201    }
 202
 203    public function testFindPkUsesFindPkComplexOnNonEmptyQueries()
 204    {
 205        BookQuery::create('b')->findPk(123, $this->con);
 206        $expected = 'SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.ID=123';
 207        $this->assertEquals($expected, $this->con->getLastExecutedQuery());
 208    }
 209
 210    public function testFindPkComplexAddsObjectToInstancePool()
 211    {
 212        $b = new Book();
 213        $b->setTitle('foo');
 214        $b->save($this->con);
 215        BookPeer::clearInstancePool();
 216
 217        BookQuery::create('b')->findPk($b->getId(), $this->con);
 218        $count = $this->con->getQueryCount();
 219
 220        $book = BookQuery::create()->findPk($b->getId(), $this->con);
 221        $this->assertEquals($b, $book);
 222        $this->assertEquals($count, $this->con->getQueryCount());
 223    }
 224
 225    public function testFindPkCallsPreSelect()
 226    {
 227        $q = new mySecondBookQuery();
 228        $this->assertFalse($q::$preSelectWasCalled);
 229        $q->findPk(123);
 230        $this->assertTrue($q::$preSelectWasCalled);
 231    }
 232
 233    public function testFindPkDoesNotCallPreSelectWhenUsingInstancePool()
 234    {
 235        $b = new Book();
 236        $b->setTitle('foo');
 237        $b->save();
 238
 239        $q = new mySecondBookQuery();
 240        $this->assertFalse($q::$preSelectWasCalled);
 241        $q->findPk($b->getId());
 242        $this->assertFalse($q::$preSelectWasCalled);
 243    }
 244
 245    public function testFindPks()
 246    {
 247        $method = new ReflectionMethod('Table4Query', 'findPks');
 248        $this->assertEquals('BaseTable4Query', $method->getDeclaringClass()->getName(), 'BaseQuery overrides findPks()');
 249    }
 250
 251    public function testFindPksSimpleKey()
 252    {
 253        BookstoreDataPopulator::depopulate();
 254        BookstoreDataPopulator::populate();
 255
 256        BookPeer::clearInstancePool();
 257
 258        // prepare the test data
 259        $c = new ModelCriteria('bookstore', 'Book');
 260        $c->orderBy('Book.Id', 'desc');
 261        $testBooks = $c->find();
 262        $testBook1 = $testBooks->pop();
 263        $testBook2 = $testBooks->pop();
 264
 265        $q = new BookQuery();
 266        $books = $q->findPks(array($testBook1->getId(), $testBook2->getId()));
 267        $this->assertEquals(array($testBook1, $testBook2), $books->getData(), 'BaseQuery overrides findPks() to make it faster');
 268    }
 269
 270    public function testFindPksCompositeKey()
 271    {
 272        BookstoreDataPopulator::depopulate();
 273        BookstoreDataPopulator::populate();
 274
 275        // save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
 276        $c = new ModelCriteria('bookstore', 'Book');
 277        $books = $c->find();
 278        foreach ($books as $book) {
 279            $book->save();
 280        }
 281
 282        BookPeer::clearInstancePool();
 283
 284        // retrieve the test data
 285        $c = new ModelCriteria('bookstore', 'BookListRel');
 286        $bookListRelTest = $c->find();
 287        $search = array();
 288        foreach ($bookListRelTest as $obj) {
 289            $search[]= $obj->getPrimaryKey();
 290        }
 291
 292        $q = new BookListRelQuery();
 293        $objs = $q->findPks($search);
 294        $this->assertEquals($bookListRelTest, $objs, 'BaseQuery overrides findPks() for composite primary keys to make it work');
 295    }
 296
 297    public function testFilterBy()
 298    {
 299        foreach (BookPeer::getFieldNames(BasePeer::TYPE_PHPNAME) as $colName) {
 300            $filterMethod = 'filterBy' . $colName;
 301            $this->assertTrue(method_exists('BookQuery', $filterMethod), 'QueryBuilder adds filterByColumn() methods for every column');
 302            $q = BookQuery::create()->$filterMethod(1);
 303            $this->assertTrue($q instanceof BookQuery, 'filterByColumn() returns the current query instance');
 304        }
 305    }
 306
 307    public function testFilterByPrimaryKeySimpleKey()
 308    {
 309        $q = BookQuery::create()->filterByPrimaryKey(12);
 310        $q1 = BookQuery::create()->add(BookPeer::ID, 12, Criteria::EQUAL);
 311        $this->assertEquals($q1, $q, 'filterByPrimaryKey() translates to a Criteria::EQUAL in the PK column');
 312
 313        $q = BookQuery::create()->setModelAlias('b', true)->filterByPrimaryKey(12);
 314        $q1 = BookQuery::create()->setModelAlias('b', true)->add('b.ID', 12, Criteria::EQUAL);
 315        $this->assertEquals($q1, $q, 'filterByPrimaryKey() uses true table alias if set');
 316    }
 317
 318    public function testFilterByPrimaryKeyCompositeKey()
 319    {
 320        BookstoreDataPopulator::depopulate();
 321        BookstoreDataPopulator::populate();
 322
 323        // save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
 324        $c = new ModelCriteria('bookstore', 'Book');
 325        $books = $c->find();
 326        foreach ($books as $book) {
 327            $book->save();
 328        }
 329
 330        BookPeer::clearInstancePool();
 331
 332        // retrieve the test data
 333        $c = new ModelCriteria('bookstore', 'BookListRel');
 334        $bookListRelTest = $c->findOne();
 335        $pk = $bookListRelTest->getPrimaryKey();
 336
 337        $q = new BookListRelQuery();
 338        $q->filterByPrimaryKey($pk);
 339
 340        $q1 = BookListRelQuery::create()
 341            ->add(BookListRelPeer::BOOK_ID, $pk[0], Criteria::EQUAL)
 342            ->add(BookListRelPeer::BOOK_CLUB_LIST_ID, $pk[1], Criteria::EQUAL);
 343        $this->assertEquals($q1, $q, 'filterByPrimaryKey() translates to a Criteria::EQUAL in the PK columns');
 344    }
 345
 346    public function testFilterByPrimaryKeysSimpleKey()
 347    {
 348        $q = BookQuery::create()->filterByPrimaryKeys(array(10, 11, 12));
 349        $q1 = BookQuery::create()->add(BookPeer::ID, array(10, 11, 12), Criteria::IN);
 350        $this->assertEquals($q1, $q, 'filterByPrimaryKeys() translates to a Criteria::IN on the PK column');
 351
 352        $q = BookQuery::create()->setModelAlias('b', true)->filterByPrimaryKeys(array(10, 11, 12));
 353        $q1 = BookQuery::create()->setModelAlias('b', true)->add('b.ID', array(10, 11, 12), Criteria::IN);
 354        $this->assertEquals($q1, $q, 'filterByPrimaryKeys() uses true table alias if set');
 355    }
 356
 357    public function testFilterByPrimaryKeysCompositeKey()
 358    {
 359        BookstoreDataPopulator::depopulate();
 360        BookstoreDataPopulator::populate();
 361
 362        // save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
 363        $c = new ModelCriteria('bookstore', 'Book');
 364        $books = $c->find();
 365        foreach ($books as $book) {
 366            $book->save();
 367        }
 368
 369        BookPeer::clearInstancePool();
 370
 371        // retrieve the test data
 372        $c = new ModelCriteria('bookstore', 'BookListRel');
 373        $bookListRelTest = $c->find();
 374        $search = array();
 375        foreach ($bookListRelTest as $obj) {
 376            $search[]= $obj->getPrimaryKey();
 377        }
 378
 379        $q = new BookListRelQuery();
 380        $q->filterByPrimaryKeys($search);
 381
 382        $q1 = BookListRelQuery::create();
 383        foreach ($search as $key) {
 384            $cton0 = $q1->getNewCriterion(BookListRelPeer::BOOK_ID, $key[0], Criteria::EQUAL);
 385            $cton1 = $q1->getNewCriterion(BookListRelPeer::BOOK_CLUB_LIST_ID, $key[1], Criteria::EQUAL);
 386            $cton0->addAnd($cton1);
 387            $q1->addOr($cton0);
 388        }
 389        $this->assertEquals($q1, $q, 'filterByPrimaryKeys() translates to a series of Criteria::EQUAL in the PK columns');
 390
 391        $q = new BookListRelQuery();
 392        $q->filterByPrimaryKeys(array());
 393
 394        $q1 = BookListRelQuery::create();
 395        $q1->add(null, '1<>1', Criteria::CUSTOM);
 396        $this->assertEquals($q1, $q, 'filterByPrimaryKeys() translates to an always failing test on empty arrays');
 397
 398    }
 399
 400    public function testFilterByIntegerPk()
 401    {
 402        $q = BookQuery::create()->filterById(12);
 403        $q1 = BookQuery::create()->add(BookPeer::ID, 12, Criteria::EQUAL);
 404        $this->assertEquals($q1, $q, 'filterByPkColumn() translates to a Criteria::EQUAL by default');
 405
 406        $q = BookQuery::create()->filterById(12, Criteria::NOT_EQUAL);
 407        $q1 = BookQuery::create()->add(BookPeer::ID, 12, Criteria::NOT_EQUAL);
 408        $this->assertEquals($q1, $q, 'filterByPkColumn() accepts an optional comparison operator');
 409
 410        $q = BookQuery::create()->setModelAlias('b', true)->filterById(12);
 411        $q1 = BookQuery::create()->setModelAlias('b', true)->add('b.ID', 12, Criteria::EQUAL);
 412        $this->assertEquals($q1, $q, 'filterByPkColumn() uses true table alias if set');
 413
 414        $q = BookQuery::create()->filterById(array(10, 11, 12));
 415        $q1 = BookQuery::create()->add(BookPeer::ID, array(10, 11, 12), Criteria::IN);
 416        $this->assertEquals($q1, $q, 'filterByPkColumn() translates to a Criteria::IN when passed a simple array key');
 417
 418        $q = BookQuery::create()->filterById(array(10, 11, 12), Criteria::NOT_IN);
 419        $q1 = BookQuery::create()->add(BookPeer::ID, array(10, 11, 12), Criteria::NOT_IN);
 420        $this->assertEquals($q1, $q, 'filterByPkColumn() accepts a comparison when passed a simple array key');
 421    }
 422
 423    public function testFilterByNumber()
 424    {
 425        $q = BookQuery::create()->filterByPrice(12);
 426        $q1 = BookQuery::create()->add(BookPeer::PRICE, 12, Criteria::EQUAL);
 427        $this->assertEquals($q1, $q, 'filterByNumColumn() translates to a Criteria::EQUAL by default');
 428
 429        $q = BookQuery::create()->filterByPrice(12, Criteria::NOT_EQUAL);
 430        $q1 = BookQuery::create()->add(BookPeer::PRICE, 12, Criteria::NOT_EQUAL);
 431        $this->assertEquals($q1, $q, 'filterByNumColumn() accepts an optional comparison operator');
 432
 433        $q = BookQuery::create()->setModelAlias('b', true)->filterByPrice(12);
 434        $q1 = BookQuery::create()->setModelAlias('b', true)->add('b.PRICE', 12, Criteria::EQUAL);
 435        $this->assertEquals($q1, $q, 'filterByNumColumn() uses true table alias if set');
 436
 437        $q = BookQuery::create()->filterByPrice(array(10, 11, 12));
 438        $q1 = BookQuery::create()->add(BookPeer::PRICE, array(10, 11, 12), Criteria::IN);
 439        $this->assertEquals($q1, $q, 'filterByNumColumn() translates to a Criteria::IN when passed a simple array key');
 440
 441        $q = BookQuery::create()->filterByPrice(array(10, 11, 12), Criteria::NOT_IN);
 442        $q1 = BookQuery::create()->add(BookPeer::PRICE, array(10, 11, 12), Criteria::NOT_IN);
 443        $this->assertEquals($q1, $q, 'filterByNumColumn() accepts a comparison when passed a simple array key');
 444
 445        $q = BookQuery::create()->filterByPrice(array('min' => 10));
 446        $q1 = BookQuery::create()->add(BookPeer::PRICE, 10, Criteria::GREATER_EQUAL);
 447        $this->assertEquals($q1, $q, 'filterByNumColumn() translates to a Criteria::GREATER_EQUAL when passed a \'min\' key');
 448
 449        $q = BookQuery::create()->filterByPrice(array('max' => 12));
 450        $q1 = BookQuery::create()->add(BookPeer::PRICE, 12, Criteria::LESS_EQUAL);
 451        $this->assertEquals($q1, $q, 'filterByNumColumn() translates to a Criteria::LESS_EQUAL when passed a \'max\' key');
 452
 453        $q = BookQuery::create()->filterByPrice(array('min' => 10, 'max' => 12));
 454        $q1 = BookQuery::create()
 455            ->add(BookPeer::PRICE, 10, Criteria::GREATER_EQUAL)
 456            ->addAnd(BookPeer::PRICE, 12, Criteria::LESS_EQUAL);
 457        $this->assertEquals($q1, $q, 'filterByNumColumn() translates to a between when passed both a \'min\' and a \'max\' key');
 458    }
 459
 460    public function testFilterByTimestamp()
 461    {
 462        $q = BookstoreEmployeeAccountQuery::create()->filterByCreated(12);
 463        $q1 = BookstoreEmployeeAccountQuery::create()->add(BookstoreEmployeeAccountPeer::CREATED, 12, Criteria::EQUAL);
 464        $this->assertEquals($q1, $q, 'filterByDateColumn() translates to a Criteria::EQUAL by default');
 465
 466        $q = BookstoreEmployeeAccountQuery::create()->filterByCreated(12, Criteria::NOT_EQUAL);
 467        $q1 = BookstoreEmployeeAccountQuery::create()->add(BookstoreEmployeeAccountPeer::CREATED, 12, Criteria::NOT_EQUAL);
 468        $this->assertEquals($q1, $q, 'filterByDateColumn() accepts an optional comparison operator');
 469
 470        $q = BookstoreEmployeeAccountQuery::create()->setModelAlias('b', true)->filterByCreated(12);
 471        $q1 = BookstoreEmployeeAccountQuery::create()->setModelAlias('b', true)->add('b.CREATED', 12, Criteria::EQUAL);
 472        $this->assertEquals($q1, $q, 'filterByDateColumn() uses true table alias if set');
 473
 474        $q = BookstoreEmployeeAccountQuery::create()->filterByCreated(array('min' => 10));
 475        $q1 = BookstoreEmployeeAccountQuery::create()->add(BookstoreEmployeeAccountPeer::CREATED, 10, Criteria::GREATER_EQUAL);
 476        $this->assertEquals($q1, $q, 'filterByDateColumn() translates to a Criteria::GREATER_EQUAL when passed a \'min\' key');
 477
 478        $q = BookstoreEmployeeAccountQuery::create()->filterByCreated(array('max' => 12));
 479        $q1 = BookstoreEmployeeAccountQuery::create()->add(BookstoreEmployeeAccountPeer::CREATED, 12, Criteria::LESS_EQUAL);
 480        $this->assertEquals($q1, $q, 'filterByDateColumn() translates to a Criteria::LESS_EQUAL when passed a \'max\' key');
 481
 482        $q = BookstoreEmployeeAccountQuery::create()->filterByCreated(array('min' => 10, 'max' => 12));
 483        $q1 = BookstoreEmployeeAccountQuery::create()
 484            ->add(BookstoreEmployeeAccountPeer::CREATED, 10, Criteria::GREATER_EQUAL)
 485            ->addAnd(BookstoreEmployeeAccountPeer::CREATED, 12, Criteria::LESS_EQUAL);
 486        $this->assertEquals($q1, $q, 'filterByDateColumn() translates to a between when passed both a \'min\' and a \'max\' key');
 487    }
 488
 489    public function testFilterByString()
 490    {
 491        $q = BookQuery::create()->filterByTitle('foo');
 492        $q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo', Criteria::EQUAL);
 493        $this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::EQUAL by default');
 494
 495        $q = BookQuery::create()->filterByTitle('foo', Criteria::NOT_EQUAL);
 496        $q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo', Criteria::NOT_EQUAL);
 497        $this->assertEquals($q1, $q, 'filterByStringColumn() accepts an optional comparison operator');
 498
 499        $q = BookQuery::create()->setModelAlias('b', true)->filterByTitle('foo');
 500        $q1 = BookQuery::create()->setModelAlias('b', true)->add('b.TITLE', 'foo', Criteria::EQUAL);
 501        $this->assertEquals($q1, $q, 'filterByStringColumn() uses true table alias if set');
 502
 503        $q = BookQuery::create()->filterByTitle(array('foo', 'bar'));
 504        $q1 = BookQuery::create()->add(BookPeer::TITLE, array('foo', 'bar'), Criteria::IN);
 505        $this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::IN when passed an array');
 506
 507        $q = BookQuery::create()->filterByTitle(array('foo', 'bar'), Criteria::NOT_IN);
 508        $q1 = BookQuery::create()->add(BookPeer::TITLE, array('foo', 'bar'), Criteria::NOT_IN);
 509        $this->assertEquals($q1, $q, 'filterByStringColumn() accepts a comparison when passed an array');
 510
 511        $q = BookQuery::create()->filterByTitle('foo%');
 512        $q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo%', Criteria::LIKE);
 513        $this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::LIKE when passed a string with a % wildcard');
 514
 515        $q = BookQuery::create()->filterByTitle('foo%', Criteria::NOT_LIKE);
 516        $q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo%', Criteria::NOT_LIKE);
 517        $this->assertEquals($q1, $q, 'filterByStringColumn() accepts a comparison when passed a string with a % wildcard');
 518
 519        $q = BookQuery::create()->filterByTitle('foo%', Criteria::EQUAL);
 520        $q1 = BookQuery::create()->add(BookPeer::TITLE, 'foo%', Criteria::EQUAL);
 521        $this->assertEquals($q1, $q, 'filterByStringColumn() accepts a comparison when passed a string with a % wildcard');
 522
 523        $q = BookQuery::create()->filterByTitle('*foo');
 524        $q1 = BookQuery::create()->add(BookPeer::TITLE, '%foo', Criteria::LIKE);
 525        $this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::LIKE when passed a string with a * wildcard, and turns * into %');
 526
 527        $q = BookQuery::create()->filterByTitle('*f%o*o%');
 528        $q1 = BookQuery::create()->add(BookPeer::TITLE, '%f%o%o%', Criteria::LIKE);
 529        $this->assertEquals($q1, $q, 'filterByStringColumn() translates to a Criteria::LIKE when passed a string with mixed wildcards, and turns *s into %s');
 530    }
 531
 532    public function testFilterByBoolean()
 533    {
 534        $q = ReviewQuery::create()->filterByRecommended(true);
 535        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::EQUAL);
 536        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a Criteria::EQUAL by default');
 537
 538        $q = ReviewQuery::create()->filterByRecommended(true, Criteria::NOT_EQUAL);
 539        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::NOT_EQUAL);
 540        $this->assertEquals($q1, $q, 'filterByBooleanColumn() accepts an optional comparison operator');
 541
 542        $q = ReviewQuery::create()->filterByRecommended(false);
 543        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
 544        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a Criteria::EQUAL by default');
 545
 546        $q = ReviewQuery::create()->setModelAlias('b', true)->filterByRecommended(true);
 547        $q1 = ReviewQuery::create()->setModelAlias('b', true)->add('b.RECOMMENDED', true, Criteria::EQUAL);
 548        $this->assertEquals($q1, $q, 'filterByBooleanColumn() uses true table alias if set');
 549
 550        $q = ReviewQuery::create()->filterByRecommended('true');
 551        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::EQUAL);
 552        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = true when passed a true string');
 553
 554        $q = ReviewQuery::create()->filterByRecommended('yes');
 555        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::EQUAL);
 556        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = true when passed a true string');
 557
 558        $q = ReviewQuery::create()->filterByRecommended('1');
 559        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, true, Criteria::EQUAL);
 560        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = true when passed a true string');
 561
 562        $q = ReviewQuery::create()->filterByRecommended('false');
 563        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
 564        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = false when passed a false string');
 565
 566        $q = ReviewQuery::create()->filterByRecommended('no');
 567        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
 568        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = false when passed a false string');
 569
 570        $q = ReviewQuery::create()->filterByRecommended('0');
 571        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
 572        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = false when passed a false string');
 573
 574        $q = ReviewQuery::create()->filterByRecommended('');
 575        $q1 = ReviewQuery::create()->add(ReviewPeer::RECOMMENDED, false, Criteria::EQUAL);
 576        $this->assertEquals($q1, $q, 'filterByBooleanColumn() translates to a = false when passed an empty string');
 577
 578    }
 579
 580    public function testFilterByFk()
 581    {
 582        $this->assertTrue(method_exists('BookQuery', 'filterByAuthor'), 'QueryBuilder adds filterByFk() methods');
 583        $this->assertTrue(method_exists('BookQuery', 'filterByPublisher'), 'QueryBuilder adds filterByFk() methods for all fkeys');
 584
 585        $this->assertTrue(method_exists('EssayQuery', 'filterByAuthorRelatedByFirstAuthor'), 'QueryBuilder adds filterByFk() methods for several fkeys on the same table');
 586        $this->assertTrue(method_exists('EssayQuery', 'filterByAuthorRelatedBySecondAuthor'), 'QueryBuilder adds filterByFk() methods for several fkeys on the same table');
 587    }
 588
 589    public function testFilterByFkSimpleKey()
 590    {
 591        BookstoreDataPopulator::depopulate();
 592        BookstoreDataPopulator::populate();
 593
 594        // prepare the test data
 595        $testBook = BookQuery::create()
 596            ->innerJoin('Book.Author') // just in case there are books with no author
 597            ->findOne();
 598        $testAuthor = $testBook->getAuthor();
 599
 600        $book = BookQuery::create()
 601            ->filterByAuthor($testAuthor)
 602            ->findOne();
 603        $this->assertEquals($testBook, $book, 'Generated query handles filterByFk() methods correctly for simple fkeys');
 604
 605        $q = BookQuery::create()->filterByAuthor($testAuthor);
 606        $q1 = BookQuery::create()->add(BookPeer::AUTHOR_ID, $testAuthor->getId(), Criteria::EQUAL);
 607        $this->assertEquals($q1, $q, 'filterByFk() translates to a Criteria::EQUAL by default');
 608
 609        $q = BookQuery::create()->filterByAuthor($testAuthor, Criteria::NOT_EQUAL);
 610        $q1 = BookQuery::create()->add(BookPeer::AUTHOR_ID, $testAuthor->getId(), Criteria::NOT_EQUAL);
 611        $this->assertEquals($q1, $q, 'filterByFk() accepts an optional comparison operator');
 612    }
 613
 614    public function testFilterByFkCompositeKey()
 615    {
 616        BookstoreDataPopulator::depopulate();
 617        BookstoreDataPopulator::populate();
 618        BookstoreDataPopulator::populateOpinionFavorite();
 619
 620        // prepare the test data
 621        $testOpinion = BookOpinionQuery::create()
 622            ->innerJoin('BookOpinion.ReaderFavorite') // just in case there are books with no author
 623            ->findOne();
 624        $testFavorite = $testOpinion->getReaderFavorite();
 625
 626        $favorite = ReaderFavoriteQuery::create()
 627            ->filterByBookOpinion($testOpinion)
 628            ->findOne();
 629        $this->assertEquals($testFavorite, $favorite, 'Generated query handles filterByFk() methods correctly for composite fkeys');
 630    }
 631
 632    public function testFilterByFkObjectCollection()
 633    {
 634        BookstoreDataPopulator::depopulate($this->con);
 635        BookstoreDataPopulator::populate($this->con);
 636
 637        $authors = AuthorQuery::create()
 638            ->orderByFirstName()
 639            ->limit(2)
 640            ->find($this->con);
 641
 642        $books = BookQuery::create()
 643            ->filterByAuthor($authors)
 644            ->find($this->con);
 645        $q1 = $this->con->getLastExecutedQuery();
 646
 647        $books = BookQuery::create()
 648            ->add(BookPeer::AUTHOR_ID, $authors->getPrimaryKeys(), Criteria::IN)
 649            ->find($this->con);
 650        $q2 = $this->con->getLastExecutedQuery();
 651
 652        $this->assertEquals($q2, $q1, 'filterByFk() accepts a collection and results to an IN query');
 653    }
 654
 655    public function testFilterByRefFk()
 656    {
 657        $this->assertTrue(method_exists('BookQuery', 'filterByReview'), 'QueryBuilder adds filterByRefFk() methods');
 658        $this->assertTrue(method_exists('BookQuery', 'filterByMedia'), 'QueryBuilder adds filterByRefFk() methods for all fkeys');
 659
 660        $this->assertTrue(method_exists('AuthorQuery', 'filterByEssayRelatedByFirstAuthor'), 'QueryBuilder adds filterByRefFk() methods for several fkeys on the same table');
 661        $this->assertTrue(method_exists('AuthorQuery', 'filterByEssayRelatedBySecondAuthor'), 'QueryBuilder adds filterByRefFk() methods for several fkeys on the same table');
 662    }
 663
 664    public function testFilterByRefFkSimpleKey()
 665    {
 666        BookstoreDataPopulator::depopulate();
 667        BookstoreDataPopulator::populate();
 668
 669        // prepare the test data
 670        $testBook = BookQuery::create()
 671            ->innerJoin('Book.Author') // just in case there are books with no author
 672            ->findOne();
 673        $testAuthor = $testBook->getAuthor();
 674
 675        $author = AuthorQuery::create()
 676            ->filterByBook($testBook)
 677            ->findOne();
 678        $this->assertEquals($testAuthor, $author, 'Generated query handles filterByRefFk() methods correctly for simple fkeys');
 679
 680        $q = AuthorQuery::create()->filterByBook($testBook);
 681        $q1 = AuthorQuery::create()->add(AuthorPeer::ID, $testBook->getAuthorId(), Criteria::EQUAL);
 682        $this->assertEquals($q1, $q, 'filterByRefFk() translates to a Criteria::EQUAL by default');
 683
 684        $q = AuthorQuery::create()->filterByBook($testBook, Criteria::NOT_EQUAL);
 685        $q1 = AuthorQuery::create()->add(AuthorPeer::ID, $testBook->getAuthorId(), Criteria::NOT_EQUAL);
 686        $this->assertEquals($q1, $q, 'filterByRefFk() accepts an optional comparison operator');
 687    }
 688
 689    public function testFilterByRelationNameCompositePk()
 690    {
 691        BookstoreDataPopulator::depopulate();
 692        BookstoreDataPopulator::populate();
 693
 694        $testLabel = RecordLabelQuery::create()
 695            ->limit(2)
 696            ->find($this->con);
 697
 698        $testRelease = ReleasePoolQuery::create()
 699            ->addJoin(ReleasePoolPeer::RECORD_LABEL_ID, RecordLabelPeer::ID)
 700            ->filterByRecordLabel($testLabel)
 701            ->find($this->con);
 702        $q1 = $this->con->getLastExecutedQuery();
 703
 704        $releasePool = ReleasePoolQuery::create()
 705            ->addJoin(ReleasePoolPeer::RECORD_LABEL_ID, RecordLabelPeer::ID)
 706            ->add(ReleasePoolPeer::RECORD_LABEL_ID, $testLabel->toKeyValue('Id', 'Id'), Criteria::IN)
 707            ->find($this->con);
 708        $q2 = $this->con->getLastExecutedQuery();
 709
 710        $this->assertEquals($q2, $q1, 'filterBy{RelationName}() only accepts arguments of type {RelationName} or PropelCollection');
 711        $this->assertEquals($releasePool, $testRelease);
 712    }
 713
 714    public function testFilterByRefFkCompositeKey()
 715    {
 716        BookstoreDataPopulator::depopulate();
 717        BookstoreDataPopulator::populate();
 718        BookstoreDataPopulator::populateOpinionFavorite();
 719
 720        // prepare the test data
 721        $testOpinion = BookOpinionQuery::create()
 722            ->innerJoin('BookOpinion.ReaderFavorite') // just in case there are books with no author
 723            ->findOne();
 724        $testFavorite = $testOpinion->getReaderFavorite();
 725
 726        $opinion = BookOpinionQuery::create()
 727            ->filterByReaderFavorite($testFavorite)
 728            ->findOne();
 729        $this->assertEquals($testOpinion, $opinion, 'Generated query handles filterByRefFk() methods correctly for composite fkeys');
 730    }
 731
 732    public function testFilterByRefFkObjectCollection()
 733    {
 734        BookstoreDataPopulator::depopulate($this->con);
 735        BookstoreDataPopulator::populate($this->con);
 736
 737        $books = BookQuery::create()
 738            ->orderByTitle()
 739            ->limit(2)
 740            ->find($this->con);
 741
 742        $authors = AuthorQuery::create()
 743            ->filterByBook($books)
 744            ->find($this->con);
 745        $q1 = $this->con->getLastExecutedQuery();
 746
 747        $authors = AuthorQuery::create()
 748            ->addJoin(AuthorPeer::ID, BookPeer::AUTHOR_ID, Criteria::LEFT_JOIN)
 749            ->add(BookPeer::ID, $books->getPrimaryKeys(), Criteria::IN)
 750            ->find($this->con);
 751        $q2 = $this->con->getLastExecutedQuery();
 752
 753        $this->assertEquals($q2, $q1, 'filterByRefFk() accepts a collection and results to an IN query in the joined table');
 754    }
 755
 756    public function testFilterByCrossFK()
 757    {
 758        $this->assertTrue(method_exists('BookQuery', 'filterByBookClubList'), 'Generated query handles filterByCrossRefFK() for many-to-many relationships');
 759        $this->assertFalse(method_exists('BookQuery', 'filterByBook'), 'Generated query handles filterByCrossRefFK() for many-to-many relationships');
 760        BookstoreDataPopulator::depopulate();
 761        BookstoreDataPopulator::populate();
 762        $blc1 = BookClubListQuery::create()->findOneByGroupLeader('Crazyleggs');
 763        $nbBooks = BookQuery::create()
 764            ->filterByBookClubList($blc1)
 765            ->count();
 766        $this->assertEquals(2, $nbBooks, 'Generated query handles filterByCrossRefFK() methods correctly');
 767    }
 768
 769    public function testJoinFk()
 770    {
 771        $q = BookQuery::create()
 772            ->joinAuthor();
 773        $q1 = BookQuery::create()
 774            ->join('Book.Author', Criteria::LEFT_JOIN);
 775        $this->assertTrue($q->equals($q1), 'joinFk() translates to a left join on non-required columns');
 776
 777        $q = BookSummaryQuery::create()
 778            ->joinSummarizedBook();
 779        $q1 = BookSummaryQuery::create()
 780            ->join('BookSummary.SummarizedBook', Criteria::INNER_JOIN);
 781        $this->assertTrue($q->equals($q1), 'joinFk() translates to an inner join on required columns');
 782
 783        $q = BookQuery::create()
 784            ->joinAuthor('a');
 785        $q1 = BookQuery::create()
 786            ->join('Book.Author a', Criteria::LEFT_JOIN);
 787        $this->assertTrue($q->equals($q1), 'joinFk() accepts a relation alias as first parameter');
 788
 789        $q = BookQuery::create()
 790            ->joinAuthor('', Criteria::INNER_JOIN);
 791        $q1 = BookQuery::create()
 792            ->join('Book.Author', Criteria::INNER_JOIN);
 793        $this->assertTrue($q->equals($q1), 'joinFk() accepts a join type as second parameter');
 794
 795        $q = EssayQuery::create()
 796            ->joinAuthorRelatedBySecondAuthor();
 797        $q1 = EssayQuery::create()
 798            ->join('Essay.AuthorRelatedBySecondAuthor', "INNER JOIN");
 799        $this->assertTrue($q->equals($q1), 'joinFk() translates to a "INNER JOIN" when this is defined as defaultJoin in the schema');
 800    }
 801
 802    public function testJoinFkAlias()
 803    {
 804        $q = BookQuery::create('b')
 805            ->joinAuthor('a');
 806        $q1 = BookQuery::create('b')
 807            ->join('b.Author a', Criteria::LEFT_JOIN);
 808        $this->assertTrue($q->equals($q1), 'joinFk() works fine with table aliases');
 809
 810        $q = BookQuery::create()
 811            ->setModelAlias('b', true)
 812            ->joinAuthor('a');
 813        $q1 = BookQuery::create()
 814            ->setModelAlias('b', true)
 815            ->join('b.Author a', Criteria::LEFT_JOIN);
 816        $this->assertTrue($q->equals($q1), 'joinFk() works fine with true table aliases');
 817    }
 818
 819    public function testJoinRefFk()
 820    {
 821        $q = AuthorQuery::create()
 822            ->joinBook();
 823        $q1 = AuthorQuery::create()
 824            ->join('Author.Book', Criteria::LEFT_JOIN);
 825        $this->assertTrue($q->equals($q1), 'joinRefFk() translates to a left join on non-required columns');
 826
 827        $q = BookQuery::create()
 828            ->joinBookSummary();
 829        $q1 = BookQuery::create()
 830            ->join('Book.BookSummary', Criteria::INNER_JOIN);
 831        $this->assertTrue($q->equals($q1), 'joinRefFk() translates to an inner join on required columns');
 832
 833        $q = AuthorQuery::create()
 834            ->joinBook('b');
 835        $q1 = AuthorQuery::create()
 836            ->join('Author.Book b', Criteria::LEFT_JOIN);
 837        $this->assertTrue($q->equals($q1), 'joinRefFk() accepts a relation alias as first parameter');
 838
 839        $q = AuthorQuery::create()
 840            ->joinBook('', Criteria::INNER_JOIN);
 841        $q1 = AuthorQuery::create()
 842            ->join('Author.Book', Criteria::INNER_JOIN);
 843        $this->assertTrue($q->equals($q1), 'joinRefFk() accepts a join type as second parameter');
 844
 845        $q = AuthorQuery::create()
 846            ->joinEssayRelatedBySecondAuthor();
 847        $q1 = AuthorQuery::create()
 848            ->join('Author.EssayRelatedBySecondAuthor', Criteria::INNER_JOIN);
 849        $this->assertTrue($q->equals($q1), 'joinRefFk() translates to a "INNER JOIN" when this is defined as defaultJoin in the schema');
 850    }
 851
 852    public function testUseFkQuerySimple()
 853    {
 854        $q = BookQuery::create()
 855            ->useAuthorQuery()
 856                ->filterByFirstName('Leo')
 857            ->endUse();
 858        $q1 = BookQuery::create()
 859            ->join('Book.Author', Criteria::LEFT_JOIN)
 860            ->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL);
 861        $this->assertTrue($q->equals($q1), 'useFkQuery() translates to a condition on a left join on non-required columns');
 862
 863        $q = BookSummaryQuery::create()
 864            ->useSummarizedBookQuery()
 865                ->filterByTitle('War And Peace')
 866            ->endUse();
 867        $q1 = BookSummaryQuery::create()
 868            ->join('BookSummary.SummarizedBook', Criteria::INNER_JOIN)
 869            ->add(BookPeer::TITLE, 'War And Peace', Criteria::EQUAL);
 870        $this->assertTrue($q->equals($q1), 'useFkQuery() translates to a condition on an inner join on required columns');
 871    }
 872
 873    public function testUseFkQueryJoinType()
 874    {
 875        $q = BookQuery::create()
 876            ->useAuthorQuery(null, Criteria::LEFT_JOIN)
 877                ->filterByFirstName('Leo')
 878            ->endUse();
 879        $q1 = BookQuery::create()
 880            ->join('Book.Author', Criteria::LEFT_JOIN)
 881            ->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL);
 882        $this->assertTrue($q->equals($q1), 'useFkQuery() accepts a join type as second parameter');
 883    }
 884
 885    public function testUseFkQueryAlias()
 886    {
 887        $q = BookQuery::create()
 888            ->useAuthorQuery('a')
 889                ->filterByFirstName('Leo')
 890            ->endUse();
 891        $join = new ModelJoin();
 892        $join->setJoinType(Criteria::LEFT_JOIN);
 893        $join->setTableMap(AuthorPeer::getTableMap());
 894        $join->setRelationMap(BookPeer::getTableMap()->getRelation('Author'), null, 'a');
 895        $join->setRelationAlias('a');
 896        $q1 = BookQuery::create()
 897            ->addAlias('a', AuthorPeer::TABLE_NAME)
 898            ->addJoinObject($join, 'a')
 899            ->add('a.FIRST_NAME', 'Leo', Criteria::EQUAL);
 900        $this->assertTrue($q->equals($q1), 'useFkQuery() uses the first argument as a table alias');
 901    }
 902
 903    public function testUseFkQueryMixed()
 904    {
 905        $q = BookQuery::create()
 906            ->useAuthorQuery()
 907                ->filterByFirstName('Leo')
 908            ->endUse()
 909            ->filterByTitle('War And Peace');
 910        $q1 = BookQuery::create()
 911            ->join('Book.Author', Criteria::LEFT_JOIN)
 912            ->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL)
 913            ->add(BookPeer::TITLE, 'War And Peace', Criteria::EQUAL);
 914        $this->assertTrue($q->equals($q1), 'useFkQuery() allows combining conditions on main and related query');
 915    }
 916
 917    public function testUseFkQueryTwice()
 918    {
 919        $q = BookQuery::create()
 920            ->useAuthorQuery()
 921                ->filterByFirstName('Leo')
 922            ->endUse()
 923            ->useAuthorQuery()
 924                ->filterByLastName('Tolstoi')
 925            ->endUse();
 926        $q1 = BookQuery::create()
 927            ->join('Book.Author', Criteria::LEFT_JOIN)
 928            ->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL)
 929            ->add(AuthorPeer::LAST_NAME, 'Tolstoi', Criteria::EQUAL);
 930        $this->assertTrue($q->equals($q1), 'useFkQuery() called twice on the same relation does not create two joins');
 931    }
 932
 933    public function testUseFkQueryTwiceTwoAliases()
 934    {
 935        $q = BookQuery::create()
 936            ->useAuthorQuery('a')
 937                ->filterByFirstName('Leo')
 938            ->endUse()
 939            ->useAuthorQuery('b')
 940                ->filterByLastName('Tolstoi')
 941            ->endUse();
 942        $join1 = new ModelJoin();
 943        $join1->setJoinType(Criteria::LEFT_JOIN);
 944        $join1->setTableMap(AuthorPeer::getTableMap());
 945        $join1->setRelationMap(BookPeer::getTableMap()->getRelation('Author'), null, 'a');
 946        $join1->setRelationAlias('a');
 947        $join2 = new ModelJoin();
 948        $join2->setJoinType(Criteria::LEFT_JOIN);
 949        $join2->setTableMap(AuthorPeer::getTableMap());
 950        $join2->setRelationMap(BookPeer::getTableMap()->getRelation('Author'), null, 'b');
 951        $join2->setRelationAlias('b');
 952        $q1 = BookQuery::create()
 953            ->addAlias('a', AuthorPeer::TABLE_NAME)
 954            ->addJoinObject($join1, 'a')
 955            ->add('a.FIRST_NAME', 'Leo', Criteria::EQUAL)
 956            ->addAlias('b', AuthorPeer::TABLE_NAME)
 957            ->addJoinObject($join2, 'b')
 958            ->add('b.LAST_NAME', 'Tolstoi', Criteria::EQUAL);
 959        $this->assertTrue($q->equals($q1), 'useFkQuery() called twice on the same relation with two aliases creates two joins');
 960    }
 961
 962    public function testUseFkQueryNested()
 963    {
 964        $q = ReviewQuery::create()
 965            ->useBookQuery()
 966                ->useAuthorQuery()
 967                    ->filterByFirstName('Leo')
 968                ->endUse()
 969            ->endUse();
 970        $q1 = ReviewQuery::create()
 971            ->join('Review.Book', Criteria::LEFT_JOIN)
 972            ->join('Book.Author', Criteria::LEFT_JOIN)
 973            ->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL);
 974        // embedded queries create joins that keep a relation to the parent
 975        // as this is not testable, we need to use another testing technique
 976        $params = array();
 977        $result = BasePeer::createSelectSql($q, $params);
 978        $expectedParams = array();
 979        $expectedResult = BasePeer::createSelectSql($q1, $expectedParams);
 980        $this->assertEquals($expectedParams, $params, 'useFkQuery() called nested creates two joins');
 981        $this->assertEquals($expectedResult, $result, 'useFkQuery() called nested creates two joins');
 982    }
 983
 984    public function testUseFkQueryTwoRelations()
 985    {
 986        $q = BookQuery::create()
 987            ->useAuthorQuery()
 988                ->filterByFirstName('Leo')
 989            ->endUse()
 990            ->usePublisherQuery()
 991                ->filterByName('Penguin')
 992            ->endUse();
 993        $q1 = BookQuery::create()
 994            ->join('Book.Author', Criteria::LEFT_JOIN)
 995            ->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL)
 996            ->join('Book.Publisher', Criteria::LEFT_JOIN)
 997            ->add(PublisherPeer::NAME, 'Penguin', Criteria::EQUAL);
 998        $this->assertTrue($q->equals($q1), 'useFkQuery() called twice on two relations creates two joins');
 999    }
1000
1001    public function testUseFkQueryNoAliasThenWith()
1002    {
1003        $con = Propel::getConnection();
1004        $books = BookQuery::create()
1005            ->useAuthorQuery()
1006                ->filterByFirstName('Leo')
1007            ->endUse()
1008            ->with('Author')
1009            ->find($con);
1010        $q1 = $con->getLastExecutedQuery();
1011        $books = BookQuery::create()
1012            ->leftJoinWithAuthor()
1013            ->add(AuthorPeer::FIRST_NAME, 'Leo', Criteria::EQUAL)
1014            ->find($con);
1015        $q2 = $con->getLastExecutedQuery();
1016        $this->assertEquals($q1, $q2, 'with() can be used after a call to useFkQuery() with no alias');
1017    }
1018
1019    public function testPrune()
1020    {
1021        $q = BookQuery::create()->prune();
1022        $this->assertTrue($q instanceof BookQuery, 'prune() returns the current Query object');
1023    }
1024
1025    public function testPruneSimpleKey()
1026    {
1027        BookstoreDataPopulator::depopulate();
1028        BookstoreDataPopulator::populate();
1029
1030        $nbBooks = BookQuery::create()->prune()->count();
1031        $this->assertEquals(4, $nbBooks, 'prune() does nothing when passed a null object');
1032
1033        $testBook = BookQuery::create()->findOne();
1034        $nbBooks = BookQuery::create()->prune($testBook)->count();
1035        $this->assertEquals(3, $nbBooks, 'prune() removes an object from the result');
1036    }
1037
1038    public function testPruneCompositeKey()
1039    {
1040        BookstoreDataPopulator::depopulate();
1041        BookstoreDataPopulator::populate();
1042
1043        // save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
1044        $c = new ModelCriteria('bookstore', 'Book');
1045        $books = $c->find();
1046        foreach ($books as $book) {
1047            $book->save();
1048        }
1049
1050        BookPeer::clearInstancePool();
1051
1052        $nbBookListRel = BookListRelQuery::create()->prune()->count();
1053        $this->assertEquals(2, $nbBookListRel, 'prune() does nothing when passed a null object');
1054
1055        $testBookListRel = BookListRelQuery::create()->findOne();
1056        $nbBookListRel = BookListRelQuery::create()->prune($testBookListRel)->count();
1057        $this->assertEquals(1, $nbBookListRel, 'prune() removes an object from the result');
1058    }
1059}
1060
1061class myCustomBookQuery extends BookQuery
1062{
1063    public static function create($modelAlias = null, $criteria = null)
1064    {
1065        if ($criteria instanceof myCustomBookQuery) {
1066            return $criteria;
1067        }
1068        $query = new myCustomBookQuery();
1069        if (null !== $modelAlias) {
1070            $query->setModelAlias($modelAlias);
1071        }
1072        if ($criteria instanceof Criteria) {
1073            $query->mergeWith($criteria);
1074        }
1075
1076        return $query;
1077    }
1078
1079}
1080
1081class mySecondBookQuery extends BookQuery
1082{
1083    public static $preSelectWasCalled = false;
1084
1085    public function __construct($dbName = 'bookstore', $modelName = 'Book', $modelAlias = null)
1086    {
1087        self::$preSelectWasCalled = false;
1088        parent::__construct($dbName, $modelName, $modelAlias);
1089    }
1090
1091    public function preSelect(PropelPDO $con)
1092    {
1093        self::$preSelectWasCalled = true;
1094    }
1095}