Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Db/Adapter/MysqlAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,9 @@ public function getColumns(string $tableName): array
if ($record['onUpdate'] ?? false) {
$column->setUpdate($record['onUpdate']);
}
if ($record['fixed'] ?? false) {
$column->setFixed(true);
}

$columns[] = $column;
}
Expand Down
32 changes: 32 additions & 0 deletions src/Db/Table/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ class Column extends DatabaseColumn
*/
protected ?string $lock = null;

/**
* @var bool|null
*/
protected ?bool $fixed = null;

/**
* Column constructor
*
Expand Down Expand Up @@ -772,6 +777,31 @@ public function getLock(): ?string
return $this->lock;
}

/**
* Sets whether field should use fixed-length storage (for binary columns).
*
* When true, binary columns will use BINARY(n) instead of VARBINARY(n).
*
* @param bool $fixed Fixed
* @return $this
*/
public function setFixed(bool $fixed)
{
$this->fixed = $fixed;

return $this;
}
Comment on lines +788 to +793
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should eventually raise the version constraint so that we can remove this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a TODO here in code? Or just track this for a future cleanup in some ticket?


/**
* Gets whether field should use fixed-length storage.
*
* @return bool|null
*/
public function getFixed(): ?bool
{
return $this->fixed;
}

/**
* Gets all allowed options. Each option must have a corresponding `setFoo` method.
*
Expand Down Expand Up @@ -802,6 +832,7 @@ protected function getValidOptions(): array
'generated',
'algorithm',
'lock',
'fixed',
];
}

Expand Down Expand Up @@ -894,6 +925,7 @@ public function toArray(): array
'default' => $default,
'generated' => $this->getGenerated(),
'unsigned' => $this->getUnsigned(),
'fixed' => $this->getFixed(),
'onUpdate' => $this->getUpdate(),
'collate' => $this->getCollation(),
'precision' => $precision,
Expand Down
3 changes: 2 additions & 1 deletion src/View/Helper/MigrationHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ public function getColumnOption(array $options): array
'scale',
'after',
'collate',
'fixed',
]);
$columnOptions = array_intersect_key($options, $wantedOptions);
if (empty($columnOptions['comment'])) {
Expand Down Expand Up @@ -495,7 +496,7 @@ public function attributes(TableSchemaInterface|string $table, string $column):
'comment', 'unsigned',
'signed', 'properties',
'autoIncrement', 'unique',
'collate',
'collate', 'fixed',
];

$attributes = [];
Expand Down
49 changes: 49 additions & 0 deletions tests/TestCase/Db/Adapter/MysqlAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3484,4 +3484,53 @@ public function testCombinedPartitionAndColumnOperations(): void
$this->assertCount(1, $rows);
$this->assertEquals('A description', $rows[0]['description']);
}

public function testBinaryColumnWithFixedOption(): void
{
$table = new Table('binary_fixed_test', [], $this->adapter);
$table->addColumn('hash', 'binary', ['limit' => 20, 'fixed' => true])
->addColumn('data', 'binary', ['limit' => 20])
->save();

$this->assertTrue($this->adapter->hasColumn('binary_fixed_test', 'hash'));
$this->assertTrue($this->adapter->hasColumn('binary_fixed_test', 'data'));

// Check that the fixed column is created as BINARY and the non-fixed as VARBINARY
$rows = $this->adapter->fetchAll('SHOW COLUMNS FROM binary_fixed_test');
$hashColumn = null;
$dataColumn = null;
foreach ($rows as $row) {
if ($row['Field'] === 'hash') {
$hashColumn = $row;
}
if ($row['Field'] === 'data') {
$dataColumn = $row;
}
}

$this->assertNotNull($hashColumn);
$this->assertNotNull($dataColumn);
$this->assertSame('binary(20)', $hashColumn['Type']);
$this->assertSame('varbinary(20)', $dataColumn['Type']);

// Verify the fixed attribute is reflected back
$columns = $this->adapter->getColumns('binary_fixed_test');
$hashCol = null;
$dataCol = null;
foreach ($columns as $col) {
if ($col->getName() === 'hash') {
$hashCol = $col;
}
if ($col->getName() === 'data') {
$dataCol = $col;
}
}

$this->assertNotNull($hashCol);
$this->assertNotNull($dataCol);
$this->assertSame('binary', $hashCol->getType());
$this->assertSame('binary', $dataCol->getType());
$this->assertTrue($hashCol->getFixed());
$this->assertNull($dataCol->getFixed());
}
}
52 changes: 52 additions & 0 deletions tests/TestCase/Db/Table/ColumnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,4 +275,56 @@ public function testUnsignedConfigurationDoesNotAffectNonIntegerTypes(): void
$decimalColumn->setName('price')->setType('decimal');
$this->assertFalse($decimalColumn->isUnsigned());
}

public function testFixedOptionDefaultsToNull(): void
{
$column = new Column();
$column->setName('data')->setType('binary');

$this->assertNull($column->getFixed());
}

public function testSetFixedTrue(): void
{
$column = new Column();
$column->setName('hash')->setType('binary')->setFixed(true);

$this->assertTrue($column->getFixed());
}

public function testSetFixedFalse(): void
{
$column = new Column();
$column->setName('data')->setType('binary')->setFixed(false);

$this->assertFalse($column->getFixed());
}

public function testSetOptionsWithFixed(): void
{
$column = new Column();
$column->setName('hash')->setType('binary');
$column->setOptions(['fixed' => true, 'limit' => 20]);

$this->assertTrue($column->getFixed());
$this->assertSame(20, $column->getLimit());
}

public function testToArrayIncludesFixed(): void
{
$column = new Column();
$column->setName('hash')->setType('binary')->setFixed(true)->setLimit(20);

$result = $column->toArray();
$this->assertTrue($result['fixed']);
}

public function testToArrayFixedNullByDefault(): void
{
$column = new Column();
$column->setName('data')->setType('binary')->setLimit(20);

$result = $column->toArray();
$this->assertNull($result['fixed']);
}
}
34 changes: 34 additions & 0 deletions tests/TestCase/View/Helper/MigrationHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -456,4 +456,38 @@ public function testGetColumnOptionConvertsCollateToCollation(): void
$this->assertArrayHasKey('collation', $result, 'collation should be set from collate value');
$this->assertSame('en_US.UTF-8', $result['collation']);
}

/**
* Test that getColumnOption includes the fixed option for binary columns
*/
public function testGetColumnOptionIncludesFixed(): void
{
$options = [
'length' => 20,
'null' => true,
'default' => null,
'fixed' => true,
];

$result = $this->helper->getColumnOption($options);

$this->assertArrayHasKey('fixed', $result);
$this->assertTrue($result['fixed']);
}

/**
* Test that getColumnOption excludes fixed when not set
*/
public function testGetColumnOptionExcludesFixedWhenNotSet(): void
{
$options = [
'length' => 20,
'null' => true,
'default' => null,
];

$result = $this->helper->getColumnOption($options);

$this->assertArrayNotHasKey('fixed', $result);
}
}
Loading