Skip to content

Commit

Permalink
add more foreign key constraint violation error codes
Browse files Browse the repository at this point in the history
  • Loading branch information
deeky666 committed Oct 26, 2014
1 parent b96c710 commit 2fffefe
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 15 deletions.
1 change: 1 addition & 0 deletions lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php
Expand Up @@ -56,6 +56,7 @@ public function convertException($message, DriverException $exception)
case '1217':
case '1451':
case '1452':
case '1701':
return new Exception\ForeignKeyConstraintViolationException($message, $exception);

case '1062':
Expand Down
4 changes: 3 additions & 1 deletion lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php
Expand Up @@ -67,6 +67,8 @@ public function convertException($message, DriverException $exception)
case '1400':
return new Exception\NotNullConstraintViolationException($message, $exception);

case '2266':
case '2291':
case '2292':
return new Exception\ForeignKeyConstraintViolationException($message, $exception);
}
Expand Down Expand Up @@ -129,7 +131,7 @@ protected function getEasyConnectString(array $params)
if (isset($params['service']) && $params['service'] == true) {
$service = 'SERVICE_NAME=' . $serviceName;
}

if (isset($params['instancename']) && ! empty($params['instancename'])) {
$instance = '(INSTANCE_NAME = ' . $params['instancename'] . ')';
}
Expand Down
9 changes: 9 additions & 0 deletions lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php
Expand Up @@ -45,6 +45,14 @@ abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDri
public function convertException($message, DriverException $exception)
{
switch ($exception->getSQLState()) {
case '0A000':
// Foreign key constraint violations during a TRUNCATE operation
// are considered "feature not supported" in PostgreSQL.
if (strpos($exception->getMessage(), 'truncate') !== false) {
return new Exception\ForeignKeyConstraintViolationException($message, $exception);
}

break;
case '23502':
return new Exception\NotNullConstraintViolationException($message, $exception);

Expand Down Expand Up @@ -76,6 +84,7 @@ public function convertException($message, DriverException $exception)
if (strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) {
return new Exception\ConnectionException($message, $exception);
}

break;
}

Expand Down
1 change: 1 addition & 0 deletions lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php
Expand Up @@ -55,6 +55,7 @@ public function convertException($message, DriverException $exception)
case '-193':
case '-196':
return new Exception\UniqueConstraintViolationException($message, $exception);
case '-194':
case '-198':
return new Exception\ForeignKeyConstraintViolationException($message, $exception);
case '-144':
Expand Down
87 changes: 73 additions & 14 deletions tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php
Expand Up @@ -2,16 +2,39 @@
namespace Doctrine\Tests\DBAL\Functional;

use Doctrine\DBAL\Driver\ExceptionConverterDriver;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;

class ExceptionTest extends \Doctrine\Tests\DbalFunctionalTestCase
{
public function setUp()
private static $running = false;

protected function setUp()
{
parent::setUp();

if ( !($this->_conn->getDriver() instanceof ExceptionConverterDriver)) {
$this->markTestSkipped('Driver does not support special exception handling.');
}

if ( ! self::$running) {
$schemaManager = $this->_conn->getSchemaManager();

$table = new Table("constraint_error_table");
$table->addColumn('id', 'integer', array());
$table->setPrimaryKey(array('id'));

$owningTable = new Table("owning_table");
$owningTable->addColumn('id', 'integer', array());
$owningTable->addColumn('constraint_id', 'integer', array());
$owningTable->setPrimaryKey(array('id'));
$owningTable->addForeignKeyConstraint($table, array('constraint_id'), array('id'));

$schemaManager->createTable($table);
$schemaManager->createTable($owningTable);

self::$running = true;
}
}

public function testPrimaryConstraintViolationException()
Expand Down Expand Up @@ -54,35 +77,72 @@ public function testTableExistsException()
}
}

public function testForeignKeyContraintViolationException()
public function testForeignKeyContraintViolationExceptionOnInsert()
{
if ( ! $this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$this->markTestSkipped("Only fails on platforms with foreign key constraints.");
}

$schema = new \Doctrine\DBAL\Schema\Schema();
$this->_conn->executeUpdate('DELETE FROM owning_table');
$this->_conn->executeUpdate('DELETE FROM constraint_error_table');

$table = $schema->createTable("constraint_error_table");
$table->addColumn('id', 'integer', array());
$table->setPrimaryKey(array('id'));
$this->_conn->insert("constraint_error_table", array('id' => 1));
$this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));

$owningTable = $schema->createTable("owning_table");
$owningTable->addColumn('id', 'integer', array());
$owningTable->addColumn('constraint_id', 'integer', array());
$owningTable->setPrimaryKey(array('id'));
$owningTable->addForeignKeyConstraint($table, array('constraint_id'), array('id'));
$this->setExpectedException('\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException');
$this->_conn->insert('owning_table', array('id' => 2, 'constraint_id' => 2));
}

foreach ($schema->toSql($this->_conn->getDatabasePlatform()) as $sql) {
$this->_conn->executeQuery($sql);
public function testForeignKeyContraintViolationExceptionOnUpdate()
{
if ( ! $this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$this->markTestSkipped("Only fails on platforms with foreign key constraints.");
}

$this->_conn->executeUpdate('DELETE FROM owning_table');
$this->_conn->executeUpdate('DELETE FROM constraint_error_table');

$this->_conn->insert("constraint_error_table", array('id' => 1));
$this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));

$this->setExpectedException('\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException');
$this->_conn->update('constraint_error_table', array('id' => 2), array('id' => 1));
}

public function testForeignKeyContraintViolationExceptionOnDelete()
{
if ( ! $this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$this->markTestSkipped("Only fails on platforms with foreign key constraints.");
}

$this->_conn->executeUpdate('DELETE FROM owning_table');
$this->_conn->executeUpdate('DELETE FROM constraint_error_table');

$this->_conn->insert("constraint_error_table", array('id' => 1));
$this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));

$this->setExpectedException('\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException');
$this->_conn->delete('constraint_error_table', array('id' => 1));
}

public function testForeignKeyContraintViolationExceptionOnTruncate()
{
$platform = $this->_conn->getDatabasePlatform();

if ( ! $platform->supportsForeignKeyConstraints()) {
$this->markTestSkipped("Only fails on platforms with foreign key constraints.");
}

$this->_conn->executeUpdate('DELETE FROM owning_table');
$this->_conn->executeUpdate('DELETE FROM constraint_error_table');

$this->_conn->insert("constraint_error_table", array('id' => 1));
$this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));

$this->setExpectedException('\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException');
$this->_conn->executeUpdate($platform->getTruncateTableSQL('constraint_error_table'));
}

public function testNotNullConstraintViolationException()
{
$schema = new \Doctrine\DBAL\Schema\Schema();
Expand Down Expand Up @@ -250,4 +310,3 @@ public function getConnectionParams()
);
}
}

0 comments on commit 2fffefe

Please sign in to comment.