Skip to content

Commit f894a35

Browse files
authored
Add feature flags to disable some breaking changes (cakephp#2159)
* Add feature flags to disable some breaking changes Signed-off-by: Matthew Peveler <[email protected]> * fix php 7.2 * flip boolean * style fixes * style * add tests * cs * review comments Signed-off-by: Matthew Peveler <[email protected]>
1 parent 2922b17 commit f894a35

File tree

8 files changed

+153
-1
lines changed

8 files changed

+153
-1
lines changed

docs/en/configuration.rst

+15
Original file line numberDiff line numberDiff line change
@@ -512,3 +512,18 @@ Within the bootstrap script, the following variables will be available:
512512
* @var \Symfony\Component\Console\Output\OutputInterface $output The executing command's output object
513513
* @var \Phinx\Console\Command\AbstractCommand $context the executing command object
514514
*/
515+
516+
Feature Flags
517+
-------------
518+
519+
For some breaking changes, Phinx offers a way to opt-out of new behavior. The following flags are available:
520+
521+
* ``unsigned_primary_keys``: Should Phinx create primary keys as unsigned integers? (default: ``true``)
522+
* ``column_null_default``: Should Phinx create columns as null by default? (default: ``true``)
523+
524+
These values can also be set by modifying class fields on the ```Phinx\Config\FeatureFlags``` class, converting
525+
the flag name to ``camelCase``, for example:
526+
527+
.. code-block:: php
528+
529+
Phinx\Config\FeatureFlags::$unsignedPrimaryKeys = false;

src/Phinx/Config/Config.php

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ public function __construct(array $configArray, ?string $configFilePath = null)
5757
{
5858
$this->configFilePath = $configFilePath;
5959
$this->values = $this->replaceTokens($configArray);
60+
61+
if (isset($this->values['feature_flags'])) {
62+
FeatureFlags::setFlagsFromConfig($this->values['feature_flags']);
63+
}
6064
}
6165

6266
/**

src/Phinx/Config/FeatureFlags.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/**
4+
* MIT License
5+
* For full license information, please view the LICENSE file that was distributed with this source code.
6+
*/
7+
8+
namespace Phinx\Config;
9+
10+
/**
11+
* Class to hold features flags to toggle breaking changes in Phinx.
12+
*
13+
* New flags should be added very sparingly.
14+
*/
15+
class FeatureFlags
16+
{
17+
/**
18+
* @var bool Should Phinx create unsigned primary keys by default?
19+
*/
20+
public static $unsignedPrimaryKeys = true;
21+
/**
22+
* @var bool Should Phinx create columns NULL by default?
23+
*/
24+
public static $columnNullDefault = true;
25+
26+
/**
27+
* Set the feature flags from the `feature_flags` section of the overall
28+
* config.
29+
*
30+
* @param array $config The `feature_flags` section of the config
31+
*/
32+
public static function setFlagsFromConfig(array $config): void
33+
{
34+
if (isset($config['unsigned_primary_keys'])) {
35+
self::$unsignedPrimaryKeys = (bool)$config['unsigned_primary_keys'];
36+
}
37+
if (isset($config['column_null_default'])) {
38+
self::$columnNullDefault = (bool)$config['column_null_default'];
39+
}
40+
}
41+
}

src/Phinx/Db/Adapter/MysqlAdapter.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Cake\Database\Driver\Mysql as MysqlDriver;
1212
use InvalidArgumentException;
1313
use PDO;
14+
use Phinx\Config\FeatureFlags;
1415
use Phinx\Db\Table\Column;
1516
use Phinx\Db\Table\ForeignKey;
1617
use Phinx\Db\Table\Index;
@@ -285,7 +286,7 @@ public function createTable(Table $table, array $columns = [], array $indexes =
285286
$column->setName($options['id'])
286287
->setType('integer')
287288
->setOptions([
288-
'signed' => $options['signed'] ?? false,
289+
'signed' => $options['signed'] ?? !FeatureFlags::$unsignedPrimaryKeys,
289290
'identity' => true,
290291
]);
291292

src/Phinx/Db/Table/Column.php

+9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Phinx\Db\Table;
99

10+
use Phinx\Config\FeatureFlags;
1011
use Phinx\Db\Adapter\AdapterInterface;
1112
use Phinx\Db\Adapter\PostgresAdapter;
1213
use RuntimeException;
@@ -158,6 +159,14 @@ class Column
158159
*/
159160
protected $values;
160161

162+
/**
163+
* Column constructor
164+
*/
165+
public function __construct()
166+
{
167+
$this->null = FeatureFlags::$columnNullDefault;
168+
}
169+
161170
/**
162171
* Sets the column name.
163172
*
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Test\Phinx\Config;
4+
5+
use Phinx\Config\FeatureFlags;
6+
use PHPUnit\Framework\TestCase;
7+
8+
class FeatureFlagsTest extends TestCase
9+
{
10+
/**
11+
* @runInSeparateProcess
12+
*/
13+
public function testSetFlagsFromConfig(): void
14+
{
15+
$config = [
16+
'unsigned_primary_keys' => false,
17+
'column_null_default' => false,
18+
];
19+
$this->assertTrue(FeatureFlags::$unsignedPrimaryKeys);
20+
$this->assertTrue(FeatureFlags::$columnNullDefault);
21+
FeatureFlags::setFlagsFromConfig($config);
22+
$this->assertFalse(FeatureFlags::$unsignedPrimaryKeys);
23+
$this->assertFalse(FeatureFlags::$columnNullDefault);
24+
}
25+
}

tests/Phinx/Db/Adapter/MysqlAdapterTest.php

+43
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace Test\Phinx\Db\Adapter;
55

66
use PDOException;
7+
use Phinx\Config\FeatureFlags;
78
use Phinx\Db\Adapter\AdapterInterface;
89
use Phinx\Db\Adapter\MysqlAdapter;
910
use Phinx\Util\Literal;
@@ -156,6 +157,11 @@ public function testCreateTable()
156157
$this->assertTrue($this->adapter->hasColumn('ntable', 'realname'));
157158
$this->assertTrue($this->adapter->hasColumn('ntable', 'email'));
158159
$this->assertFalse($this->adapter->hasColumn('ntable', 'address'));
160+
161+
$columns = $this->adapter->getColumns('ntable');
162+
$this->assertCount(3, $columns);
163+
$this->assertSame('id', $columns[0]->getName());
164+
$this->assertFalse($columns[0]->isSigned());
159165
}
160166

