Commit 18c3c175 authored by dazz's avatar dazz Committed by Benjamin Eberlei

[DBAL-407] Implement error detection on foreign key constraint exception for mysql and sqlite

parent f8b46957
...@@ -24,6 +24,7 @@ class DBALException extends \Exception ...@@ -24,6 +24,7 @@ class DBALException extends \Exception
const ERROR_DUPLICATE_KEY = 1; const ERROR_DUPLICATE_KEY = 1;
const ERROR_UNKNOWN_TABLE = 2; const ERROR_UNKNOWN_TABLE = 2;
const ERROR_TABLE_ALREADY_EXISTS = 3; const ERROR_TABLE_ALREADY_EXISTS = 3;
const ERROR_FOREIGN_KEY_CONSTRAINT = 4;
/** /**
* @param string $method * @param string $method
......
...@@ -117,6 +117,10 @@ class Driver implements \Doctrine\DBAL\Driver ...@@ -117,6 +117,10 @@ class Driver implements \Doctrine\DBAL\Driver
{ {
switch ($exception->getCode()) { switch ($exception->getCode()) {
case 23000: case 23000:
if (strpos($exception->getMessage(), 'Cannot delete or update a parent row: a foreign key constraint fails') !== false) {
return DBALException::ERROR_FOREIGN_KEY_CONSTRAINT;
}
return DBALException::ERROR_DUPLICATE_KEY; return DBALException::ERROR_DUPLICATE_KEY;
case '42S02': case '42S02':
return DBALException::ERROR_UNKNOWN_TABLE; return DBALException::ERROR_UNKNOWN_TABLE;
......
...@@ -34,7 +34,7 @@ class ExceptionTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -34,7 +34,7 @@ class ExceptionTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testTableAlreadyExists() public function testTableAlreadyExists()
{ {
$table = new \Doctrine\DBAL\Schema\Table("duplicatekey_table"); $table = new \Doctrine\DBAL\Schema\Table("alreadyexist_table");
$table->addColumn('id', 'integer', array()); $table->addColumn('id', 'integer', array());
$table->setPrimaryKey(array('id')); $table->setPrimaryKey(array('id'));
...@@ -46,5 +46,34 @@ class ExceptionTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -46,5 +46,34 @@ class ExceptionTest extends \Doctrine\Tests\DbalFunctionalTestCase
$this->_conn->executeQuery($sql); $this->_conn->executeQuery($sql);
} }
} }
public function testForeignKeyContraintException()
{
if ( ! $this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$this->markTestSkipped("Only fails on platforms with foreign key constraints.");
}
$schema = new \Doctrine\DBAL\Schema\Schema();
$table = $schema->createTable("constraint_error_table");
$table->addColumn('id', 'integer', array());
$table->setPrimaryKey(array('id'));
$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'));
foreach ($schema->toSql($this->_conn->getDatabasePlatform()) AS $sql) {
$this->_conn->executeQuery($sql);
}
$this->_conn->insert("constraint_error_table", array('id' => 1));
$this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));
$this->setExpectedException('\Doctrine\DBAL\DBALException', null, DBALException::ERROR_FOREIGN_KEY_CONSTRAINT);
$this->_conn->delete('constraint_error_table', array('id' => 1));
}
} }
\ 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