Skip to content

Commit

Permalink
Merge pull request doctrine#6830 from Tobion/fix-collation-foreign-key
Browse files Browse the repository at this point in the history
fix applying column options on foreign key columns
  • Loading branch information
lcobucci committed Nov 20, 2018
2 parents f80656c + 0be52b0 commit 41ff526
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 16 deletions.
38 changes: 22 additions & 16 deletions lib/Doctrine/ORM/Tools/SchemaTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
*/
class SchemaTool
{
private const KNOWN_COLUMN_OPTIONS = ['comment', 'unsigned', 'fixed', 'default'];

/**
* @var \Doctrine\ORM\EntityManagerInterface
*/
Expand Down Expand Up @@ -467,19 +469,8 @@ private function gatherColumn($class, array $mapping, Table $table)
$options['columnDefinition'] = $mapping['columnDefinition'];
}

if (isset($mapping['options'])) {
$knownOptions = ['comment', 'unsigned', 'fixed', 'default'];

foreach ($knownOptions as $knownOption) {
if (array_key_exists($knownOption, $mapping['options'])) {
$options[$knownOption] = $mapping['options'][$knownOption];

unset($mapping['options'][$knownOption]);
}
}

$options['customSchemaOptions'] = $mapping['options'];
}
// the 'default' option can be overwritten here
$options = $this->gatherColumnOptions($mapping) + $options;

if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == [$mapping['fieldName']]) {
$options['autoincrement'] = true;
Expand Down Expand Up @@ -690,9 +681,7 @@ private function gatherRelationJoinColumns(
$columnOptions['notnull'] = ! $joinColumn['nullable'];
}

if (isset($fieldMapping['options'])) {
$columnOptions['options'] = $fieldMapping['options'];
}
$columnOptions = $columnOptions + $this->gatherColumnOptions($fieldMapping);

if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) {
$columnOptions['length'] = $fieldMapping['length'];
Expand Down Expand Up @@ -745,6 +734,23 @@ private function gatherRelationJoinColumns(
}
}

/**
* @param mixed[] $mapping
*
* @return mixed[]
*/
private function gatherColumnOptions(array $mapping) : array
{
if (! isset($mapping['options'])) {
return [];
}

$options = array_intersect_key($mapping['options'], array_flip(self::KNOWN_COLUMN_OPTIONS));
$options['customSchemaOptions'] = array_diff_key($mapping['options'], $options);

return $options;
}

/**
* Drops the database schema for the given classes.
*
Expand Down
77 changes: 77 additions & 0 deletions tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedIdentityClass;
use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedRootClass;
use Doctrine\Tests\Models\Forum\ForumAvatar;
use Doctrine\Tests\Models\Forum\ForumBoard;
use Doctrine\Tests\Models\Forum\ForumCategory;
use Doctrine\Tests\Models\Forum\ForumUser;
use Doctrine\Tests\Models\NullDefault\NullDefaultColumn;
use Doctrine\Tests\OrmTestCase;
Expand Down Expand Up @@ -86,6 +88,44 @@ public function testPassColumnDefinitionToJoinColumn()
$this->assertEquals($customColumnDef, $table->getColumn('avatar_id')->getColumnDefinition());
}

/**
* @group 6830
*/
public function testPassColumnOptionsToJoinColumn() : void
{
$em = $this->_getTestEntityManager();
$category = $em->getClassMetadata(GH6830Category::class);
$board = $em->getClassMetadata(GH6830Board::class);

$schemaTool = new SchemaTool($em);
$schema = $schemaTool->getSchemaFromMetadata([$category, $board]);

self::assertTrue($schema->hasTable('GH6830Category'));
self::assertTrue($schema->hasTable('GH6830Board'));

$tableCategory = $schema->getTable('GH6830Category');
$tableBoard = $schema->getTable('GH6830Board');

self::assertTrue($tableBoard->hasColumn('category_id'));

self::assertSame(
$tableCategory->getColumn('id')->getFixed(),
$tableBoard->getColumn('category_id')->getFixed(),
'Foreign key/join column should have the same value of option `fixed` as the referenced column'
);

self::assertEquals(
$tableCategory->getColumn('id')->getCustomSchemaOptions(),
$tableBoard->getColumn('category_id')->getCustomSchemaOptions(),
'Foreign key/join column should have the same custom options as the referenced column'
);

self::assertEquals(
['collation' => 'latin1_bin', 'foo' => 'bar'],
$tableBoard->getColumn('category_id')->getCustomSchemaOptions()
);
}

/**
* @group DDC-283
*/
Expand Down Expand Up @@ -322,3 +362,40 @@ class SecondEntity
*/
public $name;
}

/**
* @Entity
*/
class GH6830Board
{
/**
* @Id
* @Column(type="integer")
*/
public $id;

/**
* @ManyToOne(targetEntity=GH6830Category::class, inversedBy="boards")
* @JoinColumn(name="category_id", referencedColumnName="id")
*/
public $category;
}

/**
* @Entity
*/
class GH6830Category
{
/**
* @Id
* @Column(type="string", length=8, options={"fixed":true, "collation":"latin1_bin", "foo":"bar"})
*
* @var string
*/
public $id;

/**
* @OneToMany(targetEntity=GH6830Board::class, mappedBy="category")
*/
public $boards;
}

0 comments on commit 41ff526

Please sign in to comment.