Commit ae358bd9 authored by Benjamin Eberlei's avatar Benjamin Eberlei

Merge remote branch 'origin/2.1.x' into 2.1.x

parents 79079d39 d3847864
language: php
php:
- 5.3
- 5.4
env:
- DB=mysql
- DB=pgsql
- DB=sqlite
before_script:
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests_tmp;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi"
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
- git submodule update --init
script: phpunit --configuration tests/travis/$DB.travis.xml
\ No newline at end of file
{
"name": "doctrine/dbal",
"type": "library",
"description": "Database Abstraction Layer",
"keywords": ["dbal", "database", "persistence", "queryobject"],
"homepage": "http://www.doctrine-project.org",
"license": "LGPL",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}
],
"require": {
"php": ">=5.3.2",
"doctrine/common": "2.*"
},
"autoload": {
"psr-0": { "Doctrine\\DBAL": "lib/" }
}
}
......@@ -747,8 +747,10 @@ LEFT JOIN all_cons_columns r_cols
'long' => 'string',
'clob' => 'text',
'nclob' => 'text',
'raw' => 'text',
'long raw' => 'text',
'rowid' => 'string',
'urowid' => 'string'
'urowid' => 'string',
);
}
......
......@@ -210,8 +210,7 @@ class PostgreSqlPlatform extends AbstractPlatform
(
SELECT c.oid
FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n
WHERE " .$this->getTableWhereClause($table) ."
AND n.oid = c.relnamespace
WHERE " .$this->getTableWhereClause($table) ." AND n.oid = c.relnamespace
)
AND r.contype = 'f'";
}
......@@ -259,15 +258,22 @@ class PostgreSqlPlatform extends AbstractPlatform
) AND pg_index.indexrelid = oid";
}
/**
* @param string $table
* @param string $classAlias
* @param string $namespaceAlias
* @return string
*/
private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n')
{
$whereClause = "";
$whereClause = $namespaceAlias.".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND ";
if (strpos($table, ".") !== false) {
list($schema, $table) = explode(".", $table);
$whereClause = "$classAlias.relname = '" . $table . "' AND $namespaceAlias.nspname = '" . $schema . "'";
$whereClause .= "$classAlias.relname = '" . $table . "' AND $namespaceAlias.nspname = '" . $schema . "'";
} else {
$whereClause = "$classAlias.relname = '" . $table . "'";
$whereClause .= "$classAlias.relname = '" . $table . "'";
}
return $whereClause;
}
......
......@@ -481,6 +481,7 @@ class SqlitePlatform extends AbstractPlatform
'time' => 'time',
'float' => 'float',
'double' => 'float',
'double precision' => 'float',
'real' => 'float',
'decimal' => 'decimal',
'numeric' => 'decimal',
......
......@@ -963,7 +963,14 @@ class QueryBuilder
}
}
$fromClauses[] = $fromClause;
$fromClauses[$from['alias']] = $fromClause;
}
// loop through all JOIN clasues for validation purpose
foreach ($this->sqlParts['join'] as $fromAlias => $joins) {
if ( ! isset($fromClauses[$fromAlias]) ) {
throw QueryException::unknownFromAlias($fromAlias, array_keys($fromClauses));
}
}
$query .= implode(', ', $fromClauses)
......
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Query;
use Doctrine\DBAL\DBALException;
/**
* Driver interface.
* Interface that all DBAL drivers must implement.
*
* @since 2.1.4
*/
class QueryException extends DBALException
{
static public function unknownFromAlias($alias, $registeredAliases)
{
return new self("The given alias '" . $alias . "' is not part of " .
"any FROM clause table. The currently registered FROM-clause " .
"aliases are: " . implode(", ", $registeredAliases) . ". Join clauses " .
"are bound to from clauses to provide support for mixing of multiple " .
"from and join clauses.");
}
}
\ No newline at end of file
......@@ -154,7 +154,7 @@ class MySqlSchemaManager extends AbstractSchemaManager
'length' => $length,
'unsigned' => (bool)$unsigned,
'fixed' => (bool)$fixed,
'default' => $tableColumn['default'],
'default' => isset($tableColumn['default']) ? $tableColumn['default'] : null,
'notnull' => (bool) ($tableColumn['null'] != 'YES'),
'scale' => null,
'precision' => null,
......
......@@ -475,7 +475,7 @@ class Table extends AbstractAsset
$pkCols = array();
$fkCols = array();
if ($this->hasIndex($this->_primaryKeyName)) {
if ($this->hasPrimaryKey()) {
$pkCols = $this->getPrimaryKey()->getColumns();
}
foreach ($this->getForeignKeys() AS $fk) {
......@@ -520,10 +520,13 @@ class Table extends AbstractAsset
}
/**
* @return Index
* @return Index|null
*/
public function getPrimaryKey()
{
if (!$this->hasPrimaryKey()) {
return null;
}
return $this->getIndex($this->_primaryKeyName);
}
......
......@@ -36,38 +36,38 @@ use Doctrine\DBAL\Platforms\AbstractPlatform,
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class DropSchemaSqlCollector implements Visitor
{
/**
* @var array
* @var \SplObjectStorage
*/
private $_constraints = array();
private $constraints;
/**
* @var array
* @var \SplObjectStorage
*/
private $_sequences = array();
private $sequences;
/**
* @var array
* @var \SplObjectStorage
*/
private $_tables = array();
private $tables;
/**
*
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
private $_platform = null;
private $platform;
/**
* @param AbstractPlatform $platform
*/
public function __construct(AbstractPlatform $platform)
{
$this->_platform = $platform;
$this->platform = $platform;
$this->clearQueries();
}
/**
......@@ -83,7 +83,7 @@ class DropSchemaSqlCollector implements Visitor
*/
public function acceptTable(Table $table)
{
$this->_tables[] = $this->_platform->getDropTableSQL($table->getQuotedName($this->_platform));
$this->tables->attach($table);
}
/**
......@@ -104,7 +104,8 @@ class DropSchemaSqlCollector implements Visitor
throw SchemaException::namedForeignKeyRequired($localTable, $fkConstraint);
}
$this->_constraints[] = $this->_platform->getDropForeignKeySQL($fkConstraint->getQuotedName($this->_platform), $localTable->getQuotedName($this->_platform));
$this->constraints->attach($fkConstraint);
$this->constraints[$fkConstraint] = $localTable;
}
/**
......@@ -121,15 +122,17 @@ class DropSchemaSqlCollector implements Visitor
*/
public function acceptSequence(Sequence $sequence)
{
$this->_sequences[] = $this->_platform->getDropSequenceSQL($sequence->getQuotedName($this->_platform));
$this->sequences->attach($sequence);
}
/**
* @return array
* @return void
*/
public function clearQueries()
{
$this->_constraints = $this->_sequences = $this->_tables = array();
$this->constraints = new \SplObjectStorage();
$this->sequences = new \SplObjectStorage();
$this->tables = new \SplObjectStorage();
}
/**
......@@ -137,6 +140,20 @@ class DropSchemaSqlCollector implements Visitor
*/
public function getQueries()
{
return array_merge($this->_constraints, $this->_sequences, $this->_tables);
$sql = array();
foreach ($this->constraints AS $fkConstraint) {
$localTable = $this->constraints[$fkConstraint];
$sql[] = $this->platform->getDropForeignKeySQL($fkConstraint->getQuotedName($this->platform), $localTable->getQuotedName($this->platform));
}
foreach ($this->sequences AS $sequence) {
$sql[] = $this->platform->getDropSequenceSQL($sequence->getQuotedName($this->platform));
}
foreach ($this->tables AS $table) {
$sql[] = $this->platform->getDropTableSQL($table->getQuotedName($this->platform));
}
return $sql;
}
}
......@@ -99,7 +99,7 @@ class Graphviz implements \Doctrine\DBAL\Schema\Visitor\Visitor
$label .= '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $columnLabel . '</FONT>';
$label .= '</TD><TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec"><FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="10">' . strtolower($column->getType()) . '</FONT></TD>';
$label .= '<TD BORDER="0" ALIGN="RIGHT" BGCOLOR="#eeeeec" PORT="col'.$column->getName().'">';
if (in_array($column->getName(), $table->getPrimaryKey()->getColumns())) {
if ($table->hasPrimaryKey() && in_array($column->getName(), $table->getPrimaryKey()->getColumns())) {
$label .= "\xe2\x9c\xb7";
}
$label .= '</TD></TR>';
......
......@@ -250,7 +250,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$this->assertEquals(1, count($fkConstraints), "Table 'test_create_fk1' has to have one foreign key.");
$fkConstraint = current($fkConstraints);
$this->assertType('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
$this->assertInstanceOf('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
$this->assertEquals('test_foreign', strtolower($fkConstraint->getForeignTableName()));
$this->assertEquals(array('foreign_key_test'), array_map('strtolower', $fkConstraint->getColumns()));
$this->assertEquals(array('id'), array_map('strtolower', $fkConstraint->getForeignColumns()));
......
......@@ -11,7 +11,7 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
/**
* SQLITE does not support databases.
*
* @expectedException \Exception
* @expectedException Doctrine\DBAL\DBALException
*/
public function testListDatabases()
{
......@@ -29,29 +29,7 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
}
/**
* @expectedException \Exception
*/
// This test is not correct. createSequence expects an object.
// PHPUnit wrapping the PHP error in an exception hides this but it shows up
// when the tests are run in the build (phing).
/*public function testCreateSequence()
{
$this->_sm->createSequence('seqname', 1, 1);
}*/
/**
* @expectedException \Exception
*/
// This test is not correct. createForeignKey expects an object.
// PHPUnit wrapping the PHP error in an exception hides this but it shows up
// when the tests are run in the build (phing).
/*public function testCreateForeignKey()
{
$this->_sm->createForeignKey('table', array());
}*/
/**
* @expectedException \Exception
* @expectedException Doctrine\DBAL\DBALException
*/
public function testRenameTable()
{
......
<?php
namespace Doctrine\Tests\DBAL\Functional\Ticket;
/**
* @group DBAL-168
*/
class DBAL168Test extends \Doctrine\Tests\DbalFunctionalTestCase
{
public function testDomainsTable()
{
if ($this->_conn->getDatabasePlatform()->getName() != "postgresql") {
$this->markTestSkipped('PostgreSQL only test');
}
$table = new \Doctrine\DBAL\Schema\Table("domains");
$table->addColumn('id', 'integer');
$table->addColumn('parent_id', 'integer');
$table->setPrimaryKey(array('id'));
$table->addForeignKeyConstraint('domains', array('parent_id'), array('id'));
$this->_conn->getSchemaManager()->createTable($table);
$table = $this->_conn->getSchemaManager()->listTableDetails('domains');
$this->assertEquals('domains', $table->getName());
}
}
\ No newline at end of file
......@@ -81,7 +81,11 @@ class TypeConversionTest extends \Doctrine\Tests\DbalFunctionalTestCase
$sql = "SELECT " . $columnName . " FROM type_conversion WHERE id = " . self::$typeCounter;
$actualDbValue = $typeInstance->convertToPHPValue($this->_conn->fetchColumn($sql), $this->_conn->getDatabasePlatform());
$this->assertType($expectedPhpType, $actualDbValue, "The expected type from the conversion to and back from the database should be " . $expectedPhpType);
if ($originalValue instanceof \DateTime) {
$this->assertInstanceOf($expectedPhpType, $actualDbValue, "The expected type from the conversion to and back from the database should be " . $expectedPhpType);
} else {
$this->assertInternalType($expectedPhpType, $actualDbValue, "The expected type from the conversion to and back from the database should be " . $expectedPhpType);
}
if ($type !== "datetimetz") {
$this->assertEquals($originalValue, $actualDbValue, "Conversion between values should produce the same out as in value, but doesnt!");
......
......@@ -156,7 +156,7 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase
public function testModifyLimitQueryWithOffset()
{
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC', 10, 5);
$this->assertEquals('WITH outer_tbl AS (SELECT ROW_NUMBER() OVER (ORDER BY username DESC) AS "doctrine_rownum", * FROM (SELECT * FROM user) AS inner_tbl) SELECT * FROM outer_tbl WHERE "doctrine_rownum" BETWEEN 6 AND 15', $sql);
$this->assertEquals('SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY username DESC) AS "doctrine_rownum", * FROM user) AS doctrine_tbl WHERE "doctrine_rownum" BETWEEN 6 AND 15', $sql);
}
public function testModifyLimitQueryWithAscOrderBy()
......
......@@ -548,4 +548,25 @@ class QueryBuilderTest extends \Doctrine\Tests\DbalTestCase
$this->assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string)$qb);
$this->assertEquals(10, $qb->getParameter(1));
}
/**
* @group DBAL-172
*/
public function testReferenceJoinFromJoin()
{
$qb = new QueryBuilder($this->conn);
$qb->select("l.id", "mdsh.xcode", "mdso.xcode")
->from("location_tree", "l")
->join("l", "location_tree_pos", "p", "l.id = p.tree_id")
->rightJoin("l", "hotel", "h", "h.location_id = l.id")
->leftJoin("l", "offer_location", "ol", "l.id=ol.location_id")
->leftJoin("ol", "mds_offer", "mdso", "ol.offer_id = mdso.offer_id")
->leftJoin("h", "mds_hotel", "mdsh", "h.id = mdsh.hotel_id")
->where("p.parent_id IN (:ids)")
->andWhere("(mdso.xcode IS NOT NULL OR mdsh.xcode IS NOT NULL)");
$this->setExpectedException('Doctrine\DBAL\Query\QueryException', "The given alias 'ol' is not part of any FROM clause table. The currently registered FROM-clause aliases are: l");
$this->assertEquals('', $qb->getSQL());
}
}
\ No newline at end of file
......@@ -24,7 +24,7 @@ class DateTimeTest extends \Doctrine\Tests\DbalTestCase
$date = new \DateTime('1985-09-01 10:10:10');
$expected = $date->format($this->_platform->getDateTimeTzFormatString());
$actual = is_string($this->_type->convertToDatabaseValue($date, $this->_platform));
$actual = $this->_type->convertToDatabaseValue($date, $this->_platform);
$this->assertEquals($expected, $actual);
}
......
......@@ -24,7 +24,7 @@ class DateTimeTzTest extends \Doctrine\Tests\DbalTestCase
$date = new \DateTime('1985-09-01 10:10:10');
$expected = $date->format($this->_platform->getDateTimeTzFormatString());
$actual = is_string($this->_type->convertToDatabaseValue($date, $this->_platform));
$actual = $this->_type->convertToDatabaseValue($date, $this->_platform);
$this->assertEquals($expected, $actual);
}
......
......@@ -27,7 +27,7 @@ class VarDateTimeTest extends \Doctrine\Tests\DbalTestCase
$date = new \DateTime('1985-09-01 10:10:10');
$expected = $date->format($this->_platform->getDateTimeTzFormatString());
$actual = is_string($this->_type->convertToDatabaseValue($date, $this->_platform));
$actual = $this->_type->convertToDatabaseValue($date, $this->_platform);
$this->assertEquals($expected, $actual);
}
......
<?xml version="1.0" encoding="utf-8"?>
<phpunit>
<php>
<var name="db_type" value="pdo_mysql"/>
<var name="db_host" value="localhost" />
<var name="db_username" value="travis" />
<var name="db_password" value="" />
<var name="db_name" value="doctrine_tests" />
<var name="db_port" value="3306"/>
<var name="tmpdb_type" value="pdo_mysql"/>
<var name="tmpdb_host" value="localhost" />
<var name="tmpdb_username" value="travis" />
<var name="tmpdb_password" value="" />
<var name="tmpdb_name" value="doctrine_tests_tmp" />
<var name="tmpdb_port" value="3306"/>
</php>
<testsuites>
<testsuite name="Doctrine Test Suite">
<directory>./../Doctrine/Tests</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>performance</group>
<group>locking_functional</group>
</exclude>
</groups>
</phpunit>
<?xml version="1.0" encoding="utf-8"?>
<phpunit>
<php>
<var name="db_type" value="pdo_pgsql"/>
<var name="db_host" value="localhost" />
<var name="db_username" value="postgres" />
<var name="db_password" value="" />
<var name="db_name" value="doctrine_tests" />
<var name="db_port" value="5432"/>
<var name="tmpdb_type" value="pdo_pgsql"/>
<var name="tmpdb_host" value="localhost" />
<var name="tmpdb_username" value="postgres" />
<var name="tmpdb_password" value="" />
<var name="tmpdb_name" value="doctrine_tests_tmp" />
<var name="tmpdb_port" value="5432"/>
</php>
<testsuites>
<testsuite name="Doctrine Test Suite">
<directory>./../Doctrine/Tests</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>performance</group>
<group>locking_functional</group>
</exclude>
</groups>
</phpunit>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<phpunit>
<testsuites>
<testsuite name="Doctrine Test Suite">
<directory>./../Doctrine/Tests</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>performance</group>
<group>locking_functional</group>
</exclude>
</groups>
</phpunit>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment