sintonia/library/propel/test/testsuite/runtime/query/ModelCriteriaTest.php

2068 lines
83 KiB
PHP

<?php
/**
* This file is part of the Propel package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/
require_once 'tools/helpers/bookstore/BookstoreTestBase.php';
require_once 'tools/helpers/bookstore/BookstoreDataPopulator.php';
/**
* Test class for ModelCriteria.
*
* @author Francois Zaninotto
* @version $Id: ModelCriteriaTest.php 1796 2010-06-14 11:45:49Z francois $
* @package runtime.query
*/
class ModelCriteriaTest extends BookstoreTestBase
{
protected function assertCriteriaTranslation($criteria, $expectedSql, $expectedParams, $message = '')
{
$params = array();
$result = BasePeer::createSelectSql($criteria, $params);
$this->assertEquals($expectedSql, $result, $message);
$this->assertEquals($expectedParams, $params, $message);
}
public function testGetModelName()
{
$c = new ModelCriteria('bookstore', 'Book');
$this->assertEquals('Book', $c->getModelName(), 'getModelName() returns the name of the class associated to the model class');
}
public function testGetModelPeerName()
{
$c = new ModelCriteria('bookstore', 'Book');
$this->assertEquals('BookPeer', $c->getModelPeerName(), 'getModelPeerName() returns the name of the Peer class associated to the model class');
}
public function testFormatter()
{
$c = new ModelCriteria('bookstore', 'Book');
$this->assertTrue($c->getFormatter() instanceof PropelFormatter, 'getFormatter() returns a PropelFormatter instance');
$c = new ModelCriteria('bookstore', 'Book');
$c->setFormatter(ModelCriteria::FORMAT_STATEMENT);
$this->assertTrue($c->getFormatter() instanceof PropelStatementFormatter, 'setFormatter() accepts the name of a PropelFormatter class');
try {
$c->setFormatter('Book');
$this->fail('setFormatter() throws an exception when passed the name of a class not extending PropelFormatter');
} catch(PropelException $e) {
$this->assertTrue(true, 'setFormatter() throws an exception when passed the name of a class not extending PropelFormatter');
}
$c = new ModelCriteria('bookstore', 'Book');
$formatter = new PropelStatementFormatter();
$c->setFormatter($formatter);
$this->assertTrue($c->getFormatter() instanceof PropelStatementFormatter, 'setFormatter() accepts a PropelFormatter instance');
try {
$formatter = new Book();
$c->setFormatter($formatter);
$this->fail('setFormatter() throws an exception when passed an object not extending PropelFormatter');
} catch(PropelException $e) {
$this->assertTrue(true, 'setFormatter() throws an exception when passedan object not extending PropelFormatter');
}
}
public static function conditionsForTestReplaceNames()
{
return array(
array('Book.Title = ?', 'Title', 'book.TITLE = ?'), // basic case
array('Book.Title=?', 'Title', 'book.TITLE=?'), // without spaces
array('Book.Id<= ?', 'Id', 'book.ID<= ?'), // with non-equal comparator
array('Book.AuthorId LIKE ?', 'AuthorId', 'book.AUTHOR_ID LIKE ?'), // with SQL keyword separator
array('(Book.AuthorId) LIKE ?', 'AuthorId', '(book.AUTHOR_ID) LIKE ?'), // with parenthesis
array('(Book.Id*1.5)=1', 'Id', '(book.ID*1.5)=1'), // ignore numbers
array('1=1', null, '1=1'), // with no name
array('', null, '') // with empty string
);
}
/**
* @dataProvider conditionsForTestReplaceNames
*/
public function testReplaceNames($origClause, $columnPhpName = false, $modifiedClause)
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->replaceNames($origClause);
$columns = $c->replacedColumns;
if ($columnPhpName) {
$this->assertEquals(array(BookPeer::getTableMap()->getColumnByPhpName($columnPhpName)), $columns);
}
$this->assertEquals($modifiedClause, $origClause);
}
public static function conditionsForTestReplaceMultipleNames()
{
return array(
array('(Book.Id+Book.Id)=1', array('Id', 'Id'), '(book.ID+book.ID)=1'), // match multiple names
array('CONCAT(Book.Title,"Book.Id")= ?', array('Title', 'Id'), 'CONCAT(book.TITLE,"Book.Id")= ?'), // ignore names in strings
array('CONCAT(Book.Title," Book.Id ")= ?', array('Title', 'Id'), 'CONCAT(book.TITLE," Book.Id ")= ?'), // ignore names in strings
array('MATCH (Book.Title,Book.ISBN) AGAINST (?)', array('Title', 'ISBN'), 'MATCH (book.TITLE,book.ISBN) AGAINST (?)'),
);
}
/**
* @dataProvider conditionsForTestReplaceMultipleNames
*/
public function testReplaceMultipleNames($origClause, $expectedColumns, $modifiedClause)
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->replaceNames($origClause);
$foundColumns = $c->replacedColumns;
foreach ($foundColumns as $column) {
$expectedColumn = BookPeer::getTableMap()->getColumnByPhpName(array_shift($expectedColumns));
$this->assertEquals($expectedColumn, $column);
}
$this->assertEquals($modifiedClause, $origClause);
}
public function testTableAlias()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b');
$c->where('b.Title = ?', 'foo');
$sql = "SELECT FROM `book` WHERE book.TITLE = :p1";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'setModelAlias() allows the definition of the alias after constrution');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'foo');
$sql = "SELECT FROM `book` WHERE book.TITLE = :p1";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'A ModelCriteria accepts a model name with an alias');
}
public function testTrueTableAlias()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', true);
$c->where('b.Title = ?', 'foo');
$c->join('b.Author a');
$c->where('a.FirstName = ?', 'john');
$sql = "SELECT FROM `book` `b` INNER JOIN author a ON (b.AUTHOR_ID=a.ID) WHERE b.TITLE = :p1 AND a.FIRST_NAME = :p2";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
array('table' => 'author', 'column' => 'FIRST_NAME', 'value' => 'john'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'setModelAlias() allows the definition of a true SQL alias after constrution');
}
public function testCondition()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->condition('cond1', 'Book.Title <> ?', 'foo');
$c->condition('cond2', 'Book.Title like ?', '%bar%');
$c->combine(array('cond1', 'cond2'), 'or');
$sql = "SELECT FROM `book` WHERE (book.TITLE <> :p1 OR book.TITLE like :p2)";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
array('table' => 'book', 'column' => 'TITLE', 'value' => '%bar%'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'condition() can store condition for later combination');
}
public static function conditionsForTestWhere()
{
return array(
array('Book.Title = ?', 'foo', 'book.TITLE = :p1', array(array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'))),
array('Book.AuthorId = ?', 12, 'book.AUTHOR_ID = :p1', array(array('table' => 'book', 'column' => 'AUTHOR_ID', 'value' => 12))),
array('Book.AuthorId IS NULL', null, 'book.AUTHOR_ID IS NULL', array()),
array('Book.Id BETWEEN ? AND ?', array(3, 4), 'book.ID BETWEEN :p1 AND :p2', array(array('table' => 'book', 'column' => 'ID', 'value' => 3), array('table' => 'book', 'column' => 'ID', 'value' => 4))),
array('Book.Id betWEen ? and ?', array(3, 4), 'book.ID betWEen :p1 and :p2', array(array('table' => 'book', 'column' => 'ID', 'value' => 3), array('table' => 'book', 'column' => 'ID', 'value' => 4))),
array('Book.Id IN ?', array(1, 2, 3), 'book.ID IN (:p1,:p2,:p3)', array(array('table' => 'book', 'column' => 'ID', 'value' => 1), array('table' => 'book', 'column' => 'ID', 'value' => 2), array('table' => 'book', 'column' => 'ID', 'value' => 3))),
array('Book.Id in ?', array(1, 2, 3), 'book.ID in (:p1,:p2,:p3)', array(array('table' => 'book', 'column' => 'ID', 'value' => 1), array('table' => 'book', 'column' => 'ID', 'value' => 2), array('table' => 'book', 'column' => 'ID', 'value' => 3))),
array('Book.Id IN ?', array(), '1<>1', array()),
array('Book.Id not in ?', array(), '1=1', array()),
array('UPPER(Book.Title) = ?', 'foo', 'UPPER(book.TITLE) = :p1', array(array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'))),
array('MATCH (Book.Title,Book.ISBN) AGAINST (?)', 'foo', 'MATCH (book.TITLE,book.ISBN) AGAINST (:p1)', array(array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'))),
);
}
/**
* @dataProvider conditionsForTestWhere
*/
public function testWhere($clause, $value, $sql, $params)
{
$c = new ModelCriteria('bookstore', 'Book');
$c->where($clause, $value);
$sql = 'SELECT FROM `book` WHERE ' . $sql;
$this->assertCriteriaTranslation($c, $sql, $params, 'where() accepts a string clause');
}
public function testWhereTwiceSameColumn()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->where('Book.Id IN ?', array(1, 2, 3));
$c->where('Book.Id <> ?', 5);
$params = array(
array('table' => 'book', 'column' => 'ID', 'value' => '1'),
array('table' => 'book', 'column' => 'ID', 'value' => '2'),
array('table' => 'book', 'column' => 'ID', 'value' => '3'),
array('table' => 'book', 'column' => 'ID', 'value' => '5'),
);
$sql = 'SELECT FROM `book` WHERE (book.ID IN (:p1,:p2,:p3) AND book.ID <> :p4)';
$this->assertCriteriaTranslation($c, $sql, $params, 'where() adds clauses on the same column correctly');
}
public function testWhereConditions()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->condition('cond1', 'Book.Title <> ?', 'foo');
$c->condition('cond2', 'Book.Title like ?', '%bar%');
$c->where(array('cond1', 'cond2'));
$sql = "SELECT FROM `book` WHERE (book.TITLE <> :p1 AND book.TITLE like :p2)";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
array('table' => 'book', 'column' => 'TITLE', 'value' => '%bar%'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'where() accepts an array of named conditions');
$c = new ModelCriteria('bookstore', 'Book');
$c->condition('cond1', 'Book.Title <> ?', 'foo');
$c->condition('cond2', 'Book.Title like ?', '%bar%');
$c->where(array('cond1', 'cond2'), Criteria::LOGICAL_OR);
$sql = "SELECT FROM `book` WHERE (book.TITLE <> :p1 OR book.TITLE like :p2)";
$this->assertCriteriaTranslation($c, $sql, $params, 'where() accepts an array of named conditions with operator');
}
public function testWhereNoReplacement()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'foo');
$c->where('1=1');
$sql = "SELECT FROM `book` WHERE book.TITLE = :p1 AND 1=1";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'where() results in a Criteria::CUSTOM if no column name is matched');
$c = new ModelCriteria('bookstore', 'Book');
try {
$c->where('b.Title = ?', 'foo');
$this->fail('where() throws an exception when it finds a ? but cannot determine a column');
} catch (PropelException $e) {
$this->assertTrue(true, 'where() throws an exception when it finds a ? but cannot determine a column');
}
}
public function testWhereFunction()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('UPPER(b.Title) = ?', 'foo');
$sql = "SELECT FROM `book` WHERE UPPER(book.TITLE) = :p1";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'where() accepts a complex calculation');
}
public function testOrWhere()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->where('Book.Title <> ?', 'foo');
$c->orWhere('Book.Title like ?', '%bar%');
$sql = "SELECT FROM `book` WHERE (book.TITLE <> :p1 OR book.TITLE like :p2)";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
array('table' => 'book', 'column' => 'TITLE', 'value' => '%bar%'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'orWhere() combines the clause with the previous one using OR');
}
public function testOrWhereConditions()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->where('Book.Id = ?', 12);
$c->condition('cond1', 'Book.Title <> ?', 'foo');
$c->condition('cond2', 'Book.Title like ?', '%bar%');
$c->orWhere(array('cond1', 'cond2'));
$sql = "SELECT FROM `book` WHERE (book.ID = :p1 OR (book.TITLE <> :p2 AND book.TITLE like :p3))";
$params = array(
array('table' => 'book', 'column' => 'ID', 'value' => 12),
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
array('table' => 'book', 'column' => 'TITLE', 'value' => '%bar%'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'orWhere() accepts an array of named conditions');
$c = new ModelCriteria('bookstore', 'Book');
$c->where('Book.Id = ?', 12);
$c->condition('cond1', 'Book.Title <> ?', 'foo');
$c->condition('cond2', 'Book.Title like ?', '%bar%');
$c->orWhere(array('cond1', 'cond2'), Criteria::LOGICAL_OR);
$sql = "SELECT FROM `book` WHERE (book.ID = :p1 OR (book.TITLE <> :p2 OR book.TITLE like :p3))";
$this->assertCriteriaTranslation($c, $sql, $params, 'orWhere() accepts an array of named conditions with operator');
}
public function testMixedCriteria()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->where('Book.Title = ?', 'foo');
$c->add(BookPeer::ID, array(1, 2), Criteria::IN);
$sql = 'SELECT FROM `book` WHERE book.TITLE = :p1 AND book.ID IN (:p2,:p3)';
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
array('table' => 'book', 'column' => 'ID', 'value' => 1),
array('table' => 'book', 'column' => 'ID', 'value' => 2)
);
$this->assertCriteriaTranslation($c, $sql, $params, 'ModelCriteria accepts Criteria operators');
}
public function testFilterBy()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->filterBy('Title', 'foo');
$sql = 'SELECT FROM `book` WHERE book.TITLE=:p1';
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'filterBy() accepts a simple column name');
$c = new ModelCriteria('bookstore', 'Book');
$c->filterBy('Title', 'foo', Criteria::NOT_EQUAL);
$sql = 'SELECT FROM `book` WHERE book.TITLE<>:p1';
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'filterBy() accepts a sicustom comparator');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->filterBy('Title', 'foo');
$sql = 'SELECT FROM `book` WHERE book.TITLE=:p1';
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'filterBy() accepts a simple column name, even if initialized with an alias');
}
public function testHaving()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->having('Book.Title <> ?', 'foo');
$sql = "SELECT FROM HAVING book.TITLE <> :p1";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'having() accepts a string clause');
}
public function testHavingConditions()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->condition('cond1', 'Book.Title <> ?', 'foo');
$c->condition('cond2', 'Book.Title like ?', '%bar%');
$c->having(array('cond1', 'cond2'));
$sql = "SELECT FROM HAVING (book.TITLE <> :p1 AND book.TITLE like :p2)";
$params = array(
array('table' => 'book', 'column' => 'TITLE', 'value' => 'foo'),
array('table' => 'book', 'column' => 'TITLE', 'value' => '%bar%'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'having() accepts an array of named conditions');
$c = new ModelCriteria('bookstore', 'Book');
$c->condition('cond1', 'Book.Title <> ?', 'foo');
$c->condition('cond2', 'Book.Title like ?', '%bar%');
$c->having(array('cond1', 'cond2'), Criteria::LOGICAL_OR);
$sql = "SELECT FROM HAVING (book.TITLE <> :p1 OR book.TITLE like :p2)";
$this->assertCriteriaTranslation($c, $sql, $params, 'having() accepts an array of named conditions with an operator');
}
public function testOrderBy()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->orderBy('Book.Title');
$sql = 'SELECT FROM ORDER BY book.TITLE ASC';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'orderBy() accepts a column name and adds an ORDER BY clause');
$c = new ModelCriteria('bookstore', 'Book');
$c->orderBy('Book.Title', 'desc');
$sql = 'SELECT FROM ORDER BY book.TITLE DESC';
$this->assertCriteriaTranslation($c, $sql, $params, 'orderBy() accepts an order parameter');
$c = new ModelCriteria('bookstore', 'Book');
try {
$c->orderBy('Book.Foo');
$this->fail('orderBy() throws an exception when called with an unkown column name');
} catch (PropelException $e) {
$this->assertTrue(true, 'orderBy() throws an exception when called with an unkown column name');
}
$c = new ModelCriteria('bookstore', 'Book');
try {
$c->orderBy('Book.Title', 'foo');
$this->fail('orderBy() throws an exception when called with an unkown order');
} catch (PropelException $e) {
$this->assertTrue(true, 'orderBy() throws an exception when called with an unkown order');
}
}
public function testOrderBySimpleColumn()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->orderBy('Title');
$sql = 'SELECT FROM ORDER BY book.TITLE ASC';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'orderBy() accepts a simple column name and adds an ORDER BY clause');
}
public function testOrderByAlias()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->addAsColumn('t', BookPeer::TITLE);
$c->orderBy('t');
$sql = 'SELECT book.TITLE AS t FROM ORDER BY t ASC';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'orderBy() accepts a column alias and adds an ORDER BY clause');
}
public function testGroupBy()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->groupBy('Book.AuthorId');
$sql = 'SELECT FROM GROUP BY book.AUTHOR_ID';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'groupBy() accepts a column name and adds a GROUP BY clause');
$c = new ModelCriteria('bookstore', 'Book');
try {
$c->groupBy('Book.Foo');
$this->fail('groupBy() throws an exception when called with an unkown column name');
} catch (PropelException $e) {
$this->assertTrue(true, 'groupBy() throws an exception when called with an unkown column name');
}
}
public function testGroupBySimpleColumn()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->groupBy('AuthorId');
$sql = 'SELECT FROM GROUP BY book.AUTHOR_ID';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'groupBy() accepts a simple column name and adds a GROUP BY clause');
}
public function testGroupByAlias()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->addAsColumn('t', BookPeer::TITLE);
$c->groupBy('t');
$sql = 'SELECT book.TITLE AS t FROM GROUP BY t';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'groupBy() accepts a column alias and adds a GROUP BY clause');
}
public function testDistinct()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->distinct();
$sql = 'SELECT DISTINCT FROM ';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'distinct() adds a DISTINCT clause');
}
public function testLimit()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->limit(10);
$sql = 'SELECT FROM LIMIT 10';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'limit() adds a LIMIT clause');
}
public function testOffset()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->limit(50);
$c->offset(10);
$sql = 'SELECT FROM LIMIT 10, 50';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'offset() adds an OFFSET clause');
}
public function testJoin()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author');
$sql = 'SELECT FROM `book` INNER JOIN author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() uses a relation to guess the columns');
$c = new ModelCriteria('bookstore', 'Book');
try {
$c->join('Book.Foo');
$this->fail('join() throws an exception when called with a non-existing relation');
} catch (PropelException $e) {
$this->assertTrue(true, 'join() throws an exception when called with a non-existing relation');
}
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author');
$c->where('Author.FirstName = ?', 'Leo');
$sql = 'SELECT FROM INNER JOIN author ON (book.AUTHOR_ID=author.ID) WHERE author.FIRST_NAME = :p1';
$params = array(
array('table' => 'author', 'column' => 'FIRST_NAME', 'value' => 'Leo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'join() uses a relation to guess the columns');
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Author');
$c->where('Author.FirstName = ?', 'Leo');
$sql = 'SELECT FROM INNER JOIN author ON (book.AUTHOR_ID=author.ID) WHERE author.FIRST_NAME = :p1';
$params = array(
array('table' => 'author', 'column' => 'FIRST_NAME', 'value' => 'Leo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'join() uses the current model name when given a simple relation name');
}
public function testJoinQuery()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
BookstoreDataPopulator::depopulate($con);
BookstoreDataPopulator::populate($con);
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author');
$c->where('Author.FirstName = ?', 'Neal');
$books = BookPeer::doSelect($c);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` INNER JOIN author ON (book.AUTHOR_ID=author.ID) WHERE author.FIRST_NAME = 'Neal'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'join() issues a real JOIN query');
$this->assertEquals(1, count($books), 'join() issues a real JOIN query');
}
public function testJoinRelationName()
{
$c = new ModelCriteria('bookstore', 'BookstoreEmployee');
$c->join('BookstoreEmployee.Supervisor');
$sql = 'SELECT FROM INNER JOIN bookstore_employee ON (bookstore_employee.SUPERVISOR_ID=bookstore_employee.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() uses relation names as defined in schema.xml');
}
public function testJoinComposite()
{
$c = new ModelCriteria('bookstore', 'ReaderFavorite');
$c->join('ReaderFavorite.BookOpinion');
$sql = 'SELECT FROM `reader_favorite` INNER JOIN book_opinion ON (reader_favorite.BOOK_ID=book_opinion.BOOK_ID AND reader_favorite.READER_ID=book_opinion.READER_ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() knows how to create a JOIN clause for relationships with composite fkeys');
}
public function testJoinType()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author');
$sql = 'SELECT FROM `book` INNER JOIN author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() adds an INNER JOIN by default');
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author', Criteria::INNER_JOIN);
$sql = 'SELECT FROM `book` INNER JOIN author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() adds an INNER JOIN by default');
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author', Criteria::LEFT_JOIN);
$sql = 'SELECT FROM `book` LEFT JOIN author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() can add a LEFT JOIN');
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author', Criteria::RIGHT_JOIN);
$sql = 'SELECT FROM `book` RIGHT JOIN author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() can add a RIGHT JOIN');
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author', 'incorrect join');
$sql = 'SELECT FROM `book` incorrect join author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() accepts any join string');
}
public function testJoinDirection()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author');
$sql = 'SELECT FROM `book` INNER JOIN author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() adds a JOIN clause correctly for many to one relationship');
$c = new ModelCriteria('bookstore', 'Author');
$c->join('Author.Book');
$sql = 'SELECT FROM `author` INNER JOIN book ON (author.ID=book.AUTHOR_ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() adds a JOIN clause correctly for one to many relationship');
$c = new ModelCriteria('bookstore', 'BookstoreEmployee');
$c->join('BookstoreEmployee.BookstoreEmployeeAccount');
$sql = 'SELECT FROM `bookstore_employee` INNER JOIN bookstore_employee_account ON (bookstore_employee.ID=bookstore_employee_account.EMPLOYEE_ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() adds a JOIN clause correctly for one to one relationship');
$c = new ModelCriteria('bookstore', 'BookstoreEmployeeAccount');
$c->join('BookstoreEmployeeAccount.BookstoreEmployee');
$sql = 'SELECT FROM `bookstore_employee_account` INNER JOIN bookstore_employee ON (bookstore_employee_account.EMPLOYEE_ID=bookstore_employee.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() adds a JOIN clause correctly for one to one relationship');
}
public function testJoinSeveral()
{
$c = new ModelCriteria('bookstore', 'Author');
$c->join('Author.Book');
$c->join('Book.Publisher');
$c->where('Publisher.Name = ?', 'foo');
$sql = 'SELECT FROM INNER JOIN book ON (author.ID=book.AUTHOR_ID) INNER JOIN publisher ON (book.PUBLISHER_ID=publisher.ID) WHERE publisher.NAME = :p1';
$params = array(
array('table' => 'publisher', 'column' => 'NAME', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'join() can guess relationships from related tables');
}
public function testJoinAlias()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->join('b.Author');
$sql = 'SELECT FROM `book` INNER JOIN author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() supports relation on main alias');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->join('Author');
$sql = 'SELECT FROM `book` INNER JOIN author ON (book.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() can use a simple relation name when the model has an alias');
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author a');
$sql = 'SELECT FROM `book` INNER JOIN author a ON (book.AUTHOR_ID=a.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() supports relation alias');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->join('b.Author a');
$sql = 'SELECT FROM `book` INNER JOIN author a ON (book.AUTHOR_ID=a.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() supports relation alias on main alias');
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->join('b.Author a');
$c->where('a.FirstName = ?', 'Leo');
$sql = 'SELECT FROM INNER JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE a.FIRST_NAME = :p1';
$params = array(
array('table' => 'author', 'column' => 'FIRST_NAME', 'value' => 'Leo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'join() allows the use of relation alias in where()');
$c = new ModelCriteria('bookstore', 'Author', 'a');
$c->join('a.Book b');
$c->join('b.Publisher p');
$c->where('p.Name = ?', 'foo');
$sql = 'SELECT FROM INNER JOIN book b ON (author.ID=b.AUTHOR_ID) INNER JOIN publisher p ON (b.PUBLISHER_ID=p.ID) WHERE p.NAME = :p1';
$params = array(
array('table' => 'publisher', 'column' => 'NAME', 'value' => 'foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'join() allows the use of relation alias in further join()');
}
public function testJoinTrueTableAlias()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', true);
$c->join('b.Author');
$sql = 'SELECT FROM `book` `b` INNER JOIN author ON (b.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() supports relation on true table alias');
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', true);
$c->join('Author');
$sql = 'SELECT FROM `book` `b` INNER JOIN author ON (b.AUTHOR_ID=author.ID)';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'join() supports relation without alias name on true table alias');
}
public function testJoinOnSameTable()
{
$c = new ModelCriteria('bookstore', 'BookstoreEmployee', 'be');
$c->join('be.Supervisor sup');
$c->join('sup.Subordinate sub');
$c->where('sub.Name = ?', 'Foo');
$sql = 'SELECT FROM INNER JOIN bookstore_employee sup ON (bookstore_employee.SUPERVISOR_ID=sup.ID) INNER JOIN bookstore_employee sub ON (sup.ID=sub.SUPERVISOR_ID) WHERE sub.NAME = :p1';
$params = array(
array('table' => 'bookstore_employee', 'column' => 'NAME', 'value' => 'Foo'),
);
$this->assertCriteriaTranslation($c, $sql, $params, 'join() allows two joins on the same table thanks to aliases');
}
public function testJoinAliasQuery()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->join('b.Author a');
$c->where('a.FirstName = ?', 'Leo');
$books = BookPeer::doSelect($c, $con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` INNER JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE a.FIRST_NAME = 'Leo'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'join() allows the use of relation alias in where()');
$c = new ModelCriteria('bookstore', 'BookstoreEmployee', 'be');
$c->join('be.Supervisor sup');
$c->join('sup.Subordinate sub');
$c->where('sub.Name = ?', 'Foo');
$employees = BookstoreEmployeePeer::doSelect($c, $con);
$expectedSQL = "SELECT bookstore_employee.ID, bookstore_employee.CLASS_KEY, bookstore_employee.NAME, bookstore_employee.JOB_TITLE, bookstore_employee.SUPERVISOR_ID FROM `bookstore_employee` INNER JOIN bookstore_employee sup ON (bookstore_employee.SUPERVISOR_ID=sup.ID) INNER JOIN bookstore_employee sub ON (sup.ID=sub.SUPERVISOR_ID) WHERE sub.NAME = 'Foo'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'join() allows the use of relation alias in further joins()');
}
public function testGetJoin()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author');
$joins = $c->getJoins();
$this->assertEquals($joins['Author'], $c->getJoin('Author'), "getJoin() returns a specific Join from the ModelCriteria");
}
public function testWith()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->join('Book.Author');
$c->with('Author');
$withs = $c->getWith();
$this->assertTrue(array_key_exists('Author', $withs), 'with() adds an entry to the internal list of Withs');
$this->assertTrue($withs['Author'] instanceof ModelJoin, 'with() references the ModelJoin object');
}
/**
* @expectedException PropelException
*/
public function testWithThrowsExceptionWhenJoinLacks()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->with('Author');
}
public function testWithAlias()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->join('Book.Author a');
$c->with('a');
$withs = $c->getWith();
$this->assertTrue(array_key_exists('a', $withs), 'with() uses the alias for the index of the internal list of Withs');
}
/**
* @expectedException PropelException
*/
public function testWithThrowsExceptionWhenNotUsingAlias()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->join('Book.Author a');
$c->with('Author');
}
public function testWithAddsSelectColumns()
{
$c = new TestableModelCriteria('bookstore', 'Book');
BookPeer::addSelectColumns($c);
$c->join('Book.Author');
$c->with('Author');
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
AuthorPeer::ID,
AuthorPeer::FIRST_NAME,
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'with() adds the columns of the related table');
}
public function testWithAliasAddsSelectColumns()
{
$c = new TestableModelCriteria('bookstore', 'Book');
BookPeer::addSelectColumns($c);
$c->join('Book.Author a');
$c->with('a');
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
'a.ID',
'a.FIRST_NAME',
'a.LAST_NAME',
'a.EMAIL',
'a.AGE'
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'with() adds the columns of the related table');
}
public function testWithAddsSelectColumnsOfMainTable()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->join('Book.Author');
$c->with('Author');
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
AuthorPeer::ID,
AuthorPeer::FIRST_NAME,
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'with() adds the columns of the main table if required');
}
public function testWithAliasAddsSelectColumnsOfMainTable()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', true);
$c->join('b.Author a');
$c->with('a');
$expectedColumns = array(
'b.ID',
'b.TITLE',
'b.ISBN',
'b.PRICE',
'b.PUBLISHER_ID',
'b.AUTHOR_ID',
'a.ID',
'a.FIRST_NAME',
'a.LAST_NAME',
'a.EMAIL',
'a.AGE'
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'with() adds the columns of the main table with an alias if required');
}
public function testWithOneToManyAddsSelectColumns()
{
$c = new TestableModelCriteria('bookstore', 'Author');
AuthorPeer::addSelectColumns($c);
$c->leftJoin('Author.Book');
$c->with('Book');
$expectedColumns = array(
AuthorPeer::ID,
AuthorPeer::FIRST_NAME,
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE,
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'with() adds the columns of the related table even in a one-to-many relationship');
}
public function testJoinWith()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->joinWith('Book.Author');
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
AuthorPeer::ID,
AuthorPeer::FIRST_NAME,
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'joinWith() adds the join');
$joins = $c->getJoins();
$join = $joins['Author'];
$this->assertEquals(Criteria::INNER_JOIN, $join->getJoinType(), 'joinWith() adds an INNER JOIN by default');
}
public function testJoinWithType()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->joinWith('Book.Author', Criteria::LEFT_JOIN);
$joins = $c->getJoins();
$join = $joins['Author'];
$this->assertEquals(Criteria::LEFT_JOIN, $join->getJoinType(), 'joinWith() accepts a join type as second parameter');
}
public function testJoinWithAlias()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->joinWith('Book.Author a');
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
'a.ID',
'a.FIRST_NAME',
'a.LAST_NAME',
'a.EMAIL',
'a.AGE'
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'joinWith() adds the join with the alias');
}
public function testJoinWithSeveral()
{
$c = new TestableModelCriteria('bookstore', 'Review');
$c->joinWith('Review.Book');
$c->joinWith('Book.Author');
$c->joinWith('Book.Publisher');
$expectedColumns = array(
ReviewPeer::ID,
ReviewPeer::REVIEWED_BY,
ReviewPeer::REVIEW_DATE,
ReviewPeer::RECOMMENDED,
ReviewPeer::STATUS,
ReviewPeer::BOOK_ID,
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
AuthorPeer::ID,
AuthorPeer::FIRST_NAME,
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE,
PublisherPeer::ID,
PublisherPeer::NAME
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'joinWith() adds the with');
$joins = $c->getJoins();
$expectedJoinKeys = array('Book', 'Author', 'Publisher');
$this->assertEquals($expectedJoinKeys, array_keys($joins), 'joinWith() adds the join');
}
public function testJoinWithTwice()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->join('Book.Review');
$c->joinWith('Book.Author');
$c->joinWith('Book.Review');
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
AuthorPeer::ID,
AuthorPeer::FIRST_NAME,
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE,
ReviewPeer::ID,
ReviewPeer::REVIEWED_BY,
ReviewPeer::REVIEW_DATE,
ReviewPeer::RECOMMENDED,
ReviewPeer::STATUS,
ReviewPeer::BOOK_ID,
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'joinWith() adds the with');
$joins = $c->getJoins();
$expectedJoinKeys = array('Review', 'Author');
$this->assertEquals($expectedJoinKeys, array_keys($joins), 'joinWith() adds the join');
}
public static function conditionsForTestWithColumn()
{
return array(
array('Book.Title', 'BookTitle', 'book.TITLE AS BookTitle'),
array('Book.Title', null, 'book.TITLE AS BookTitle'),
array('UPPER(Book.Title)', null, 'UPPER(book.TITLE) AS UPPERBookTitle'),
array('CONCAT(Book.Title, Book.ISBN)', 'foo', 'CONCAT(book.TITLE, book.ISBN) AS foo'),
);
}
/**
* @dataProvider conditionsForTestWithColumn
*/
public function testWithColumn($clause, $alias, $selectTranslation)
{
$c = new ModelCriteria('bookstore', 'Book');
$c->withColumn($clause, $alias);
$sql = 'SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID, ' . $selectTranslation . ' FROM `book`';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'withColumn() adds a calculated column to the select clause');
}
public function testWithColumnAndSelectColumns()
{
$c = new ModelCriteria('bookstore', 'Book');
$c->withColumn('UPPER(Book.Title)', 'foo');
$sql = 'SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID, UPPER(book.TITLE) AS foo FROM `book`';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'withColumn() adds the object columns if the criteria has no select columns');
$c = new ModelCriteria('bookstore', 'Book');
$c->addSelectColumn('book.ID');
$c->withColumn('UPPER(Book.Title)', 'foo');
$sql = 'SELECT book.ID, UPPER(book.TITLE) AS foo FROM `book`';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'withColumn() does not add the object columns if the criteria already has select columns');
$c = new ModelCriteria('bookstore', 'Book');
$c->addSelectColumn('book.ID');
$c->withColumn('UPPER(Book.Title)', 'foo');
$c->addSelectColumn('book.TITLE');
$sql = 'SELECT book.ID, book.TITLE, UPPER(book.TITLE) AS foo FROM `book`';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'withColumn() does adds as column after the select columns even though the withColumn() method was called first');
$c = new ModelCriteria('bookstore', 'Book');
$c->addSelectColumn('book.ID');
$c->withColumn('UPPER(Book.Title)', 'foo');
$c->withColumn('UPPER(Book.ISBN)', 'isbn');
$sql = 'SELECT book.ID, UPPER(book.TITLE) AS foo, UPPER(book.ISBN) AS isbn FROM `book`';
$params = array();
$this->assertCriteriaTranslation($c, $sql, $params, 'withColumn() called repeatedly adds several as colums');
}
public function testKeepQuery()
{
$c = BookQuery::create();
$this->assertFalse($c->isKeepQuery(), 'keepQuery is disabled by default');
$c->keepQuery();
$this->assertTrue($c->isKeepQuery(), 'keepQuery() enables the keepQuery property');
$c->keepQuery(false);
$this->assertFalse($c->isKeepQuery(), 'keepQuery(false) disables the keepQuery property');
}
public function testKeepQueryFind()
{
$c = BookQuery::create();
$c->filterByTitle('foo');
$c->find();
$expected = array('book.ID', 'book.TITLE', 'book.ISBN', 'book.PRICE', 'book.PUBLISHER_ID', 'book.AUTHOR_ID');
$this->assertEquals($expected, $c->getSelectColumns(), 'find() modifies the query by default');
$c = BookQuery::create();
$c->filterByTitle('foo');
$c->keepQuery();
$c->find();
$this->assertEquals(array(), $c->getSelectColumns(), 'keepQuery() forces find() to use a clone and keep the original query unmodified');
}
public function testKeepQueryFindOne()
{
$c = BookQuery::create();
$c->filterByTitle('foo');
$c->findOne();
$this->assertEquals(1, $c->getLimit(), 'findOne() modifies the query by default');
$c = BookQuery::create();
$c->filterByTitle('foo');
$c->keepQuery();
$c->findOne();
$this->assertEquals(0, $c->getLimit(), 'keepQuery() forces findOne() to use a clone and keep the original query unmodified');
}
public function testKeepQueryFindPk()
{
$c = BookQuery::create();
$c->findPk(1);
$expected = array('book.ID', 'book.TITLE', 'book.ISBN', 'book.PRICE', 'book.PUBLISHER_ID', 'book.AUTHOR_ID');
$this->assertEquals($expected, $c->getSelectColumns(), 'findPk() modifies the query by default');
$c = BookQuery::create();
$c->keepQuery();
$c->findPk(1);
$this->assertEquals(array(), $c->getSelectColumns(), 'keepQuery() forces findPk() to use a clone and keep the original query unmodified');
}
public function testKeepQueryCount()
{
$c = BookQuery::create();
$c->orderByTitle();
$c->count();
$this->assertEquals(array(), $c->getOrderByColumns(), 'count() modifies the query by default');
$c = BookQuery::create();
$c->orderByTitle();
$c->keepQuery();
$c->count();
$this->assertEquals(array('book.TITLE ASC'), $c->getOrderByColumns(), 'keepQuery() forces count() to use a clone and keep the original query unmodified');
}
public function testFind()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'foo');
$books = $c->find();
$this->assertTrue($books instanceof PropelCollection, 'find() returns a collection by default');
$this->assertEquals(0, count($books), 'find() returns an empty array when the query returns no result');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->join('b.Author a');
$c->where('a.FirstName = ?', 'Neal');
$books = $c->find();
$this->assertTrue($books instanceof PropelCollection, 'find() returns a collection by default');
$this->assertEquals(1, count($books), 'find() returns as many rows as the results in the query');
$book = $books->shift();
$this->assertTrue($book instanceof Book, 'find() returns an array of Model objects by default');
$this->assertEquals('Quicksilver', $book->getTitle(), 'find() returns the model objects matching the query');
}
public function testFindAddsSelectColumns()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->find($con);
$sql = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book`";
$this->assertEquals($sql, $con->getLastExecutedQuery(), 'find() adds the select columns of the current model');
}
public function testFindTrueAliasAddsSelectColumns()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', true);
$books = $c->find($con);
$sql = "SELECT b.ID, b.TITLE, b.ISBN, b.PRICE, b.PUBLISHER_ID, b.AUTHOR_ID FROM `book` `b`";
$this->assertEquals($sql, $con->getLastExecutedQuery(), 'find() uses the true model alias if available');
}
public function testFindOne()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'foo');
$book = $c->findOne();
$this->assertNull($book, 'findOne() returns null when the query returns no result');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->orderBy('b.Title');
$book = $c->findOne();
$this->assertTrue($book instanceof Book, 'findOne() returns a Model object by default');
$this->assertEquals('Don Juan', $book->getTitle(), 'find() returns the model objects matching the query');
}
public function testFindOneOrCreateNotExists()
{
BookQuery::create()->deleteAll();
$book = BookQuery::create('b')
->where('b.Title = ?', 'foo')
->filterByPrice(125)
->findOneOrCreate();
$this->assertTrue($book instanceof Book, 'findOneOrCreate() returns an instance of the model when the request has no result');
$this->assertTrue($book->isNew(), 'findOneOrCreate() returns a new instance of the model when the request has no result');
$this->assertEquals('foo', $book->getTitle(), 'findOneOrCreate() returns a populated objects based on the conditions');
$this->assertEquals(125, $book->getPrice(), 'findOneOrCreate() returns a populated objects based on the conditions');
}
public function testFindOneOrCreateNotExistsFormatter()
{
BookQuery::create()->deleteAll();
$book = BookQuery::create('b')
->where('b.Title = ?', 'foo')
->filterByPrice(125)
->setFormatter(ModelCriteria::FORMAT_ARRAY)
->findOneOrCreate();
$this->assertTrue(is_array($book), 'findOneOrCreate() uses the query formatter even when the request has no result');
$this->assertEquals('foo', $book['Title'], 'findOneOrCreate() returns a populated array based on the conditions');
$this->assertEquals(125, $book['Price'], 'findOneOrCreate() returns a populated array based on the conditions');
}
public function testFindOneOrCreateExists()
{
BookQuery::create()->deleteAll();
$book = new Book();
$book->setTitle('foo');
$book->setPrice(125);
$book->save();
$book = BookQuery::create('b')
->where('b.Title = ?', 'foo')
->filterByPrice(125)
->findOneOrCreate();
$this->assertTrue($book instanceof Book, 'findOneOrCreate() returns an instance of the model when the request has one result');
$this->assertFalse($book->isNew(), 'findOneOrCreate() returns an existing instance of the model when the request has one result');
$this->assertEquals('foo', $book->getTitle(), 'findOneOrCreate() returns a populated objects based on the conditions');
$this->assertEquals(125, $book->getPrice(), 'findOneOrCreate() returns a populated objects based on the conditions');
}
public function testFindPkSimpleKey()
{
BookstoreDataPopulator::depopulate();
$c = new ModelCriteria('bookstore', 'Book');
$book = $c->findPk(765432);
$this->assertNull($book, 'findPk() returns null when the primary key is not found');
BookstoreDataPopulator::populate();
// retrieve the test data
$c = new ModelCriteria('bookstore', 'Book');
$testBook = $c->findOne();
$c = new ModelCriteria('bookstore', 'Book');
$book = $c->findPk($testBook->getId());
$this->assertEquals($testBook, $book, 'findPk() returns a model object corresponding to the pk');
}
public function testFindPksSimpleKey()
{
BookstoreDataPopulator::depopulate();
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->findPks(array(765432, 434535));
$this->assertEquals($books instanceof PropelCollection, 'findPks() returns a PropelCollection');
$this->assertEquals(0, count($books), 'findPks() returns an empty collection when the primary keys are not found');
BookstoreDataPopulator::populate();
// retrieve the test data
$c = new ModelCriteria('bookstore', 'Book');
$testBooks = $c->find();
$testBook1 = $testBooks->pop();
$testBook2 = $testBooks->pop();
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->findPks(array($testBook1->getId(), $testBook2->getId()));
$this->assertEquals(array($testBook2, $testBook1), $books->getData(), 'findPks() returns an array of model objects corresponding to the pks');
}
public function testFindPkCompositeKey()
{
BookstoreDataPopulator::depopulate();
$c = new ModelCriteria('bookstore', 'BookListRel');
$bookListRel = $c->findPk(array(1, 2));
$this->assertNull($bookListRel, 'findPk() returns null when the composite primary key is not found');
Propel::enableInstancePooling();
BookstoreDataPopulator::populate();
// save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->find();
foreach ($books as $book) {
$book->save();
}
// retrieve the test data
$c = new ModelCriteria('bookstore', 'BookListRel');
$bookListRelTest = $c->findOne();
$pk = $bookListRelTest->getPrimaryKey();
$c = new ModelCriteria('bookstore', 'BookListRel');
$bookListRel = $c->findPk($pk);
$this->assertEquals($bookListRelTest, $bookListRel, 'findPk() can find objects with composite primary keys');
}
/**
* @expectedException PropelException
*/
public function testFindPksCompositeKey()
{
$c = new ModelCriteria('bookstore', 'BookListRel');
$bookListRel = $c->findPks(array(array(1, 2)));
}
public function testFindBy()
{
try {
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->findBy('Foo', 'Bar');
$this->fail('findBy() throws an exception when called on an unknown column name');
} catch (PropelException $e) {
$this->assertTrue(true, 'findBy() throws an exception when called on an unknown column name');
}
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->findBy('Title', 'Don Juan', $con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'findBy() adds simple column conditions');
$this->assertTrue($books instanceof PropelCollection, 'findBy() issues a find()');
$this->assertEquals(1, count($books), 'findBy() adds simple column conditions');
$book = $books->shift();
$this->assertTrue($book instanceof Book, 'findBy() returns an array of Model objects by default');
$this->assertEquals('Don Juan', $book->getTitle(), 'findBy() returns the model objects matching the query');
}
public function testFindByArray()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->findByArray(array('Title' => 'Don Juan', 'ISBN' => 12345), $con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan' AND book.ISBN=12345";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'findByArray() adds multiple column conditions');
}
public function testFindOneBy()
{
try {
$c = new ModelCriteria('bookstore', 'Book');
$book = $c->findOneBy('Foo', 'Bar');
$this->fail('findOneBy() throws an exception when called on an unknown column name');
} catch (PropelException $e) {
$this->assertTrue(true, 'findOneBy() throws an exception when called on an unknown column name');
}
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$book = $c->findOneBy('Title', 'Don Juan', $con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'findOneBy() adds simple column conditions');
$this->assertTrue($book instanceof Book, 'findOneBy() returns a Model object by default');
$this->assertEquals('Don Juan', $book->getTitle(), 'findOneBy() returns the model object matching the query');
}
public function testFindOneByArray()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$book = $c->findOneByArray(array('Title' => 'Don Juan', 'ISBN' => 12345), $con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan' AND book.ISBN=12345 LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'findOneBy() adds multiple column conditions');
}
public function testCount()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'foo');
$nbBooks = $c->count();
$this->assertTrue(is_int($nbBooks), 'count() returns an integer');
$this->assertEquals(0, $nbBooks, 'count() returns 0 when the query returns no result');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->join('b.Author a');
$c->where('a.FirstName = ?', 'Neal');
$nbBooks = $c->count();
$this->assertTrue(is_int($nbBooks), 'count() returns an integer');
$this->assertEquals(1, $nbBooks, 'count() returns the number of results in the query');
}
public function testPaginate()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->join('b.Author a');
$c->where('a.FirstName = ?', 'Neal');
$books = $c->paginate(1, 5);
$this->assertTrue($books instanceof PropelModelPager, 'paginate() returns a PropelModelPager');
$this->assertEquals(1, count($books), 'paginate() returns a countable pager with the correct count');
foreach ($books as $book) {
$this->assertEquals('Neal', $book->getAuthor()->getFirstName(), 'paginate() returns an iterable pager');
}
}
public function testDelete()
{
BookstoreDataPopulator::depopulate();
BookstoreDataPopulator::populate();
$c = new ModelCriteria('bookstore', 'Book');
try {
$nbBooks = $c->delete();
$this->fail('delete() throws an exception when called on an empty Criteria');
} catch (PropelException $e) {
$this->assertTrue(true, 'delete() throws an exception when called on an empty Criteria');
}
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'foo');
$nbBooks = $c->delete();
$this->assertTrue(is_int($nbBooks), 'delete() returns an integer');
$this->assertEquals(0, $nbBooks, 'delete() returns 0 when the query deleted no rows');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'Don Juan');
$nbBooks = $c->delete();
$this->assertTrue(is_int($nbBooks), 'delete() returns an integer');
$this->assertEquals(1, $nbBooks, 'delete() returns the number of the deleted rows');
$c = new ModelCriteria('bookstore', 'Book');
$nbBooks = $c->count();
$this->assertEquals(3, $nbBooks, 'delete() deletes rows in the database');
}
public function testDeleteUsingTableAlias()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', false);
$c->where('b.Title = ?', 'foo');
$c->delete();
$expectedSQL = "DELETE FROM `book` WHERE book.TITLE = 'foo'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'delete() also works on tables with table alias');
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', true);
$c->where('b.Title = ?', 'foo');
$c->delete();
$expectedSQL = "DELETE b FROM `book` AS b WHERE b.TITLE = 'foo'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'delete() also works on tables with true table alias');
}
public function testDeleteAll()
{
BookstoreDataPopulator::depopulate();
BookstoreDataPopulator::populate();
$c = new ModelCriteria('bookstore', 'Book');
$nbBooks = $c->deleteAll();
$this->assertTrue(is_int($nbBooks), 'deleteAll() returns an integer');
$this->assertEquals(4, $nbBooks, 'deleteAll() returns the number of deleted rows');
BookstoreDataPopulator::depopulate();
BookstoreDataPopulator::populate();
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'Don Juan');
$nbBooks = $c->deleteAll();
$this->assertEquals(4, $nbBooks, 'deleteAll() ignores conditions on the criteria');
}
public function testUpdate()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
BookstoreDataPopulator::depopulate($con);
BookstoreDataPopulator::populate($con);
$count = $con->getQueryCount();
$c = new ModelCriteria('bookstore', 'Book');
$nbBooks = $c->update(array('Title' => 'foo'), $con);
$this->assertEquals(4, $nbBooks, 'update() returns the number of updated rows');
$this->assertEquals($count + 1, $con->getQueryCount(), 'update() updates all the objects in one query by default');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'foo');
$nbBooks = $c->count();
$this->assertEquals(4, $nbBooks, 'update() updates all records by default');
BookstoreDataPopulator::depopulate($con);
BookstoreDataPopulator::populate($con);
$count = $con->getQueryCount();
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'Don Juan');
$nbBooks = $c->update(array('ISBN' => '3456'), $con);
$this->assertEquals(1, $nbBooks, 'update() updates only the records matching the criteria');
$this->assertEquals($count + 1, $con->getQueryCount(), 'update() updates all the objects in one query by default');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'Don Juan');
$book = $c->findOne();
$this->assertEquals('3456', $book->getISBN(), 'update() updates only the records matching the criteria');
}
public function testUpdateUsingTableAlias()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', false);
$c->where('b.Title = ?', 'foo');
$c->update(array('Title' => 'foo2'), $con);
$expectedSQL = "UPDATE `book` SET `TITLE`='foo2' WHERE book.TITLE = 'foo'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'update() also works on tables with table alias');
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('b', true);
$c->where('b.Title = ?', 'foo');
$c->update(array('Title' => 'foo2'), $con);
$expectedSQL = "UPDATE `book` `b` SET `TITLE`='foo2' WHERE b.TITLE = 'foo'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'update() also works on tables with true table alias');
}
public function testUpdateOneByOne()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
BookstoreDataPopulator::depopulate($con);
BookstoreDataPopulator::populate($con);
// save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->find();
foreach ($books as $book) {
$book->save();
}
$count = $con->getQueryCount();
$c = new ModelCriteria('bookstore', 'Book');
$nbBooks = $c->update(array('Title' => 'foo'), $con, true);
$this->assertEquals(4, $nbBooks, 'update() returns the number of updated rows');
$this->assertEquals($count + 1 + 4, $con->getQueryCount(), 'update() updates the objects one by one when called with true as last parameter');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'foo');
$nbBooks = $c->count();
$this->assertEquals(4, $nbBooks, 'update() updates all records by default');
BookstoreDataPopulator::depopulate($con);
BookstoreDataPopulator::populate($con);
// save all books to make sure related objects are also saved - BookstoreDataPopulator keeps some unsaved
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->find();
foreach ($books as $book) {
$book->save();
}
$count = $con->getQueryCount();
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'Don Juan');
$nbBooks = $c->update(array('ISBN' => '3456'), $con, true);
$this->assertEquals(1, $nbBooks, 'update() updates only the records matching the criteria');
$this->assertEquals($count + 1 + 1, $con->getQueryCount(), 'update() updates the objects one by one when called with true as last parameter');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->where('b.Title = ?', 'Don Juan');
$book = $c->findOne();
$this->assertEquals('3456', $book->getISBN(), 'update() updates only the records matching the criteria');
}
public static function conditionsForTestGetRelationName()
{
return array(
array('Author', 'Author'),
array('Book.Author', 'Author'),
array('Author.Book', 'Book'),
array('Book.Author a', 'a'),
);
}
/**
* @dataProvider conditionsForTestGetRelationName
*/
public function testGetRelationName($relation, $relationName)
{
$this->assertEquals($relationName, ModelCriteria::getrelationName($relation));
}
public function testMagicJoin()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->leftJoin('b.Author a');
$c->where('a.FirstName = ?', 'Leo');
$books = $c->findOne($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` LEFT JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE a.FIRST_NAME = 'Leo' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'leftJoin($x) is turned into join($x, Criteria::LEFT_JOIN)');
$books = BookQuery::create()
->leftJoinAuthor('a')
->where('a.FirstName = ?', 'Leo')
->findOne($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` LEFT JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE a.FIRST_NAME = 'Leo' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'leftJoinX() is turned into join($x, Criteria::LEFT_JOIN)');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->innerJoin('b.Author a');
$c->where('a.FirstName = ?', 'Leo');
$books = $c->findOne($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` INNER JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE a.FIRST_NAME = 'Leo' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'innerJoin($x) is turned into join($x, Criteria::INNER_JOIN)');
$books = BookQuery::create()
->innerJoinAuthor('a')
->where('a.FirstName = ?', 'Leo')
->findOne($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` INNER JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE a.FIRST_NAME = 'Leo' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'innerJoinX() is turned into join($x, Criteria::INNER_JOIN)');
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->rightJoin('b.Author a');
$c->where('a.FirstName = ?', 'Leo');
$books = $c->findOne($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` RIGHT JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE a.FIRST_NAME = 'Leo' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'rightJoin($x) is turned into join($x, Criteria::RIGHT_JOIN)');
$books = BookQuery::create()
->rightJoinAuthor('a')
->where('a.FirstName = ?', 'Leo')
->findOne($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` RIGHT JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE a.FIRST_NAME = 'Leo' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'rightJoinX() is turned into join($x, Criteria::RIGHT_JOIN)');
$books = BookQuery::create()
->leftJoinAuthor()
->where('Author.FirstName = ?', 'Leo')
->findOne($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` LEFT JOIN author ON (book.AUTHOR_ID=author.ID) WHERE author.FIRST_NAME = 'Leo' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'leftJoinX() is turned into join($x, Criteria::LEFT_JOIN)');
}
public function testMagicJoinWith()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->leftJoinWith('Book.Author a');
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
'a.ID',
'a.FIRST_NAME',
'a.LAST_NAME',
'a.EMAIL',
'a.AGE'
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'leftJoinWith() adds the join with the alias');
$joins = $c->getJoins();
$join = $joins['a'];
$this->assertEquals(Criteria::LEFT_JOIN, $join->getJoinType(), 'leftJoinWith() adds a LEFT JOIN');
}
public function testMagicJoinWithRelation()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->joinWithAuthor();
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
AuthorPeer::ID,
AuthorPeer::FIRST_NAME,
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'joinWithXXX() adds the join with the XXX relation');
$joins = $c->getJoins();
$join = $joins['Author'];
$this->assertEquals(Criteria::INNER_JOIN, $join->getJoinType(), 'joinWithXXX() adds an INNER JOIN');
}
public function testMagicJoinWithTypeAndRelation()
{
$c = new TestableModelCriteria('bookstore', 'Book');
$c->leftJoinWithAuthor();
$expectedColumns = array(
BookPeer::ID,
BookPeer::TITLE,
BookPeer::ISBN,
BookPeer::PRICE,
BookPeer::PUBLISHER_ID,
BookPeer::AUTHOR_ID,
AuthorPeer::ID,
AuthorPeer::FIRST_NAME,
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE
);
$this->assertEquals($expectedColumns, $c->getSelectColumns(), 'leftJoinWithXXX() adds the join with the XXX relation');
$joins = $c->getJoins();
$join = $joins['Author'];
$this->assertEquals(Criteria::LEFT_JOIN, $join->getJoinType(), 'leftJoinWithXXX() adds an INNER JOIN');
}
public function testMagicFind()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->findByTitle('Don Juan');
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'findByXXX($value) is turned into findBy(XXX, $value)');
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->findByTitleAndISBN('Don Juan', 1234);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan' AND book.ISBN=1234";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'findByXXXAndYYY($value) is turned into findBy(array(XXX,YYY), $value)');
$c = new ModelCriteria('bookstore', 'Book');
$book = $c->findOneByTitle('Don Juan');
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan' LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'findOneByXXX($value) is turned into findOneBy(XXX, $value)');
$c = new ModelCriteria('bookstore', 'Book');
$book = $c->findOneByTitleAndISBN('Don Juan', 1234);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan' AND book.ISBN=1234 LIMIT 1";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'findOneByXXX($value) is turned into findOneBy(XXX, $value)');
}
public function testMagicFilterBy()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->filterByTitle('Don Juan')->find($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` WHERE book.TITLE='Don Juan'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'filterByXXX($value) is turned into filterBy(XXX, $value)');
}
public function testMagicOrderBy()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->orderByTitle()->find($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` ORDER BY book.TITLE ASC";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'orderByXXX() is turned into orderBy(XXX)');
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->orderByTitle(Criteria::DESC)->find($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` ORDER BY book.TITLE DESC";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'orderByXXX($direction) is turned into orderBy(XXX, $direction)');
}
public function testMagicGroupBy()
{
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c = new ModelCriteria('bookstore', 'Book');
$books = $c->groupByTitle()->find($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` GROUP BY book.TITLE";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'groupByXXX() is turned into groupBy(XXX)');
}
public function testUseQuery()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->thisIsMe = true;
$c->where('b.Title = ?', 'foo');
$c->setOffset(10);
$c->leftJoin('b.Author');
$c2 = $c->useQuery('Author');
$this->assertTrue($c2 instanceof AuthorQuery, 'useQuery() returns a secondary Criteria');
$this->assertEquals($c, $c2->getPrimaryCriteria(), 'useQuery() sets the primary Criteria os the secondary Criteria');
$c2->where('Author.FirstName = ?', 'john');
$c2->limit(5);
$c = $c2->endUse();
$this->assertTrue($c->thisIsMe, 'endUse() returns the Primary Criteria');
$this->assertEquals('Book', $c->getModelName(), 'endUse() returns the Primary Criteria');
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c->find($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` LEFT JOIN author ON (book.AUTHOR_ID=author.ID) WHERE book.TITLE = 'foo' AND author.FIRST_NAME = 'john' LIMIT 10, 5";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'useQuery() and endUse() allow to merge a secondary criteria');
}
public function testUseQueryAlias()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->thisIsMe = true;
$c->where('b.Title = ?', 'foo');
$c->setOffset(10);
$c->leftJoin('b.Author a');
$c2 = $c->useQuery('a');
$this->assertTrue($c2 instanceof AuthorQuery, 'useQuery() returns a secondary Criteria');
$this->assertEquals($c, $c2->getPrimaryCriteria(), 'useQuery() sets the primary Criteria os the secondary Criteria');
$this->assertEquals(array('a' => 'author'), $c2->getAliases(), 'useQuery() sets the secondary Criteria alias correctly');
$c2->where('a.FirstName = ?', 'john');
$c2->limit(5);
$c = $c2->endUse();
$this->assertTrue($c->thisIsMe, 'endUse() returns the Primary Criteria');
$this->assertEquals('Book', $c->getModelName(), 'endUse() returns the Primary Criteria');
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c->find($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` LEFT JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE book.TITLE = 'foo' AND a.FIRST_NAME = 'john' LIMIT 10, 5";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'useQuery() and endUse() allow to merge a secondary criteria');
}
public function testUseQueryCustomClass()
{
$c = new ModelCriteria('bookstore', 'Book', 'b');
$c->thisIsMe = true;
$c->where('b.Title = ?', 'foo');
$c->setLimit(10);
$c->leftJoin('b.Author a');
$c2 = $c->useQuery('a', 'ModelCriteriaForUseQuery');
$this->assertTrue($c2 instanceof ModelCriteriaForUseQuery, 'useQuery() returns a secondary Criteria with the custom class');
$c2->withNoName();
$c = $c2->endUse();
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c->find($con);
$expectedSQL = "SELECT book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID FROM `book` LEFT JOIN author a ON (book.AUTHOR_ID=a.ID) WHERE book.TITLE = 'foo' AND a.FIRST_NAME IS NOT NULL AND a.LAST_NAME IS NOT NULL LIMIT 10";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'useQuery() and endUse() allow to merge a custom secondary criteria');
}
public function testUseQueryJoinWithFind()
{
$c = new ModelCriteria('bookstore', 'Review');
$c->joinWith('Book');
$c2 = $c->useQuery('Book');
$joins = $c->getJoins();
$this->assertEquals($c->getPreviousJoin(), null, 'The default value for previousJoin remains null');
$this->assertEquals($c2->getPreviousJoin(), $joins['Book'], 'useQuery() sets the previousJoin');
// join Book with Author, which is possible since previousJoin is set, which makes resolving of relations possible during hydration
$c2->joinWith('Author');
$c = $c2->endUse();
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c->find($con);
$expectedSQL = "SELECT review.ID, review.REVIEWED_BY, review.REVIEW_DATE, review.RECOMMENDED, review.STATUS, review.BOOK_ID, book.ID, book.TITLE, book.ISBN, book.PRICE, book.PUBLISHER_ID, book.AUTHOR_ID, author.ID, author.FIRST_NAME, author.LAST_NAME, author.EMAIL, author.AGE FROM `review` INNER JOIN book ON (review.BOOK_ID=book.ID) INNER JOIN author ON (book.AUTHOR_ID=author.ID)";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'useQuery() and joinWith() can be used together and form a correct query');
}
public function testUseQueryCustomRelationPhpName()
{
$c = new ModelCriteria('bookstore', 'BookstoreContest');
$c->leftJoin('BookstoreContest.Work');
$c2 = $c->useQuery('Work');
$this->assertTrue($c2 instanceof BookQuery, 'useQuery() returns a secondary Criteria');
$this->assertEquals($c, $c2->getPrimaryCriteria(), 'useQuery() sets the primary Criteria os the secondary Criteria');
//$this->assertEquals(array('a' => 'author'), $c2->getAliases(), 'useQuery() sets the secondary Criteria alias correctly');
$c2->where('Work.Title = ?', 'War And Peace');
$c = $c2->endUse();
$this->assertEquals('BookstoreContest', $c->getModelName(), 'endUse() returns the Primary Criteria');
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c->find($con);
$expectedSQL = "SELECT bookstore_contest.BOOKSTORE_ID, bookstore_contest.CONTEST_ID, bookstore_contest.PRIZE_BOOK_ID FROM `bookstore_contest` LEFT JOIN book ON (bookstore_contest.PRIZE_BOOK_ID=book.ID) WHERE book.TITLE = 'War And Peace'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'useQuery() and endUse() allow to merge a secondary criteria');
}
public function testUseQueryCustomRelationPhpNameAndAlias()
{
$c = new ModelCriteria('bookstore', 'BookstoreContest');
$c->leftJoin('BookstoreContest.Work w');
$c2 = $c->useQuery('w');
$this->assertTrue($c2 instanceof BookQuery, 'useQuery() returns a secondary Criteria');
$this->assertEquals($c, $c2->getPrimaryCriteria(), 'useQuery() sets the primary Criteria os the secondary Criteria');
//$this->assertEquals(array('a' => 'author'), $c2->getAliases(), 'useQuery() sets the secondary Criteria alias correctly');
$c2->where('w.Title = ?', 'War And Peace');
$c = $c2->endUse();
$this->assertEquals('BookstoreContest', $c->getModelName(), 'endUse() returns the Primary Criteria');
$con = Propel::getConnection(BookPeer::DATABASE_NAME);
$c->find($con);
$expectedSQL = "SELECT bookstore_contest.BOOKSTORE_ID, bookstore_contest.CONTEST_ID, bookstore_contest.PRIZE_BOOK_ID FROM `bookstore_contest` LEFT JOIN book w ON (bookstore_contest.PRIZE_BOOK_ID=w.ID) WHERE w.TITLE = 'War And Peace'";
$this->assertEquals($expectedSQL, $con->getLastExecutedQuery(), 'useQuery() and endUse() allow to merge a secondary criteria');
}
public function testMergeWithJoins()
{
$c1 = new ModelCriteria('bookstore', 'Book', 'b');
$c1->leftJoin('b.Author a');
$c2 = new ModelCriteria('bookstore', 'Author');
$c1->mergeWith($c2);
$joins = $c1->getJoins();
$this->assertEquals(1, count($joins), 'mergeWith() does not remove an existing join');
$this->assertEquals('LEFT JOIN : book.AUTHOR_ID=a.ID(ignoreCase not considered)', $joins['a']->toString(), 'mergeWith() does not remove an existing join');
$c1 = new ModelCriteria('bookstore', 'Book', 'b');
$c2 = new ModelCriteria('bookstore', 'Book', 'b');
$c2->leftJoin('b.Author a');
$c1->mergeWith($c2);
$joins = $c1->getJoins();
$this->assertEquals(1, count($joins), 'mergeWith() merge joins to an empty join');
$this->assertEquals('LEFT JOIN : book.AUTHOR_ID=a.ID(ignoreCase not considered)', $joins['a']->toString(), 'mergeWith() merge joins to an empty join');
$c1 = new ModelCriteria('bookstore', 'Book', 'b');
$c1->leftJoin('b.Author a');
$c2 = new ModelCriteria('bookstore', 'Book', 'b');
$c2->innerJoin('b.Publisher p');
$c1->mergeWith($c2);
$joins = $c1->getJoins();
$this->assertEquals(2, count($joins), 'mergeWith() merge joins to an existing join');
$this->assertEquals('LEFT JOIN : book.AUTHOR_ID=a.ID(ignoreCase not considered)', $joins['a']->toString(), 'mergeWith() merge joins to an empty join');
$this->assertEquals('INNER JOIN : book.PUBLISHER_ID=p.ID(ignoreCase not considered)', $joins['p']->toString(), 'mergeWith() merge joins to an empty join');
}
public function testMergeWithWiths()
{
$c1 = new ModelCriteria('bookstore', 'Book', 'b');
$c1->leftJoinWith('b.Author a');
$c2 = new ModelCriteria('bookstore', 'Author');
$c1->mergeWith($c2);
$with = $c1->getWith();
$this->assertEquals(1, count($with), 'mergeWith() does not remove an existing join');
$this->assertEquals('LEFT JOIN : book.AUTHOR_ID=a.ID(ignoreCase not considered) tableMap: AuthorTableMap relationMap: Author previousJoin: null relationAlias: a', $with['a']->__toString(), 'mergeWith() does not remove an existing join');
$c1 = new ModelCriteria('bookstore', 'Book', 'b');
$c2 = new ModelCriteria('bookstore', 'Book', 'b');
$c2->leftJoinWith('b.Author a');
$c1->mergeWith($c2);
$with = $c1->getWith();
$this->assertEquals(1, count($with), 'mergeWith() merge joins to an empty join');
$this->assertEquals('LEFT JOIN : book.AUTHOR_ID=a.ID(ignoreCase not considered) tableMap: AuthorTableMap relationMap: Author previousJoin: null relationAlias: a', $with['a']->__toString(), 'mergeWith() merge joins to an empty join');
$c1 = new ModelCriteria('bookstore', 'Book', 'b');
$c1->leftJoinWith('b.Author a');
$c2 = new ModelCriteria('bookstore', 'Book', 'b');
$c2->innerJoinWith('b.Publisher p');
$c1->mergeWith($c2);
$with = $c1->getWith();
$this->assertEquals(2, count($with), 'mergeWith() merge joins to an existing join');
$this->assertEquals('LEFT JOIN : book.AUTHOR_ID=a.ID(ignoreCase not considered) tableMap: AuthorTableMap relationMap: Author previousJoin: null relationAlias: a', $with['a']->__toString(), 'mergeWith() merge joins to an empty join');
$this->assertEquals('INNER JOIN : book.PUBLISHER_ID=p.ID(ignoreCase not considered) tableMap: PublisherTableMap relationMap: Publisher previousJoin: null relationAlias: p', $with['p']->__toString(), 'mergeWith() merge joins to an empty join');
}
public function testGetAliasedColName()
{
$c = new ModelCriteria('bookstore', 'Book');
$this->assertEquals(BookPeer::TITLE, $c->getAliasedColName(BookPeer::TITLE), 'getAliasedColName() returns the input when the table has no alias');
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('foo');
$this->assertEquals(BookPeer::TITLE, $c->getAliasedColName(BookPeer::TITLE), 'getAliasedColName() returns the input when the table has a query alias');
$c = new ModelCriteria('bookstore', 'Book');
$c->setModelAlias('foo', true);
$this->assertEquals('foo.TITLE', $c->getAliasedColName(BookPeer::TITLE), 'getAliasedColName() returns the column name with table alias when the table has a true alias');
}
public function testAddUsingAliasNoAlias()
{
$c1 = new ModelCriteria('bookstore', 'Book');
$c1->addUsingAlias(BookPeer::TITLE, 'foo');
$c2 = new ModelCriteria('bookstore', 'Book');
$c2->add(BookPeer::TITLE, 'foo');
$this->assertEquals($c2, $c1, 'addUsingalias() translates to add() when the table has no alias');
}
public function testAddUsingAliasQueryAlias()
{
$c1 = new ModelCriteria('bookstore', 'Book', 'b');
$c1->addUsingAlias(BookPeer::TITLE, 'foo');
$c2 = new ModelCriteria('bookstore', 'Book', 'b');
$c2->add(BookPeer::TITLE, 'foo');
$this->assertEquals($c2, $c1, 'addUsingalias() translates the colname using the table alias before calling add() when the table has a true alias');
}
public function testAddUsingAliasTrueAlias()
{
$c1 = new ModelCriteria('bookstore', 'Book');
$c1->setModelAlias('b', true);
$c1->addUsingAlias(BookPeer::TITLE, 'foo');
$c2 = new ModelCriteria('bookstore', 'Book');
$c2->setModelAlias('b', true);
$c2->add('b.TITLE', 'foo');
$this->assertEquals($c2, $c1, 'addUsingalias() translates to add() when the table has a true alias');
}
public function testAddUsingAliasTwice()
{
$c1 = new ModelCriteria('bookstore', 'Book');
$c1->addUsingAlias(BookPeer::TITLE, 'foo');
$c1->addUsingAlias(BookPeer::TITLE, 'bar');
$c2 = new ModelCriteria('bookstore', 'Book');
$c2->add(BookPeer::TITLE, 'foo');
$c2->addAnd(BookPeer::TITLE, 'bar');
$this->assertEquals($c2, $c1, 'addUsingalias() translates to addAnd() when the table already has a condition on the column');
}
public function testAddUsingAliasTrueAliasTwice()
{
$c1 = new ModelCriteria('bookstore', 'Book');
$c1->setModelAlias('b', true);
$c1->addUsingAlias(BookPeer::TITLE, 'foo');
$c1->addUsingAlias(BookPeer::TITLE, 'bar');
$c2 = new ModelCriteria('bookstore', 'Book');
$c2->setModelAlias('b', true);
$c2->add('b.TITLE', 'foo');
$c2->addAnd('b.TITLE', 'bar');
$this->assertEquals($c2, $c1, 'addUsingalias() translates to addAnd() when the table already has a condition on the column');
}
public function testClone()
{
$bookQuery1 = BookQuery::create()
->filterByPrice(1);
$bookQuery2 = clone $bookQuery1;
$bookQuery2
->filterByPrice(2);
$params = array();
$sql = BasePeer::createSelectSql($bookQuery1, $params);
$this->assertEquals('SELECT FROM `book` WHERE book.PRICE=:p1', $sql, 'conditions applied on a cloned query don\'t get applied on the original query');
}
}
class TestableModelCriteria extends ModelCriteria
{
public $joins = array();
public function replaceNames(&$clause)
{
return parent::replaceNames($clause);
}
}
class ModelCriteriaForUseQuery extends ModelCriteria
{
public function __construct($dbName = 'bookstore', $modelName = 'Author', $modelAlias = null)
{
parent::__construct($dbName, $modelName, $modelAlias);
}
public function withNoName()
{
return $this
->filterBy('FirstName', null, Criteria::ISNOTNULL)
->where($this->getModelAliasOrName() . '.LastName IS NOT NULL');
}
}