161167
public function testCreateTableWithComment()
@@ -421,6 +427,25 @@ public function testCreateTableWithLatin1Collate()
421427
$this->assertEquals('latin1_general_ci', $row['Collation']);
422428
}
423429

430+
public function testCreateTableWithSignedPK()
431+
{
432+
$table = new \Phinx\Db\Table('ntable', ['signed' => true], $this->adapter);
433+
$table->addColumn('realname', 'string')
434+
->addColumn('email', 'integer')
435+
->save();
436+
$this->assertTrue($this->adapter->hasTable('ntable'));
437+
$this->assertTrue($this->adapter->hasColumn('ntable', 'id'));
438+
$this->assertTrue($this->adapter->hasColumn('ntable', 'realname'));
439+
$this->assertTrue($this->adapter->hasColumn('ntable', 'email'));
440+
$this->assertFalse($this->adapter->hasColumn('ntable', 'address'));
441+
$column_definitions = $this->adapter->getColumns('ntable');
442+
foreach ($column_definitions as $column_definition) {
443+
if ($column_definition->getName() === 'id') {
444+
$this->assertTrue($column_definition->getSigned());
445+
}
446+
}
447+
}
448+
424449
public function testCreateTableWithUnsignedPK()
425450
{
426451
$table = new \Phinx\Db\Table('ntable', ['signed' => false], $this->adapter);
@@ -459,6 +484,24 @@ public function testCreateTableWithUnsignedNamedPK()
459484
$this->assertFalse($this->adapter->hasColumn('ntable', 'address'));
460485
}
461486

487+
/**
488+
* @runInSeparateProcess
489+
*/
490+
public function testUnsignedPksFeatureFlag()
491+
{
492+
$this->adapter->connect();
493+
494+
FeatureFlags::$unsignedPrimaryKeys = false;
495+
496+
$table = new \Phinx\Db\Table('table1', [], $this->adapter);
497+
$table->create();
498+
499+
$columns = $this->adapter->getColumns('table1');
500+
$this->assertCount(1, $columns);
501+
$this->assertSame('id', $columns[0]->getName());
502+
$this->assertTrue($columns[0]->getSigned());
503+
}
504+
462505
public function testCreateTableWithLimitPK()
463506
{
464507
$table = new \Phinx\Db\Table('ntable', ['id' => 'id', 'limit' => 4], $this->adapter);

tests/Phinx/Db/Table/ColumnTest.php

+14
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Test\Phinx\Db\Table;
44

5+
use Phinx\Config\FeatureFlags;
56
use Phinx\Db\Table\Column;
67
use PHPUnit\Framework\TestCase;
78
use RuntimeException;
@@ -28,4 +29,17 @@ public function testSetOptionsIdentity()
2829
$this->assertFalse($column->isNull());
2930
$this->assertTrue($column->isIdentity());
3031
}
32+
33+
/**
34+
* @runInSeparateProcess
35+
*/
36+
public function testColumnNullFeatureFlag()
37+
{
38+
$column = new Column();
39+
$this->assertTrue($column->isNull());
40+
41+
FeatureFlags::$columnNullDefault = false;
42+
$column = new Column();
43+
$this->assertFalse($column->isNull());
44+
}
3145
}

0 commit comments

Comments
 (0)