diff --git a/docs/en/index.rst b/docs/en/index.rst index 1c6a2af0..1a92b87d 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -987,8 +987,10 @@ Feature Flags Migrations uses Phinx, which has some feature flags that are disabled by default for now, but can enabled if you want them to: -* ``unsigned_primary_keys``: Should Phinx create primary keys as unsigned integers? (default: ``false``) -* ``column_null_default``: Should Phinx create columns as null by default? (default: ``false``) +* ``unsigned_primary_keys``: Should Migrations create primary keys as unsigned integers? (default: ``false``) +* ``column_null_default``: Should Migrations create columns as null by default? (default: ``false``) +* ``add_timestamps_use_datetime``: Should Migrations use ``DATETIME`` type + columns for the columns added by ``addTimestamps()``. Set them via Configure to enable (e.g. in ``config/app.php``):: diff --git a/src/Db/Adapter/MysqlAdapter.php b/src/Db/Adapter/MysqlAdapter.php index 3bf1aa3a..4930d584 100644 --- a/src/Db/Adapter/MysqlAdapter.php +++ b/src/Db/Adapter/MysqlAdapter.php @@ -425,6 +425,9 @@ public function getColumns(string $tableName): array if ($columnInfo['Extra'] === 'auto_increment') { $column->setIdentity(true); } + if ($columnInfo['Extra'] === 'on update CURRENT_TIMESTAMP') { + $column->setUpdate('CURRENT_TIMESTAMP'); + } if (isset($phinxType['values'])) { $column->setValues($phinxType['values']); diff --git a/src/Db/Table.php b/src/Db/Table.php index ad010a1c..30a62003 100644 --- a/src/Db/Table.php +++ b/src/Db/Table.php @@ -8,6 +8,7 @@ namespace Migrations\Db; +use Cake\Core\Configure; use InvalidArgumentException; use Migrations\Db\Action\AddColumn; use Migrations\Db\Action\AddForeignKey; @@ -35,6 +36,8 @@ * * TODO(mark) Having both Migrations\Db\Table and Migrations\Db\Table\Table seems redundant. * The table models should be joined together so that we have a simpler API exposed. + * + * @internal */ class Table { @@ -543,9 +546,14 @@ public function addTimestamps(string|false|null $createdAt = 'created_at', strin if (!$createdAt && !$updatedAt) { throw new RuntimeException('Cannot set both created_at and updated_at columns to false'); } + $timestampConfig = (bool)Configure::read('Migrations.add_timestamps_use_datetime'); + $timestampType = 'timestamp'; + if ($timestampConfig === true) { + $timestampType = 'datetime'; + } if ($createdAt) { - $this->addColumn($createdAt, 'timestamp', [ + $this->addColumn($createdAt, $timestampType, [ 'null' => false, 'default' => 'CURRENT_TIMESTAMP', 'update' => '', @@ -553,7 +561,7 @@ public function addTimestamps(string|false|null $createdAt = 'created_at', strin ]); } if ($updatedAt) { - $this->addColumn($updatedAt, 'timestamp', [ + $this->addColumn($updatedAt, $timestampType, [ 'null' => true, 'default' => null, 'update' => 'CURRENT_TIMESTAMP', diff --git a/src/Db/Table/Table.php b/src/Db/Table/Table.php index ad826709..9b2685b1 100644 --- a/src/Db/Table/Table.php +++ b/src/Db/Table/Table.php @@ -10,6 +10,9 @@ use InvalidArgumentException; +/** + * @internal + */ class Table { /** diff --git a/tests/TestCase/Db/Adapter/MysqlAdapterTest.php b/tests/TestCase/Db/Adapter/MysqlAdapterTest.php index c16d4a8e..2bb30860 100644 --- a/tests/TestCase/Db/Adapter/MysqlAdapterTest.php +++ b/tests/TestCase/Db/Adapter/MysqlAdapterTest.php @@ -484,6 +484,36 @@ public function testUnsignedPksFeatureFlag() $this->assertTrue($columns[0]->getSigned()); } + /** + * @runInSeparateProcess + */ + public function testAddTimestampsFeatureFlag() + { + Configure::write('Migrations.add_timestamps_use_datetime', true); + $this->adapter->connect(); + + $table = new Table('table1', [], $this->adapter); + $table->addTimestamps(); + $table->create(); + + $columns = $this->adapter->getColumns('table1'); + + $this->assertCount(3, $columns); + $this->assertSame('id', $columns[0]->getName()); + + $this->assertEquals('created_at', $columns[1]->getName()); + $this->assertEquals('datetime', $columns[1]->getType()); + $this->assertEquals('', $columns[1]->getUpdate()); + $this->assertFalse($columns[1]->isNull()); + $this->assertEquals('CURRENT_TIMESTAMP', $columns[1]->getDefault()); + + $this->assertEquals('updated_at', $columns[2]->getName()); + $this->assertEquals('datetime', $columns[2]->getType()); + $this->assertEquals('CURRENT_TIMESTAMP', $columns[2]->getUpdate()); + $this->assertTrue($columns[2]->isNull()); + $this->assertNull($columns[2]->getDefault()); + } + public function testCreateTableWithLimitPK() { $table = new Table('ntable', ['id' => 'id', 'limit' => 4], $this->adapter);