Commit b0bbe281 authored by beberlei's avatar beberlei

[2.0] DDC-169 - Introduced handling of schema / database case-sensitivity...

[2.0] DDC-169 - Introduced handling of schema / database case-sensitivity differences and to allow compability between different platforms.
parent 15f84f6e
...@@ -35,11 +35,20 @@ namespace Doctrine\DBAL\Schema; ...@@ -35,11 +35,20 @@ namespace Doctrine\DBAL\Schema;
*/ */
abstract class AbstractAsset abstract class AbstractAsset
{ {
const CASE_UPPER = "upper";
const CASE_LOWER = "lower";
const CASE_KEEP = "keep";
/** /**
* @var string * @var string
*/ */
protected $_name; protected $_name;
/**
* @var int
*/
protected $_caseMode = self::CASE_KEEP;
/** /**
* Set name of this asset * Set name of this asset
* *
...@@ -57,7 +66,7 @@ abstract class AbstractAsset ...@@ -57,7 +66,7 @@ abstract class AbstractAsset
*/ */
public function getName() public function getName()
{ {
return $this->_name; return $this->_foldIdentifier($this->_name);
} }
/** /**
...@@ -82,4 +91,47 @@ abstract class AbstractAsset ...@@ -82,4 +91,47 @@ abstract class AbstractAsset
$parts[] = $postfix; $parts[] = $postfix;
return trim(implode("_", $parts), '_'); return trim(implode("_", $parts), '_');
} }
/**
* Set the case mode of this asset.
*
* @param string $caseMode
* @return void
*/
public function setCaseMode($caseMode)
{
if (!in_array($caseMode, array(self::CASE_KEEP, self::CASE_LOWER, self::CASE_UPPER))) {
throw SchemaException::invalidCaseModeGiven($caseMode);
}
$this->_caseMode = $caseMode;
}
/**
* Fold the case of the identifier based on the CASE_* constants.
*
* This has never to be applied on write operation, only on read! This ensures that you can change
* the case at any point. For the keys of arrays however we always store them in lower-case which
* makes it easy to access them. This affects the maps in Schema and Table instances.
*
* @param string $identifier
* @return string
*/
protected function _foldIdentifier($identifier)
{
if ($this->_caseMode == self::CASE_UPPER) {
return strtoupper($identifier);
} else if ($this->_caseMode == self::CASE_LOWER) {
return strtolower($identifier);
}
return $identifier;
}
/**
* @param array $identifiers
* @return array
*/
protected function _foldIdentifiers($identifiers)
{
return array_map(array($this, '_foldIdentifier'), $identifiers);
}
} }
\ No newline at end of file
...@@ -213,6 +213,8 @@ abstract class AbstractSchemaManager ...@@ -213,6 +213,8 @@ abstract class AbstractSchemaManager
/** /**
* List the indexes for a given table returning an array of Index instances. * List the indexes for a given table returning an array of Index instances.
* *
* Keys of the portable indexes list are all lower-cased.
*
* @param string $table The name of the table * @param string $table The name of the table
* @return Index[] $tableIndexes * @return Index[] $tableIndexes
*/ */
...@@ -830,12 +832,21 @@ abstract class AbstractSchemaManager ...@@ -830,12 +832,21 @@ abstract class AbstractSchemaManager
return $tableConstraint; return $tableConstraint;
} }
/**
* Independent of the database the keys of the column list result are lowercased.
*
* The name of the created column instance however is kept in its case.
*
* @param array $tableColumns
* @return array
*/
protected function _getPortableTableColumnList($tableColumns) protected function _getPortableTableColumnList($tableColumns)
{ {
$list = array(); $list = array();
foreach ($tableColumns as $key => $column) { foreach ($tableColumns as $key => $column) {
if ($column = $this->_getPortableTableColumnDefinition($column)) { if ($column = $this->_getPortableTableColumnDefinition($column)) {
$list[$column->getName()] = $column; $name = strtolower($column->getName());
$list[$name] = $column;
} }
} }
return $list; return $list;
...@@ -864,6 +875,7 @@ abstract class AbstractSchemaManager ...@@ -864,6 +875,7 @@ abstract class AbstractSchemaManager
if($tableIndex['primary']) { if($tableIndex['primary']) {
$keyName = 'primary'; $keyName = 'primary';
} }
$keyName = strtolower($keyName);
if(!isset($result[$keyName])) { if(!isset($result[$keyName])) {
$result[$keyName] = array( $result[$keyName] = array(
......
...@@ -72,12 +72,12 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint ...@@ -72,12 +72,12 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
*/ */
public function getLocalColumns() public function getLocalColumns()
{ {
return $this->_localColumnNames; return $this->_foldIdentifiers($this->_localColumnNames);
} }
public function getColumns() public function getColumns()
{ {
return $this->_localColumnNames; return $this->_foldIdentifiers($this->_localColumnNames);
} }
/** /**
...@@ -85,7 +85,7 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint ...@@ -85,7 +85,7 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
*/ */
public function getForeignTableName() public function getForeignTableName()
{ {
return $this->_foreignTableName; return $this->_foldIdentifier($this->_foreignTableName);
} }
/** /**
...@@ -93,7 +93,7 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint ...@@ -93,7 +93,7 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
*/ */
public function getForeignColumns() public function getForeignColumns()
{ {
return $this->_foreignColumnNames; return $this->_foldIdentifiers($this->_foreignColumnNames);
} }
public function hasOption($name) public function hasOption($name)
......
...@@ -76,7 +76,7 @@ class Index extends AbstractAsset implements Constraint ...@@ -76,7 +76,7 @@ class Index extends AbstractAsset implements Constraint
*/ */
public function getColumns() public function getColumns()
{ {
return $this->_columns; return $this->_foldIdentifiers($this->_columns);
} }
/** /**
...@@ -102,6 +102,7 @@ class Index extends AbstractAsset implements Constraint ...@@ -102,6 +102,7 @@ class Index extends AbstractAsset implements Constraint
*/ */
public function hasColumnAtPosition($columnName, $pos=0) public function hasColumnAtPosition($columnName, $pos=0)
{ {
return \array_search($columnName, $this->_columns) === $pos; $columnName = $this->_foldIdentifier($columnName);
return \array_search($columnName, $this->getColumns()) === $pos;
} }
} }
\ No newline at end of file
...@@ -65,6 +65,8 @@ class Schema extends AbstractAsset ...@@ -65,6 +65,8 @@ class Schema extends AbstractAsset
*/ */
protected function _addTable(Table $table) protected function _addTable(Table $table)
{ {
$table->setCaseMode($this->_caseMode);
$tableName = strtolower($table->getName()); $tableName = strtolower($table->getName());
if(isset($this->_tables[$tableName])) { if(isset($this->_tables[$tableName])) {
throw SchemaException::tableAlreadyExists($tableName); throw SchemaException::tableAlreadyExists($tableName);
...@@ -78,6 +80,8 @@ class Schema extends AbstractAsset ...@@ -78,6 +80,8 @@ class Schema extends AbstractAsset
*/ */
protected function _addSequence(Sequence $sequence) protected function _addSequence(Sequence $sequence)
{ {
$sequence->setCaseMode($this->_caseMode);
$seqName = strtolower($sequence->getName()); $seqName = strtolower($sequence->getName());
if (isset($this->_sequences[$seqName])) { if (isset($this->_sequences[$seqName])) {
throw SchemaException::sequenceAlreadyExists($seqName); throw SchemaException::sequenceAlreadyExists($seqName);
......
...@@ -109,4 +109,9 @@ class SchemaException extends \Doctrine\DBAL\DBALException ...@@ -109,4 +109,9 @@ class SchemaException extends \Doctrine\DBAL\DBALException
{ {
return new self("There exists no foreign key with the name '".$fkName."'.", self::FOREIGNKEY_DOESNT_EXIST); return new self("There exists no foreign key with the name '".$fkName."'.", self::FOREIGNKEY_DOESNT_EXIST);
} }
static public function invalidCaseModeGiven()
{
return new self("Invalid case mode given to Schema Asset.");
}
} }
\ No newline at end of file
...@@ -96,7 +96,7 @@ class Table extends AbstractAsset ...@@ -96,7 +96,7 @@ class Table extends AbstractAsset
*/ */
public function __construct($tableName, array $columns=array(), array $indexes=array(), array $fkConstraints=array(), $idGeneratorType=self::ID_NONE, array $options=array()) public function __construct($tableName, array $columns=array(), array $indexes=array(), array $fkConstraints=array(), $idGeneratorType=self::ID_NONE, array $options=array())
{ {
$this->_name = $tableName; $this->_setName($tableName);
$this->_idGeneratorType = $idGeneratorType; $this->_idGeneratorType = $idGeneratorType;
foreach ($columns AS $column) { foreach ($columns AS $column) {
...@@ -215,7 +215,6 @@ class Table extends AbstractAsset ...@@ -215,7 +215,6 @@ class Table extends AbstractAsset
*/ */
public function renameColumn($oldColumnName, $newColumnName) public function renameColumn($oldColumnName, $newColumnName)
{ {
$columnName = strtolower($columnName);
$column = $this->getColumn($oldColumnName); $column = $this->getColumn($oldColumnName);
$this->dropColumn($oldColumnName); $this->dropColumn($oldColumnName);
...@@ -232,7 +231,6 @@ class Table extends AbstractAsset ...@@ -232,7 +231,6 @@ class Table extends AbstractAsset
*/ */
public function changeColumn($columnName, array $options) public function changeColumn($columnName, array $options)
{ {
$columnName = strtolower($columnName);
$column = $this->getColumn($columnName); $column = $this->getColumn($columnName);
$column->setOptions($options); $column->setOptions($options);
return $this; return $this;
...@@ -339,9 +337,13 @@ class Table extends AbstractAsset ...@@ -339,9 +337,13 @@ class Table extends AbstractAsset
*/ */
protected function _addColumn(Column $column) protected function _addColumn(Column $column)
{ {
$columnName = strtolower($column->getName()); $column->setCaseMode($this->_caseMode);
$columnName = $column->getName();
$columnName = strtolower($columnName);
if (isset($this->_columns[$columnName])) { if (isset($this->_columns[$columnName])) {
throw SchemaException::columnAlreadyExists($this->_name, $columnName); throw SchemaException::columnAlreadyExists($this->getName(), $columnName);
} }
$this->_columns[$columnName] = $column; $this->_columns[$columnName] = $column;
...@@ -355,7 +357,10 @@ class Table extends AbstractAsset ...@@ -355,7 +357,10 @@ class Table extends AbstractAsset
*/ */
protected function _addIndex(Index $index) protected function _addIndex(Index $index)
{ {
$index->setCaseMode($this->_caseMode);
$indexName = $index->getName(); $indexName = $index->getName();
$indexName = strtolower($indexName);
if (isset($this->_indexes[$indexName]) || ($this->_primaryKeyName != false && $index->isPrimary())) { if (isset($this->_indexes[$indexName]) || ($this->_primaryKeyName != false && $index->isPrimary())) {
throw SchemaException::indexAlreadyExists($indexName); throw SchemaException::indexAlreadyExists($indexName);
...@@ -374,6 +379,8 @@ class Table extends AbstractAsset ...@@ -374,6 +379,8 @@ class Table extends AbstractAsset
*/ */
protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint) protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint)
{ {
$constraint->setCaseMode($this->_caseMode);
if(strlen($constraint->getName())) { if(strlen($constraint->getName())) {
$name = $constraint->getName(); $name = $constraint->getName();
} else { } else {
...@@ -381,6 +388,7 @@ class Table extends AbstractAsset ...@@ -381,6 +388,7 @@ class Table extends AbstractAsset
array_merge((array)$this->getName(), $constraint->getLocalColumns()), "fk" array_merge((array)$this->getName(), $constraint->getLocalColumns()), "fk"
); );
} }
$name = strtolower($name);
$this->_fkConstraints[$name] = $constraint; $this->_fkConstraints[$name] = $constraint;
} }
...@@ -393,6 +401,7 @@ class Table extends AbstractAsset ...@@ -393,6 +401,7 @@ class Table extends AbstractAsset
*/ */
public function hasForeignKey($constraintName) public function hasForeignKey($constraintName)
{ {
$constraintName = strtolower($constraintName);
return isset($this->_fkConstraints[$constraintName]); return isset($this->_fkConstraints[$constraintName]);
} }
...@@ -402,6 +411,7 @@ class Table extends AbstractAsset ...@@ -402,6 +411,7 @@ class Table extends AbstractAsset
*/ */
public function getForeignKey($constraintName) public function getForeignKey($constraintName)
{ {
$constraintName = strtolower($constraintName);
if(!$this->hasForeignKey($constraintName)) { if(!$this->hasForeignKey($constraintName)) {
throw SchemaException::foreignKeyDoesNotExist($constraintName); throw SchemaException::foreignKeyDoesNotExist($constraintName);
} }
...@@ -476,6 +486,7 @@ class Table extends AbstractAsset ...@@ -476,6 +486,7 @@ class Table extends AbstractAsset
*/ */
public function hasIndex($indexName) public function hasIndex($indexName)
{ {
$indexName = strtolower($indexName);
return (isset($this->_indexes[$indexName])); return (isset($this->_indexes[$indexName]));
} }
...@@ -485,6 +496,7 @@ class Table extends AbstractAsset ...@@ -485,6 +496,7 @@ class Table extends AbstractAsset
*/ */
public function getIndex($indexName) public function getIndex($indexName)
{ {
$indexName = strtolower($indexName);
if (!$this->hasIndex($indexName)) { if (!$this->hasIndex($indexName)) {
throw SchemaException::indexDoesNotExist($indexName); throw SchemaException::indexDoesNotExist($indexName);
} }
......
...@@ -109,15 +109,6 @@ class CreateSchemaSqlCollector implements Visitor ...@@ -109,15 +109,6 @@ class CreateSchemaSqlCollector implements Visitor
} }
/**
* @param Table $table
* @param Constraint $constraint
*/
public function acceptCheckConstraint(Table $table, Constraint $constraint)
{
}
/** /**
* @param Sequence $sequence * @param Sequence $sequence
*/ */
......
...@@ -107,15 +107,6 @@ class DropSchemaSqlCollector implements Visitor ...@@ -107,15 +107,6 @@ class DropSchemaSqlCollector implements Visitor
); );
} }
/**
* @param Table $table
* @param Constraint $constraint
*/
public function acceptCheckConstraint(Table $table, Constraint $constraint)
{
}
/** /**
* @param Table $table * @param Table $table
* @param Index $index * @param Index $index
......
...@@ -62,12 +62,6 @@ interface Visitor ...@@ -62,12 +62,6 @@ interface Visitor
*/ */
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint); public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint);
/**
* @param Table $table
* @param Constraint $constraint
*/
public function acceptCheckConstraint(Table $table, Constraint $constraint);
/** /**
* @param Table $table * @param Table $table
* @param Index $index * @param Index $index
......
...@@ -69,7 +69,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -69,7 +69,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$foundTable = false; $foundTable = false;
foreach ($tables AS $table) { foreach ($tables AS $table) {
$this->assertType('Doctrine\DBAL\Schema\Table', $table); $this->assertType('Doctrine\DBAL\Schema\Table', $table);
if (strtolower($table->getName()) == 'list_tables_test') { if ($table->getName() == 'list_tables_test') {
$foundTable = true; $foundTable = true;
$this->assertTrue($table->hasColumn('id')); $this->assertTrue($table->hasColumn('id'));
...@@ -94,10 +94,12 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -94,10 +94,12 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$columns = $this->_sm->listTableColumns('list_table_columns'); $columns = $this->_sm->listTableColumns('list_table_columns');
$columns = \array_change_key_case($columns, CASE_LOWER); foreach ($columns AS $column) {
$column->setCaseMode("lower");
}
$this->assertArrayHasKey('id', $columns); $this->assertArrayHasKey('id', $columns);
$this->assertEquals('id', strtolower($columns['id']->getname())); $this->assertEquals('id', $columns['id']->getname());
$this->assertType('Doctrine\DBAL\Types\IntegerType', $columns['id']->gettype()); $this->assertType('Doctrine\DBAL\Types\IntegerType', $columns['id']->gettype());
$this->assertEquals(false, $columns['id']->getunsigned()); $this->assertEquals(false, $columns['id']->getunsigned());
$this->assertEquals(true, $columns['id']->getnotnull()); $this->assertEquals(true, $columns['id']->getnotnull());
...@@ -105,7 +107,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -105,7 +107,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$this->assertType('array', $columns['id']->getPlatformOptions()); $this->assertType('array', $columns['id']->getPlatformOptions());
$this->assertArrayHasKey('test', $columns); $this->assertArrayHasKey('test', $columns);
$this->assertEquals('test', strtolower($columns['test']->getname())); $this->assertEquals('test', $columns['test']->getname());
$this->assertType('Doctrine\DBAL\Types\StringType', $columns['test']->gettype()); $this->assertType('Doctrine\DBAL\Types\StringType', $columns['test']->gettype());
$this->assertEquals(255, $columns['test']->getlength()); $this->assertEquals(255, $columns['test']->getlength());
$this->assertEquals(false, $columns['test']->getfixed()); $this->assertEquals(false, $columns['test']->getfixed());
...@@ -113,7 +115,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -113,7 +115,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$this->assertEquals(null, $columns['test']->getdefault()); $this->assertEquals(null, $columns['test']->getdefault());
$this->assertType('array', $columns['test']->getPlatformOptions()); $this->assertType('array', $columns['test']->getPlatformOptions());
$this->assertEquals('foo', strtolower($columns['foo']->getname())); $this->assertEquals('foo', ($columns['foo']->getname()));
$this->assertType('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype()); $this->assertType('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype());
$this->assertEquals(null, $columns['foo']->getlength()); $this->assertEquals(null, $columns['foo']->getlength());
$this->assertEquals(false, $columns['foo']->getunsigned()); $this->assertEquals(false, $columns['foo']->getunsigned());
...@@ -122,7 +124,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -122,7 +124,7 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$this->assertEquals(null, $columns['foo']->getdefault()); $this->assertEquals(null, $columns['foo']->getdefault());
$this->assertType('array', $columns['foo']->getPlatformOptions()); $this->assertType('array', $columns['foo']->getPlatformOptions());
$this->assertEquals('bar', strtolower($columns['bar']->getname())); $this->assertEquals('bar', ($columns['bar']->getname()));
$this->assertType('Doctrine\DBAL\Types\DecimalType', $columns['bar']->gettype()); $this->assertType('Doctrine\DBAL\Types\DecimalType', $columns['bar']->gettype());
$this->assertEquals(null, $columns['bar']->getlength()); $this->assertEquals(null, $columns['bar']->getlength());
$this->assertEquals(10, $columns['bar']->getprecision()); $this->assertEquals(10, $columns['bar']->getprecision());
...@@ -133,19 +135,19 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -133,19 +135,19 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$this->assertEquals(null, $columns['bar']->getdefault()); $this->assertEquals(null, $columns['bar']->getdefault());
$this->assertType('array', $columns['bar']->getPlatformOptions()); $this->assertType('array', $columns['bar']->getPlatformOptions());
$this->assertEquals('baz1', strtolower($columns['baz1']->getname())); $this->assertEquals('baz1', ($columns['baz1']->getname()));
$this->assertType('Doctrine\DBAL\Types\DateTimeType', $columns['baz1']->gettype()); $this->assertType('Doctrine\DBAL\Types\DateTimeType', $columns['baz1']->gettype());
$this->assertEquals(true, $columns['baz1']->getnotnull()); $this->assertEquals(true, $columns['baz1']->getnotnull());
$this->assertEquals(null, $columns['baz1']->getdefault()); $this->assertEquals(null, $columns['baz1']->getdefault());
$this->assertType('array', $columns['baz1']->getPlatformOptions()); $this->assertType('array', $columns['baz1']->getPlatformOptions());
$this->assertEquals('baz2', strtolower($columns['baz2']->getname())); $this->assertEquals('baz2', ($columns['baz2']->getname()));
$this->assertContains($columns['baz2']->gettype()->getName(), array('Time', 'Date', 'DateTime')); $this->assertContains($columns['baz2']->gettype()->getName(), array('Time', 'Date', 'DateTime'));
$this->assertEquals(true, $columns['baz2']->getnotnull()); $this->assertEquals(true, $columns['baz2']->getnotnull());
$this->assertEquals(null, $columns['baz2']->getdefault()); $this->assertEquals(null, $columns['baz2']->getdefault());
$this->assertType('array', $columns['baz2']->getPlatformOptions()); $this->assertType('array', $columns['baz2']->getPlatformOptions());
$this->assertEquals('baz3', strtolower($columns['baz3']->getname())); $this->assertEquals('baz3', ($columns['baz3']->getname()));
$this->assertContains($columns['baz2']->gettype()->getName(), array('Time', 'Date', 'DateTime')); $this->assertContains($columns['baz2']->gettype()->getName(), array('Time', 'Date', 'DateTime'));
$this->assertEquals(true, $columns['baz3']->getnotnull()); $this->assertEquals(true, $columns['baz3']->getnotnull());
$this->assertEquals(null, $columns['baz3']->getdefault()); $this->assertEquals(null, $columns['baz3']->getdefault());
...@@ -212,11 +214,15 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -212,11 +214,15 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$fkeys = $this->_sm->listTableForeignKeys('test_create_fk1'); $fkeys = $this->_sm->listTableForeignKeys('test_create_fk1');
foreach ($fkeys AS $fkey) {
$fkey->setCaseMode("lower");
}
$this->assertEquals(1, count($fkeys)); $this->assertEquals(1, count($fkeys));
$this->assertType('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]); $this->assertType('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
$this->assertEquals(array('foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns())); $this->assertEquals(array('foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
$this->assertEquals(array('id'), array_map('strtolower', $fkeys[0]->getForeignColumns())); $this->assertEquals(array('id'), array_map('strtolower', $fkeys[0]->getForeignColumns()));
$this->assertEquals('test_create_fk2', strtolower($fkeys[0]->getForeignTableName())); $this->assertEquals('test_create_fk2', ($fkeys[0]->getForeignTableName()));
if($fkeys[0]->hasOption('onUpdate')) { if($fkeys[0]->hasOption('onUpdate')) {
$this->assertEquals('CASCADE', $fkeys[0]->getOption('onUpdate')); $this->assertEquals('CASCADE', $fkeys[0]->getOption('onUpdate'));
......
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