From 4aa4d874400f334d0151a078ba0039f082347bba Mon Sep 17 00:00:00 2001 From: Matthew Peveler Date: Thu, 14 Oct 2021 11:14:04 -1000 Subject: [PATCH 01/59] Add docs for MysqlAdapter::FIRST constant --- docs/en/migrations.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/en/migrations.rst b/docs/en/migrations.rst index 1413abab2..6a858ec4f 100644 --- a/docs/en/migrations.rst +++ b/docs/en/migrations.rst @@ -1142,7 +1142,8 @@ To rename a column, access an instance of the Table object then call the Adding a Column After Another Column ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When adding a column you can dictate its position using the ``after`` option. +When adding a column with the MySQL adapter, you can dictate its position using the ``after`` option, +where its value is the name of the column to position it after. .. code-block:: php @@ -1163,6 +1164,10 @@ When adding a column you can dictate its position using the ``after`` option. } } +This would create the new column ``city`` and have it be positioned after the ``email`` column. You +can use the `\Phinx\Db\Adapter\MysqlAdapter\FIRST` constant to specify that the new column should +created as the first column in that table. + Dropping a Column ~~~~~~~~~~~~~~~~~ From 79492ef162184fc5a1879ac49c5e2877eebbf4b9 Mon Sep 17 00:00:00 2001 From: Matthew Peveler Date: Thu, 14 Oct 2021 21:12:02 -1000 Subject: [PATCH 02/59] review comments --- docs/en/migrations.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/migrations.rst b/docs/en/migrations.rst index 6a858ec4f..d9c00939a 100644 --- a/docs/en/migrations.rst +++ b/docs/en/migrations.rst @@ -1164,7 +1164,7 @@ where its value is the name of the column to position it after. } } -This would create the new column ``city`` and have it be positioned after the ``email`` column. You +This would create the new column ``city`` and position it after the ``email`` column. You can use the `\Phinx\Db\Adapter\MysqlAdapter\FIRST` constant to specify that the new column should created as the first column in that table. From 9008ac19bc178972c9bd3abe96aa79d15f3391f7 Mon Sep 17 00:00:00 2001 From: Matthew Peveler Date: Thu, 14 Oct 2021 21:59:03 -1000 Subject: [PATCH 03/59] Support using mysql int constants on same types --- src/Phinx/Db/Adapter/MysqlAdapter.php | 16 ++++++++ tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 42 +++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 7a82eec12..5aa23e898 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -1019,12 +1019,28 @@ public function getSqlType($type, $limit = null) case static::PHINX_TYPE_BIT: return ['name' => 'bit', 'limit' => $limit ?: 64]; case static::PHINX_TYPE_BIG_INTEGER: + if ($limit === static::INT_BIG) { + $limit = 20; + } + return ['name' => 'bigint', 'limit' => $limit ?: 20]; case static::PHINX_TYPE_MEDIUM_INTEGER: + if ($limit === static::INT_MEDIUM) { + $limit = 8; + } + return ['name' => 'mediumint', 'limit' => $limit ?: 8]; case static::PHINX_TYPE_SMALL_INTEGER: + if ($limit === static::INT_SMALL) { + $limit = 6; + } + return ['name' => 'smallint', 'limit' => $limit ?: 6]; case static::PHINX_TYPE_TINY_INTEGER: + if ($limit === static::INT_TINY) { + $limit = 4; + } + return ['name' => 'tinyint', 'limit' => $limit ?: 4]; case static::PHINX_TYPE_INTEGER: if ($limit && $limit >= static::INT_TINY) { diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index d25817cb3..45d85adeb 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -884,6 +884,48 @@ public function testChangeColumnDefaultToNull() $this->assertNull($rows[1]['Default']); } + public function sqlTypeProvider() + { + // TODO: add tests for missing types + return [ + // tinyint + [AdapterInterface::PHINX_TYPE_TINY_INTEGER, null, 'tinyint', 4], + [AdapterInterface::PHINX_TYPE_TINY_INTEGER, 2, 'tinyint', 2], + [AdapterInterface::PHINX_TYPE_TINY_INTEGER, MysqlAdapter::INT_TINY, 'tinyint', 4], + // smallint + [AdapterInterface::PHINX_TYPE_SMALL_INTEGER, null, 'smallint', 6], + [AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 3, 'smallint', 3], + [AdapterInterface::PHINX_TYPE_SMALL_INTEGER, MysqlAdapter::INT_SMALL, 'smallint', 6], + // medium + [AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, null, 'mediumint', 8], + [AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 2, 'mediumint', 2], + [AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, MysqlAdapter::INT_MEDIUM, 'mediumint', 8], + // integer + [AdapterInterface::PHINX_TYPE_INTEGER, null, 'int', 11], + [AdapterInterface::PHINX_TYPE_INTEGER, 4, 'int', 4], + [AdapterInterface::PHINX_TYPE_INTEGER, MysqlAdapter::INT_TINY, 'tinyint', 4], + [AdapterInterface::PHINX_TYPE_INTEGER, MysqlAdapter::INT_SMALL, 'smallint', 6], + [AdapterInterface::PHINX_TYPE_INTEGER, MysqlAdapter::INT_MEDIUM, 'mediumint', 8], + [AdapterInterface::PHINX_TYPE_INTEGER, MysqlAdapter::INT_REGULAR, 'int', 11], + [AdapterInterface::PHINX_TYPE_INTEGER, MysqlAdapter::INT_BIG, 'bigint', 20], + // bigint + [AdapterInterface::PHINX_TYPE_BIG_INTEGER, null, 'bigint', 20], + [AdapterInterface::PHINX_TYPE_BIG_INTEGER, 4, 'bigint', 4], + [AdapterInterface::PHINX_TYPE_BIG_INTEGER, MysqlAdapter::INT_BIG, 'bigint', 20], + ]; + } + + /** + * @dataProvider sqlTypeProvider + * The second argument is not typed as MysqlAdapter::INT_BIG is a float, and all other values are integers + */ + public function testGetSqlType(string $type, $limit, string $expectedType, int $expectedLimit) + { + $sqlType = $this->adapter->getSqlType($type, $limit); + $this->assertEquals($expectedType, $sqlType['name']); + $this->assertEquals($expectedLimit, $sqlType['limit']); + } + public function testLongTextColumn() { $table = new \Phinx\Db\Table('t', [], $this->adapter); From 46d2937fa47fd7454ce028ebbc5e1feee7abb614 Mon Sep 17 00:00:00 2001 From: Matthew Peveler Date: Thu, 14 Oct 2021 22:09:46 -1000 Subject: [PATCH 04/59] review comment --- tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index 45d85adeb..9492f6af8 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -922,8 +922,8 @@ public function sqlTypeProvider() public function testGetSqlType(string $type, $limit, string $expectedType, int $expectedLimit) { $sqlType = $this->adapter->getSqlType($type, $limit); - $this->assertEquals($expectedType, $sqlType['name']); - $this->assertEquals($expectedLimit, $sqlType['limit']); + $this->assertSame($expectedType, $sqlType['name']); + $this->assertSame($expectedLimit, $sqlType['limit']); } public function testLongTextColumn() From 206f2207ee7a2722e3142c8df3a614fe9378922f Mon Sep 17 00:00:00 2001 From: Matthew Peveler Date: Sun, 24 Oct 2021 09:29:51 -1000 Subject: [PATCH 05/59] remove todo, rename function --- tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index 9492f6af8..e6c5a80c2 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -884,9 +884,8 @@ public function testChangeColumnDefaultToNull() $this->assertNull($rows[1]['Default']); } - public function sqlTypeProvider() + public function sqlTypeIntConversionProvider() { - // TODO: add tests for missing types return [ // tinyint [AdapterInterface::PHINX_TYPE_TINY_INTEGER, null, 'tinyint', 4], @@ -916,10 +915,10 @@ public function sqlTypeProvider() } /** - * @dataProvider sqlTypeProvider + * @dataProvider sqlTypeIntConversionProvider * The second argument is not typed as MysqlAdapter::INT_BIG is a float, and all other values are integers */ - public function testGetSqlType(string $type, $limit, string $expectedType, int $expectedLimit) + public function testGetSqlTypeIntegerConversion(string $type, $limit, string $expectedType, int $expectedLimit) { $sqlType = $this->adapter->getSqlType($type, $limit); $this->assertSame($expectedType, $sqlType['name']); From b791ba7b6eab2bf1824de9aada36da649884269a Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Wed, 27 Oct 2021 06:11:19 +0100 Subject: [PATCH 06/59] Change getPhinxType to use limits for integers if detected --- src/Phinx/Db/Adapter/MysqlAdapter.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 5aa23e898..9f44528c4 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -1135,15 +1135,15 @@ public function getPhinxType($sqlTypeDef) break; case 'tinyint': $type = static::PHINX_TYPE_TINY_INTEGER; - $limit = static::INT_TINY; + $limit = $limit ?? static::INT_TINY; break; case 'smallint': $type = static::PHINX_TYPE_SMALL_INTEGER; - $limit = static::INT_SMALL; + $limit = $limit ?? static::INT_SMALL; break; case 'mediumint': $type = static::PHINX_TYPE_MEDIUM_INTEGER; - $limit = static::INT_MEDIUM; + $limit = $limit ?? static::INT_MEDIUM; break; case 'int': $type = static::PHINX_TYPE_INTEGER; @@ -1209,7 +1209,7 @@ public function getPhinxType($sqlTypeDef) try { // Call this to check if parsed type is supported. - $this->getSqlType($type, $limit); + ['type' => $type, 'limit' => $limit] = $this->getSqlType($type, $limit); } catch (UnsupportedColumnTypeException $e) { $type = Literal::from($type); } From c0d3b9a1a111cd448b139f50984ff87291fed483 Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Wed, 27 Oct 2021 09:38:30 +0100 Subject: [PATCH 07/59] Revert "Change getPhinxType to use limits for integers if detected" This reverts commit b791ba7b6eab2bf1824de9aada36da649884269a. --- src/Phinx/Db/Adapter/MysqlAdapter.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 9f44528c4..5aa23e898 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -1135,15 +1135,15 @@ public function getPhinxType($sqlTypeDef) break; case 'tinyint': $type = static::PHINX_TYPE_TINY_INTEGER; - $limit = $limit ?? static::INT_TINY; + $limit = static::INT_TINY; break; case 'smallint': $type = static::PHINX_TYPE_SMALL_INTEGER; - $limit = $limit ?? static::INT_SMALL; + $limit = static::INT_SMALL; break; case 'mediumint': $type = static::PHINX_TYPE_MEDIUM_INTEGER; - $limit = $limit ?? static::INT_MEDIUM; + $limit = static::INT_MEDIUM; break; case 'int': $type = static::PHINX_TYPE_INTEGER; @@ -1209,7 +1209,7 @@ public function getPhinxType($sqlTypeDef) try { // Call this to check if parsed type is supported. - ['type' => $type, 'limit' => $limit] = $this->getSqlType($type, $limit); + $this->getSqlType($type, $limit); } catch (UnsupportedColumnTypeException $e) { $type = Literal::from($type); } From a01ccf062c742a5e6200ff185046d3c997980cc7 Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Wed, 27 Oct 2021 13:13:08 +0100 Subject: [PATCH 08/59] Capture case where getColumns returns physical limit for integer columns instead of display width --- src/Phinx/Db/Adapter/MysqlAdapter.php | 42 +++++++++++++-------- tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 33 ++++++++++++++++ 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 5aa23e898..5a52b4ccd 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -75,6 +75,12 @@ class MysqlAdapter extends PdoAdapter public const INT_REGULAR = 4294967295; public const INT_BIG = 18446744073709551615; + public const INT_DISPLAY_TINY = 4; + public const INT_DISPLAY_SMALL = 6; + public const INT_DISPLAY_MEDIUM = 8; + public const INT_DISPLAY_REGULAR = 11; + public const INT_DISPLAY_BIG = 20; + public const BIT = 64; public const TYPE_YEAR = 'year'; @@ -1020,25 +1026,25 @@ public function getSqlType($type, $limit = null) return ['name' => 'bit', 'limit' => $limit ?: 64]; case static::PHINX_TYPE_BIG_INTEGER: if ($limit === static::INT_BIG) { - $limit = 20; + $limit = static::INT_DISPLAY_BIG; } return ['name' => 'bigint', 'limit' => $limit ?: 20]; case static::PHINX_TYPE_MEDIUM_INTEGER: if ($limit === static::INT_MEDIUM) { - $limit = 8; + $limit = static::INT_DISPLAY_MEDIUM; } return ['name' => 'mediumint', 'limit' => $limit ?: 8]; case static::PHINX_TYPE_SMALL_INTEGER: if ($limit === static::INT_SMALL) { - $limit = 6; + $limit = static::INT_DISPLAY_SMALL; } return ['name' => 'smallint', 'limit' => $limit ?: 6]; case static::PHINX_TYPE_TINY_INTEGER: if ($limit === static::INT_TINY) { - $limit = 4; + $limit = static::INT_DISPLAY_TINY; } return ['name' => 'tinyint', 'limit' => $limit ?: 4]; @@ -1053,11 +1059,11 @@ public function getSqlType($type, $limit = null) 'tinyint' => static::INT_TINY, ]; $limits = [ - 'tinyint' => 4, - 'smallint' => 6, - 'mediumint' => 8, - 'int' => 11, - 'bigint' => 20, + 'tinyint' => static::INT_DISPLAY_TINY, + 'smallint' => static::INT_DISPLAY_SMALL, + 'mediumint' => static::INT_DISPLAY_MEDIUM, + 'int' => static::INT_DISPLAY_REGULAR, + 'bigint' => static::INT_DISPLAY_BIG, ]; foreach ($sizes as $name => $length) { if ($limit >= $length) { @@ -1070,7 +1076,7 @@ public function getSqlType($type, $limit = null) } } } elseif (!$limit) { - $limit = 11; + $limit = static::INT_DISPLAY_REGULAR; } return ['name' => 'int', 'limit' => $limit]; @@ -1135,24 +1141,24 @@ public function getPhinxType($sqlTypeDef) break; case 'tinyint': $type = static::PHINX_TYPE_TINY_INTEGER; - $limit = static::INT_TINY; + $limit = $limit ?? static::INT_DISPLAY_TINY; break; case 'smallint': $type = static::PHINX_TYPE_SMALL_INTEGER; - $limit = static::INT_SMALL; + $limit = $limit ?? static::INT_DISPLAY_SMALL; break; case 'mediumint': $type = static::PHINX_TYPE_MEDIUM_INTEGER; - $limit = static::INT_MEDIUM; + $limit = $limit ?? static::INT_DISPLAY_MEDIUM; break; case 'int': $type = static::PHINX_TYPE_INTEGER; - if ($limit === 11) { + if ($limit === static::INT_DISPLAY_REGULAR) { $limit = null; } break; case 'bigint': - if ($limit === 20) { + if ($limit === static::INT_DISPLAY_BIG) { $limit = null; } $type = static::PHINX_TYPE_BIG_INTEGER; @@ -1209,7 +1215,11 @@ public function getPhinxType($sqlTypeDef) try { // Call this to check if parsed type is supported. - $this->getSqlType($type, $limit); + $sqlTypeDetails = $this->getSqlType($type, $limit); + $limit = $limit ?? $sqlTypeDetails['limit'] ?? null; +// if ($type !== $sqlTypeDetails['name']) { +// $type = $sqlTypeDetails['name']; +// } } catch (UnsupportedColumnTypeException $e) { $type = Literal::from($type); } diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index e6c5a80c2..604ba3936 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -2175,4 +2175,37 @@ public function testInvalidPdoAttribute($attribute) $this->expectExceptionMessage('Invalid PDO attribute: ' . $attribute . ' (\PDO::' . strtoupper($attribute) . ')'); $adapter->connect(); } + + public function integerDataTypesSQLProvider() + { + return [ + ['bigint', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], + ['bigint(20)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], + ['bigint(10)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 10, 'scale' => null]], + ['bigint(1) unsigned', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 1, 'scale' => null]], + ['int', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], + ['int(10) unsigned', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 10, 'scale' => null]], + ['int(11)', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], + ['mediumint', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 8, 'scale' => null]], + ['mediumint(6)', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 6, 'scale' => null]], + ['mediumint(8) unsigned', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 8, 'scale' => null]], + ['smallint', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 6, 'scale' => null]], + ['smallint(2)', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 2, 'scale' => null]], + ['smallint(5) unsigned', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 5, 'scale' => null]], + ['tinyint', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 4, 'scale' => null]], + ['tinyint(3) unsigned', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 3, 'scale' => null]], + ['tinyint(4)', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 4, 'scale' => null]], + ['tinyint(1)', ['name' => AdapterInterface::PHINX_TYPE_BOOLEAN, 'limit' => 1, 'scale' => null]], + ]; + } + /** + * @dataProvider integerDataTypesSQLProvider + */ + public function testGetPhinxTypeFromSQLDefinition(string $sqlDefinition, array $expectedResponse) + { + $result = $this->adapter->getPhinxType($sqlDefinition); + + $this->assertSame($expectedResponse['name'], $result['name'], "Type mismatch - got '{$result['name']}' when expecting '{$expectedResponse['name']}'"); + $this->assertSame($expectedResponse['limit'], $result['limit'], "Field upper boundary mismatch - got '{$result['limit']}' when expecting '{$expectedResponse['limit']}'"); + } } From 231b80224fc9b4e839aae1377d7cd482cca96967 Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Wed, 27 Oct 2021 13:15:34 +0100 Subject: [PATCH 09/59] Remove attempt at capturing oversize INT width --- src/Phinx/Db/Adapter/MysqlAdapter.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 5a52b4ccd..c2844f9cc 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -1217,9 +1217,6 @@ public function getPhinxType($sqlTypeDef) // Call this to check if parsed type is supported. $sqlTypeDetails = $this->getSqlType($type, $limit); $limit = $limit ?? $sqlTypeDetails['limit'] ?? null; -// if ($type !== $sqlTypeDetails['name']) { -// $type = $sqlTypeDetails['name']; -// } } catch (UnsupportedColumnTypeException $e) { $type = Literal::from($type); } From 757e2a53988c9fd23720431a450f5af5a71703f3 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 27 Oct 2021 12:20:09 +0000 Subject: [PATCH 10/59] Fixing style errors. --- tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index 604ba3936..022326cc2 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -2198,6 +2198,7 @@ public function integerDataTypesSQLProvider() ['tinyint(1)', ['name' => AdapterInterface::PHINX_TYPE_BOOLEAN, 'limit' => 1, 'scale' => null]], ]; } + /** * @dataProvider integerDataTypesSQLProvider */ From 451aeb3ecf1cda3321e0bed295792fad1588b367 Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Wed, 27 Oct 2021 13:23:24 +0100 Subject: [PATCH 11/59] Remove surplus whitespace --- src/Phinx/Db/Adapter/MysqlAdapter.php | 10 +++--- tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 34 ++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index c2844f9cc..7bcde47d8 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -75,11 +75,11 @@ class MysqlAdapter extends PdoAdapter public const INT_REGULAR = 4294967295; public const INT_BIG = 18446744073709551615; - public const INT_DISPLAY_TINY = 4; - public const INT_DISPLAY_SMALL = 6; - public const INT_DISPLAY_MEDIUM = 8; - public const INT_DISPLAY_REGULAR = 11; - public const INT_DISPLAY_BIG = 20; + public const INT_DISPLAY_TINY = 4; + public const INT_DISPLAY_SMALL = 6; + public const INT_DISPLAY_MEDIUM = 8; + public const INT_DISPLAY_REGULAR = 11; + public const INT_DISPLAY_BIG = 20; public const BIT = 64; diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index 604ba3936..8317beb71 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -2179,23 +2179,23 @@ public function testInvalidPdoAttribute($attribute) public function integerDataTypesSQLProvider() { return [ - ['bigint', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], - ['bigint(20)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], - ['bigint(10)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 10, 'scale' => null]], - ['bigint(1) unsigned', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 1, 'scale' => null]], - ['int', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], - ['int(10) unsigned', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 10, 'scale' => null]], - ['int(11)', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], - ['mediumint', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 8, 'scale' => null]], - ['mediumint(6)', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 6, 'scale' => null]], - ['mediumint(8) unsigned', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 8, 'scale' => null]], - ['smallint', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 6, 'scale' => null]], - ['smallint(2)', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 2, 'scale' => null]], - ['smallint(5) unsigned', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 5, 'scale' => null]], - ['tinyint', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 4, 'scale' => null]], - ['tinyint(3) unsigned', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 3, 'scale' => null]], - ['tinyint(4)', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 4, 'scale' => null]], - ['tinyint(1)', ['name' => AdapterInterface::PHINX_TYPE_BOOLEAN, 'limit' => 1, 'scale' => null]], + ['bigint', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], + ['bigint(20)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], + ['bigint(10)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 10, 'scale' => null]], + ['bigint(1) unsigned', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 1, 'scale' => null]], + ['int', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], + ['int(10) unsigned', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 10, 'scale' => null]], + ['int(11)', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], + ['mediumint', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 8, 'scale' => null]], + ['mediumint(6)', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 6, 'scale' => null]], + ['mediumint(8) unsigned', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 8, 'scale' => null]], + ['smallint', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 6, 'scale' => null]], + ['smallint(2)', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 2, 'scale' => null]], + ['smallint(5) unsigned', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 5, 'scale' => null]], + ['tinyint', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 4, 'scale' => null]], + ['tinyint(3) unsigned', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 3, 'scale' => null]], + ['tinyint(4)', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 4, 'scale' => null]], + ['tinyint(1)', ['name' => AdapterInterface::PHINX_TYPE_BOOLEAN, 'limit' => 1, 'scale' => null]], ]; } /** From a683e381ad17c26f2e3814ba937e889f9784f1f0 Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Wed, 27 Oct 2021 13:49:03 +0100 Subject: [PATCH 12/59] Remove more surplus whitespace --- tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index 9c7c05fab..801baf2e8 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -2181,7 +2181,7 @@ public function integerDataTypesSQLProvider() return [ ['bigint', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], ['bigint(20)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], - ['bigint(10)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 10, 'scale' => null]], + ['bigint(10)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 10, 'scale' => null]], ['bigint(1) unsigned', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 1, 'scale' => null]], ['int', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], ['int(10) unsigned', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 10, 'scale' => null]], From dbb5a9945a2efac10a51ffe937c87394bfe2d8c4 Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Thu, 28 Oct 2021 11:47:42 +0100 Subject: [PATCH 13/59] Reorganise tests into subgroups --- tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index 801baf2e8..26d21df9d 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -2179,23 +2179,28 @@ public function testInvalidPdoAttribute($attribute) public function integerDataTypesSQLProvider() { return [ - ['bigint', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], + // Types without a width should always have a null limit + ['bigint', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => null, 'scale' => null]], + ['int', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => null, 'scale' => null]], + ['mediumint', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => null, 'scale' => null]], + ['smallint', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => null, 'scale' => null]], + ['tinyint', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => null, 'scale' => null]], + + // Types which include a width should always have that as their limit ['bigint(20)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 20, 'scale' => null]], ['bigint(10)', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 10, 'scale' => null]], ['bigint(1) unsigned', ['name' => AdapterInterface::PHINX_TYPE_BIG_INTEGER, 'limit' => 1, 'scale' => null]], - ['int', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], - ['int(10) unsigned', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 10, 'scale' => null]], ['int(11)', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 11, 'scale' => null]], - ['mediumint', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 8, 'scale' => null]], + ['int(10) unsigned', ['name' => AdapterInterface::PHINX_TYPE_INTEGER, 'limit' => 10, 'scale' => null]], ['mediumint(6)', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 6, 'scale' => null]], ['mediumint(8) unsigned', ['name' => AdapterInterface::PHINX_TYPE_MEDIUM_INTEGER, 'limit' => 8, 'scale' => null]], - ['smallint', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 6, 'scale' => null]], ['smallint(2)', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 2, 'scale' => null]], ['smallint(5) unsigned', ['name' => AdapterInterface::PHINX_TYPE_SMALL_INTEGER, 'limit' => 5, 'scale' => null]], - ['tinyint', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 4, 'scale' => null]], ['tinyint(3) unsigned', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 3, 'scale' => null]], ['tinyint(4)', ['name' => AdapterInterface::PHINX_TYPE_TINY_INTEGER, 'limit' => 4, 'scale' => null]], - ['tinyint(1)', ['name' => AdapterInterface::PHINX_TYPE_BOOLEAN, 'limit' => 1, 'scale' => null]], + + // Special case for commonly used boolean type + ['tinyint(1)', ['name' => AdapterInterface::PHINX_TYPE_BOOLEAN, 'limit' => null, 'scale' => null]], ]; } From 2d79967891e5b16eb069ce1deda784c72cdced04 Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Thu, 28 Oct 2021 11:48:23 +0100 Subject: [PATCH 14/59] Comment out limit rewriting (pending removal) --- src/Phinx/Db/Adapter/MysqlAdapter.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 7bcde47d8..112d42e6c 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -1141,26 +1141,26 @@ public function getPhinxType($sqlTypeDef) break; case 'tinyint': $type = static::PHINX_TYPE_TINY_INTEGER; - $limit = $limit ?? static::INT_DISPLAY_TINY; +// $limit = $limit ?? static::INT_DISPLAY_TINY; break; case 'smallint': $type = static::PHINX_TYPE_SMALL_INTEGER; - $limit = $limit ?? static::INT_DISPLAY_SMALL; +// $limit = $limit ?? static::INT_DISPLAY_SMALL; break; case 'mediumint': $type = static::PHINX_TYPE_MEDIUM_INTEGER; - $limit = $limit ?? static::INT_DISPLAY_MEDIUM; +// $limit = $limit ?? static::INT_DISPLAY_MEDIUM; break; case 'int': $type = static::PHINX_TYPE_INTEGER; - if ($limit === static::INT_DISPLAY_REGULAR) { - $limit = null; - } +// if ($limit === static::INT_DISPLAY_REGULAR) { +// $limit = null; +// } break; case 'bigint': - if ($limit === static::INT_DISPLAY_BIG) { - $limit = null; - } +// if ($limit === static::INT_DISPLAY_BIG) { +// $limit = null; +// } $type = static::PHINX_TYPE_BIG_INTEGER; break; case 'bit': @@ -1215,8 +1215,7 @@ public function getPhinxType($sqlTypeDef) try { // Call this to check if parsed type is supported. - $sqlTypeDetails = $this->getSqlType($type, $limit); - $limit = $limit ?? $sqlTypeDetails['limit'] ?? null; + $this->getSqlType($type, $limit); } catch (UnsupportedColumnTypeException $e) { $type = Literal::from($type); } From 88f356cecec489c261034afee25efbf726acb21b Mon Sep 17 00:00:00 2001 From: Oliver Rose Date: Mon, 1 Nov 2021 08:57:26 +0000 Subject: [PATCH 15/59] Commented sections removed --- src/Phinx/Db/Adapter/MysqlAdapter.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 112d42e6c..921933a50 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -1141,26 +1141,17 @@ public function getPhinxType($sqlTypeDef) break; case 'tinyint': $type = static::PHINX_TYPE_TINY_INTEGER; -// $limit = $limit ?? static::INT_DISPLAY_TINY; break; case 'smallint': $type = static::PHINX_TYPE_SMALL_INTEGER; -// $limit = $limit ?? static::INT_DISPLAY_SMALL; break; case 'mediumint': $type = static::PHINX_TYPE_MEDIUM_INTEGER; -// $limit = $limit ?? static::INT_DISPLAY_MEDIUM; break; case 'int': $type = static::PHINX_TYPE_INTEGER; -// if ($limit === static::INT_DISPLAY_REGULAR) { -// $limit = null; -// } break; case 'bigint': -// if ($limit === static::INT_DISPLAY_BIG) { -// $limit = null; -// } $type = static::PHINX_TYPE_BIG_INTEGER; break; case 'bit': From ac0a2fb6d657303846cd7ace06535b05f87b2726 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Thu, 11 Nov 2021 09:58:47 -0500 Subject: [PATCH 16/59] Add docs deploy via github actions. --- .github/workflows/deploy_docs_0x.yml | 22 ++++++++++++++++++++++ docs.Dockerfile | 10 +++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/deploy_docs_0x.yml diff --git a/.github/workflows/deploy_docs_0x.yml b/.github/workflows/deploy_docs_0x.yml new file mode 100644 index 000000000..ecdbbf41c --- /dev/null +++ b/.github/workflows/deploy_docs_0x.yml @@ -0,0 +1,22 @@ +--- +name: 'deploy_docs_0x' + +on: + push: + branches: + - master + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Cloning repo + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Push to dokku + uses: dokku/github-action@master + with: + git_remote_url: 'ssh://dokku@apps.cakephp.org:22/phinx-docs' + ssh_private_key: ${{ secrets.DOKKU_SSH_PRIVATE_KEY }} diff --git a/docs.Dockerfile b/docs.Dockerfile index 97da985ca..6c3aa7938 100644 --- a/docs.Dockerfile +++ b/docs.Dockerfile @@ -9,11 +9,19 @@ RUN cd /data/docs-builder && \ # Build a small nginx container with just the static site in it. -FROM nginx:1.15-alpine +FROM markstory/cakephp-docs-builder:runtime as runtime +# Configure search index script +ENV LANGS="en es fr ja" +ENV SEARCH_SOURCE="/data/docs" +ENV SEARCH_URL_PREFIX="/phinx/0" + +COPY --from=builder /data/docs /data/docs COPY --from=builder /data/website /data/website COPY --from=builder /data/docs-builder/nginx.conf /etc/nginx/conf.d/default.conf # Move files into final location RUN cp -R /data/website/html/* /usr/share/nginx/html \ && rm -rf /data/website/ + +CMD ["/data/run.sh"] From e71f2dea5706d2abdfecc56623eefa19a78eca7e Mon Sep 17 00:00:00 2001 From: Mark Story Date: Thu, 11 Nov 2021 10:03:21 -0500 Subject: [PATCH 17/59] Only deploy docs on tags. --- .github/workflows/deploy_docs_0x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy_docs_0x.yml b/.github/workflows/deploy_docs_0x.yml index ecdbbf41c..0e168695e 100644 --- a/.github/workflows/deploy_docs_0x.yml +++ b/.github/workflows/deploy_docs_0x.yml @@ -3,8 +3,8 @@ name: 'deploy_docs_0x' on: push: - branches: - - master + tags: + - v0.* jobs: deploy: From 630079e10edcb67d6d747f50e242c5b26fd113e1 Mon Sep 17 00:00:00 2001 From: Matthew Peveler Date: Sat, 13 Nov 2021 08:25:07 -1000 Subject: [PATCH 18/59] Fix adding column to sqlite table created outside phinx Co-authored-by: SlavaAurim --- src/Phinx/Db/Adapter/SQLiteAdapter.php | 15 +++++++++++ tests/Phinx/Db/Adapter/SQLiteAdapterTest.php | 27 ++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/Phinx/Db/Adapter/SQLiteAdapter.php b/src/Phinx/Db/Adapter/SQLiteAdapter.php index bb291c8c3..8e2883bdc 100644 --- a/src/Phinx/Db/Adapter/SQLiteAdapter.php +++ b/src/Phinx/Db/Adapter/SQLiteAdapter.php @@ -734,6 +734,21 @@ protected function getDeclaringSql($tableName) } } + $columnsInfo = $this->getTableInfo($tableName); + + foreach ($columnsInfo as $column) { + $columnName = $column['name']; + $columnNamePattern = "\"$columnName\"|`$columnName`|\\[$columnName\\]|$columnName"; + $columnNamePattern = "#([\(,]+\\s*)($columnNamePattern)(\\s)#iU"; + + $sql = preg_replace($columnNamePattern, "$1`$columnName`$3", $sql); + } + + $tableNamePattern = "\"$tableName\"|`$tableName`|\\[$tableName\\]|$tableName"; + $tableNamePattern = "#^(CREATE TABLE)\s*($tableNamePattern)\s*(\()#Ui"; + + $sql = preg_replace($tableNamePattern, "$1 `$tableName` $3", $sql, 1); + return $sql; } diff --git a/tests/Phinx/Db/Adapter/SQLiteAdapterTest.php b/tests/Phinx/Db/Adapter/SQLiteAdapterTest.php index f260f4ed7..08c94bee3 100644 --- a/tests/Phinx/Db/Adapter/SQLiteAdapterTest.php +++ b/tests/Phinx/Db/Adapter/SQLiteAdapterTest.php @@ -488,6 +488,33 @@ public function testAddColumnWithDefaultEmptyString() $this->assertEquals("''", $rows[1]['dflt_value']); } + public function irregularCreateTableProvider() + { + return [ + ["CREATE TABLE \"users\"\n( `id` INTEGER NOT NULL )", ['id', 'foo']], + ['CREATE TABLE users ( id INTEGER NOT NULL )', ['id', 'foo']], + ["CREATE TABLE [users]\n(\nid INTEGER NOT NULL)", ['id', 'foo']], + ["CREATE TABLE \"users\" ([id] \n INTEGER NOT NULL\n, \"bar\" INTEGER)", ['id', 'bar', 'foo']], + ]; + } + + /** + * @dataProvider irregularCreateTableProvider + */ + public function testAddColumnToIrregularCreateTableStatements(string $createTableSql, array $expectedColumns): void + { + $this->adapter->execute($createTableSql); + $table = new \Phinx\Db\Table('users', [], $this->adapter); + $table->addColumn('foo', 'string'); + $table->update(); + + $columns = $this->adapter->getColumns('users'); + $columnCount = count($columns); + for ($i = 0; $i < $columnCount; $i++) { + $this->assertEquals($expectedColumns[$i], $columns[$i]->getName()); + } + } + public function testAddDoubleColumn() { $table = new \Phinx\Db\Table('table1', [], $this->adapter); From 1ea6b02c9b3ffa9d693393f12607a7f711628ddf Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 15 Nov 2021 12:11:17 -0500 Subject: [PATCH 19/59] Remove CMD from docs container. --- docs.Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs.Dockerfile b/docs.Dockerfile index 6c3aa7938..b910b01d0 100644 --- a/docs.Dockerfile +++ b/docs.Dockerfile @@ -23,5 +23,3 @@ COPY --from=builder /data/docs-builder/nginx.conf /etc/nginx/conf.d/default.conf # Move files into final location RUN cp -R /data/website/html/* /usr/share/nginx/html \ && rm -rf /data/website/ - -CMD ["/data/run.sh"] From 10ca315adc217211ab266de7cd30f8d8e1de8284 Mon Sep 17 00:00:00 2001 From: LeeJenkinsFRU <94388495+LeeJenkinsFRU@users.noreply.github.com> Date: Wed, 17 Nov 2021 15:23:34 -0500 Subject: [PATCH 20/59] Change incorrect reference to $this Line 309: $this->table('status')->insert($rows)->save() should probably just be $table('status')->insert($rows)->save() without referencing $this. --- docs/en/migrations.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/migrations.rst b/docs/en/migrations.rst index d9c00939a..c30ffffe0 100644 --- a/docs/en/migrations.rst +++ b/docs/en/migrations.rst @@ -306,7 +306,7 @@ insert methods in your migrations. ] ]; - $this->table('status')->insert($rows)->save(); + $table('status')->insert($rows)->save(); } /** From d8a5db54d48c183e95d9f7d9eaa1ef5b1848eea1 Mon Sep 17 00:00:00 2001 From: Matthew Peveler Date: Thu, 18 Nov 2021 07:11:56 -1000 Subject: [PATCH 21/59] Clean up insert data doc example Signed-off-by: Matthew Peveler --- docs/en/migrations.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/migrations.rst b/docs/en/migrations.rst index c30ffffe0..4dc814063 100644 --- a/docs/en/migrations.rst +++ b/docs/en/migrations.rst @@ -284,15 +284,15 @@ insert methods in your migrations. */ public function up() { + $table = $this->table('status'); + // inserting only one row $singleRow = [ 'id' => 1, 'name' => 'In Progress' ]; - $table = $this->table('status'); - $table->insert($singleRow); - $table->saveData(); + $table->insert($singleRow)->saveData(); // inserting multiple rows $rows = [ @@ -306,7 +306,7 @@ insert methods in your migrations. ] ]; - $table('status')->insert($rows)->save(); + $table->insert($rows)->saveData(); } /** From 72b3bcaa2f7e822536697293bd1d172deeeb82a3 Mon Sep 17 00:00:00 2001 From: saeideng Date: Sat, 4 Dec 2021 21:48:41 +0330 Subject: [PATCH 22/59] check Symfony 6 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8a1b680d8..2da8eb8d2 100644 --- a/composer.json +++ b/composer.json @@ -28,8 +28,8 @@ "php": ">=7.2", "cakephp/database": "^4.0", "psr/container": "^1.0 || ^2.0", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/config": "^3.4|^4.0|^5.0" + "symfony/console": "^3.4|^4.0|^5.0|^6.0", + "symfony/config": "^3.4|^4.0|^5.0|^6.0" }, "require-dev": { "ext-json": "*", From 9380acc3662a984cf724c9cb2876eae334bca57e Mon Sep 17 00:00:00 2001 From: Mark Scherer Date: Sat, 4 Dec 2021 22:03:25 +0100 Subject: [PATCH 23/59] Add lowest dep check to CI (#2046) --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 783b2b338..d52730175 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,6 +95,10 @@ jobs: vendor/bin/phpunit fi + - name: Prefer lowest check + if: matrix.prefer-lowest == 'prefer-lowest' + run: composer require --dev dereuromark/composer-prefer-lowest && vendor/bin/validate-prefer-lowest -m + - name: Submit code coverage if: matrix.php-version == '8.0' uses: codecov/codecov-action@v1 From 0ea695e9a673348bb84628e9d5edcbfb20b8a121 Mon Sep 17 00:00:00 2001 From: Eremeev Ales Date: Mon, 13 Dec 2021 15:31:44 +0100 Subject: [PATCH 24/59] Do not print information output with option --no-info --- src/Phinx/Console/Command/AbstractCommand.php | 25 +++++-- src/Phinx/Console/Command/Breakpoint.php | 4 +- src/Phinx/Console/Command/Create.php | 10 +-- src/Phinx/Console/Command/ListAliases.php | 3 +- src/Phinx/Console/Command/Migrate.php | 22 +++--- src/Phinx/Console/Command/Rollback.php | 18 ++--- src/Phinx/Console/Command/SeedCreate.php | 4 +- src/Phinx/Console/Command/SeedRun.php | 18 ++--- src/Phinx/Console/Command/Status.php | 8 +-- src/Phinx/Console/Command/Test.php | 4 +- src/Phinx/Console/PhinxApplication.php | 8 ++- src/Phinx/Migration/Manager.php | 67 +++++++++++++------ .../Console/Output/RawBufferedOutput.php | 4 +- 13 files changed, 116 insertions(+), 79 deletions(-) diff --git a/src/Phinx/Console/Command/AbstractCommand.php b/src/Phinx/Console/Command/AbstractCommand.php index 516965838..2e59ed6b7 100644 --- a/src/Phinx/Console/Command/AbstractCommand.php +++ b/src/Phinx/Console/Command/AbstractCommand.php @@ -58,6 +58,11 @@ abstract class AbstractCommand extends Command */ protected $manager; + /** + * @var int + */ + protected $verbosityLevel = OutputInterface::OUTPUT_NORMAL | OutputInterface::VERBOSITY_NORMAL; + /** * Exit code for when command executes successfully * @@ -96,6 +101,7 @@ protected function configure() { $this->addOption('--configuration', '-c', InputOption::VALUE_REQUIRED, 'The configuration file to load'); $this->addOption('--parser', '-p', InputOption::VALUE_REQUIRED, 'Parser used to read the config file. Defaults to YAML'); + $this->addOption('--no-info', null, InputOption::VALUE_NONE, 'Hides all debug information'); } /** @@ -107,6 +113,10 @@ protected function configure() */ public function bootstrap(InputInterface $input, OutputInterface $output) { + if ($input->hasParameterOption('--no-info')) { + $this->verbosityLevel = OutputInterface::VERBOSITY_VERBOSE; + } + /** @var \Phinx\Config\ConfigInterface|null $config */ $config = $this->getConfig(); if (!$config) { @@ -117,26 +127,26 @@ public function bootstrap(InputInterface $input, OutputInterface $output) $bootstrap = $this->getConfig()->getBootstrapFile(); if ($bootstrap) { - $output->writeln('using bootstrap ' . Util::relativePath($bootstrap) . ' '); + $output->writeln('using bootstrap ' . Util::relativePath($bootstrap) . ' ', $this->verbosityLevel); Util::loadPhpFile($bootstrap, $input, $output, $this); } // report the paths $paths = $this->getConfig()->getMigrationPaths(); - $output->writeln('using migration paths '); + $output->writeln('using migration paths ', $this->verbosityLevel); foreach (Util::globAll($paths) as $path) { - $output->writeln(' - ' . realpath($path) . ''); + $output->writeln(' - ' . realpath($path) . '', $this->verbosityLevel); } try { $paths = $this->getConfig()->getSeedPaths(); - $output->writeln('using seed paths '); + $output->writeln('using seed paths ', $this->verbosityLevel); foreach (Util::globAll($paths) as $path) { - $output->writeln(' - ' . realpath($path) . ''); + $output->writeln(' - ' . realpath($path) . '', $this->verbosityLevel); } } catch (UnexpectedValueException $e) { // do nothing as seeds are optional @@ -263,7 +273,7 @@ protected function locateConfigFile(InputInterface $input) protected function loadConfig(InputInterface $input, OutputInterface $output) { $configFilePath = $this->locateConfigFile($input); - $output->writeln('using config file ' . Util::relativePath($configFilePath)); + $output->writeln('using config file ' . Util::relativePath($configFilePath), $this->verbosityLevel); $parser = $input->getOption('parser'); @@ -301,7 +311,7 @@ protected function loadConfig(InputInterface $input, OutputInterface $output) throw new InvalidArgumentException(sprintf('\'%s\' is not a valid parser.', $parser)); } - $output->writeln('using config parser ' . $parser); + $output->writeln('using config parser ' . $parser, $this->verbosityLevel); $this->setConfig($config); } @@ -317,6 +327,7 @@ protected function loadManager(InputInterface $input, OutputInterface $output) { if ($this->getManager() === null) { $manager = new Manager($this->getConfig(), $input, $output); + $manager->setVerbosityLevel($this->verbosityLevel); $container = $this->getConfig()->getContainer(); if ($container !== null) { $manager->setContainer($container); diff --git a/src/Phinx/Console/Command/Breakpoint.php b/src/Phinx/Console/Command/Breakpoint.php index 7230d72d6..7c077eb6a 100644 --- a/src/Phinx/Console/Command/Breakpoint.php +++ b/src/Phinx/Console/Command/Breakpoint.php @@ -68,9 +68,9 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($environment === null) { $environment = $this->getConfig()->getDefaultEnvironment(); - $output->writeln('warning no environment specified, defaulting to: ' . $environment); + $output->writeln('warning no environment specified, defaulting to: ' . $environment, $this->verbosityLevel); } else { - $output->writeln('using environment ' . $environment); + $output->writeln('using environment ' . $environment, $this->verbosityLevel); } if (!$this->getConfig()->hasEnvironment($environment)) { diff --git a/src/Phinx/Console/Command/Create.php b/src/Phinx/Console/Command/Create.php index 75f805d97..8fad84806 100644 --- a/src/Phinx/Console/Command/Create.php +++ b/src/Phinx/Console/Command/Create.php @@ -297,17 +297,17 @@ protected function execute(InputInterface $input, OutputInterface $output) $creationClass->postMigrationCreation($filePath, $className, $this->getConfig()->getMigrationBaseClassName()); } - $output->writeln('using migration base class ' . $classes['$useClassName']); + $output->writeln('using migration base class ' . $classes['$useClassName'], $this->verbosityLevel); if (!empty($altTemplate)) { - $output->writeln('using alternative template ' . $altTemplate); + $output->writeln('using alternative template ' . $altTemplate, $this->verbosityLevel); } elseif (!empty($creationClassName)) { - $output->writeln('using template creation class ' . $creationClassName); + $output->writeln('using template creation class ' . $creationClassName, $this->verbosityLevel); } else { - $output->writeln('using default template'); + $output->writeln('using default template', $this->verbosityLevel); } - $output->writeln('created ' . Util::relativePath($filePath)); + $output->writeln('created ' . Util::relativePath($filePath), $this->verbosityLevel); return self::CODE_SUCCESS; } diff --git a/src/Phinx/Console/Command/ListAliases.php b/src/Phinx/Console/Command/ListAliases.php index 2c791e7ab..bb8122c6b 100644 --- a/src/Phinx/Console/Command/ListAliases.php +++ b/src/Phinx/Console/Command/ListAliases.php @@ -61,7 +61,8 @@ function ($alias, $class) use ($maxAliasLength, $maxClassLength) { array_keys($aliases), $aliases ) - ) + ), + $this->verbosityLevel ); } else { $output->writeln( diff --git a/src/Phinx/Console/Command/Migrate.php b/src/Phinx/Console/Command/Migrate.php index 684e30ac6..e116de2b1 100644 --- a/src/Phinx/Console/Command/Migrate.php +++ b/src/Phinx/Console/Command/Migrate.php @@ -68,9 +68,9 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($environment === null) { $environment = $this->getConfig()->getDefaultEnvironment(); - $output->writeln('warning no environment specified, defaulting to: ' . $environment); + $output->writeln('warning no environment specified, defaulting to: ' . $environment, $this->verbosityLevel); } else { - $output->writeln('using environment ' . $environment); + $output->writeln('using environment ' . $environment, $this->verbosityLevel); } if (!$this->getConfig()->hasEnvironment($environment)) { @@ -81,15 +81,15 @@ protected function execute(InputInterface $input, OutputInterface $output) $envOptions = $this->getConfig()->getEnvironment($environment); if (isset($envOptions['adapter'])) { - $output->writeln('using adapter ' . $envOptions['adapter']); + $output->writeln('using adapter ' . $envOptions['adapter'], $this->verbosityLevel); } if (isset($envOptions['wrapper'])) { - $output->writeln('using wrapper ' . $envOptions['wrapper']); + $output->writeln('using wrapper ' . $envOptions['wrapper'], $this->verbosityLevel); } if (isset($envOptions['name'])) { - $output->writeln('using database ' . $envOptions['name']); + $output->writeln('using database ' . $envOptions['name'], $this->verbosityLevel); } else { $output->writeln('Could not determine database name! Please specify a database name in your config file.'); @@ -97,17 +97,17 @@ protected function execute(InputInterface $input, OutputInterface $output) } if (isset($envOptions['table_prefix'])) { - $output->writeln('using table prefix ' . $envOptions['table_prefix']); + $output->writeln('using table prefix ' . $envOptions['table_prefix'], $this->verbosityLevel); } if (isset($envOptions['table_suffix'])) { - $output->writeln('using table suffix ' . $envOptions['table_suffix']); + $output->writeln('using table suffix ' . $envOptions['table_suffix'], $this->verbosityLevel); } $versionOrder = $this->getConfig()->getVersionOrder(); - $output->writeln('ordering by ' . $versionOrder . ' time'); + $output->writeln('ordering by ' . $versionOrder . ' time', $this->verbosityLevel); if ($fake) { - $output->writeln('warning performing fake migrations'); + $output->writeln('warning performing fake migrations', $this->verbosityLevel); } try { @@ -132,8 +132,8 @@ protected function execute(InputInterface $input, OutputInterface $output) return self::CODE_ERROR; } - $output->writeln(''); - $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . ''); + $output->writeln('', $this->verbosityLevel); + $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . '', $this->verbosityLevel); return self::CODE_SUCCESS; } diff --git a/src/Phinx/Console/Command/Rollback.php b/src/Phinx/Console/Command/Rollback.php index 3be48af83..f4ec64082 100644 --- a/src/Phinx/Console/Command/Rollback.php +++ b/src/Phinx/Console/Command/Rollback.php @@ -79,9 +79,9 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($environment === null) { $environment = $config->getDefaultEnvironment(); - $output->writeln('warning no environment specified, defaulting to: ' . $environment); + $output->writeln('warning no environment specified, defaulting to: ' . $environment, $this->verbosityLevel); } else { - $output->writeln('using environment ' . $environment); + $output->writeln('using environment ' . $environment, $this->verbosityLevel); } if (!$this->getConfig()->hasEnvironment($environment)) { @@ -92,22 +92,22 @@ protected function execute(InputInterface $input, OutputInterface $output) $envOptions = $config->getEnvironment($environment); if (isset($envOptions['adapter'])) { - $output->writeln('using adapter ' . $envOptions['adapter']); + $output->writeln('using adapter ' . $envOptions['adapter'], $this->verbosityLevel); } if (isset($envOptions['wrapper'])) { - $output->writeln('using wrapper ' . $envOptions['wrapper']); + $output->writeln('using wrapper ' . $envOptions['wrapper'], $this->verbosityLevel); } if (isset($envOptions['name'])) { - $output->writeln('using database ' . $envOptions['name']); + $output->writeln('using database ' . $envOptions['name'], $this->verbosityLevel); } $versionOrder = $this->getConfig()->getVersionOrder(); - $output->writeln('ordering by ' . $versionOrder . ' time'); + $output->writeln('ordering by ' . $versionOrder . ' time', $this->verbosityLevel); if ($fake) { - $output->writeln('warning performing fake rollbacks'); + $output->writeln('warning performing fake rollbacks', $this->verbosityLevel); } // rollback the specified environment @@ -123,8 +123,8 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->getManager()->rollback($environment, $target, $force, $targetMustMatchVersion, $fake); $end = microtime(true); - $output->writeln(''); - $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . ''); + $output->writeln('', $this->verbosityLevel); + $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . '', $this->verbosityLevel); return self::CODE_SUCCESS; } diff --git a/src/Phinx/Console/Command/SeedCreate.php b/src/Phinx/Console/Command/SeedCreate.php index a91024121..f45a23a40 100644 --- a/src/Phinx/Console/Command/SeedCreate.php +++ b/src/Phinx/Console/Command/SeedCreate.php @@ -197,8 +197,8 @@ protected function execute(InputInterface $input, OutputInterface $output) )); } - $output->writeln('using seed base class ' . $classes['$useClassName']); - $output->writeln('created ' . Util::relativePath($filePath)); + $output->writeln('using seed base class ' . $classes['$useClassName'], $this->verbosityLevel); + $output->writeln('created ' . Util::relativePath($filePath), $this->verbosityLevel); return self::CODE_SUCCESS; } diff --git a/src/Phinx/Console/Command/SeedRun.php b/src/Phinx/Console/Command/SeedRun.php index 996009848..c4344a05c 100644 --- a/src/Phinx/Console/Command/SeedRun.php +++ b/src/Phinx/Console/Command/SeedRun.php @@ -60,9 +60,9 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($environment === null) { $environment = $this->getConfig()->getDefaultEnvironment(); - $output->writeln('warning no environment specified, defaulting to: ' . $environment); + $output->writeln('warning no environment specified, defaulting to: ' . $environment, $this->verbosityLevel); } else { - $output->writeln('using environment ' . $environment); + $output->writeln('using environment ' . $environment, $this->verbosityLevel); } if (!$this->getConfig()->hasEnvironment($environment)) { @@ -73,15 +73,15 @@ protected function execute(InputInterface $input, OutputInterface $output) $envOptions = $this->getConfig()->getEnvironment($environment); if (isset($envOptions['adapter'])) { - $output->writeln('using adapter ' . $envOptions['adapter']); + $output->writeln('using adapter ' . $envOptions['adapter'], $this->verbosityLevel); } if (isset($envOptions['wrapper'])) { - $output->writeln('using wrapper ' . $envOptions['wrapper']); + $output->writeln('using wrapper ' . $envOptions['wrapper'], $this->verbosityLevel); } if (isset($envOptions['name'])) { - $output->writeln('using database ' . $envOptions['name']); + $output->writeln('using database ' . $envOptions['name'], $this->verbosityLevel); } else { $output->writeln('Could not determine database name! Please specify a database name in your config file.'); @@ -89,10 +89,10 @@ protected function execute(InputInterface $input, OutputInterface $output) } if (isset($envOptions['table_prefix'])) { - $output->writeln('using table prefix ' . $envOptions['table_prefix']); + $output->writeln('using table prefix ' . $envOptions['table_prefix'], $this->verbosityLevel); } if (isset($envOptions['table_suffix'])) { - $output->writeln('using table suffix ' . $envOptions['table_suffix']); + $output->writeln('using table suffix ' . $envOptions['table_suffix'], $this->verbosityLevel); } $start = microtime(true); @@ -109,8 +109,8 @@ protected function execute(InputInterface $input, OutputInterface $output) $end = microtime(true); - $output->writeln(''); - $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . ''); + $output->writeln('', $this->verbosityLevel); + $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . '', $this->verbosityLevel); return self::CODE_SUCCESS; } diff --git a/src/Phinx/Console/Command/Status.php b/src/Phinx/Console/Command/Status.php index 9288f780f..df80234b6 100644 --- a/src/Phinx/Console/Command/Status.php +++ b/src/Phinx/Console/Command/Status.php @@ -59,9 +59,9 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($environment === null) { $environment = $this->getConfig()->getDefaultEnvironment(); - $output->writeln('warning no environment specified, defaulting to: ' . $environment); + $output->writeln('warning no environment specified, defaulting to: ' . $environment, $this->verbosityLevel); } else { - $output->writeln('using environment ' . $environment); + $output->writeln('using environment ' . $environment, $this->verbosityLevel); } if (!$this->getConfig()->hasEnvironment($environment)) { @@ -71,10 +71,10 @@ protected function execute(InputInterface $input, OutputInterface $output) } if ($format !== null) { - $output->writeln('using format ' . $format); + $output->writeln('using format ' . $format, $this->verbosityLevel); } - $output->writeln('ordering by ' . $this->getConfig()->getVersionOrder() . ' time'); + $output->writeln('ordering by ' . $this->getConfig()->getVersionOrder() . ' time', $this->verbosityLevel); // print the status $result = $this->getManager()->printStatus($environment, $format); diff --git a/src/Phinx/Console/Command/Test.php b/src/Phinx/Console/Command/Test.php index bfd1fc4c9..269c87299 100644 --- a/src/Phinx/Console/Command/Test.php +++ b/src/Phinx/Console/Command/Test.php @@ -82,7 +82,7 @@ protected function execute(InputInterface $input, OutputInterface $output) )); } - $output->writeln(sprintf('validating environment %s', $envName)); + $output->writeln(sprintf('validating environment %s', $envName), $this->verbosityLevel); $environment = new Environment( $envName, $this->getConfig()->getEnvironment($envName) @@ -91,7 +91,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $environment->getAdapter()->connect(); } - $output->writeln('success!'); + $output->writeln('success!', $this->verbosityLevel); return self::CODE_SUCCESS; } diff --git a/src/Phinx/Console/PhinxApplication.php b/src/Phinx/Console/PhinxApplication.php index bd72ebf14..3ba34a23b 100644 --- a/src/Phinx/Console/PhinxApplication.php +++ b/src/Phinx/Console/PhinxApplication.php @@ -60,9 +60,11 @@ public function doRun(InputInterface $input, OutputInterface $output) { // always show the version information except when the user invokes the help // command as that already does it - if (($input->hasParameterOption(['--help', '-h']) !== false) || ($input->getFirstArgument() !== null && $input->getFirstArgument() !== 'list')) { - $output->writeln($this->getLongVersion()); - $output->writeln(''); + if ($input->hasParameterOption('--no-info') === false) { + if (($input->hasParameterOption(['--help', '-h']) !== false) || ($input->getFirstArgument() !== null && $input->getFirstArgument() !== 'list')) { + $output->writeln($this->getLongVersion()); + $output->writeln(''); + } } return parent::doRun($input, $output); diff --git a/src/Phinx/Migration/Manager.php b/src/Phinx/Migration/Manager.php index 5a24cb6b7..b03957143 100644 --- a/src/Phinx/Migration/Manager.php +++ b/src/Phinx/Migration/Manager.php @@ -63,6 +63,11 @@ class Manager */ protected $container; + /** + * @var int + */ + private $verbosityLevel = OutputInterface::OUTPUT_NORMAL | OutputInterface::VERBOSITY_NORMAL; + /** * @param \Phinx\Config\ConfigInterface $config Configuration Object * @param \Symfony\Component\Console\Input\InputInterface $input Console Input @@ -100,7 +105,7 @@ public function printStatus($environment, $format = null) if (count($migrations)) { // rewrite using Symfony Table Helper as we already have this library // included and it will fix formatting issues (e.g drawing the lines) - $output->writeln(''); + $output->writeln('', $this->verbosityLevel); switch ($this->getConfig()->getVersionOrder()) { case Config::VERSION_ORDER_CREATION_TIME: @@ -113,8 +118,8 @@ public function printStatus($environment, $format = null) throw new RuntimeException('Invalid version_order configuration option'); } - $output->writeln(" Status $migrationIdAndStartedHeader Finished Migration Name "); - $output->writeln('----------------------------------------------------------------------------------'); + $output->writeln(" Status $migrationIdAndStartedHeader Finished Migration Name ", $this->verbosityLevel); + $output->writeln('----------------------------------------------------------------------------------', $this->verbosityLevel); $env = $this->getEnvironment($environment); $versions = $env->getVersionLog(); @@ -189,17 +194,20 @@ public function printStatus($environment, $format = null) } $maxNameLength = max($maxNameLength, strlen($migration->getName())); - $output->writeln(sprintf( - '%s %14.0f %19s %19s %s', - $status, - $migration->getVersion(), - ($version ? $version['start_time'] : ''), - ($version ? $version['end_time'] : ''), - $migration->getName() - )); + $output->writeln( + sprintf( + '%s %14.0f %19s %19s %s', + $status, + $migration->getVersion(), + ($version ? $version['start_time'] : ''), + ($version ? $version['end_time'] : ''), + $migration->getName() + ), + $this->verbosityLevel + ); if ($version && $version['breakpoint']) { - $output->writeln(' BREAKPOINT SET'); + $output->writeln(' BREAKPOINT SET', $this->verbosityLevel); } $finalMigrations[] = ['migration_status' => trim(strip_tags($status)), 'migration_id' => sprintf('%14.0f', $migration->getVersion()), 'migration_name' => $migration->getName()]; @@ -214,12 +222,12 @@ public function printStatus($environment, $format = null) } } else { // there are no migrations - $output->writeln(''); - $output->writeln('There are no available migrations. Try creating one using the create command.'); + $output->writeln('', $this->verbosityLevel); + $output->writeln('There are no available migrations. Try creating one using the create command.', $this->verbosityLevel); } // write an empty line - $output->writeln(''); + $output->writeln('', $this->verbosityLevel); if ($format !== null) { switch ($format) { @@ -287,7 +295,7 @@ public function migrateToDateTime($environment, DateTime $dateTime, $fake = fals if (count($outstandingMigrations) > 0) { $migration = max($outstandingMigrations); - $this->getOutput()->writeln('Migrating to version ' . $migration); + $this->getOutput()->writeln('Migrating to version ' . $migration, $this->verbosityLevel); $this->migrate($environment, $migration, $fake); } } @@ -364,11 +372,12 @@ public function migrate($environment, $version = null, $fake = false) */ public function executeMigration($name, MigrationInterface $migration, $direction = MigrationInterface::UP, $fake = false) { - $this->getOutput()->writeln(''); + $this->getOutput()->writeln('', $this->verbosityLevel); $this->getOutput()->writeln( ' ==' . ' ' . $migration->getVersion() . ' ' . $migration->getName() . ':' . - ' ' . ($direction === MigrationInterface::UP ? 'migrating' : 'reverting') . '' + ' ' . ($direction === MigrationInterface::UP ? 'migrating' : 'reverting') . '', + $this->verbosityLevel ); // Execute the migration and log the time elapsed. @@ -380,7 +389,8 @@ public function executeMigration($name, MigrationInterface $migration, $directio ' ==' . ' ' . $migration->getVersion() . ' ' . $migration->getName() . ':' . ' ' . ($direction === MigrationInterface::UP ? 'migrated' : 'reverted') . - ' ' . sprintf('%.4fs', $end - $start) . '' + ' ' . sprintf('%.4fs', $end - $start) . '', + $this->verbosityLevel ); } @@ -393,11 +403,12 @@ public function executeMigration($name, MigrationInterface $migration, $directio */ public function executeSeed($name, SeedInterface $seed) { - $this->getOutput()->writeln(''); + $this->getOutput()->writeln('', $this->verbosityLevel); $this->getOutput()->writeln( ' ==' . ' ' . $seed->getName() . ':' . - ' seeding' + ' seeding', + $this->verbosityLevel ); // Execute the seeder and log the time elapsed. @@ -409,7 +420,8 @@ public function executeSeed($name, SeedInterface $seed) ' ==' . ' ' . $seed->getName() . ':' . ' seeded' . - ' ' . sprintf('%.4fs', $end - $start) . '' + ' ' . sprintf('%.4fs', $end - $start) . '', + $this->verbosityLevel ); } @@ -1060,4 +1072,15 @@ public function unsetBreakpoint($environment, $version) { $this->markBreakpoint($environment, $version, self::BREAKPOINT_UNSET); } + + /** + * @param int $verbosityLevel Verbosity level for info messages + * @return $this + */ + public function setVerbosityLevel(int $verbosityLevel) + { + $this->verbosityLevel = $verbosityLevel; + + return $this; + } } diff --git a/tests/Phinx/Console/Output/RawBufferedOutput.php b/tests/Phinx/Console/Output/RawBufferedOutput.php index 886a460b0..b8d1e2573 100644 --- a/tests/Phinx/Console/Output/RawBufferedOutput.php +++ b/tests/Phinx/Console/Output/RawBufferedOutput.php @@ -13,8 +13,8 @@ class RawBufferedOutput extends \Symfony\Component\Console\Output\BufferedOutput * @param int $options * @return void */ - public function writeln($messages, $options = self::OUTPUT_RAW) + public function writeln($messages, $options = 0) { - $this->write($messages, true, $options); + $this->write($messages, true, $options | self::OUTPUT_RAW); } } From b1f6d222dd75d1ef8240955126f3607a3190d210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20K=C3=B6hler?= Date: Wed, 22 Dec 2021 15:54:22 +0100 Subject: [PATCH 25/59] Fix docs spell error Replace `specific` with `specify`, and alter the sentence slightly to indicate that both options can be set simultaneously. --- src/Phinx/Db/Table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Phinx/Db/Table.php b/src/Phinx/Db/Table.php index 256a4c279..cbc91e736 100644 --- a/src/Phinx/Db/Table.php +++ b/src/Phinx/Db/Table.php @@ -380,7 +380,7 @@ public function hasColumn($columnName) /** * Add an index to a database table. * - * In $options you can specific unique = true/false or name (index name). + * In $options you can specify unique = true/false, and name (index name). * * @param string|array|\Phinx\Db\Table\Index $columns Table Column(s) * @param array $options Index Options From aed7687ba93ccb85463425a1e2ae7ceb59f692de Mon Sep 17 00:00:00 2001 From: Matthias Wirtz Date: Fri, 31 Dec 2021 10:31:14 +0100 Subject: [PATCH 26/59] support cache query parameter --- docs/en/configuration.rst | 1 + src/Phinx/Db/Adapter/SQLiteAdapter.php | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/en/configuration.rst b/docs/en/configuration.rst index 376829373..35f143a40 100644 --- a/docs/en/configuration.rst +++ b/docs/en/configuration.rst @@ -371,6 +371,7 @@ Declaring an SQLite database uses a simplified structure: testing: adapter: sqlite memory: true # Setting memory to *any* value overrides name + cache: shared # Determines if the new database is opened using shared cache mode or with a private cache SQL Server ````````````````` diff --git a/src/Phinx/Db/Adapter/SQLiteAdapter.php b/src/Phinx/Db/Adapter/SQLiteAdapter.php index 8e2883bdc..7500d47a6 100644 --- a/src/Phinx/Db/Adapter/SQLiteAdapter.php +++ b/src/Phinx/Db/Adapter/SQLiteAdapter.php @@ -157,7 +157,18 @@ public function connect() // use a memory database if the option was specified if (!empty($options['memory']) || $options['name'] === static::MEMORY) { - $dsn = 'sqlite:' . static::MEMORY; + $params = []; + if (!empty($options['cache'])) { + $params[] = 'cache=' . $options['cache']; + } + if ($params) { + if (PHP_VERSION_ID < 80100) { + throw new RuntimeException('SQLite URI support requires PHP 8.1.'); + } + $dsn = 'sqlite:file:' . $options['name'] . '?' . implode('&', $params); + } else { + $dsn = 'sqlite:' . static::MEMORY; + } } else { $dsn = 'sqlite:' . $options['name'] . $this->suffix; } From e0ac9f643f108ee99b6bbeb27cae2d651cde6bc6 Mon Sep 17 00:00:00 2001 From: Matthias Wirtz Date: Sun, 2 Jan 2022 07:56:40 +0100 Subject: [PATCH 27/59] add support for mode --- docs/en/configuration.rst | 13 ++++++++++++- src/Phinx/Db/Adapter/SQLiteAdapter.php | 24 ++++++++++++++---------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/docs/en/configuration.rst b/docs/en/configuration.rst index 35f143a40..8d3b7d200 100644 --- a/docs/en/configuration.rst +++ b/docs/en/configuration.rst @@ -371,7 +371,18 @@ Declaring an SQLite database uses a simplified structure: testing: adapter: sqlite memory: true # Setting memory to *any* value overrides name - cache: shared # Determines if the new database is opened using shared cache mode or with a private cache + +Starting with PHP 8.1 the SQlite adapter supports ``cache`` and ``mode`` +query parameters by using the `URI scheme `_ as long as ``open_basedir`` is unset. + +.. code-block:: yaml + + environments: + testing: + adapter: sqlite + name: my_app + mode: memory # Determines if the new database is opened read-only, read-write, read-write and created if it does not exist, or that the database is a pure in-memory database that never interacts with disk, respectively. + cache: shared # Determines if the new database is opened using shared cache mode or with a private cache. SQL Server ````````````````` diff --git a/src/Phinx/Db/Adapter/SQLiteAdapter.php b/src/Phinx/Db/Adapter/SQLiteAdapter.php index 7500d47a6..e3b579dcd 100644 --- a/src/Phinx/Db/Adapter/SQLiteAdapter.php +++ b/src/Phinx/Db/Adapter/SQLiteAdapter.php @@ -155,22 +155,26 @@ public function connect() $options = $this->getOptions(); - // use a memory database if the option was specified - if (!empty($options['memory']) || $options['name'] === static::MEMORY) { + if (PHP_VERSION_ID < 80100 && (!empty($options['mode']) || !empty($options['cache']))) { + throw new RuntimeException('SQLite URI support requires PHP 8.1.'); + } elseif ((!empty($options['mode']) || !empty($options['cache'])) && !empty($options['memory'])) { + throw new RuntimeException('Memory must not be set when cache or mode are.'); + } elseif (PHP_VERSION_ID >= 80100) { $params = []; if (!empty($options['cache'])) { $params[] = 'cache=' . $options['cache']; } - if ($params) { - if (PHP_VERSION_ID < 80100) { - throw new RuntimeException('SQLite URI support requires PHP 8.1.'); - } - $dsn = 'sqlite:file:' . $options['name'] . '?' . implode('&', $params); - } else { - $dsn = 'sqlite:' . static::MEMORY; + if (!empty($options['mode'])) { + $params[] = 'mode=' . $options['mode']; } + $dsn = 'sqlite:file:' . $options['name'] . '?' . implode('&', $params); } else { - $dsn = 'sqlite:' . $options['name'] . $this->suffix; + // use a memory database if the option was specified + if (!empty($options['memory']) || $options['name'] === static::MEMORY) { + $dsn = 'sqlite:' . static::MEMORY; + } else { + $dsn = 'sqlite:' . $options['name'] . $this->suffix; + } } $driverOptions = []; From e49c9b06d44235cb7c806e3c7f0f7c620012feff Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Tue, 4 Jan 2022 20:34:11 +0100 Subject: [PATCH 28/59] improve tests for create command --- src/Phinx/Console/Command/Create.php | 16 -- tests/Phinx/Console/Command/CreateTest.php | 173 +++++++++++++++++++++ 2 files changed, 173 insertions(+), 16 deletions(-) diff --git a/src/Phinx/Console/Command/Create.php b/src/Phinx/Console/Command/Create.php index 75f805d97..1d00c137e 100644 --- a/src/Phinx/Console/Command/Create.php +++ b/src/Phinx/Console/Command/Create.php @@ -99,12 +99,6 @@ protected function getMigrationPath(InputInterface $input, OutputInterface $outp } $paths = $this->getConfig()->getMigrationPaths(); - - // No paths? That's a problem. - if (empty($paths)) { - throw new Exception('No migration paths set in your Phinx configuration file.'); - } - $paths = Util::globAll($paths); if (empty($paths)) { @@ -143,16 +137,6 @@ protected function execute(InputInterface $input, OutputInterface $output) // get the migration path from the config $path = $this->getMigrationPath($input, $output); - if (!file_exists($path)) { - /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */ - $helper = $this->getHelper('question'); - $question = $this->getCreateMigrationDirectoryQuestion(); - - if ($helper->ask($input, $output, $question)) { - mkdir($path, 0755, true); - } - } - $this->verifyMigrationDirectory($path); $config = $this->getConfig(); diff --git a/tests/Phinx/Console/Command/CreateTest.php b/tests/Phinx/Console/Command/CreateTest.php index 48d1eab2f..c7fa2544f 100644 --- a/tests/Phinx/Console/Command/CreateTest.php +++ b/tests/Phinx/Console/Command/CreateTest.php @@ -441,4 +441,177 @@ public function testSimpleTemplateGeneratorsIsCorrectlyPopulated(array $config, $expectedMigration = "useClassName Phinx\\Migration\\AbstractMigration / className {$commandLine['name']} / version {$match['Version']} / baseClassName AbstractMigration"; $this->assertStringEqualsFile($match['MigrationFilename'], $expectedMigration, 'Failed to create migration file from template generator correctly.'); } + + public function testNoMigrationsPathConfig() + { + $application = new PhinxApplication(); + $application->add(new Create()); + + /** @var Create $command */ + $command = $application->find('create'); + + /** @var Manager $managerStub mock the manager class */ + $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + ->setConstructorArgs([$this->config, $this->input, $this->output]) + ->getMock(); + + $this->config->offsetSet('paths', []); + $command->setConfig($this->config); + $command->setManager($managerStub); + + $commandTester = new CommandTester($command); + + $this->expectException(Exception::class); + $this->expectExceptionMessage('Migrations path missing from config file'); + + $commandTester->execute(['command' => $command->getName()]); + } + + public function testMultipleMigrationsPaths() + { + $application = new PhinxApplication(); + $application->add(new Create()); + + /** @var Create $command */ + $command = $application->find('create'); + + /** @var Manager $managerStub mock the manager class */ + $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + ->setConstructorArgs([$this->config, $this->input, $this->output]) + ->getMock(); + + @mkdir(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'othermigrations', 0777, true); + $this->config->offsetSet('paths', [ + 'migrations' => [ + sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'migrations', + sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'othermigrations', + ], + ]); + $command->setConfig($this->config); + $command->setManager($managerStub); + + $commandTester = new CommandTester($command); + $commandTester->execute(['command' => $command->getName()]); + + $files = array_diff(scandir($this->config->getMigrationPaths()[0]), ['.', '..']); + $this->assertCount(1, $files); + $fileName = current($files); + $this->assertMatchesRegularExpression('/^[0-9]{14}.php/', $fileName); + $date = substr($fileName, 0, 14); + $this->assertFileExists($this->config->getMigrationPaths()[0]); + $prefix = "assertStringStartsWith($prefix, file_get_contents($this->config->getMigrationPaths()[0] . DIRECTORY_SEPARATOR . $fileName)); + } + + public function testNoMigrationsPath() + { + TestUtils::recursiveRmdir(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'migrations'); + + $application = new PhinxApplication(); + $application->add(new Create()); + + /** @var Create $command */ + $command = $application->find('create'); + + /** @var Manager $managerStub mock the manager class */ + $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + ->setConstructorArgs([$this->config, $this->input, $this->output]) + ->getMock(); + + $command->setConfig($this->config); + $command->setManager($managerStub); + + $commandTester = new CommandTester($command); + + $this->expectException(Exception::class); + $this->expectExceptionMessage('You probably used curly braces to define migration path in your Phinx configuration file, '); + + $commandTester->execute(['command' => $command->getName()]); + } + + public function testInvalidClassName(): void + { + $application = new PhinxApplication(); + $application->add(new Create()); + + /** @var Create $command */ + $command = $application->find('create'); + + /** @var Manager $managerStub mock the manager class */ + $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + ->setConstructorArgs([$this->config, $this->input, $this->output]) + ->getMock(); + + $command->setConfig($this->config); + $command->setManager($managerStub); + + $commandTester = new CommandTester($command); + + $this->expectException(Exception::class); + $this->expectExceptionMessage('The migration class name "Th1sI5ÄnInvalüdClaßnam€" is invalid. Please use CamelCase format.'); + + $commandTester->execute([ + 'command' => $command->getName(), + 'name' => 'Th1sI5ÄnInvalüdClaßnam€', + ]); + } + + public function testCreateWithPath(): void + { + $application = new PhinxApplication(); + $application->add(new Create()); + + /** @var Create $command */ + $command = $application->find('create'); + + /** @var Manager $managerStub mock the manager class */ + $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + ->setConstructorArgs([$this->config, $this->input, $this->output]) + ->getMock(); + + $command->setConfig($this->config); + $command->setManager($managerStub); + + $path = $this->config->getMigrationPaths()[0]; + + $commandTester = new CommandTester($command); + $commandTester->execute(['command' => $command->getName(), '--path' => $path]); + + $files = array_diff(scandir($path), ['.', '..']); + $this->assertCount(1, $files); + $fileName = current($files); + $this->assertMatchesRegularExpression('/^[0-9]{14}.php/', $fileName); + $date = substr($fileName, 0, 14); + $this->assertFileExists($this->config->getMigrationPaths()[0]); + $prefix = "assertStringStartsWith($prefix, file_get_contents($this->config->getMigrationPaths()[0] . DIRECTORY_SEPARATOR . $fileName)); + } + + public function testNoAltTemplate(): void + { + $application = new PhinxApplication(); + $application->add(new Create()); + + /** @var Create $command */ + $command = $application->find('create'); + + /** @var Manager $managerStub mock the manager class */ + $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + ->setConstructorArgs([$this->config, $this->input, $this->output]) + ->getMock(); + + $this->config->offsetSet('templates', [ + 'file' => 'MyTemplate', + ]); + + $command->setConfig($this->config); + $command->setManager($managerStub); + + $commandTester = new CommandTester($command); + + $this->expectException(Exception::class); + $this->expectExceptionMessage('The alternative template file "MyTemplate" does not exist'); + + $commandTester->execute(['command' => $command->getName()]); + } } From 6ec64fc7a1067ff58a248bc26edfe2ef81aff136 Mon Sep 17 00:00:00 2001 From: mscherer Date: Fri, 14 Jan 2022 22:10:24 +0100 Subject: [PATCH 29/59] Fix up allow-plugins config --- composer.json | 60 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index 2da8eb8d2..52afaa379 100644 --- a/composer.json +++ b/composer.json @@ -2,28 +2,39 @@ "name": "robmorgan/phinx", "type": "library", "description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.", - "keywords": ["phinx", "migrations", "database", "db", "database migrations"], + "keywords": [ + "phinx", + "migrations", + "database", + "db", + "database migrations" + ], "homepage": "https://phinx.org", "license": "MIT", - "authors": [{ - "name": "Rob Morgan", - "email": "robbym@gmail.com", - "homepage": "https://robmorgan.id.au", - "role": "Lead Developer" - }, { - "name": "Woody Gilk", - "email": "woody.gilk@gmail.com", - "homepage": "https://shadowhand.me", - "role": "Developer" - }, { - "name": "Richard Quadling", - "email": "rquadling@gmail.com", - "role": "Developer" - }, { - "name": "CakePHP Community", - "role": "Developer", - "homepage": "https://github.com/cakephp/phinx/graphs/contributors" - }], + "authors": [ + { + "name": "Rob Morgan", + "email": "robbym@gmail.com", + "homepage": "https://robmorgan.id.au", + "role": "Lead Developer" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com", + "homepage": "https://shadowhand.me", + "role": "Developer" + }, + { + "name": "Richard Quadling", + "email": "rquadling@gmail.com", + "role": "Developer" + }, + { + "name": "CakePHP Community", + "role": "Developer", + "homepage": "https://github.com/cakephp/phinx/graphs/contributors" + } + ], "require": { "php": ">=7.2", "cakephp/database": "^4.0", @@ -65,5 +76,12 @@ "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^0.12 && mv composer.backup composer.json", "test": "phpunit --colors=always" }, - "bin": ["bin/phinx"] + "bin": [ + "bin/phinx" + ], + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + } } From f3ee4ae3083fd153c86eb77eb938650060c53a4c Mon Sep 17 00:00:00 2001 From: saeideng Date: Fri, 21 Jan 2022 23:17:08 +0330 Subject: [PATCH 30/59] Revert "improve tests for create command" --- src/Phinx/Console/Command/Create.php | 16 ++ tests/Phinx/Console/Command/CreateTest.php | 173 --------------------- 2 files changed, 16 insertions(+), 173 deletions(-) diff --git a/src/Phinx/Console/Command/Create.php b/src/Phinx/Console/Command/Create.php index c70668928..8fad84806 100644 --- a/src/Phinx/Console/Command/Create.php +++ b/src/Phinx/Console/Command/Create.php @@ -99,6 +99,12 @@ protected function getMigrationPath(InputInterface $input, OutputInterface $outp } $paths = $this->getConfig()->getMigrationPaths(); + + // No paths? That's a problem. + if (empty($paths)) { + throw new Exception('No migration paths set in your Phinx configuration file.'); + } + $paths = Util::globAll($paths); if (empty($paths)) { @@ -137,6 +143,16 @@ protected function execute(InputInterface $input, OutputInterface $output) // get the migration path from the config $path = $this->getMigrationPath($input, $output); + if (!file_exists($path)) { + /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */ + $helper = $this->getHelper('question'); + $question = $this->getCreateMigrationDirectoryQuestion(); + + if ($helper->ask($input, $output, $question)) { + mkdir($path, 0755, true); + } + } + $this->verifyMigrationDirectory($path); $config = $this->getConfig(); diff --git a/tests/Phinx/Console/Command/CreateTest.php b/tests/Phinx/Console/Command/CreateTest.php index c7fa2544f..48d1eab2f 100644 --- a/tests/Phinx/Console/Command/CreateTest.php +++ b/tests/Phinx/Console/Command/CreateTest.php @@ -441,177 +441,4 @@ public function testSimpleTemplateGeneratorsIsCorrectlyPopulated(array $config, $expectedMigration = "useClassName Phinx\\Migration\\AbstractMigration / className {$commandLine['name']} / version {$match['Version']} / baseClassName AbstractMigration"; $this->assertStringEqualsFile($match['MigrationFilename'], $expectedMigration, 'Failed to create migration file from template generator correctly.'); } - - public function testNoMigrationsPathConfig() - { - $application = new PhinxApplication(); - $application->add(new Create()); - - /** @var Create $command */ - $command = $application->find('create'); - - /** @var Manager $managerStub mock the manager class */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') - ->setConstructorArgs([$this->config, $this->input, $this->output]) - ->getMock(); - - $this->config->offsetSet('paths', []); - $command->setConfig($this->config); - $command->setManager($managerStub); - - $commandTester = new CommandTester($command); - - $this->expectException(Exception::class); - $this->expectExceptionMessage('Migrations path missing from config file'); - - $commandTester->execute(['command' => $command->getName()]); - } - - public function testMultipleMigrationsPaths() - { - $application = new PhinxApplication(); - $application->add(new Create()); - - /** @var Create $command */ - $command = $application->find('create'); - - /** @var Manager $managerStub mock the manager class */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') - ->setConstructorArgs([$this->config, $this->input, $this->output]) - ->getMock(); - - @mkdir(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'othermigrations', 0777, true); - $this->config->offsetSet('paths', [ - 'migrations' => [ - sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'migrations', - sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'othermigrations', - ], - ]); - $command->setConfig($this->config); - $command->setManager($managerStub); - - $commandTester = new CommandTester($command); - $commandTester->execute(['command' => $command->getName()]); - - $files = array_diff(scandir($this->config->getMigrationPaths()[0]), ['.', '..']); - $this->assertCount(1, $files); - $fileName = current($files); - $this->assertMatchesRegularExpression('/^[0-9]{14}.php/', $fileName); - $date = substr($fileName, 0, 14); - $this->assertFileExists($this->config->getMigrationPaths()[0]); - $prefix = "assertStringStartsWith($prefix, file_get_contents($this->config->getMigrationPaths()[0] . DIRECTORY_SEPARATOR . $fileName)); - } - - public function testNoMigrationsPath() - { - TestUtils::recursiveRmdir(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'migrations'); - - $application = new PhinxApplication(); - $application->add(new Create()); - - /** @var Create $command */ - $command = $application->find('create'); - - /** @var Manager $managerStub mock the manager class */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') - ->setConstructorArgs([$this->config, $this->input, $this->output]) - ->getMock(); - - $command->setConfig($this->config); - $command->setManager($managerStub); - - $commandTester = new CommandTester($command); - - $this->expectException(Exception::class); - $this->expectExceptionMessage('You probably used curly braces to define migration path in your Phinx configuration file, '); - - $commandTester->execute(['command' => $command->getName()]); - } - - public function testInvalidClassName(): void - { - $application = new PhinxApplication(); - $application->add(new Create()); - - /** @var Create $command */ - $command = $application->find('create'); - - /** @var Manager $managerStub mock the manager class */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') - ->setConstructorArgs([$this->config, $this->input, $this->output]) - ->getMock(); - - $command->setConfig($this->config); - $command->setManager($managerStub); - - $commandTester = new CommandTester($command); - - $this->expectException(Exception::class); - $this->expectExceptionMessage('The migration class name "Th1sI5ÄnInvalüdClaßnam€" is invalid. Please use CamelCase format.'); - - $commandTester->execute([ - 'command' => $command->getName(), - 'name' => 'Th1sI5ÄnInvalüdClaßnam€', - ]); - } - - public function testCreateWithPath(): void - { - $application = new PhinxApplication(); - $application->add(new Create()); - - /** @var Create $command */ - $command = $application->find('create'); - - /** @var Manager $managerStub mock the manager class */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') - ->setConstructorArgs([$this->config, $this->input, $this->output]) - ->getMock(); - - $command->setConfig($this->config); - $command->setManager($managerStub); - - $path = $this->config->getMigrationPaths()[0]; - - $commandTester = new CommandTester($command); - $commandTester->execute(['command' => $command->getName(), '--path' => $path]); - - $files = array_diff(scandir($path), ['.', '..']); - $this->assertCount(1, $files); - $fileName = current($files); - $this->assertMatchesRegularExpression('/^[0-9]{14}.php/', $fileName); - $date = substr($fileName, 0, 14); - $this->assertFileExists($this->config->getMigrationPaths()[0]); - $prefix = "assertStringStartsWith($prefix, file_get_contents($this->config->getMigrationPaths()[0] . DIRECTORY_SEPARATOR . $fileName)); - } - - public function testNoAltTemplate(): void - { - $application = new PhinxApplication(); - $application->add(new Create()); - - /** @var Create $command */ - $command = $application->find('create'); - - /** @var Manager $managerStub mock the manager class */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') - ->setConstructorArgs([$this->config, $this->input, $this->output]) - ->getMock(); - - $this->config->offsetSet('templates', [ - 'file' => 'MyTemplate', - ]); - - $command->setConfig($this->config); - $command->setManager($managerStub); - - $commandTester = new CommandTester($command); - - $this->expectException(Exception::class); - $this->expectExceptionMessage('The alternative template file "MyTemplate" does not exist'); - - $commandTester->execute(['command' => $command->getName()]); - } } From d73fc6724f02d8a011094fed495c0410be203c2f Mon Sep 17 00:00:00 2001 From: Matthias Wirtz Date: Sat, 22 Jan 2022 16:07:05 +0100 Subject: [PATCH 31/59] do not force into using uri scheme if no params are set --- src/Phinx/Db/Adapter/SQLiteAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Phinx/Db/Adapter/SQLiteAdapter.php b/src/Phinx/Db/Adapter/SQLiteAdapter.php index e3b579dcd..ba7f53b7f 100644 --- a/src/Phinx/Db/Adapter/SQLiteAdapter.php +++ b/src/Phinx/Db/Adapter/SQLiteAdapter.php @@ -159,7 +159,7 @@ public function connect() throw new RuntimeException('SQLite URI support requires PHP 8.1.'); } elseif ((!empty($options['mode']) || !empty($options['cache'])) && !empty($options['memory'])) { throw new RuntimeException('Memory must not be set when cache or mode are.'); - } elseif (PHP_VERSION_ID >= 80100) { + } elseif (PHP_VERSION_ID >= 80100 && (!empty($options['mode']) || !empty($options['cache']))) { $params = []; if (!empty($options['cache'])) { $params[] = 'cache=' . $options['cache']; From b80ee4de48a69f03fa25599b30ac39617530dc73 Mon Sep 17 00:00:00 2001 From: Matthias Wirtz Date: Mon, 24 Jan 2022 06:42:45 +0100 Subject: [PATCH 32/59] empty if not set --- src/Phinx/Db/Adapter/SQLiteAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Phinx/Db/Adapter/SQLiteAdapter.php b/src/Phinx/Db/Adapter/SQLiteAdapter.php index ba7f53b7f..3521d22bf 100644 --- a/src/Phinx/Db/Adapter/SQLiteAdapter.php +++ b/src/Phinx/Db/Adapter/SQLiteAdapter.php @@ -167,7 +167,7 @@ public function connect() if (!empty($options['mode'])) { $params[] = 'mode=' . $options['mode']; } - $dsn = 'sqlite:file:' . $options['name'] . '?' . implode('&', $params); + $dsn = 'sqlite:file:' . $options['name'] ?? '' . '?' . implode('&', $params); } else { // use a memory database if the option was specified if (!empty($options['memory']) || $options['name'] === static::MEMORY) { From b882f78d068008e6caf57c06e8e42b91fd6505ec Mon Sep 17 00:00:00 2001 From: Antonio de la Vega Date: Thu, 27 Jan 2022 16:49:38 +0100 Subject: [PATCH 33/59] feat(Postgres): Add full text search index types --- src/Phinx/Db/Adapter/PostgresAdapter.php | 11 ++++++++++- tests/Phinx/Db/Adapter/PostgresAdapterTest.php | 13 +++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Phinx/Db/Adapter/PostgresAdapter.php b/src/Phinx/Db/Adapter/PostgresAdapter.php index b9b637d94..38fa50969 100644 --- a/src/Phinx/Db/Adapter/PostgresAdapter.php +++ b/src/Phinx/Db/Adapter/PostgresAdapter.php @@ -35,6 +35,8 @@ class PostgresAdapter extends PdoAdapter self::PHINX_TYPE_BINARYUUID, ]; + const FULLTEXT_INDEX_TYPES = ['gin', 'gist']; + /** * Columns with comments * @@ -1264,8 +1266,15 @@ protected function getIndexSqlDefinition(Index $index, $tableName) $includedColumns = $index->getInclude() ? sprintf('INCLUDE ("%s")', implode('","', $index->getInclude())) : ''; + $createIndexSentence = 'CREATE %s INDEX %s ON %s '; + if(in_array($index->getType(), self::FULLTEXT_INDEX_TYPES, true)) { + $createIndexSentence .= ' USING ' . $index->getType() .'(%s) %s;'; + } else { + $createIndexSentence .= '(%s) %s;'; + } + return sprintf( - 'CREATE %s INDEX %s ON %s (%s) %s;', + $createIndexSentence, ($index->getType() === Index::UNIQUE ? 'UNIQUE' : ''), $this->quoteColumnName($indexName), $this->quoteTableName($tableName), diff --git a/tests/Phinx/Db/Adapter/PostgresAdapterTest.php b/tests/Phinx/Db/Adapter/PostgresAdapterTest.php index 5c89ff589..8a5cfcda5 100644 --- a/tests/Phinx/Db/Adapter/PostgresAdapterTest.php +++ b/tests/Phinx/Db/Adapter/PostgresAdapterTest.php @@ -352,6 +352,19 @@ public function testCreateTableWithUniqueIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_email'])); } + public function testCreateTableWithFullTextSearchIndexes() + { + $table = new \Phinx\Db\Table('table1', [], $this->adapter); + $table->addColumn('names', 'jsonb') + ->addColumn('texts', 'jsonb') + ->addIndex('names', ['gin' => true]) + ->addIndex('texts', ['gist' => true]) + ->save(); + + $this->assertTrue($this->adapter->hasIndex('table1', ['names'])); + $this->assertTrue($this->adapter->hasIndex('table1', ['texts'])); + } + public function testCreateTableWithNamedIndexes() { $table = new \Phinx\Db\Table('table1', [], $this->adapter); From bff508c3167c3721d87ef7edef902d3c16fba93f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 27 Jan 2022 15:54:28 +0000 Subject: [PATCH 34/59] Fixing style errors. --- src/Phinx/Db/Adapter/PostgresAdapter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Phinx/Db/Adapter/PostgresAdapter.php b/src/Phinx/Db/Adapter/PostgresAdapter.php index 38fa50969..06690c53e 100644 --- a/src/Phinx/Db/Adapter/PostgresAdapter.php +++ b/src/Phinx/Db/Adapter/PostgresAdapter.php @@ -1267,8 +1267,8 @@ protected function getIndexSqlDefinition(Index $index, $tableName) $includedColumns = $index->getInclude() ? sprintf('INCLUDE ("%s")', implode('","', $index->getInclude())) : ''; $createIndexSentence = 'CREATE %s INDEX %s ON %s '; - if(in_array($index->getType(), self::FULLTEXT_INDEX_TYPES, true)) { - $createIndexSentence .= ' USING ' . $index->getType() .'(%s) %s;'; + if (in_array($index->getType(), self::FULLTEXT_INDEX_TYPES, true)) { + $createIndexSentence .= ' USING ' . $index->getType() . '(%s) %s;'; } else { $createIndexSentence .= '(%s) %s;'; } From 498adcd99fe873ab380e19fd598ec190fc14d97f Mon Sep 17 00:00:00 2001 From: Antonio de la Vega Date: Thu, 27 Jan 2022 17:22:56 +0100 Subject: [PATCH 35/59] fix(Postgres): Update test. removes gist support --- src/Phinx/Db/Adapter/PostgresAdapter.php | 4 ++-- tests/Phinx/Db/Adapter/PostgresAdapterTest.php | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Phinx/Db/Adapter/PostgresAdapter.php b/src/Phinx/Db/Adapter/PostgresAdapter.php index 38fa50969..73014628a 100644 --- a/src/Phinx/Db/Adapter/PostgresAdapter.php +++ b/src/Phinx/Db/Adapter/PostgresAdapter.php @@ -35,7 +35,7 @@ class PostgresAdapter extends PdoAdapter self::PHINX_TYPE_BINARYUUID, ]; - const FULLTEXT_INDEX_TYPES = ['gin', 'gist']; + const GIN_INDEX_TYPE = 'gin'; /** * Columns with comments @@ -1267,7 +1267,7 @@ protected function getIndexSqlDefinition(Index $index, $tableName) $includedColumns = $index->getInclude() ? sprintf('INCLUDE ("%s")', implode('","', $index->getInclude())) : ''; $createIndexSentence = 'CREATE %s INDEX %s ON %s '; - if(in_array($index->getType(), self::FULLTEXT_INDEX_TYPES, true)) { + if($index->getType() === self::GIN_INDEX_TYPE) { $createIndexSentence .= ' USING ' . $index->getType() .'(%s) %s;'; } else { $createIndexSentence .= '(%s) %s;'; diff --git a/tests/Phinx/Db/Adapter/PostgresAdapterTest.php b/tests/Phinx/Db/Adapter/PostgresAdapterTest.php index 8a5cfcda5..47eded3cb 100644 --- a/tests/Phinx/Db/Adapter/PostgresAdapterTest.php +++ b/tests/Phinx/Db/Adapter/PostgresAdapterTest.php @@ -356,13 +356,10 @@ public function testCreateTableWithFullTextSearchIndexes() { $table = new \Phinx\Db\Table('table1', [], $this->adapter); $table->addColumn('names', 'jsonb') - ->addColumn('texts', 'jsonb') - ->addIndex('names', ['gin' => true]) - ->addIndex('texts', ['gist' => true]) + ->addIndex('names', ['type' => 'gin']) ->save(); $this->assertTrue($this->adapter->hasIndex('table1', ['names'])); - $this->assertTrue($this->adapter->hasIndex('table1', ['texts'])); } public function testCreateTableWithNamedIndexes() From 35ee97dab08fab673fc0073f549040317441c94f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 27 Jan 2022 16:24:43 +0000 Subject: [PATCH 36/59] Fixing style errors. --- src/Phinx/Db/Adapter/PostgresAdapter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Phinx/Db/Adapter/PostgresAdapter.php b/src/Phinx/Db/Adapter/PostgresAdapter.php index 73014628a..fe0c88027 100644 --- a/src/Phinx/Db/Adapter/PostgresAdapter.php +++ b/src/Phinx/Db/Adapter/PostgresAdapter.php @@ -1267,8 +1267,8 @@ protected function getIndexSqlDefinition(Index $index, $tableName) $includedColumns = $index->getInclude() ? sprintf('INCLUDE ("%s")', implode('","', $index->getInclude())) : ''; $createIndexSentence = 'CREATE %s INDEX %s ON %s '; - if($index->getType() === self::GIN_INDEX_TYPE) { - $createIndexSentence .= ' USING ' . $index->getType() .'(%s) %s;'; + if ($index->getType() === self::GIN_INDEX_TYPE) { + $createIndexSentence .= ' USING ' . $index->getType() . '(%s) %s;'; } else { $createIndexSentence .= '(%s) %s;'; } From 12179a84456784058a4d104d601d0c188a2b3a54 Mon Sep 17 00:00:00 2001 From: Antonio de la Vega Date: Thu, 27 Jan 2022 17:27:58 +0100 Subject: [PATCH 37/59] fix(Postgres): Add visibility to constant --- src/Phinx/Db/Adapter/PostgresAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Phinx/Db/Adapter/PostgresAdapter.php b/src/Phinx/Db/Adapter/PostgresAdapter.php index fe0c88027..f510ba97d 100644 --- a/src/Phinx/Db/Adapter/PostgresAdapter.php +++ b/src/Phinx/Db/Adapter/PostgresAdapter.php @@ -35,7 +35,7 @@ class PostgresAdapter extends PdoAdapter self::PHINX_TYPE_BINARYUUID, ]; - const GIN_INDEX_TYPE = 'gin'; + private const GIN_INDEX_TYPE = 'gin'; /** * Columns with comments From 31d79dc3d4309edb03f616f551bcab3901761273 Mon Sep 17 00:00:00 2001 From: Antonio de la Vega Date: Thu, 27 Jan 2022 18:38:55 +0100 Subject: [PATCH 38/59] doc(postgres): Add GIN index documentation --- docs/en/migrations.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/en/migrations.rst b/docs/en/migrations.rst index 4dc814063..37e3e6b53 100644 --- a/docs/en/migrations.rst +++ b/docs/en/migrations.rst @@ -1388,6 +1388,24 @@ The SQL Server and PostgreSQL adapters also supports ``include`` (non-key) colum } } +In addition PostgreSQL adapters also supports Generalized Inverted Index ``gin`` indexes. + +.. code-block:: php + + table('users'); + $table->addColumn('address', 'string') + ->addIndex('address', ['type' => 'gin']) + ->create(); + } + } Removing indexes is as easy as calling the ``removeIndex()`` method. You must call this method for each index. From c81dfd77e4a811165ff08facdf5efeabd059cf62 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 4 Feb 2022 23:07:21 -0500 Subject: [PATCH 39/59] Add workflow dispatch so I can rebuild docs & docs indexes. --- .github/workflows/deploy_docs_0x.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/deploy_docs_0x.yml b/.github/workflows/deploy_docs_0x.yml index 0e168695e..65585333b 100644 --- a/.github/workflows/deploy_docs_0x.yml +++ b/.github/workflows/deploy_docs_0x.yml @@ -5,6 +5,12 @@ on: push: tags: - v0.* + workflow_dispatch: + inputs: + branch: + description: Branch to run on + default: master + required: true jobs: deploy: From a153a2d44b86bcfe5249bd6943d54cda4d401b6a Mon Sep 17 00:00:00 2001 From: saeideng Date: Tue, 8 Mar 2022 10:43:36 +0330 Subject: [PATCH 40/59] Bump phpstan --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 52afaa379..3be47a368 100644 --- a/composer.json +++ b/composer.json @@ -73,7 +73,7 @@ "cs-check": "phpcs -np app/ src/ tests/", "cs-fix": "phpcbf -np app/ src/ tests/", "stan": "phpstan analyse src/", - "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^0.12 && mv composer.backup composer.json", + "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:~1.4.0 && mv composer.backup composer.json", "test": "phpunit --colors=always" }, "bin": [ From 1202f16e01ec42e8f5caa3d916a3325514edce23 Mon Sep 17 00:00:00 2001 From: Matthew Peveler Date: Wed, 9 Mar 2022 08:36:50 -0500 Subject: [PATCH 41/59] Remove out-of-date translated docs --- docs.Dockerfile | 4 +- docs/config/all.py | 2 +- docs/es/commands.rst | 292 --------- docs/es/conf.py | 9 - docs/es/contents.rst | 8 - docs/fr/commands.rst | 339 ---------- docs/fr/conf.py | 9 - docs/fr/configuration.rst | 308 --------- docs/fr/contents.rst | 11 - docs/fr/index.rst | 57 -- docs/fr/migrations.rst | 1305 ------------------------------------- docs/fr/seeding.rst | 217 ------ docs/ja/commands.rst | 338 ---------- docs/ja/conf.py | 9 - docs/ja/configuration.rst | 305 --------- docs/ja/contents.rst | 12 - docs/ja/index.rst | 60 -- docs/ja/migrations.rst | 1293 ------------------------------------ docs/ja/seeding.rst | 214 ------ 19 files changed, 3 insertions(+), 4789 deletions(-) delete mode 100644 docs/es/commands.rst delete mode 100644 docs/es/conf.py delete mode 100644 docs/es/contents.rst delete mode 100644 docs/fr/commands.rst delete mode 100644 docs/fr/conf.py delete mode 100644 docs/fr/configuration.rst delete mode 100644 docs/fr/contents.rst delete mode 100644 docs/fr/index.rst delete mode 100644 docs/fr/migrations.rst delete mode 100644 docs/fr/seeding.rst delete mode 100644 docs/ja/commands.rst delete mode 100644 docs/ja/conf.py delete mode 100644 docs/ja/configuration.rst delete mode 100644 docs/ja/contents.rst delete mode 100644 docs/ja/index.rst delete mode 100644 docs/ja/migrations.rst delete mode 100644 docs/ja/seeding.rst diff --git a/docs.Dockerfile b/docs.Dockerfile index b910b01d0..e41aed21d 100644 --- a/docs.Dockerfile +++ b/docs.Dockerfile @@ -5,14 +5,14 @@ COPY docs /data/docs # Build docs with sphinx RUN cd /data/docs-builder && \ - make website LANGS="en es fr ja" SOURCE=/data/docs DEST=/data/website + make website LANGS="en" SOURCE=/data/docs DEST=/data/website # Build a small nginx container with just the static site in it. FROM markstory/cakephp-docs-builder:runtime as runtime # Configure search index script -ENV LANGS="en es fr ja" +ENV LANGS="en" ENV SEARCH_SOURCE="/data/docs" ENV SEARCH_URL_PREFIX="/phinx/0" diff --git a/docs/config/all.py b/docs/config/all.py index 0276971e8..df79d5327 100644 --- a/docs/config/all.py +++ b/docs/config/all.py @@ -25,7 +25,7 @@ ] # Languages available. -languages = ['en', 'es', 'fr', 'ja'] +languages = ['en'] # The GitHub branch name for this version of the docs # for edit links to point at. diff --git a/docs/es/commands.rst b/docs/es/commands.rst deleted file mode 100644 index 685c22932..000000000 --- a/docs/es/commands.rst +++ /dev/null @@ -1,292 +0,0 @@ -. index:: - single: Commands - -Comandos -######## - -Phinx se corre usando un numero de comandos. - -Migracion de Comandos -===================== - -Comando de Inicio - -El comanado de inicio (manera corta de inicialización) se usa para preparar el proyecto Phinix. Este comando genera el archivo phinx.yml en el directorio raiz del proyecto: - -.. code-block:: bash - - $ cd yourapp - $ phinx init . - -Abre este archivo en tu editor de texto para configurar tu projecto. Por favot mira el :doc:`Configuration ` para mas información. - -Comando de creación. --------------------- - -El comando de creación se usa para crear un nuevo archivo de migración. Requiere un argumento: el nombre de la migración. El nombre de la migracion debera especificarse en el formato CamelCase: - -.. code-block:: bash - - $ phinx create MyNewMigration - -Abre el nuevo archivo de migración en tu editor de texto para agregar las transformaciones de tu base de datos. Phinx crea archivos de migracion usando direcciones especificas en tu archivo phinx.yml . Por favor mire :doc:`Configuration ` para mas información. - -Usted puede sobreescribir el archivo modelo usado por Phinx suministrando una alternativa del modelo de archivo: - -.. code-block:: bash - - $ phinx create MyNewMigration --template="" - -Tambien puedes suministrar un modelo de clase general. Esta clase deberá implementar la interfaz ``Phinx\Migration\CreationInterface``. - -.. code-block:: bash - - $ phinx create MyNewMigration --class="" - -Además de proveer el modelo para la migracion, la clase tambien puede definir una "callback" que sera llamada una vez que el archivo de migración haya sido generado por el modelo. - -No puede usar ``--template`` y ``--class`` juntos. - -El comando de migración ------------------------ - -El comando de migración corre todas las migraciones que se encuentren disponibles, opcionalmente hasta una version especificada. - -.. code-block:: bash - - $ phinx migrate -e development - -Para migrar a una version especifica se utiliza el parametro ``--targe`` o ``-t`` resumido. - -.. code-block:: bash - - $ phinx migrate -e development -t 20110103081132 - -Use ``--dry-run`` para imprimir las consultas a la salida sin ejecutarlas - -.. code-block:: bash - - $ phinx migrate --dry-run - - -El comando para revertir ------------------------- - -El comando para revertir se utiliza para deshacer las migraciones anteriores ejecutadas por Phinx. Es lo opuesto al comando Migrar. - -Puede revertir a la migración anterior usando el comando rollback sin argumentos. - -.. code-block:: bash - - $ phinx rollback -e development - -Para revertir todas las migraciones a una versión específica, use el parámetro ``--target`` o ``-t`` para abreviar - -.. code-block:: bash - - $ phinx rollback -e development -t 20120103083322 - -Especificar 0 como la versión de destino revertirá todas las migraciones. - -.. code-block:: bash - - $ phinx rollback -e development -t 0 - -Para revertir todas las migraciones a una fecha específica, use el parámetro ``--date`` o -d para abreviar. - -.. code-block:: bash - - $ phinx rollback -e development -d 2012 - $ phinx rollback -e development -d 201201 - $ phinx rollback -e development -d 20120103 - $ phinx rollback -e development -d 2012010312 - $ phinx rollback -e development -d 201201031205 - $ phinx rollback -e development -d 20120103120530 - -Si se establece un punto de interrupción, bloqueando más reversiones, puede anular el punto de interrupción utilizando el parámetro ``--force`` o ``-f`` para abreviar - -.. code-block:: bash - - $ phinx rollback -e development -t 0 -f - -Utilice ``--dry-run`` para imprimir las consultas a la salida estándar sin ejecutarlas - -.. code-block:: bash - - $ phinx rollback --dry-run - -.. note:: - - When rolling back, Phinx orders the executed migrations using the order specified in the version_order option of your phinx.yml file. Please see the :doc:`Configuration ` chapter for more information. - -El comando de estado --------------------- - -El comando Estado imprime una lista de todas las migraciones, junto con su estado actual. Puede usar este comando para determinar qué migraciones se han ejecutado. - -.. code-block:: bash - - $ phinx status -e development - -La salida de este comando es 0 si la base de datos está actualizada (es decir, todas las migraciones están activas) o uno de los siguientes códigos de lo contrario: - -#. Queda por lo menos una migración por ejecutar. -#: se ejecutó una migración y se registró en la base de datos, pero ahora falta -el archivo de migración - -El comando de interrupción ---------------------------- - -El comando Punto de interrupción se usa para establecer puntos de interrupción, lo que le permite limitar los retrotracción. Puede alternar el punto de interrupción de la migración más reciente al no proporcionar ningún parámetro - -.. code-block:: bash - - $ phinx breakpoint -e development - -Para alternar un punto de interrupción en una versión específica, use el parámetro ``--target`` o ``-t`` para abreviar - -.. code-block:: bash - - $ phinx breakpoint -e development -t 20120103083322 - -Puede eliminar todos los puntos de interrupción utilizando el parámetro ``--remove-all`` o ``-r`` para abreviar. - -.. code-block:: bash - - $ phinx breakpoint -e development -r - -Los puntos de interrupción son visibles cuando ejecuta el comando de estado. - -"Database Seeding" ------------------- - -El comando Crear semilla se puede usar para crear nuevas clases de base de datos. Requiere un argumento, el nombre de la clase. El nombre de la clase debe especificarse en formato CamelCase. - -.. code-block:: bash - - $ phinx seed:create MyNewSeeder - -Abra el nuevo archivo semilla en su editor de texto para agregar los comandos semilla de su base de datos. Phinx crea archivos semilla utilizando la ruta especificada en su archivo phinx.yml. Consulte el capítulo: doc: `Configuration ` para obtener más información. - -El comando de ejecución de semillas ------------------------------------ - -El comando Seed Run ejecuta todas las clases semilla disponibles u opcionalmente solo una. - -.. code-block:: bash - - $ phinx seed:run -e development - -Para ejecutar solo una clase semilla, use el parámetro ``--seed`` o ``-s`` para abreviar. - -.. code-block:: bash - - $ phinx seed:run -e development -s MyNewSeeder - - -Parámetro del archivo de configuración --------------------------------------- - -Al ejecutar Phinx desde la línea de comandos, puede especificar un archivo de configuración usando el parámetro ``--configuration`` o ``-c``. Además de YAML, el archivo de configuración puede ser la salida calculada de un archivo PHP como una matriz de PHP:: - - [ - "migrations" => "application/migrations" - ], - "environments" => [ - "default_migration_table" => "phinxlog", - "default_environment" => "dev", - "dev" => [ - "adapter" => "mysql", - "host" => $_ENV['DB_HOST'], - "name" => $_ENV['DB_NAME'], - "user" => $_ENV['DB_USER'], - "pass" => $_ENV['DB_PASS'], - "port" => $_ENV['DB_PORT'], - ] - ] - ]; - -Phinx detecta automáticamente qué analizador de idioma usar para los archivos con las extensiones ``.yml`` y ``.php``. El analizador apropiado también se puede especificar a través de los parámetros ``--parser`` y ``-p``. Cualquier otra cosa que no sea "php" se trata como YAML. - -Al usar una matriz de PHP, puede proporcionar una clave de conexión con una instancia de PDO existente. También es importante pasar el nombre de la base de datos, ya que Phinx lo requiere para ciertos métodos como ``hasTable()``:: - - [ - "migrations" => "application/migrations" - ], - "environments" => [ - "default_migration_table" => "phinxlog", - "default_environment" => "dev", - "dev" => [ - "name" => "dev_db", - "connection" => $pdo_instance - ] - ] - ]; - -Ejecutando Phinx en una aplicación web --------------------------------------- - -Phinx también se puede ejecutar dentro de una aplicación web utilizando la clase ``Phinx\Wrapper\TextWrapper``. Un ejemplo de esto se proporciona en **app/web.php**, que se puede ejecutar como un servidor independiente: - -.. code-block:: bash - - $ php -S localhost:8000 vendor/robmorgan/phinx/app/web.php - -Esto creará un servidor web local en http://localhost:8000 que mostrará el estado actual de la migración de forma predeterminada. Para ejecutar las migraciones, use http://localhost:8000/migrate y para revertir use http: // localhost: 8000 / rollback. - -La aplicación web incluida es solo un ejemplo y no debe utilizarse en producción - - -.. note:: - Para modificar las variables de configuración en tiempo de ejecución - e invalidar ``%%PHINX_DBNAME%%`` u otra opción dinámica, establezca ``$ - _SERVER['PHINX_DBNAME']`` antes de ejecutar los comandos. Las opciones - disponibles están documentadas en la página de Configuración. - -Usando Phinx con PHPUnit ------------------------- - -Phinx puede usarse dentro de las pruebas de su unidad para preparar o sembrar la base de datos. Puedes usarlo programáticamente:: - - public function setUp () - { - $app = new PhinxApplication(); - $app->setAutoExit(false); - $app->run(new StringInput('migrate'), new NullOutput()); - } - -Si usa una base de datos de memoria, deberá darle a Phinx una instancia de PDO específica. Puedes interactuar con Phinx directamente usando la clase Manager:: - - use PDO; - use Phinx\Config\Config; - use Phinx\Migration\Manager; - use PHPUnit\Framework\TestCase; - use Symfony\Component\Console\Input\StringInput; - use Symfony\Component\Console\Output\NullOutput; - - class DatabaseTestCase extends TestCase { - - public function setUp () - { - $pdo = new PDO('sqlite::memory:', null, null, [ - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION - ]); - $configArray = require('phinx.php'); - $configArray['environments']['test'] = [ - 'adapter' => 'sqlite', - 'connection' => $pdo - ]; - $config = new Config($configArray); - $manager = new Manager($config, new StringInput(' '), new NullOutput()); - $manager->migrate('test'); - $manager->seed('test'); - // You can change default fetch mode after the seeding - $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); - $this->pdo = $pdo; - } - - } diff --git a/docs/es/conf.py b/docs/es/conf.py deleted file mode 100644 index 4691ece6a..000000000 --- a/docs/es/conf.py +++ /dev/null @@ -1,9 +0,0 @@ -import sys, os - -# Append the top level directory of the docs, so we can import from the config dir. -sys.path.insert(0, os.path.abspath('..')) - -# Pull in all the configuration options defined in the global config file.. -from config.all import * - -language = 'es' diff --git a/docs/es/contents.rst b/docs/es/contents.rst deleted file mode 100644 index 9bbcc9cbe..000000000 --- a/docs/es/contents.rst +++ /dev/null @@ -1,8 +0,0 @@ -Contents -######## - -.. toctree:: - :maxdepth: 2 - :caption: Phinx - - commands diff --git a/docs/fr/commands.rst b/docs/fr/commands.rst deleted file mode 100644 index c9c833460..000000000 --- a/docs/fr/commands.rst +++ /dev/null @@ -1,339 +0,0 @@ -.. index:: - single: Commands - -Commands -######## - -Phinx is run using a number of commands. - -Migration Commands -================== - -The Init Command - -The Init command (short for initialize) is used to prepare your project for -Phinx. This command generates the ``phinx.yml`` file in the root of your -project directory. - -.. code-block:: bash - - $ cd yourapp - $ phinx init . - -Open this file in your text editor to setup your project configuration. Please -see the :doc:`Configuration ` chapter for more information. - -The Create Command ------------------- - -The Create command is used to create a new migration file. It requires one -argument: the name of the migration. The migration name should be specified in -CamelCase format. - -.. code-block:: bash - - $ phinx create MyNewMigration - -Open the new migration file in your text editor to add your database -transformations. Phinx creates migration files using the path specified in your -``phinx.yml`` file. Please see the :doc:`Configuration ` chapter -for more information. - -You are able to override the template file used by Phinx by supplying an -alternative template filename. - -.. code-block:: bash - - $ phinx create MyNewMigration --template="" - -You can also supply a template generating class. This class must implement the -interface ``Phinx\Migration\CreationInterface``. - -.. code-block:: bash - - $ phinx create MyNewMigration --class="" - -In addition to providing the template for the migration, the class can also define -a callback that will be called once the migration file has been generated from the -template. - -You cannot use ``--template`` and ``--class`` together. - -The Migrate Command -------------------- - -The Migrate command runs all of the available migrations, optionally up to a -specific version. - -.. code-block:: bash - - $ phinx migrate -e development - -To migrate to a specific version then use the ``--target`` parameter or ``-t`` -for short. - -.. code-block:: bash - - $ phinx migrate -e development -t 20110103081132 - -Use ``--dry-run`` to print the queries to standard output without executing them - -.. code-block:: bash - - $ phinx migrate --dry-run - -The Rollback Command --------------------- - -The Rollback command is used to undo previous migrations executed by Phinx. It -is the opposite of the Migrate command. - -You can rollback to the previous migration by using the ``rollback`` command -with no arguments. - -.. code-block:: bash - - $ phinx rollback -e development - -To rollback all migrations to a specific version then use the ``--target`` -parameter or ``-t`` for short. - -.. code-block:: bash - - $ phinx rollback -e development -t 20120103083322 - -Specifying 0 as the target version will revert all migrations. - -.. code-block:: bash - - $ phinx rollback -e development -t 0 - -To rollback all migrations to a specific date then use the ``--date`` -parameter or ``-d`` for short. - -.. code-block:: bash - - $ phinx rollback -e development -d 2012 - $ phinx rollback -e development -d 201201 - $ phinx rollback -e development -d 20120103 - $ phinx rollback -e development -d 2012010312 - $ phinx rollback -e development -d 201201031205 - $ phinx rollback -e development -d 20120103120530 - -If a breakpoint is set, blocking further rollbacks, you can override the -breakpoint using the ``--force`` parameter or ``-f`` for short. - -.. code-block:: bash - - $ phinx rollback -e development -t 0 -f - -Use ``--dry-run`` to print the queries to standard output without executing them - -.. code-block:: bash - - $ phinx rollback --dry-run - -.. note:: - - When rolling back, Phinx orders the executed migrations using - the order specified in the ``version_order`` option of your - ``phinx.yml`` file. - Please see the :doc:`Configuration ` chapter for more information. - -The Status Command ------------------- - -The Status command prints a list of all migrations, along with their current -status. You can use this command to determine which migrations have been run. - -.. code-block:: bash - - $ phinx status -e development - -This command exits with code 0 if the database is up-to-date (ie. all migrations are up) or one of the following codes otherwise: - -* 1: There is at least one migration left to be executed. -* 2: There was a migration run and recorded in the database, but the migration file is now missing. - -The Breakpoint Command ----------------------- - -The Breakpoint command is used to set breakpoints, allowing you to limit -rollbacks. You can toggle the breakpoint of the most recent migration by -not supplying any parameters. - -.. code-block:: bash - - $ phinx breakpoint -e development - -To toggle a breakpoint on a specific version then use the ``--target`` -parameter or ``-t`` for short. - -.. code-block:: bash - - $ phinx breakpoint -e development -t 20120103083322 - -You can remove all the breakpoints by using the ``--remove-all`` parameter -or ``-r`` for short. - -.. code-block:: bash - - $ phinx breakpoint -e development -r - -Breakpoints are visible when you run the ``status`` command. - -Database Seeding -================ - -The Seed Create Command ------------------------ - -The Seed Create command can be used to create new database seed classes. It -requires one argument, the name of the class. The class name should be specified -in CamelCase format. - -.. code-block:: bash - - $ phinx seed:create MyNewSeeder - -Open the new seed file in your text editor to add your database seed commands. -Phinx creates seed files using the path specified in your ``phinx.yml`` file. -Please see the :doc:`Configuration ` chapter for more information. - -The Seed Run Command --------------------- - -The Seed Run command runs all of the available seed classes or optionally just -one. - -.. code-block:: bash - - $ phinx seed:run -e development - -To run only one seed class use the ``--seed`` parameter or ``-s`` for short. - -.. code-block:: bash - - $ phinx seed:run -e development -s MyNewSeeder - -Configuration File Parameter ----------------------------- - -When running Phinx from the command line, you may specify a configuration file -using the ``--configuration`` or ``-c`` parameter. In addition to YAML, the -configuration file may be the computed output of a PHP file as a PHP array: - -.. code-block:: php - - [ - "migrations" => "application/migrations" - ], - "environments" => [ - "default_migration_table" => "phinxlog", - "default_environment" => "dev", - "dev" => [ - "adapter" => "mysql", - "host" => $_ENV['DB_HOST'], - "name" => $_ENV['DB_NAME'], - "user" => $_ENV['DB_USER'], - "pass" => $_ENV['DB_PASS'], - "port" => $_ENV['DB_PORT'], - ] - ] - ]; - -Phinx auto-detects which language parser to use for files with ``*.yml`` and ``*.php`` extensions. The appropriate -parser may also be specified via the ``--parser`` and ``-p`` parameters. Anything other than ``"php"`` is treated as YAML. - -When using a PHP array, you can provide a ``connection`` key with an existing PDO instance. It is also important to pass -the database name too, as Phinx requires this for certain methods such as ``hasTable()``: - -.. code-block:: php - - [ - "migrations" => "application/migrations" - ], - "environments" => [ - "default_migration_table" => "phinxlog", - "default_environment" => "dev", - "dev" => [ - "name" => "dev_db", - "connection" => $pdo_instance - ] - ] - ]; - -Running Phinx in a Web App --------------------------- - -Phinx can also be run inside of a web application by using the ``Phinx\Wrapper\TextWrapper`` -class. An example of this is provided in ``app/web.php``, which can be run as a -standalone server: - -.. code-block:: bash - - $ php -S localhost:8000 vendor/robmorgan/phinx/app/web.php - -This will create local web server at ``__ which will show current -migration status by default. To run migrations up, use ``__ -and to rollback use ``__. - -**The included web app is only an example and should not be used in production!** - -.. note:: - - To modify configuration variables at runtime and override ``%%PHINX_DBNAME%%`` - or other another dynamic option, set ``$_SERVER['PHINX_DBNAME']`` before - running commands. Available options are documented in the Configuration page. - -Using Phinx with PHPUnit --------------------------- - -Phinx can be used within your unit tests to prepare or seed the database. You can use it programatically : - -.. code-block:: php - - public function setUp () - { - $app = new PhinxApplication(); - $app->setAutoExit(false); - $app->run(new StringInput('migrate'), new NullOutput()); - } - -If you use a memory database, you'll need to give Phinx a specific PDO instance. You can interact with Phinx directly using the Manager class : - -.. code-block:: php - - use PDO; - use Phinx\Config\Config; - use Phinx\Migration\Manager; - use PHPUnit\Framework\TestCase; - use Symfony\Component\Console\Input\StringInput; - use Symfony\Component\Console\Output\NullOutput; - - class DatabaseTestCase extends TestCase { - - public function setUp () - { - $pdo = new PDO('sqlite::memory:', null, null, [ - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION - ]); - $configArray = require('phinx.php'); - $configArray['environments']['test'] = [ - 'adapter' => 'sqlite', - 'connection' => $pdo - ]; - $config = new Config($configArray); - $manager = new Manager($config, new StringInput(' '), new NullOutput()); - $manager->migrate('test'); - $manager->seed('test'); - // You can change default fetch mode after the seeding - $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); - $this->pdo = $pdo; - } - - } diff --git a/docs/fr/conf.py b/docs/fr/conf.py deleted file mode 100644 index b02032efa..000000000 --- a/docs/fr/conf.py +++ /dev/null @@ -1,9 +0,0 @@ -import sys, os - -# Append the top level directory of the docs, so we can import from the config dir. -sys.path.insert(0, os.path.abspath('..')) - -# Pull in all the configuration options defined in the global config file.. -from config.all import * - -language = 'fr' diff --git a/docs/fr/configuration.rst b/docs/fr/configuration.rst deleted file mode 100644 index bf9142a2b..000000000 --- a/docs/fr/configuration.rst +++ /dev/null @@ -1,308 +0,0 @@ -.. index:: - single: Configuration - -Configuration -============= - -When you initialize your project using the :doc:`Init Command`, Phinx -creates a default file called ``phinx.yml`` in the root of your project directory. -This file uses the YAML data serialization format. - -If a ``--configuration`` command line option is given, Phinx will load the -specified file. Otherwise, it will attempt to find ``phinx.php``, ``phinx.json``, -``phinx.yml`` or ``phinx.yaml`` and load the first file found. See the -:doc:`Commands ` chapter for more information. - -.. warning:: - - Remember to store the configuration file outside of a publicly accessible - directory on your webserver. This file contains your database credentials - and may be accidentally served as plain text. - -Note that while JSON and YAML files are *parsed*, the PHP file is *included*. -This means that: - -* It must `return` an array of configuration items. -* The variable scope is local, i.e. you would need to explicitly declare - any global variables your initialization file reads or modifies. -* Its standard output is suppressed. -* Unlike with JSON and YAML, it is possible to omit environment connection details - and instead specify ``connection`` which must contain an initialized PDO instance. - This is useful when you want your migrations to interact with your application - and/or share the same connection. However remember to also pass the database name - as Phinx cannot infer this from the PDO connection. - -:: - - getDatabase()->getPdo(); - - return ['environments' => - [ - 'default_environment' => 'development', - 'development' => [ - 'name' => 'devdb', - 'connection' => $pdo, - ] - ] - ]; - -Migration Paths ---------------- - -The first option specifies the path to your migration directory. Phinx uses -``%%PHINX_CONFIG_DIR%%/db/migrations`` by default. - -.. note:: - - ``%%PHINX_CONFIG_DIR%%`` is a special token and is automatically replaced - with the root directory where your ``phinx.yml`` file is stored. - -In order to overwrite the default ``%%PHINX_CONFIG_DIR%%/db/migrations``, you -need to add the following to the yaml configuration. - -.. code-block:: yaml - - paths: - migrations: /your/full/path - -You can also provide multiple migration paths by using an array in your configuration: - -.. code-block:: yaml - - paths: - migrations: - - application/module1/migrations - - application/module2/migrations - -You can also use the ``%%PHINX_CONFIG_DIR%%`` token in your path. - -.. code-block:: yaml - - paths: - migrations: '%%PHINX_CONFIG_DIR%%/your/relative/path' - -Migrations are captured with ``glob``, so you can define a pattern for multiple -directories. - -.. code-block:: yaml - - paths: - migrations: '%%PHINX_CONFIG_DIR%%/module/*/{data,scripts}/migrations' - -Custom Migration Base ---------------------- - -By default all migrations will extend from Phinx's ``AbstractMigration`` class. -This can be set to a custom class that extends from ``AbstractMigration`` by -setting ``migration_base_class`` in your config: - -.. code-block:: yaml - - migration_base_class: MyMagicalMigration - -Seed Paths ----------- - -The second option specifies the path to your seed directory. Phinx uses -``%%PHINX_CONFIG_DIR%%/db/seeds`` by default. - -.. note:: - - ``%%PHINX_CONFIG_DIR%%`` is a special token and is automatically replaced - with the root directory where your ``phinx.yml`` file is stored. - -In order to overwrite the default ``%%PHINX_CONFIG_DIR%%/db/seeds``, you -need to add the following to the yaml configuration. - -.. code-block:: yaml - - paths: - seeds: /your/full/path - -You can also provide multiple seed paths by using an array in your configuration: - -.. code-block:: yaml - - paths: - seeds: - - /your/full/path1 - - /your/full/path2 - -You can also use the ``%%PHINX_CONFIG_DIR%%`` token in your path. - -.. code-block:: yaml - - paths: - seeds: '%%PHINX_CONFIG_DIR%%/your/relative/path' - -Environments ------------- - -One of the key features of Phinx is support for multiple database environments. -You can use Phinx to create migrations on your development environment, then -run the same migrations on your production environment. Environments are -specified under the ``environments`` nested collection. For example: - -.. code-block:: yaml - - environments: - default_migration_table: phinxlog - default_environment: development - production: - adapter: mysql - host: localhost - name: production_db - user: root - pass: '' - port: 3306 - charset: utf8 - collation: utf8_unicode_ci - -would define a new environment called ``production``. - -In a situation when multiple developers work on the same project and each has -a different environment (e.g. a convention such as ``--``), or when you need to have separate -environments for separate purposes (branches, testing, etc) use environment -variable `PHINX_ENVIRONMENT` to override the default environment in the yaml -file: - -.. code-block:: bash - - export PHINX_ENVIRONMENT=dev-`whoami`-`hostname` - -Table Prefix and Suffix ------------------------ - -You can define a table prefix and table suffix: - -.. code-block:: yaml - - environments: - development: - .... - table_prefix: dev_ - table_suffix: _v1 - testing: - .... - table_prefix: test_ - table_suffix: _v2 - -Socket Connections ------------------- - -When using the MySQL adapter, it is also possible to use sockets instead of -network connections. The socket path is configured with ``unix_socket``: - -.. code-block:: yaml - - environments: - default_migration_table: phinxlog - default_environment: development - production: - adapter: mysql - name: production_db - user: root - pass: '' - unix_socket: /var/run/mysql/mysql.sock - charset: utf8 - -External Variables ------------------- - -Phinx will automatically grab any environment variable prefixed with ``PHINX_`` -and make it available as a token in the config file. The token will have -exactly the same name as the variable but you must access it by wrapping two -``%%`` symbols on either side. e.g: ``%%PHINX_DBUSER%%``. This is especially -useful if you wish to store your secret database credentials directly on the -server and not in a version control system. This feature can be easily -demonstrated by the following example: - -.. code-block:: yaml - - environments: - default_migration_table: phinxlog - default_environment: development - production: - adapter: mysql - host: '%%PHINX_DBHOST%%' - name: '%%PHINX_DBNAME%%' - user: '%%PHINX_DBUSER%%' - pass: '%%PHINX_DBPASS%%' - port: 3306 - charset: utf8 - -Supported Adapters ------------------- - -Phinx currently supports the following database adapters natively: - -* `MySQL `_: specify the ``mysql`` adapter. -* `PostgreSQL `_: specify the ``pgsql`` adapter. -* `SQLite `_: specify the ``sqlite`` adapter. -* `SQL Server `_: specify the ``sqlsrv`` adapter. - -SQLite -~~~~~~ - -Declaring an SQLite database uses a simplified structure: - -.. code-block:: yaml - - environments: - development: - adapter: sqlite - name: ./data/derby - testing: - adapter: sqlite - memory: true # Setting memory to *any* value overrides name - -SQL Server -~~~~~~~~~~ - -When using the ``sqlsrv`` adapter and connecting to a named instance you should -omit the ``port`` setting as SQL Server will negotiate the port automatically. -Additionally, omit the ``charset: utf8`` or change to ``charset: 65001`` which -corresponds to UTF8 for SQL Server. - -Custom Adapters -~~~~~~~~~~~~~~~ - -You can provide a custom adapter by registering an implementation of the -``Phinx\\Db\\Adapter\\AdapterInterface`` with ``AdapterFactory``: - -.. code-block:: php - - $name = 'fizz'; - $class = 'Acme\Adapter\FizzAdapter'; - - AdapterFactory::instance()->registerAdapter($name, $class); - -Adapters can be registered any time before `$app->run()` is called, which normally -called by `bin/phinx`. - -Aliases -------- - -Template creation class names can be aliased and used with the ``--class`` command line option for the :doc:`Create Command `. - -The aliased classes will still be required to implement the ``Phinx\Migration\CreationInterface`` interface. - -.. code-block:: yaml - - aliases: - permission: \Namespace\Migrations\PermissionMigrationTemplateGenerator - view: \Namespace\Migrations\ViewMigrationTemplateGenerator - -Version Order -------------- - -When rolling back or printing the status of migrations, Phinx orders the executed migrations according to the -``version_order`` option, which can have the following values: - -* ``creation`` (the default): migrations are ordered by their creation time, which is also part of their filename. -* ``execution``: migrations are ordered by their execution time, also known as start time. diff --git a/docs/fr/contents.rst b/docs/fr/contents.rst deleted file mode 100644 index e5dae97bc..000000000 --- a/docs/fr/contents.rst +++ /dev/null @@ -1,11 +0,0 @@ -Contenus -======== - -.. toctree:: - :maxdepth: 2 - - index - migrations - seeding - commands - configuration diff --git a/docs/fr/index.rst b/docs/fr/index.rst deleted file mode 100644 index ac9d0a04d..000000000 --- a/docs/fr/index.rst +++ /dev/null @@ -1,57 +0,0 @@ -Phinx Migrations -################ - -Phinx est un utilitaire autonome en ligne de commande pour gérer les Migrations de bases de données. Le plugin officiel de Migrations de CakePHP est basé sur cet outil. - -Phinx rend ridiculement simple la gestion des migrations de bases de données pour vos applications PHP. En moins de 5 minutes, -vous pouvez installer Composer et créer votre première migration de base de données. Phinx ne s'occupe que de la migration des -bases de données, il laisse de côté les aspects ORM de la base de données et le cadre applicatif. - -Introduction -============ - -Les bons développeurs gèrent toujours leurs codes sources avec un outil de gestion de versions, -alors pourquoi ne feraient-ils pas la même chose avec leurs schémas de bases de données. - -Phinx permet aux développeurs de modifier et de manipuler leurs bases de données d'une façon claire et concise. Il évite -d'avoir à écrire du SQL à la main et offre à la place une API puissante pour écrire des scripts de migration en utilisant PHP. -Les développeurs peuvent alors versionner ces fichiers de migration en utilisant leur outil de versionnement préféré. Cela rend -les migrations Phinx indépendantes des moteurs de base de données. Phinx conserve la trace des migrations précédentes, cela -permet de se concentrer un peu plus sur l'amélioration de votre application et un peu moins sur l'état de votre base de -données. - -Objectifs -========= - -Phinx a été développé avec les objectifs suivants en tête : - -* Être portable entre les principaux moteurs de base de données. -* Être indépendant de tout framework PHP. -* Être aisement installable. -* Être utilisable facilement en ligne de commande. -* Être intégrable avec d'autres outils PHP (Phing, PHPUnit) et des frameworks web. - -Installation -============ - -Phinx devrait être installé en utilisant Composer, qui est un outil pour la gestion des dépendances en PHP. Visiter le site -internet de `Composer `_ pour avoir plus d’informations. - -.. note:: - - Phinx a besoin au minimum de PHP 5.4 (ou supérieur) - -Pour installer Phinx, il suffit simplement de l'appeler via Composer - -.. code-block:: bash - - php composer.phar require robmorgan/phinx - -Créez les dossiers ``db/migrations`` dans votre projet en vous assurant que les droits sont bien configurés. -C’est à cet endroit que vos fichiers de migrations devraient être créés et laissés. - -Phinx peut maintenant être exécuté depuis la racine de votre projet. - -.. code-block:: bash - - vendor/bin/phinx init diff --git a/docs/fr/migrations.rst b/docs/fr/migrations.rst deleted file mode 100644 index 46a9bf988..000000000 --- a/docs/fr/migrations.rst +++ /dev/null @@ -1,1305 +0,0 @@ -.. index:: - single: Writing Migrations - -Writing Migrations -================== - -Phinx relies on migrations in order to transform your database. Each migration -is represented by a PHP class in a unique file. It is preferred that you write -your migrations using the Phinx PHP API, but raw SQL is also supported. - -Creating a New Migration ------------------------- - -Generating a skeleton migration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Let's start by creating a new Phinx migration. Run Phinx using the ``create`` -command: - -.. code-block:: bash - - $ php vendor/bin/phinx create MyNewMigration - -This will create a new migration in the format -``YYYYMMDDHHMMSS_my_new_migration.php``, where the first 14 characters are -replaced with the current timestamp down to the second. - -If you have specified multiple migration paths, you will be asked to select -which path to create the new migration in. - -Phinx automatically creates a skeleton migration file with a single method:: - - table('user_logins'); - $table->addColumn('user_id', 'integer') - ->addColumn('created', 'datetime') - ->create(); - } - - /** - * Migrate Up. - */ - public function up() - { - - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -When executing this migration, Phinx will create the ``user_logins`` table on -the way up and automatically figure out how to drop the table on the way down. -Please be aware that when a ``change`` method exists, Phinx will automatically -ignore the ``up`` and ``down`` methods. If you need to use these methods it is -recommended to create a separate migration file. - -.. note:: - - When creating or updating tables inside a ``change()`` method you must use - the Table ``create()`` and ``update()`` methods. Phinx cannot automatically - determine whether a ``save()`` call is creating a new table or modifying an - existing one. - -Phinx can only reverse the following commands: - -- createTable -- renameTable -- addColumn -- renameColumn -- addIndex -- addForeignKey - -If a command cannot be reversed then Phinx will throw a -``IrreversibleMigrationException`` exception when it's migrating down. - -The Up Method -~~~~~~~~~~~~~ - -The up method is automatically run by Phinx when you are migrating up and it -detects the given migration hasn't been executed previously. You should use the -up method to transform the database with your intended changes. - -The Down Method -~~~~~~~~~~~~~~~ - -The down method is automatically run by Phinx when you are migrating down and -it detects the given migration has been executed in the past. You should use -the down method to reverse/undo the transformations described in the up method. - -Executing Queries ------------------ - -Queries can be executed with the ``execute()`` and ``query()`` methods. The -``execute()`` method returns the number of affected rows whereas the -``query()`` method returns the result as a -`PDOStatement `_:: - - execute('DELETE FROM users'); // returns the number of affected rows - - // query() - $stmt = $this->query('SELECT * FROM users'); // returns PDOStatement - $rows = $stmt->fetchAll(); // returns the result as an array - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -.. note:: - - These commands run using the PHP Data Objects (PDO) extension which - defines a lightweight, consistent interface for accessing databases - in PHP. Always make sure your queries abide with PDOs before using - the ``execute()`` command. This is especially important when using - DELIMITERs during insertion of stored procedures or triggers which - don't support DELIMITERs. - -.. warning:: - - When using ``execute()`` or ``query()`` with a batch of queries, PDO doesn't - throw an exception if there is an issue with one or more of the queries - in the batch. - - As such, the entire batch is assumed to have passed without issue. - - If Phinx was to iterate any potential result sets, looking to see if one - had an error, then Phinx would be denying access to all the results as there - is no facility in PDO to get a previous result set - `nextRowset() `_ - - but no ``previousSet()``). - - So, as a consequence, due to the design decision in PDO to not throw - an exception for batched queries, Phinx is unable to provide the fullest - support for error handling when batches of queries are supplied. - - Fortunately though, all the features of PDO are available, so multiple batches - can be controlled within the migration by calling upon - `nextRowset() `_ - and examining `errorInfo `_. - -Fetching Rows -------------- - -There are two methods available to fetch rows. The ``fetchRow()`` method will -fetch a single row, whilst the ``fetchAll()`` method will return multiple rows. -Both methods accept raw SQL as their only parameter:: - - fetchRow('SELECT * FROM users'); - - // fetch an array of messages - $rows = $this->fetchAll('SELECT * FROM messages'); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -Inserting Data --------------- - -Phinx makes it easy to insert data into your tables. Whilst this feature is -intended for the :doc:`seed feature `, you are also free to use the -insert methods in your migrations:: - - 1, - 'name' => 'In Progress' - ]; - - $table = $this->table('status'); - $table->insert($singleRow); - $table->saveData(); - - // inserting multiple rows - $rows = [ - [ - 'id' => 2, - 'name' => 'Stopped' - ], - [ - 'id' => 3, - 'name' => 'Queued' - ] - ]; - - // this is a handy shortcut - $this->insert('status', $rows); - } - - /** - * Migrate Down. - */ - public function down() - { - $this->execute('DELETE FROM status'); - } - } - -.. note:: - - You cannot use the insert methods inside a ``change()`` method. Please use the - ``up()`` and ``down()`` methods. - -Working With Tables -------------------- - -The Table Object -~~~~~~~~~~~~~~~~ - -The Table object is one of the most useful APIs provided by Phinx. It allows -you to easily manipulate database tables using PHP code. You can retrieve an -instance of the Table object by calling the ``table()`` method from within -your database migration:: - - table('tableName'); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -You can then manipulate this table using the methods provided by the Table -object. - -The Save Method -~~~~~~~~~~~~~~~ - -When working with the Table object, Phinx stores certain operations in a -pending changes cache. - -When in doubt, it is recommended you call this method. It will commit any -pending changes to the database. - -Creating a Table -~~~~~~~~~~~~~~~~ - -Creating a table is really easy using the Table object. Let's create a table to -store a collection of users:: - - table('users'); - $users->addColumn('username', 'string', ['limit' => 20]) - ->addColumn('password', 'string', ['limit' => 40]) - ->addColumn('password_salt', 'string', ['limit' => 40]) - ->addColumn('email', 'string', ['limit' => 100]) - ->addColumn('first_name', 'string', ['limit' => 30]) - ->addColumn('last_name', 'string', ['limit' => 30]) - ->addColumn('created', 'datetime') - ->addColumn('updated', 'datetime', ['null' => true]) - ->addIndex(['username', 'email'], ['unique' => true]) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -Columns are added using the ``addColumn()`` method. We create a unique index -for both the username and email columns using the ``addIndex()`` method. -Finally calling ``save()`` commits the changes to the database. - -.. note:: - - Phinx automatically creates an auto-incrementing primary key column called ``id`` for every - table. - -The ``id`` option sets the name of the automatically created identity field, while the ``primary_key`` -option selects the field or fields used for primary key. ``id`` will always override the ``primary_key`` -option unless it's set to false. If you don't need a primary key set ``id`` to false without -specifying a ``primary_key``, and no primary key will be created. - -To specify an alternate primary key, you can specify the ``primary_key`` option -when accessing the Table object. Let's disable the automatic ``id`` column and -create a primary key using two columns instead:: - - table('followers', ['id' => false, 'primary_key' => ['user_id', 'follower_id']]); - $table->addColumn('user_id', 'integer') - ->addColumn('follower_id', 'integer') - ->addColumn('created', 'datetime') - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -Setting a single ``primary_key`` doesn't enable the ``AUTO_INCREMENT`` option. -To simply change the name of the primary key, we need to override the default -``id`` field name:: - - table('followers', ['id' => 'user_id']); - $table->addColumn('follower_id', 'integer') - ->addColumn('created', 'timestamp', ['default' => 'CURRENT_TIMESTAMP']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -In addition, the MySQL adapter supports following options: - -========= =========== -Option Description -========= =========== -comment set a text comment on the table -engine define table engine *(defaults to `InnoDB`)* -collation define table collation *(defaults to `utf8_general_ci`)* -signed whether the primary key is ``signed`` -========= =========== - -By default the primary key is ``signed``. -To simply set it to unsigned just pass ``signed`` option with a ``false`` -value:: - - table('followers', ['signed' => false]); - $table->addColumn('follower_id', 'integer') - ->addColumn('created', 'timestamp', ['default' => 'CURRENT_TIMESTAMP']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -Valid Column Types -~~~~~~~~~~~~~~~~~~ - -Column types are specified as strings and can be one of: - -- biginteger -- binary -- boolean -- date -- datetime -- decimal -- float -- integer -- string -- text -- time -- timestamp -- uuid - -In addition, the MySQL adapter supports ``enum``, ``set``, ``blob`` and ``json`` -column types. (``json`` in MySQL 5.7 and above) - -In addition, the Postgres adapter supports ``smallint``, ``json``, ``jsonb``, -``uuid``, ``cidr``, ``inet`` and ``macaddr`` column types (PostgreSQL 9.3 and -above). - -For valid options, see the ref:`Valid Column Options`_ below. - -Determining Whether a Table Exists -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can determine whether or not a table exists by using the ``hasTable()`` -method:: - - hasTable('users'); - if ($exists) { - // do something - } - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -Dropping a Table -~~~~~~~~~~~~~~~~ - -Tables can be dropped quite easily using the ``dropTable()`` method. It is a -good idea to recreate the table again in the ``down()`` method:: - - dropTable('users'); - } - - /** - * Migrate Down. - */ - public function down() - { - $users = $this->table('users'); - $users->addColumn('username', 'string', ['limit' => 20]) - ->addColumn('password', 'string', ['limit' => 40]) - ->addColumn('password_salt', 'string', ['limit' => 40]) - ->addColumn('email', 'string', ['limit' => 100]) - ->addColumn('first_name', 'string', ['limit' => 30]) - ->addColumn('last_name', 'string', ['limit' => 30]) - ->addColumn('created', 'datetime') - ->addColumn('updated', 'datetime', ['null' => true]) - ->addIndex(['username', 'email'], ['unique' => true]) - ->save(); - } - } - -Renaming a Table -~~~~~~~~~~~~~~~~ - -To rename a table access an instance of the Table object then call the -``rename()`` method:: - - table('users'); - $table->rename('legacy_users'); - } - - /** - * Migrate Down. - */ - public function down() - { - $table = $this->table('legacy_users'); - $table->rename('users'); - } - } - -Working With Columns --------------------- - -.. _valid-column-types: - -Valid Column Types -~~~~~~~~~~~~~~~~~~ - -Column types are specified as strings and can be one of: - -- biginteger -- binary -- boolean -- char -- date -- datetime -- decimal -- float -- integer -- string -- text -- time -- timestamp -- uuid - -In addition, the MySQL adapter supports ``enum``, ``set`` and ``blob`` column types. - -In addition, the Postgres adapter supports ``smallint``, ``json``, ``jsonb``, ``uuid``, ``cidr``, ``inet`` and ``macaddr`` column types -(PostgreSQL 9.3 and above). - -Valid Column Options -~~~~~~~~~~~~~~~~~~~~ - -The following are valid column options: - -For any column type: - -======= =========== -Option Description -======= =========== -limit set maximum length for strings, also hints column types in adapters (see note below) -length alias for ``limit`` -default set default value or action -null allow ``NULL`` values (should not be used with primary keys!) -after specify the column that a new column should be placed after -comment set a text comment on the column -======= =========== - -For ``decimal`` columns: - -========= =========== -Option Description -========= =========== -precision combine with ``scale`` set to set decimal accuracy -scale combine with ``precision`` to set decimal accuracy -signed enable or disable the ``unsigned`` option *(only applies to MySQL)* -========= =========== - -For ``enum`` and ``set`` columns: - -========= =========== -Option Description -========= =========== -values Can be a comma separated list or an array of values -========= =========== - -For ``integer`` and ``biginteger`` columns: - -======== =========== -Option Description -======== =========== -identity enable or disable automatic incrementing -signed enable or disable the ``unsigned`` option *(only applies to MySQL)* -======== =========== - -For ``timestamp`` columns: - -======== =========== -Option Description -======== =========== -default set default value (use with ``CURRENT_TIMESTAMP``) -update set an action to be triggered when the row is updated (use with ``CURRENT_TIMESTAMP``) -timezone enable or disable the ``with time zone`` option for ``time`` and ``timestamp`` columns *(only applies to Postgres)* -======== =========== - -You can add ``created_at`` and ``updated_at`` timestamps to a table using the -``addTimestamps()`` method. This method also allows you to supply alternative -names:: - - table('users')->addTimestamps(null, 'amended_at')->create(); - } - } - -For ``boolean`` columns: - -======== =========== -Option Description -======== =========== -signed enable or disable the ``unsigned`` option *(only applies to MySQL)* -======== =========== - -For ``string`` and ``text`` columns: - -========= =========== -Option Description -========= =========== -collation set collation that differs from table defaults *(only applies to MySQL)* -encoding set character set that differs from table defaults *(only applies to MySQL)* -========= =========== - -For foreign key definitions: - -====== =========== -Option Description -====== =========== -update set an action to be triggered when the row is updated -delete set an action to be triggered when the row is deleted -====== =========== - -You can pass one or more of these options to any column with the optional -third argument array. - -Limit Option and PostgreSQL -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When using the PostgreSQL adapter, additional hinting of database column type can be -made for ``integer`` columns. Using ``limit`` with one the following options will -modify the column type accordingly: - -============ ============== -Limit Column Type -============ ============== -INT_SMALL SMALLINT -============ ============== - -.. code-block:: php - - use Phinx\Db\Adapter\PostgresAdapter; - - //... - - $table = $this->table('cart_items'); - $table->addColumn('user_id', 'integer') - ->addColumn('subtype_id', 'integer', ['limit' => PostgresAdapter::INT_SMALL]) - ->create(); - -Limit Option and MySQL -~~~~~~~~~~~~~~~~~~~~~~ - -When using the MySQL adapter, additional hinting of database column type can be -made for ``integer``, ``text`` and ``blob`` columns. Using ``limit`` with -one the following options will modify the column type accordingly: - -============ ============== -Limit Column Type -============ ============== -BLOB_TINY TINYBLOB -BLOB_REGULAR BLOB -BLOB_MEDIUM MEDIUMBLOB -BLOB_LONG LONGBLOB -TEXT_TINY TINYTEXT -TEXT_REGULAR TEXT -TEXT_MEDIUM MEDIUMTEXT -TEXT_LONG LONGTEXT -INT_TINY TINYINT -INT_SMALL SMALLINT -INT_MEDIUM MEDIUMINT -INT_REGULAR INT -INT_BIG BIGINT -============ ============== - -.. code-block:: php - - use Phinx\Db\Adapter\MysqlAdapter; - - //... - - $table = $this->table('cart_items'); - $table->addColumn('user_id', 'integer') - ->addColumn('product_id', 'integer', ['limit' => MysqlAdapter::INT_BIG]) - ->addColumn('subtype_id', 'integer', ['limit' => MysqlAdapter::INT_SMALL]) - ->addColumn('quantity', 'integer', ['limit' => MysqlAdapter::INT_TINY]) - ->create(); - -Get a column list -~~~~~~~~~~~~~~~~~ - -To retrieve all table columns, simply create a `table` object and call `getColumns()` -method. This method will return an array of Column classes with basic info. Example below:: - - table('users')->getColumns(); - ... - } - - /** - * Migrate Down. - */ - public function down() - { - ... - } - } - -Checking whether a column exists -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can check if a table already has a certain column by using the -``hasColumn()`` method:: - - table('user'); - $column = $table->hasColumn('username'); - - if ($column) { - // do something - } - - } - } - -Renaming a Column -~~~~~~~~~~~~~~~~~ - -To rename a column, access an instance of the Table object then call the -``renameColumn()`` method:: - - table('users'); - $table->renameColumn('bio', 'biography'); - } - - /** - * Migrate Down. - */ - public function down() - { - $table = $this->table('users'); - $table->renameColumn('biography', 'bio'); - } - } - -Adding a Column After Another Column -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When adding a column you can dictate its position using the ``after`` option:: - - table('users'); - $table->addColumn('city', 'string', ['after' => 'email']) - ->update(); - } - } - -Dropping a Column -~~~~~~~~~~~~~~~~~ - -To drop a column, use the ``removeColumn()`` method:: - - table('users'); - $table->removeColumn('short_name') - ->save(); - } - } - -Specifying a Column Limit -~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can limit the maximum length of a column by using the ``limit`` option:: - - table('tags'); - $table->addColumn('short_name', 'string', ['limit' => 30]) - ->update(); - } - } - -Changing Column Attributes -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To change column type or options on an existing column, use the -``changeColumn()`` method. See :ref:`valid-column-types` and `Valid Column -Options`_ for allowed values:: - - table('users'); - $users->changeColumn('email', 'string', ['limit' => 255]) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -Working With Indexes --------------------- - -To add an index to a table you can simply call the ``addIndex()`` method on the -table object:: - - table('users'); - $table->addColumn('city', 'string') - ->addIndex(['city']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -By default Phinx instructs the database adapter to create a normal index. We -can pass an additional parameter ``unique`` to the ``addIndex()`` method to -specify a unique index. We can also explicitly specify a name for the index -using the ``name`` parameter:: - - table('users'); - $table->addColumn('email', 'string') - ->addIndex(['email'], ['unique' => true, 'name' => 'idx_users_email']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -The MySQL adapter also supports ``fulltext`` indexes. If you are using a version -before 5.6 you must ensure the table uses the ``MyISAM`` engine:: - - table('users', ['engine' => 'MyISAM']); - $table->addColumn('email', 'string') - ->addIndex('email', ['type' => 'fulltext']) - ->create(); - } - } - -Removing indexes is as easy as calling the ``removeIndex()`` method. You must -call this method for each index:: - - table('users'); - $table->removeIndex(['email']); - - // alternatively, you can delete an index by its name, ie: - $table->removeIndexByName('idx_users_email'); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -.. note:: - - There is no need to call the ``save()`` method when using - ``removeIndex()``. The index will be removed immediately. - -Working With Foreign Keys -------------------------- - -Phinx has support for creating foreign key constraints on your database tables. -Let's add a foreign key to an example table:: - - table('tags'); - $table->addColumn('tag_name', 'string') - ->save(); - - $refTable = $this->table('tag_relationships'); - $refTable->addColumn('tag_id', 'integer') - ->addForeignKey('tag_id', 'tags', 'id', ['delete'=> 'SET_NULL', 'update'=> 'NO_ACTION']) - ->save(); - - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -"On delete" and "On update" actions are defined with a 'delete' and 'update' -options array. Possibles values are 'SET_NULL', 'NO_ACTION', 'CASCADE' and -'RESTRICT'. Constraint name can be changed with the 'constraint' option. - -It is also possible to pass ``addForeignKey()`` an array of columns. This -allows us to establish a foreign key relationship to a table which uses -a combined key:: - - table('follower_events'); - $table->addColumn('user_id', 'integer') - ->addColumn('follower_id', 'integer') - ->addColumn('event_id', 'integer') - ->addForeignKey(['user_id', 'follower_id'], - 'followers', - ['user_id', 'follower_id'], - ['delete'=> 'NO_ACTION', 'update'=> 'NO_ACTION', 'constraint' => 'user_follower_id']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -We can add named foreign keys using the ``constraint`` parameter. This feature -is supported as of Phinx version 0.6.5:: - - table('your_table'); - $table->addForeignKey('foreign_id', 'reference_table', ['id'], - ['constraint'=>'your_foreign_key_name']); - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -We can also easily check if a foreign key exists:: - - table('tag_relationships'); - $exists = $table->hasForeignKey('tag_id'); - if ($exists) { - // do something - } - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -Finally, to delete a foreign key, use the ``dropForeignKey`` method:: - - table('tag_relationships'); - $table->dropForeignKey('tag_id'); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } diff --git a/docs/fr/seeding.rst b/docs/fr/seeding.rst deleted file mode 100644 index 235228547..000000000 --- a/docs/fr/seeding.rst +++ /dev/null @@ -1,217 +0,0 @@ -.. index:: - single: Database Seeding - -Database Seeding -================ - -In version 0.5.0 Phinx introduced support for seeding your database with test -data. Seed classes are a great way to easily fill your database with data after -it's created. By default they are stored in the ``seeds`` directory; however, -this path can be changed in your configuration file. - -.. note:: - - Database seeding is entirely optional, and Phinx does not create a ``seeds`` - directory by default. - -Creating a New Seed Class -------------------------- - -Phinx includes a command to easily generate a new seed class: - -.. code-block:: bash - - $ php vendor/bin/phinx seed:create UserSeeder - -If you have specified multiple seed paths, you will be asked to select which -path to create the new seed class in. - -It is based on a skeleton template:: - - 'foo', - 'created' => date('Y-m-d H:i:s'), - ], - [ - 'body' => 'bar', - 'created' => date('Y-m-d H:i:s'), - ] - ]; - - $posts = $this->table('posts'); - $posts->insert($data) - ->save(); - } - } - -.. note:: - - You must call the ``save()`` method to commit your data to the table. Phinx - will buffer data until you do so. - -Integrating with the Faker library -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It's trivial to use the awesome -`Faker library `_ in your seed classes. -Simply install it using Composer: - -.. code-block:: bash - - $ composer require fzaninotto/faker - -Then use it in your seed classes:: - - $faker->userName, - 'password' => sha1($faker->password), - 'password_salt' => sha1('foo'), - 'email' => $faker->email, - 'first_name' => $faker->firstName, - 'last_name' => $faker->lastName, - 'created' => date('Y-m-d H:i:s'), - ]; - } - - $this->insert('users', $data); - } - } - -Truncating Tables ------------------ - -In addition to inserting data Phinx makes it trivial to empty your tables using -the SQL ``TRUNCATE`` command:: - - 'foo', - 'created' => date('Y-m-d H:i:s'), - ], - [ - 'body' => 'bar', - 'created' => date('Y-m-d H:i:s'), - ] - ]; - - $posts = $this->table('posts'); - $posts->insert($data) - ->save(); - - // empty the table - $posts->truncate(); - } - } - -.. note:: - - SQLite doesn't natively support the ``TRUNCATE`` command so behind the scenes - ``DELETE FROM`` is used. It is recommended to call the ``VACUUM`` command - after truncating a table. Phinx does not do this automatically. - -Executing Seed Classes ----------------------- - -This is the easy part. To seed your database, simply use the ``seed:run`` command: - -.. code-block:: bash - - $ php vendor/bin/phinx seed:run - -By default, Phinx will execute all available seed classes. If you would like to -run a specific class, simply pass in the name of it using the ``-s`` parameter: - -.. code-block:: bash - - $ php vendor/bin/phinx seed:run -s UserSeeder - -You can also run multiple seeders: - -.. code-block:: bash - - $ php vendor/bin/phinx seed:run -s UserSeeder -s PermissionSeeder -s LogSeeder - -You can also use the ``-v`` parameter for more output verbosity: - -.. code-block:: bash - - $ php vendor/bin/phinx seed:run -v - -The Phinx seed functionality provides a simple mechanism to easily and repeatably -insert test data into your database. diff --git a/docs/ja/commands.rst b/docs/ja/commands.rst deleted file mode 100644 index 51c7bf27d..000000000 --- a/docs/ja/commands.rst +++ /dev/null @@ -1,338 +0,0 @@ -.. index:: - single: Commands - -コマンド -######## - -Phinx は多くのコマンドを使用して実行されます。 - -マイグレーションコマンド -======================== - -init コマンド ----------------- - -init コマンド (initialize の略) は、Phinx のプロジェクトを準備するために使用されます。 -このコマンドはプロジェクトディレクトリーのルートに ``phinx.yml`` ファイルを生成します。 - -.. code-block:: bash - - $ cd yourapp - $ phinx init . - -このファイルをテキストエディターで開き、プロジェクトの設定を行います。 -詳しくは :doc:`設定 ` の章をご覧下さい。 - -create コマンド ---------------- - -create コマンドは、新しいマイグレーションファイルを作成するために使用されます。 -1つの引数、つまりマイグレーション名が必要です。 -マイグレーション名は、キャメルケース形式で指定する必要があります。 - -.. code-block:: bash - - $ phinx create MyNewMigration - -新しいマイグレーションファイルをテキストエディターで開き、データベースの変更を追加します。 -Phinx は ``phinx.yml`` ファイルで指定されたパスを使ってマイグレーションファイルを作成します。 -詳しくは :doc:`設定 ` の章をご覧下さい。 - -代替のテンプレートファイル名を指定することで、 -Phinx が使用するテンプレートファイルを上書きすることができます。 - -.. code-block:: bash - - $ phinx create MyNewMigration --template="" - -テンプレート生成クラスを提供することもできます。このクラスはインタフェース -``Phinx\Migration\CreationInterface`` を実装しなければなりません。 - -.. code-block:: bash - - $ phinx create MyNewMigration --class="" - -マイグレーションのテンプレートを提供するだけでなく、クラスはマイグレーションファイルが -テンプレートから生成されると呼び出されるコールバックを定義することもできます。 - -``--template`` と ``--class`` の両方を使用することはできません。 - -migrate コマンド ----------------- - -migrate コマンドは、すべての使用可能なマイグレーションを実行します。 -オプションで特定のバージョンまで実行できます。 - -.. code-block:: bash - - $ phinx migrate -e development - -特定のバージョンにマイグレーションするには、 ``--target`` パラメーターまたは省略して -``-t`` を使用します。 - -.. code-block:: bash - - $ phinx migrate -e development -t 20110103081132 - -``--dry-run`` を使って、クエリーを実行せずに標準出力に出力します。 - -.. code-block:: bash - - $ phinx migrate --dry-run - -rollback コマンド ------------------ - -rollback コマンドは、Phinx によって実行された以前のマイグレーションを取り消すために使用されます。 -これは、migrate コマンドの反対です。 - -引数を指定せずに ``rollback`` コマンドを使用すると、以前の移行にロールバックすることができます。 - -.. code-block:: bash - - $ phinx rollback -e development - -すべてのマイグレーションを特定のバージョンにロールバックするには、 ``--target`` パラメーターまたは -省略して ``-t`` を使用します。 - -.. code-block:: bash - - $ phinx rollback -e development -t 20120103083322 - -ターゲットバージョンとして 0 を指定すると、すべてのマイグレーションが元に戻ります。 - -.. code-block:: bash - - $ phinx rollback -e development -t 0 - -すべてのマイグレーションを特定の日付にロールバックするには、 ``--date`` パラメーターまたは省略して -``-d`` を省略して使用します。 - -.. code-block:: bash - - $ phinx rollback -e development -d 2012 - $ phinx rollback -e development -d 201201 - $ phinx rollback -e development -d 20120103 - $ phinx rollback -e development -d 2012010312 - $ phinx rollback -e development -d 201201031205 - $ phinx rollback -e development -d 20120103120530 - -ブレークポイントが設定され、さらにロールバックをブロックしている場合は、 ``--force`` パラメーターまたは -``-f`` を使ってブレークポイントをオーバーライドすることができます。 - -.. code-block:: bash - - $ phinx rollback -e development -t 0 -f - -``--dry-run`` を使って、クエリーを実行せずに標準出力に出力します。 - -.. code-block:: bash - - $ phinx rollback --dry-run - -.. note:: - - ロールバックすると、Phinx は ``phinx.yml`` ファイルの ``version_order`` オプションで - 指定された順序で実行されたマイグレーションを処理します。 - 詳しくは :doc:`設定 ` の章をご覧下さい。 - -status コマンド ---------------- - -status コマンドは、すべてのマイグレーションのリストを現在のステータスとともに表示します。 -このコマンドを使用して、実行されたマイグレーションを確認できます。 - -.. code-block:: bash - - $ phinx status -e development - -このコマンドは、データベースが最新の場合(つまり、すべてのマイグレーションが稼働している場合) -コード0で終了します。またはそれ以外の場合は、次のコードのいずれかで終了します。 - -* 1: 実行されるマイグレーションが少なくとも1つ残っています。 -* 2: マイグレーションが実行され、データベースに記録されましたが、マイグレーションファイルが有りません。 - -breakpoint コマンド -------------------- - -breakpoint コマンドは、ブレークポイントを設定するために使用され、ロールバックを制限することができます。 -最新のマイグレーションのブレークポイントは、パラメーターを指定しないで切り替えることができます。 - -.. code-block:: bash - - $ phinx breakpoint -e development - -特定のバージョンでブレークポイントを切り替えるには、 ``--target`` パラメーターまたは省略して -``-t`` を使用します。 - -.. code-block:: bash - - $ phinx breakpoint -e development -t 20120103083322 - -全てのブレークポイントを削除するには、 ``--remove-all`` パラメーターまたは省略して -``-r`` を使用します。 - -.. code-block:: bash - - $ phinx breakpoint -e development -r - -ブレークポイントは、 ``status`` コマンドを実行すると表示されます。 - -データベースの初期データ投入 -============================ - -seed:create コマンド --------------------- - -seed:create コマンドを使用して、新しいデータベースシードクラスを作成できます。 -1つの引数、クラスの名前が必要です。クラス名はキャメルケース形式で指定する必要があります。 - -.. code-block:: bash - - $ phinx seed:create MyNewSeeder - -テキストエディターで新しいシードファイルを開き、データベースシードコマンドを追加します。 -Phinx は ``phinx.yml`` ファイルで指定されたパスを使ってシードファイルを作成します。 -詳しくは :doc:`設定 ` の章をご覧下さい。 - -seed:run コマンド ------------------ - -seed:run コマンドは、使用可能なすべてのシードクラスを実行するか、オプションで1つだけを実行します。 - -.. code-block:: bash - - $ phinx seed:run -e development - -シードクラスを1つだけ実行するには、 ``--seed`` パラメーターまたは省略して ``-s`` を使用します。 - -.. code-block:: bash - - $ phinx seed:run -e development -s MyNewSeeder - -設定ファイルパラメーター ------------------------- - -コマンドラインから Phinx を実行するときは、 ``--configuration`` または -``-c`` パラメーターを使って設定ファイルを指定することができます。 -YAML に加えて、設定ファイルは PHP 配列として PHP ファイルの計算された出力でもよいです。 - -.. code-block:: php - - [ - "migrations" => "application/migrations" - ], - "environments" => [ - "default_migration_table" => "phinxlog", - "default_environment" => "dev", - "dev" => [ - "adapter" => "mysql", - "host" => $_ENV['DB_HOST'], - "name" => $_ENV['DB_NAME'], - "user" => $_ENV['DB_USER'], - "pass" => $_ENV['DB_PASS'], - "port" => $_ENV['DB_PORT'], - ] - ] - ]; - -Phinx は ``*.yml`` と ``*.php`` 拡張子を持つファイルにどの言語パーサーを使うかを自動的に検出します。 -適切なパーサーは、 ``--parser`` と ``-p`` パラメーターで指定することもできます。 -``"php"`` 以外は YAML として扱われます。 - -PHP 配列を使用する場合、既存の PDO インスタンスに ``connection`` キーを提供することができます。 -Phinx は ``hasTable()`` のような特定のメソッドに対してデータベース名を必要とするため、 -データベース名も渡すことも重要です。 - -.. code-block:: php - - [ - "migrations" => "application/migrations" - ], - "environments" => [ - "default_migration_table" => "phinxlog", - "default_environment" => "dev", - "dev" => [ - "name" => "dev_db", - "connection" => $pdo_instance - ] - ] - ]; - -ウェブアプリ内で Phinx を実行 ------------------------------ - -Phinx は ``Phinx\Wrapper\TextWrapper`` クラスを使ってウェブアプリケーションの内部で -実行することもできます。この例は ``app/web.php`` で提供されています。 -これはスタンドアロンサーバーとして実行できます。 - -.. code-block:: bash - - $ php -S localhost:8000 vendor/robmorgan/phinx/app/web.php - -これはデフォルトで現在のマイグレーションの状態を表示する ``__ -にローカルウェブサーバーを作成します。マイグレーションを実行するには、 -``__ を使用し、ロールバックには -``__ を使用します。 - -**付属のウェブアプリは一例に過ぎません、本番環境では使用しないでください!** - -.. note:: - - 実行時に設定変数を変更し、 ``%%PHINX_DBNAME%%`` やその他の動的オプションを変更するには、 - コマンドを実行する前に ``$_SERVER['PHINX_DBNAME']`` を設定します。 - 使用可能なオプションは、設定ページに記載されています。 - -PHPUnit で Phinx を使用 ------------------------ - -Phinx は、ユニットテスト内でデータベースを準備またはシードするために使用できます。 -プログラムによって使用することができます。 - -.. code-block:: php - - public function setUp () - { - $app = new PhinxApplication(); - $app->setAutoExit(false); - $app->run(new StringInput('migrate'), new NullOutput()); - } - -メモリーデータベースを使用する場合は、Phinx に特定の PDO インスタンスを提供する必要があります。 -Manager クラスを使用して Phinx と直接対話することができます。 - -.. code-block:: php - - use PDO; - use Phinx\Config\Config; - use Phinx\Migration\Manager; - use PHPUnit\Framework\TestCase; - use Symfony\Component\Console\Input\StringInput; - use Symfony\Component\Console\Output\NullOutput; - - class DatabaseTestCase extends TestCase { - - public function setUp () - { - $pdo = new PDO('sqlite::memory:', null, null, [ - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION - ]); - $configArray = require('phinx.php'); - $configArray['environments']['test'] = [ - 'adapter' => 'sqlite', - 'connection' => $pdo - ]; - $config = new Config($configArray); - $manager = new Manager($config, new StringInput(' '), new NullOutput()); - $manager->migrate('test'); - $manager->seed('test'); - // シード後にデフォルトのフェッチモードを変更することができます - $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); - $this->pdo = $pdo; - } - - } diff --git a/docs/ja/conf.py b/docs/ja/conf.py deleted file mode 100644 index 5871da648..000000000 --- a/docs/ja/conf.py +++ /dev/null @@ -1,9 +0,0 @@ -import sys, os - -# Append the top level directory of the docs, so we can import from the config dir. -sys.path.insert(0, os.path.abspath('..')) - -# Pull in all the configuration options defined in the global config file.. -from config.all import * - -language = 'ja' diff --git a/docs/ja/configuration.rst b/docs/ja/configuration.rst deleted file mode 100644 index 169c78ef0..000000000 --- a/docs/ja/configuration.rst +++ /dev/null @@ -1,305 +0,0 @@ -.. index:: - single: Configuration - -構成設定 -============= - -:doc:`init コマンド ` を使ってプロジェクトを初期化すると、 -Phinx はプロジェクトディレクトリーのルートに ``phinx.yml`` というデフォルトファイルを作成します。 -このファイルは、YAML データのシリアル化形式を使用します。 - -``--configuration`` コマンドラインオプションが与えられた場合、Phinx は指定されたファイルを -ロードします。それ以外の場合は、 ``phinx.php`` 、 ``phinx.json`` , ``phinx.yml``, -または ``phinx.yaml`` を見つけて、最初に見つかったファイルを読み込みます。詳しくは、 -:doc:`コマンド ` の章をご覧下さい。 - -.. warning:: - - 設定ファイルは、ウェブサーバー上の一般公開されているディレクトリーの外に保存してください。 - このファイルにはデータベースの信用情報が含まれており、 - 誤ってプレーンテキストとして提供される可能性があります。 - -JSON ファイルと YAML ファイルは *パース* されますが、PHP ファイルは *インクルード* されています。 -つまり、こういうことです。 - -* 設定項目の配列を `return` する必要があります。 -* 変数スコープはローカルです。つまり、初期化ファイルが読み取ったり変更したりするグローバル変数を - 明示的に宣言する必要があります。 -* その標準出力は抑制されます。 -* JSON や YAML とは異なり、環境接続の詳細を省略し、代わりに初期化された PDO インスタンスを含む - ``connection`` を指定することができます。 - これは、マイグレーションがアプリケーションとやり取りしたり、同じ接続を共有したりする場合に便利です。 - ただし、Phinx は PDO 接続からデータベース名を推測できないため、データベース名を渡すことを - 忘れないでください。 - -:: - - getDatabase()->getPdo(); - - return ['environments' => - [ - 'default_environment' => 'development', - 'development' => [ - 'name' => 'devdb', - 'connection' => $pdo, - ] - ] - ]; - -マイグレーションのパス ----------------------- - -最初のオプションは、マイグレーションのディレクトリーへのパスを指定します。 -デフォルトでは Phinx は ``%%PHINX_CONFIG_DIR%%/db/migrations`` を使用します。 - -.. note:: - - ``%%PHINX_CONFIG_DIR%%`` は特別なトークンで、 - ``phinx.yml`` ファイルが保存されているルートディレクトリーに自動的に置き換えられます。 - -デフォルトの ``%%PHINX_CONFIG_DIR%%/db/migrations`` を上書きするには、 -yaml 設定に次の行を追加する必要があります。 - -.. code-block:: yaml - - paths: - migrations: /your/full/path - -また、設定内の配列を使用して複数のマイグレーションパスを提供することもできます。 - -.. code-block:: yaml - - paths: - migrations: - - application/module1/migrations - - application/module2/migrations - -パスに ``%%PHINX_CONFIG_DIR%%`` トークンを使うこともできます。 - -.. code-block:: yaml - - paths: - migrations: '%%PHINX_CONFIG_DIR%%/your/relative/path' - -マイグレーションは ``glob`` で取り込まれるので、複数のディレクトリーのパターンを定義することができます。 - -.. code-block:: yaml - - paths: - migrations: '%%PHINX_CONFIG_DIR%%/module/*/{data,scripts}/migrations' - -カスタムベースクラス ---------------------- - -デフォルトでは、すべてのマイグレーションは Phinx の ``AbstractMigration`` クラスを継承します。 -これは、設定の中で ``migration_base_class`` を設定することによって、 ``AbstractMigration`` -を継承したカスタムクラスに設定することができます。 - -.. code-block:: yaml - - migration_base_class: MyMagicalMigration - -シードのパス ------------- - -2番目のオプションは、シードディレクトリーへのパスを指定します。 -デフォルトでは Phinx は ``%%PHINX_CONFIG_DIR%%/db/seeds`` を使用します。 - -.. note:: - - ``%%PHINX_CONFIG_DIR%%`` は特別なトークンで、 - ``phinx.yml`` ファイルが保存されているルートディレクトリーに自動的に置き換えられます。 - -デフォルトの ``%%PHINX_CONFIG_DIR%%/db/seeds`` を上書きするには、 -yaml 設定に以下を追加する必要があります。 - -.. code-block:: yaml - - paths: - seeds: /your/full/path - -また、設定内で配列を使用して複数のシードパスを指定することもできます。 - -.. code-block:: yaml - - paths: - seeds: - - /your/full/path1 - - /your/full/path2 - -パスに ``%%PHINX_CONFIG_DIR%%`` トークンを使うこともできます。 - -.. code-block:: yaml - - paths: - seeds: '%%PHINX_CONFIG_DIR%%/your/relative/path' - -環境 ----- - -Phinx の主な機能の1つは、複数のデータベース環境をサポートすることです。Phinx を使用して、 -開発環境でマイグレーションを作成した後、本番環境で同じマイグレーションを実行することができます。 -環境は ``environments`` 以下にネストされたコレクションで指定されます。例: - -.. code-block:: yaml - - environments: - default_migration_table: phinxlog - default_environment: development - production: - adapter: mysql - host: localhost - name: production_db - user: root - pass: '' - port: 3306 - charset: utf8 - collation: utf8_unicode_ci - -上記は ``production`` と呼ばれる新しい環境を定義します。 - -複数の開発者が同じプロジェクトで作業し、それぞれが異なる環境を持つ状況 -(例えば、 ``--`` のような規約)、 -または、別々の目的(ブランチ、テストなど)のために別々の環境を持つ必要がある場合には、 -環境変数 `PHINX_ENVIRONMENT` を使用して yaml ファイルのデフォルト環境を上書きします。 - -.. code-block:: bash - - export PHINX_ENVIRONMENT=dev-`whoami`-`hostname` - -テーブルのプレフィクスとサフィックス ------------------------------------- - -テーブルのプレフィックスとサフィックスを定義することができます。 - -.. code-block:: yaml - - environments: - development: - .... - table_prefix: dev_ - table_suffix: _v1 - testing: - .... - table_prefix: test_ - table_suffix: _v2 - -ソケット接続 ------------- - -MySQL アダプターを使用する場合、ネットワーク接続の代わりにソケットを使用することもできます。 -ソケットのパスは ``unix_socket`` で設定されます。 - -.. code-block:: yaml - - environments: - default_migration_table: phinxlog - default_environment: development - production: - adapter: mysql - name: production_db - user: root - pass: '' - unix_socket: /var/run/mysql/mysql.sock - charset: utf8 - -外部変数 --------- - -Phinx は ``PHINX_`` というプレフィックスが付いた環境変数を自動的に取得し、 -設定ファイルのトークンとして利用できるようにします。 -トークンは変数とまったく同じ名前になりますが、どちらの側にも2つの -``%%`` のシンボルをラップすることによってアクセスする必要があります。 -例: ``%%PHINX_DBUSER%%`` 。これは、秘密のデータベース資格情報をバージョン管理システムではなく -サーバーに直接格納する場合に特に便利です。この機能は、次の例で簡単に実証できます。 - -.. code-block:: yaml - - environments: - default_migration_table: phinxlog - default_environment: development - production: - adapter: mysql - host: '%%PHINX_DBHOST%%' - name: '%%PHINX_DBNAME%%' - user: '%%PHINX_DBUSER%%' - pass: '%%PHINX_DBPASS%%' - port: 3306 - charset: utf8 - -サポートするアダプター ----------------------- - -Phinx は現在、次のデータベースアダプターをネイティブにサポートしています。 - -* `MySQL `_: ``mysql`` アダプターを指定。 -* `PostgreSQL `_: ``pgsql`` アダプターを指定。 -* `SQLite `_: ``sqlite`` アダプターを指定。 -* `SQL Server `_: ``sqlsrv`` アダプターを指定。 - -SQLite -~~~~~~ - -SQLite データベースを宣言すると、単純化された構造が使用されます。 - -.. code-block:: yaml - - environments: - development: - adapter: sqlite - name: ./data/derby - testing: - adapter: sqlite - memory: true # *任意* の値で memory を設定すると、 name が上書きされます - -SQL Server -~~~~~~~~~~ - -``sqlsrv`` アダプターを使用して名前付きインスタンスに接続するときは、 -SQL Server が自動的にポートをネゴシエートするので、 ``port`` 設定を省略してください。 -さらに、 ``charset: utf8`` を省略するか、SQL Server の UTF8 に対応する -``charset: 65001`` に変更してください。 - -カスタムアダプター -~~~~~~~~~~~~~~~~~~ - -``Phinx\\Db\\Adapter\\AdapterInterface`` の実装を ``AdapterFactory`` で登録することで -カスタムアダプターを提供できます。 - -.. code-block:: php - - $name = 'fizz'; - $class = 'Acme\Adapter\FizzAdapter'; - - AdapterFactory::instance()->registerAdapter($name, $class); - -アダプターは `$app->run()` が呼び出される前にいつでも登録することができます。 -通常は `bin/phinx` によって呼び出されます。 - -エイリアス ----------- - -テンプレート作成クラス名は、別名をつけて :doc:`create コマンド` の -``--class`` コマンドラインオプションで使うことができます。 - -エイリアス化されたクラスは ``Phinx\Migration\CreationInterface`` インタフェースを実装する -必要があります。 - -.. code-block:: yaml - - aliases: - permission: \Namespace\Migrations\PermissionMigrationTemplateGenerator - view: \Namespace\Migrations\ViewMigrationTemplateGenerator - -バージョンの順序 ----------------- - -マイグレーションの状態をロールバックまたは表示するとき、Phinx は ``version_order`` -オプションに従って実行されたマイグレーションを処理します。これは次の値をとります。 - -* ``creation`` (デフォルト): マイグレーションはファイル名の一部でもある作成時間順に並べ替えられます。 -* ``execution``: マイグレーションは実行時間(開始時間とも呼ばれます)によって順序付けられます。 diff --git a/docs/ja/contents.rst b/docs/ja/contents.rst deleted file mode 100644 index abb198fd1..000000000 --- a/docs/ja/contents.rst +++ /dev/null @@ -1,12 +0,0 @@ -コンテンツ -=========== - -.. toctree:: - :maxdepth: 2 - :caption: Phinx - - index - migrations - seeding - commands - configuration diff --git a/docs/ja/index.rst b/docs/ja/index.rst deleted file mode 100644 index 65bd83c68..000000000 --- a/docs/ja/index.rst +++ /dev/null @@ -1,60 +0,0 @@ -Phinx マイグレーション -###################### - -Phinx は、データベースのマイグレーションを管理するためのスタンドアロンのコマンドラインツールです。 -CakePHP の公式 Migrations プラグインはこのツールに基づいています。 - -Phinx は、あなたの PHP アプリケーションのデータベースマイグレーションを超簡単に管理できます。 -5分以内に、Composer を使用して Phinx をインストールし、最初のデータベースマイグレーションを作成できます。 -Phinx は、データベース ORM システムやアプリケーションフレームワークを使わずに、マイグレーションします。 - -はじめに -============ - -良い開発者は常に SCM システムを使ってコードをバージョン管理します。それでは、なぜ、 -データベーススキーマについても同じことをしないのでしょうか? - -Phinx は、開発者がデータベースを明確かつ簡潔な方法で変更および操作できるようにします。 -これは手作業で SQL を書くことを避け、代わりに PHP コードを使用してマイグレーションを作成するための -強力な API を提供します。開発者は、好みの SCM システムを使用して、これらのマイグレーションを -バージョン管理することができます。これにより、異なるデータベースシステム間で Phinx のマイグレーションを -移植可能にします。Phinx はどのマイグレーションが実行されたかを把握しているので、 -データベースの状態については心配する必要はなく、より良いソフトウェアを構築することに -集中することができます。 - -ゴール -======= - -Phinx は以下の目標を念頭に置いて開発されました。 - -* 最も普及しているデータベースベンダー間の可搬性。 -* PHP フレームワークに依存しない。 -* シンプルなインストール手順。 -* 使いやすいコマンドライン操作。 -* 他のさまざまな PHP ツール(Phing、PHPUnit)やウェブフレームワークとの統合。 - -インストール -============= - -Phinx は、PHP の依存関係管理のためのツールである Composer を使用してインストールする必要があります。 -詳しくは `Composer `_ のウェブサイトを見てください。 - -.. note:: - - Phinx には少なくともPHP 5.4(またはそれ以降)が必要です。 - -Phinx をインストールするには、Composer を使用する必要があります。 - -.. code-block:: bash - - php composer.phar require robmorgan/phinx - -適切なパーミッションを持つ ``db/migrations`` 構造に従って、プロジェクト内にフォルダーを作成します。 -これは、マイグレーションファイルが存在し、書き込み可能である場所です。 - -今、プロジェクト内から Phinx を実行できるようになりました。 - -.. code-block:: bash - - vendor/bin/phinx init - diff --git a/docs/ja/migrations.rst b/docs/ja/migrations.rst deleted file mode 100644 index 3d9b83f75..000000000 --- a/docs/ja/migrations.rst +++ /dev/null @@ -1,1293 +0,0 @@ -.. index:: - single: Writing Migrations - -マイグレーションを書く -====================== - -Phinx は、データベースを変換するためにマイグレーションに依存しています。 -各マイグレーションは、一意のファイル内の PHP クラスによって表されます。 -Phinx の PHP API を使用してマイグレーションを記述することをお勧めしますが、 -生の SQL もサポートされています。 - -新しいマイグレーションの作成 ----------------------------- - -マイグレーションファイルのスケルトンを生成 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -新しい Phinx マイグレーションを作成することから始めましょう。 -``create`` コマンドを使って Phinx を実行してください。 - -.. code-block:: bash - - $ php vendor/bin/phinx create MyNewMigration - -これにより、 ``YYYYMMDDHHMMSS_my_new_migration.php`` という形式で -新しいマイグレーションが作成されます。最初の14文字は現在のタイムスタンプで置き換えられます。 - -複数のマイグレーションのパスを指定した場合は、新しいマイグレーションを作成するパスを -選択するよう求められます。 - -Phinx は、単一の方法でスケルトンのマイグレーションファイルを自動的に作成します。 :: - - table('user_logins'); - $table->addColumn('user_id', 'integer') - ->addColumn('created', 'datetime') - ->create(); - } - - /** - * Migrate Up. - */ - public function up() - { - - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -このマイグレーションを実行すると、Phinx は up すると ``user_logins`` テーブルを作成し、 -down するとテーブルを削除する方法を自動的に見つけ出します。 ``change`` メソッドが存在する場合、 -Phinx は自動的に ``up`` メソッドと ``down`` メソッドを無視することに注意してください。 -これらのメソッドを使う必要がある場合、別のマイグレーションファイルを作成することをお勧めします。 - -.. note:: - - ``change()`` メソッドの中でテーブルを作成または更新する場合は、Table の ``create()`` - と ``update()`` メソッドを使用する必要があります。Phinx は、 ``save()`` の呼び出しが - 新しいテーブルを作成しているのか、既存のテーブルを変更しているのかを自動的に判断することはできません。 - -Phinx は、次のコマンドでのみ、逆にすることができます。 - -- createTable -- renameTable -- addColumn -- renameColumn -- addIndex -- addForeignKey - -コマンドを元に戻せない場合、Phinx はマイグレーション中に ``IrreversibleMigrationException`` -例外をスローします。 - -up メソッド -~~~~~~~~~~~ - -up メソッドは、マイグレーション中に Phinx によって自動的に実行され、 -指定されたマイグレーションが以前に実行されていないことを検出します。 -データベースを目的の変更に変換するには、up メソッドを使用する必要があります。 - -down メソッド -~~~~~~~~~~~~~ - -down メソッドは、マイグレーション中に Phinx によって自動的に実行され、 -指定されたマイグレーションが過去に実行されたことを検出します。 -up メソッドで記述された変換を元に戻すには、down メソッドを使用する必要があります。 - -クエリーの実行 --------------- - -クエリーは、 ``execute()`` と ``query()`` メソッドで実行できます。 -``execute()`` メソッドは影響を受ける行の数を返しますが、 ``query()`` メソッドは結果を -`PDOStatement `_ -として返します。 :: - - execute('DELETE FROM users'); // 影響を受ける行の数を返します - - // query() - $stmt = $this->query('SELECT * FROM users'); // PDOStatement を返します - $rows = $stmt->fetchAll(); // 配列として結果を返します - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -.. note:: - - これらのコマンドは、PHP のデータベースにアクセスするための軽量で一貫した - インターフェースを定義する PHP Data Objects(PDO)拡張を使用して実行されます。 - ``execute()`` コマンドを使う前に、必ずクエリーが PDO に従っていることを確認してください。 - これは、DELIMITER をサポートしていないストアードプロシージャーまたはトリガーの挿入時に - DELIMITER を使用する場合に特に重要です。 - -.. warning:: - - クエリーのバッチで ``execute()`` や ``query()`` を使用すると、 - PDO はバッチに1つ以上のクエリーに問題があったとしても、例外をスローしません。 - - したがって、バッチ全体が問題なく通過したものとみなされます。 - - Phinx が潜在的な結果セットを反復して、1つのエラーがあることを発見した場合、 - 以前の結果セットを得る機能が PDO にはないため、Phinx はすべての結果へのアクセスを拒否します。 - (``previousSet()`` ではなく - `nextRowset() `_) 。 - - その結果、バッチ処理されたクエリーの例外を投げないようにする PDO の設計上の決定により、 - Phinx はクエリーのバッチが提供されたときにエラー処理を最大限にサポートすることができません。 - - 幸いにも、PDO のすべての機能が利用可能であるため、 - `nextRowset() `_ - を呼び出して `errorInfo `_ - を調べることで、複数のバッチをマイグレーション中に制御することができます。 - -行の取得 --------- - -行を取得するには2つのメソッドがあります。 ``fetchRow()`` メソッドは単一の行を取得し、 -``fetchAll()`` メソッドは複数の行を返します。どちらのメソッドも、唯一のパラメーターとして -生の SQL を受け取ります。 :: - - fetchRow('SELECT * FROM users'); - - // メッセージの配列を取得 - $rows = $this->fetchAll('SELECT * FROM messages'); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -データの挿入 ------------- - -Phinx ではテーブルにデータを簡単に挿入できます。この機能は :doc:`シード機能 ` -を対象としていますが、マイグレーションでも insert メソッドを自由に使うこともできます。 :: - - 1, - 'name' => 'In Progress' - ]; - - $table = $this->table('status'); - $table->insert($singleRow); - $table->saveData(); - - // 複数行の追加 - $rows = [ - [ - 'id' => 2, - 'name' => 'Stopped' - ], - [ - 'id' => 3, - 'name' => 'Queued' - ] - ]; - - // これは便利なショートカットです - $this->insert('status', $rows); - } - - /** - * Migrate Down. - */ - public function down() - { - $this->execute('DELETE FROM status'); - } - } - -.. note:: - - insert メソッドは、 ``change()`` メソッドの中で使うことはできません。 - ``up()`` と ``down()`` メソッドを使用してください。 - -テーブルの操作 -------------------- - -Table オブジェクト -~~~~~~~~~~~~~~~~~~ - -Table オブジェクトは、 Phinx が提供する最も便利な API の一つです。 -これにより、PHP コードを使用して簡単にデータベーステーブルを操作できます。 -データベースのマイグレーションの中から ``table()`` メソッドを呼び出すことによって、 -Table オブジェクトのインスタンスを取得することができます。 :: - - table('tableName'); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -次に、Table オブジェクトによって提供されるメソッドを使用して、このテーブルを操作できます。 - -save メソッド -~~~~~~~~~~~~~ - -Table オブジェクトを操作する場合、Phinx は特定の操作を保留中の変更キャッシュに保存します。 - -疑わしいときは、このメソッドを呼び出すことをお勧めします。 -これは、データベースに対する保留中の変更をコミットします。 - -テーブルの作成 -~~~~~~~~~~~~~~ - -テーブルの作成は、Table オブジェクトを使用するととても簡単です。 -ユーザーのコレクションを格納するテーブルを作成しましょう。 :: - - table('users'); - $users->addColumn('username', 'string', ['limit' => 20]) - ->addColumn('password', 'string', ['limit' => 40]) - ->addColumn('password_salt', 'string', ['limit' => 40]) - ->addColumn('email', 'string', ['limit' => 100]) - ->addColumn('first_name', 'string', ['limit' => 30]) - ->addColumn('last_name', 'string', ['limit' => 30]) - ->addColumn('created', 'datetime') - ->addColumn('updated', 'datetime', ['null' => true]) - ->addIndex(['username', 'email'], ['unique' => true]) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -カラムは ``addColumn()`` メソッドを使って追加されます。 ``addIndex()`` メソッドを使用して、 -username と email カラムの両方に一意なインデックスを作成します。 -最後に ``save()`` を呼び出すと、データベースへの変更がコミットされます。 - -.. note:: - - Phinx は、すべてのテーブルに対して ``id`` という名前のオートインクリメントの主キーを - 自動的に作成します。 - -``id`` オプションは自動的に作成された識別フィールドの名前を設定し、 -``primary_key`` オプションは主キーに使われるフィールドを選択します。 -``id`` は、 false に設定されていない限り、 ``primary_key`` オプションを上書きします。 -主キーが必要ない場合は、 ``primary_key`` を指定せずに ``id`` を false に設定してください。 -主キーは作成されません。 - -別の主キーを指定するには、Table オブジェクトにアクセスする際に ``primary_key`` -オプションを指定します。自動的な ``id`` カラムを無効にし、 -代わりに2つのカラムを使って主キーを作成しましょう。 :: - - table('followers', ['id' => false, 'primary_key' => ['user_id', 'follower_id']]); - $table->addColumn('user_id', 'integer') - ->addColumn('follower_id', 'integer') - ->addColumn('created', 'datetime') - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -1つの ``primary_key`` を設定しても、 ``AUTO_INCREMENT`` オプションは有効になりません。 -単純に主キーの名前を変更するには、デフォルトの ``id`` フィールド名を上書きする必要があります。 :: - - table('followers', ['id' => 'user_id']); - $table->addColumn('follower_id', 'integer') - ->addColumn('created', 'timestamp', ['default' => 'CURRENT_TIMESTAMP']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -さらに、MySQL アダプターは次のオプションをサポートしています。 - -========== =========== -オプション 説明 -========== =========== -comment テーブルにテキストコメントを設定 -engine テーブルエンジンの定義 *(デフォルトは `InnoDB`)* -collation テーブル照合順序の定義 *(デフォルトは `utf8_general_ci`)* -signed 主キーが ``符号付き`` かどうか -========== =========== - -デフォルトでは、主キーは ``符号付き`` です。 -単純に unsigned に設定するには ``signed`` オプションに ``false`` の値を渡します。 :: - - table('followers', ['signed' => false]); - $table->addColumn('follower_id', 'integer') - ->addColumn('created', 'timestamp', ['default' => 'CURRENT_TIMESTAMP']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -有効なカラムの型 -~~~~~~~~~~~~~~~~~~ - -カラム型は文字列として指定され、次のいずれかになります。 - -- biginteger -- binary -- boolean -- date -- datetime -- decimal -- float -- integer -- string -- text -- time -- timestamp -- uuid - -さらに、MySQL アダプターは、 ``enum`` 、 ``set`` 、 ``blob`` 、 ``json`` -カラム型をサポートしています。 (``json`` は MySQL 5.7 以降) - -さらに、Postgres アダプターは、 ``smallint`` 、 ``json`` 、 ``jsonb`` 、 ``uuid`` 、 -``cidr`` 、 ``inet`` 、 ``macaddr`` カラム型をサポートしています。(PostgreSQL 9.3 以降) - -有効なオプションについては、以下の `有効なカラムのオプション`_ を参照してください。 - -テーブルが存在するかどうかの判断 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``hasTable()`` メソッドを使うことによって、テーブルが存在するかどうかを判断することができます。 :: - - hasTable('users'); - if ($exists) { - // 何かします - } - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -テーブルの削除 -~~~~~~~~~~~~~~~~ - -Table は ``dropTable()`` メソッドを使って非常に簡単に削除することができます。 -テーブルを ``down()`` メソッドで再作成することは良い考えです。 :: - - dropTable('users'); - } - - /** - * Migrate Down. - */ - public function down() - { - $users = $this->table('users'); - $users->addColumn('username', 'string', ['limit' => 20]) - ->addColumn('password', 'string', ['limit' => 40]) - ->addColumn('password_salt', 'string', ['limit' => 40]) - ->addColumn('email', 'string', ['limit' => 100]) - ->addColumn('first_name', 'string', ['limit' => 30]) - ->addColumn('last_name', 'string', ['limit' => 30]) - ->addColumn('created', 'datetime') - ->addColumn('updated', 'datetime', ['null' => true]) - ->addIndex(['username', 'email'], ['unique' => true]) - ->save(); - } - } - -テーブル名の変更 -~~~~~~~~~~~~~~~~ - -テーブルの名前を変更するには、Table オブジェクトのインスタンスにアクセスし、 -``rename()`` メソッドを呼び出します。 :: - - table('users'); - $table->rename('legacy_users') - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - $table = $this->table('legacy_users'); - $table->rename('users') - ->save(); - } - } - -カラムの操作 --------------------- - -.. _valid-column-types: - -有効なカラムの型 -~~~~~~~~~~~~~~~~~~ - -カラムの型は文字列として指定され、次のいずれかになります。 - -- biginteger -- binary -- boolean -- char -- date -- datetime -- decimal -- float -- integer -- string -- text -- time -- timestamp -- uuid - -さらに、MySQL アダプターは、 ``enum`` 、 ``set`` 、 ``blob`` 、 ``json`` -カラム型をサポートしています。 (``json`` は MySQL 5.7 以降) - -さらに、Postgres アダプターは、 ``smallint`` 、 ``json`` 、 ``jsonb`` 、 ``uuid`` 、 -``cidr`` 、 ``inet`` 、 ``macaddr`` カラム型をサポートしています。(PostgreSQL 9.3 以降) - - -有効なカラムのオプション -~~~~~~~~~~~~~~~~~~~~~~~~ - -有効なカラムのオプションは次のとおりです。 - -全てのカラム型: - -========== =========== -オプション 説明 -========== =========== -limit 文字列の最大長を設定します。また、アダプターのカラムの種類を示します(下記の注を参照) -length ``limit`` の別名 -default デフォルトの値やアクションを設定 -null ``NULL`` 値の許可 (主キーで使用してはいけません!) -after 新しいカラムの前に配置するカラムを指定 -comment カラムのテキストコメントを設定 -========== =========== - -``decimal`` カラム: - -========== =========== -オプション 説明 -========== =========== -precision ``scale`` と組み合わせ、数値全体の桁数を設定 -scale ``precision`` と組み合わせ、少数点以下の桁数を設定 -signed ``unsigned`` オプションを有効または無効にする *(MySQL のみ適用)* -========== =========== - -``enum`` と ``set`` カラム: - -========== =========== -オプション 説明 -========== =========== -values カンマ区切りリストまたは値の配列 -========== =========== - -``integer`` と ``biginteger`` カラム: - -========== =========== -オプション 説明 -========== =========== -identity 自動インクリメントを有効または無効にする -signed ``unsigned`` オプションを有効または無効にする *(MySQL のみ適用)* -========== =========== - -``timestamp`` カラム: - -========== =========== -オプション 説明 -========== =========== -default デフォルト値を設定 (``CURRENT_TIMESTAMP`` を使用) -update 行が更新されたときにトリガーされるアクションを設定 (``CURRENT_TIMESTAMP`` を使用) -timezone ``time`` と ``timestamp`` カラムの ``with time zone`` オプションを有効または無効にする *(Postgres のみ適用)* -========== =========== - -``addTimestamps()`` を使うことで、テーブルに ``created_at`` と ``updated_at`` -タイムスタンプを追加できます。このメソッドでは、代わりの名を指定することもできます。 :: - - table('users')->addTimestamps(null, 'amended_at')->create(); - } - } - -``boolean`` カラム: - -========== =========== -オプション 説明 -========== =========== -signed ``unsigned`` オプションを有効または無効にする *(MySQL のみ適用)* -========== =========== - -``string`` と ``text`` カラム: - -========== =========== -オプション 説明 -========== =========== -collation テーブルのデフォルトとは異なる照合順序を設定 *(MySQL のみ適用)* -encoding テーブルのデフォルトとは異なる文字セットを設定 *(MySQL のみ適用)* -========== =========== - -外部キーの定義: - -========== =========== -オプション 説明 -========== =========== -update 行が更新されたときにトリガーされるアクションを設定 -delete 行が削除されたときにトリガーされるアクションを設定 -========== =========== - -オプションの第3引数配列を使用して、これらのオプションの1つ以上を任意のカラムに渡すことができます。 - -PostgreSQL の Limit オプション -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -PostgreSQL アダプターを使用する場合、 ``integer`` カラムに対してデータベースのカラム型のヒントを -追加することができます。次のいずれかのオプションで ``limit`` を使うと、 -それに応じてカラムの型が変更されます。 - -============ ============== -Limit カラム型 -============ ============== -INT_SMALL SMALLINT -============ ============== - -.. code-block:: php - - use Phinx\Db\Adapter\PostgresAdapter; - - //... - - $table = $this->table('cart_items'); - $table->addColumn('user_id', 'integer') - ->addColumn('subtype_id', 'integer', ['limit' => PostgresAdapter::INT_SMALL]) - ->create(); - -MySQL の Limit オプション -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -MySQL アダプターを使用する場合、 ``integer`` 、 ``text`` 、および ``blob`` カラムに対して、 -データベースのカラム型のヒントを追加することができます。次のいずれかのオプションで ``limit`` を使うと、 -それに応じてカラムの型が変更されます。 - -============ ============== -Limit カラム型 -============ ============== -BLOB_TINY TINYBLOB -BLOB_REGULAR BLOB -BLOB_MEDIUM MEDIUMBLOB -BLOB_LONG LONGBLOB -TEXT_TINY TINYTEXT -TEXT_REGULAR TEXT -TEXT_MEDIUM MEDIUMTEXT -TEXT_LONG LONGTEXT -INT_TINY TINYINT -INT_SMALL SMALLINT -INT_MEDIUM MEDIUMINT -INT_REGULAR INT -INT_BIG BIGINT -============ ============== - -.. code-block:: php - - use Phinx\Db\Adapter\MysqlAdapter; - - //... - - $table = $this->table('cart_items'); - $table->addColumn('user_id', 'integer') - ->addColumn('product_id', 'integer', ['limit' => MysqlAdapter::INT_BIG]) - ->addColumn('subtype_id', 'integer', ['limit' => MysqlAdapter::INT_SMALL]) - ->addColumn('quantity', 'integer', ['limit' => MysqlAdapter::INT_TINY]) - ->create(); - -カラム一覧の取得 -~~~~~~~~~~~~~~~~~ - -すべてのテーブルのカラムを取得するには、 `table` オブジェクトを作成し、 -`getColumns()` メソッドを呼び出します。 -このメソッドは、基本情報を持つ Column クラスの配列を返します。 例:: - - table('users')->getColumns(); - ... - } - - /** - * Migrate Down. - */ - public function down() - { - ... - } - } - -カラムが存在するかどうかの確認 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``hasColumn()`` メソッドを使ってテーブルに特定のカラムがすでにあるかどうかを調べることができます。 :: - - table('user'); - $column = $table->hasColumn('username'); - - if ($column) { - // 何かします - } - - } - } - -カラム名の変更 -~~~~~~~~~~~~~~~~~ - -カラムの名前を変更するには、Table オブジェクトのインスタンスにアクセスし、 -``renameColumn()`` メソッドを呼び出します。 :: - - table('users'); - $table->renameColumn('bio', 'biography') - ->update(); - } - - /** - * Migrate Down. - */ - public function down() - { - $table = $this->table('users'); - $table->renameColumn('biography', 'bio') - ->update(); - } - } - -別のカラムの後にカラムの追加 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -列を追加するときに、 ``after`` オプションを使用してその位置を指定することができます。 :: - - table('users'); - $table->addColumn('city', 'string', ['after' => 'email']) - ->update(); - } - } - -カラムの削除 -~~~~~~~~~~~~~~~~~ - -カラムを削除するには、 ``removeColumn()`` メソッドを使用してください。 :: - - table('users'); - $table->removeColumn('short_name') - ->save(); - } - } - -カラムの制限を指定 -~~~~~~~~~~~~~~~~~~~~~~~~~ - -``limit`` オプションを使ってカラムの最大長を制限できます。 :: - - table('tags'); - $table->addColumn('short_name', 'string', ['limit' => 30]) - ->update(); - } - } - -カラムの属性を変更 -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -既存のカラムのカラム型またはオプションを変更するには、 ``changeColumn()`` メソッドを使用します。 -使用可能な値に関しては、 :ref:`valid-column-types` や `有効なカラムのオプション`_ をご覧ください。 :: - - table('users'); - $users->changeColumn('email', 'string', ['limit' => 255]) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -インデックスの操作 --------------------- - -テーブルにインデックスを追加するには、テーブルオブジェクトに対して -``addIndex()`` メソッドを呼び出すことができます。 :: - - table('users'); - $table->addColumn('city', 'string') - ->addIndex(['city']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -デフォルトでは、Phinx はデータベースアダプターに通常のインデックスを作成するよう指示します。 -一意のインデックスを指定するために、 ``unique`` を ``addIndex()`` メソッドに渡すことができます。 -また、 ``name`` パラメーターを使ってインデックスの名前を明示的に指定することもできます。 :: - - table('users'); - $table->addColumn('email', 'string') - ->addIndex(['email'], ['unique' => true, 'name' => 'idx_users_email']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -MySQL アダプターは、 ``fulltext`` インデックスもサポートしています。 -5.6 より前のバージョンを使用している場合は、 -テーブルが ``MyISAM`` エンジンを使用していることを確認する必要があります。 :: - - table('users', ['engine' => 'MyISAM']); - $table->addColumn('email', 'string') - ->addIndex('email', ['type' => 'fulltext']) - ->create(); - } - } - -``removeIndex()`` メソッドを呼び出すと簡単にインデックスが削除できます。 -各インデックスに対してこのメソッドを呼び出す必要があります。 :: - - table('users'); - $table->removeIndex(['email']) - ->save(); - - // あるいは、インデックスの名前で削除することもできます。例: - $table->removeIndexByName('idx_users_email') - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -外部キーの操作 --------------- - -Phinx は、データベーステーブルに外部キー制約を作成する機能をサポートしています。 -例のテーブルに外部キーを追加しましょう。 :: - - table('tags'); - $table->addColumn('tag_name', 'string') - ->save(); - - $refTable = $this->table('tag_relationships'); - $refTable->addColumn('tag_id', 'integer') - ->addForeignKey('tag_id', 'tags', 'id', ['delete'=> 'SET_NULL', 'update'=> 'NO_ACTION']) - ->save(); - - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -「削除時」および「更新時」アクションは、 'delete' および 'update' オプション配列で定義されます。 -使用可能な値は、 'SET_NULL'、 'NO_ACTION'、 'CASCADE' および 'RESTRICT' です。 -制約名は 'constraint' オプションで変更できます。 - -``addForeignKey()`` にカラムの配列を渡すこともできます。 -これにより、複合キーを使用するテーブルとの外部キー関係を確立することができます。 :: - - table('follower_events'); - $table->addColumn('user_id', 'integer') - ->addColumn('follower_id', 'integer') - ->addColumn('event_id', 'integer') - ->addForeignKey(['user_id', 'follower_id'], - 'followers', - ['user_id', 'follower_id'], - ['delete'=> 'NO_ACTION', 'update'=> 'NO_ACTION', 'constraint' => 'user_follower_id']) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -``constraint`` パラメーターを使って名前付きの外部キーを追加することができます。 -この機能は Phinx バージョン 0.6.5 でサポートされます。 :: - - table('your_table'); - $table->addForeignKey('foreign_id', 'reference_table', ['id'], - ['constraint'=>'your_foreign_key_name']); - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -外部キーが存在するかどうかも簡単に確認できます。 :: - - table('tag_relationships'); - $exists = $table->hasForeignKey('tag_id'); - if ($exists) { - // 何かします - } - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } - -最後に、外部キーを削除するには、 ``dropForeignKey`` メソッドを使用します。 :: - - table('tag_relationships'); - $table->dropForeignKey('tag_id'); - } - - /** - * Migrate Down. - */ - public function down() - { - - } - } diff --git a/docs/ja/seeding.rst b/docs/ja/seeding.rst deleted file mode 100644 index 92680bee0..000000000 --- a/docs/ja/seeding.rst +++ /dev/null @@ -1,214 +0,0 @@ -.. index:: - single: Database Seeding - -データベースの初期データ投入 -============================ - -バージョン0.5.0 では、Phinx はデータベースにテストデータをシードするためのサポートを導入しました。 -シードクラスは、作成済みのデータをデータベースに簡単に投入するための優れた方法です。 -デフォルトでは ``seeds`` ディレクトリーに保存されます。 ただし、このパスは設定ファイルで変更できます。 - -.. note:: - - データベースのシードは完全にオプションで、 - Phinx はデフォルトで ``seeds`` ディレクトリーを作成しません。 - -シードクラスの新規作成 ----------------------- - -Phinx には、新しいシードクラスを簡単に生成するコマンドが含まれています。 - -.. code-block:: bash - - $ php vendor/bin/phinx seed:create UserSeeder - -複数のシードのパスを指定した場合は、新しいシードクラスを作成するパスを選択するように求められます。 - -以下は、スケルトンテンプレートを元にしています。 :: - - 'foo', - 'created' => date('Y-m-d H:i:s'), - ], - [ - 'body' => 'bar', - 'created' => date('Y-m-d H:i:s'), - ] - ]; - - $posts = $this->table('posts'); - $posts->insert($data) - ->save(); - } - } - -.. note:: - - ``save()`` メソッドを呼び出して、データをテーブルにコミットする必要があります。 - Phinx はデータをバッファリングします。 - -Faker ライブラリーとの統合 -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -シードクラスですばらしい `Faker ライブラリー `_ -を使うのは簡単です。Composer を使用してインストールするだけです。 - -.. code-block:: bash - - $ composer require fzaninotto/faker - -そして、シードクラスの中で、それを使用してください。 :: - - $faker->userName, - 'password' => sha1($faker->password), - 'password_salt' => sha1('foo'), - 'email' => $faker->email, - 'first_name' => $faker->firstName, - 'last_name' => $faker->lastName, - 'created' => date('Y-m-d H:i:s'), - ]; - } - - $this->insert('users', $data); - } - } - -テーブルのデータ消去 --------------------- - -データを挿入することに加えて、Phinx は SQL の ``TRUNCATE`` コマンドを使って -テーブルを空にすることを容易にします。 :: - - 'foo', - 'created' => date('Y-m-d H:i:s'), - ], - [ - 'body' => 'bar', - 'created' => date('Y-m-d H:i:s'), - ] - ]; - - $posts = $this->table('posts'); - $posts->insert($data) - ->save(); - - // テーブルを空にします - $posts->truncate(); - } - } - -.. note:: - - SQLite は ``TRUNCATE`` コマンドをネイティブにサポートしていないので、 ``DELETE FROM`` - が使用されています。テーブルのデータ消去後、 ``VACUUM`` コマンドを呼び出すことをお勧めします。 - Phinx はこれを自動的には行いません。 - -シードクラスの実行 ------------------- - -これは簡単な部分です。データベースをシードするには、 ``seed:run`` コマンドを使います。 - -.. code-block:: bash - - $ php vendor/bin/phinx seed:run - -デフォルトでは、Phinx は利用可能なすべてのシードクラスを実行します。 -特定のクラスを実行したい場合は、 ``-s`` パラメーターを使ってそのクラスの名前を渡します。 - -.. code-block:: bash - - $ php vendor/bin/phinx seed:run -s UserSeeder - -複数のシーダーを実行することもできます。 - -.. code-block:: bash - - $ php vendor/bin/phinx seed:run -s UserSeeder -s PermissionSeeder -s LogSeeder - -``-v`` パラメーターを使用して、より詳細な出力を表示することもできます。 - -.. code-block:: bash - - $ php vendor/bin/phinx seed:run -v - -Phinx のシード機能は、テストデータをデータベースに簡単かつ繰り返し挿入するための -簡単なメカニズムを提供します。 From 15be5d26634a6ac25c44b96810cc7d971d3b9965 Mon Sep 17 00:00:00 2001 From: Remy Bos <27890746+sjokkateer@users.noreply.github.com> Date: Sun, 13 Mar 2022 14:46:05 +0100 Subject: [PATCH 42/59] TEXT WRAPPER: Refactor shorthand ternary & add tests --- src/Phinx/Wrapper/TextWrapper.php | 17 ++++++-- tests/Phinx/Wrapper/TextWrapperTest.php | 58 +++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 tests/Phinx/Wrapper/TextWrapperTest.php diff --git a/src/Phinx/Wrapper/TextWrapper.php b/src/Phinx/Wrapper/TextWrapper.php index afa137dfd..efe1a42fe 100644 --- a/src/Phinx/Wrapper/TextWrapper.php +++ b/src/Phinx/Wrapper/TextWrapper.php @@ -73,7 +73,7 @@ public function getExitCode() public function getStatus($env = null) { $command = ['status']; - if ($env ?: $this->hasOption('environment')) { + if ($this->hasEnvValue($env)) { $command += ['-e' => $env ?: $this->getOption('environment')]; } if ($this->hasOption('configuration')) { @@ -89,6 +89,15 @@ public function getStatus($env = null) return $this->executeRun($command); } + /** + * @param string|null $env environment name + * @return bool + */ + private function hasEnvValue($env): bool + { + return $env || $this->hasOption('environment'); + } + /** * Returns the output from running the "migrate" command. * @@ -99,7 +108,7 @@ public function getStatus($env = null) public function getMigrate($env = null, $target = null) { $command = ['migrate']; - if ($env ?: $this->hasOption('environment')) { + if ($this->hasEnvValue($env)) { $command += ['-e' => $env ?: $this->getOption('environment')]; } if ($this->hasOption('configuration')) { @@ -126,7 +135,7 @@ public function getMigrate($env = null, $target = null) public function getSeed($env = null, $target = null, $seed = null) { $command = ['seed:run']; - if ($env ?: $this->hasOption('environment')) { + if ($this->hasEnvValue($env)) { $command += ['-e' => $env ?: $this->getOption('environment')]; } if ($this->hasOption('configuration')) { @@ -156,7 +165,7 @@ public function getSeed($env = null, $target = null, $seed = null) public function getRollback($env = null, $target = null) { $command = ['rollback']; - if ($env ?: $this->hasOption('environment')) { + if ($this->hasEnvValue($env)) { $command += ['-e' => $env ?: $this->getOption('environment')]; } if ($this->hasOption('configuration')) { diff --git a/tests/Phinx/Wrapper/TextWrapperTest.php b/tests/Phinx/Wrapper/TextWrapperTest.php new file mode 100644 index 000000000..13203c915 --- /dev/null +++ b/tests/Phinx/Wrapper/TextWrapperTest.php @@ -0,0 +1,58 @@ +createMock(PhinxApplication::class); + $app + ->expects($this->once()) + ->method('doRun') + ->with(new ArrayInput($expectedCommand)) + ->willReturn(0); + + $wrapper = new TextWrapper($app, $options); + + $wrapper->getStatus($env); + } + + public function envValueProvider(): array + { + return [ + 'env-value-only' => [ + self::ANY_ENV_VALUE, + [], + ['status', '-e' => self::ANY_ENV_VALUE], + ], + 'options-env-value-only' => [ + null, + ['environment' => self::ANY_ENV_VALUE], + ['status', '-e' => self::ANY_ENV_VALUE], + ], + 'both-values' => [ + self::ANY_ENV_VALUE, + ['environment' => self::ANY_ENV_VALUE . 'additional'], + ['status', '-e' => self::ANY_ENV_VALUE], + ], + 'no-values' => [ + null, + [], + ['status'], + ], + ]; + } +} From 137c802de977fd11bb3d131d8cd608cd2e291bdf Mon Sep 17 00:00:00 2001 From: saeid Date: Wed, 16 Mar 2022 19:34:40 +0330 Subject: [PATCH 43/59] fix phpstan errors --- phpstan-baseline.neon | 39 +++++++++++++++++++++++++++++++++++-- phpstan.neon | 1 - src/Phinx/Config/Config.php | 2 +- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index dd036a951..1ada84a96 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,7 +1,42 @@ parameters: ignoreErrors: - - message: "#^Call to function is_subclass_of\\(\\) with non\\-empty\\-string and 'Phinx\\\\\\\\Migration…' will always evaluate to false\\.$#" + message: "#^Variable \\$tval on left side of \\?\\? always exists and is not nullable\\.$#" + count: 1 + path: src/Phinx/Config/Config.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" count: 2 - path: src/Phinx/Console/Command/Create.php + path: src/Phinx/Db/Adapter/MysqlAdapter.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Phinx/Db/Adapter/PostgresAdapter.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Phinx/Db/Adapter/SQLiteAdapter.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Phinx/Db/Adapter/SqlServerAdapter.php + + - + message: "#^Ternary operator condition is always true\\.$#" + count: 2 + path: src/Phinx/Db/Adapter/SqlServerAdapter.php + + - + message: "#^Property Phinx\\\\Migration\\\\Manager\\\\Environment\\:\\:\\$adapter \\(Phinx\\\\Db\\\\Adapter\\\\AdapterInterface\\) in isset\\(\\) is not nullable\\.$#" + count: 1 + path: src/Phinx/Migration/Manager/Environment.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Phinx/Migration/Manager/Environment.php diff --git a/phpstan.neon b/phpstan.neon index ff3b3c000..703cfce6e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,4 +10,3 @@ parameters: - src/ ignoreErrors: - '#Unsafe usage of new static\(\)\.#' - - '#Parameter \#2 \$callback of function array_filter expects callable\(mixed, mixed\): bool, .+ given.#' diff --git a/src/Phinx/Config/Config.php b/src/Phinx/Config/Config.php index 0b5e9090b..4301bacac 100644 --- a/src/Phinx/Config/Config.php +++ b/src/Phinx/Config/Config.php @@ -140,7 +140,7 @@ public static function fromPhp($configFilePath) */ public function getEnvironments() { - if (isset($this->values) && isset($this->values['environments'])) { + if (isset($this->values['environments'])) { $environments = []; foreach ($this->values['environments'] as $key => $value) { if (is_array($value)) { From 2027a5296e7ab9444d409846a64306779b83cc8c Mon Sep 17 00:00:00 2001 From: ndm2 Date: Sat, 19 Mar 2022 21:33:15 +0100 Subject: [PATCH 44/59] Fix some syntax errors. --- docs/en/configuration.rst | 4 ++-- docs/en/index.rst | 2 ++ docs/en/namespaces.rst | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/en/configuration.rst b/docs/en/configuration.rst index 8d3b7d200..b24b4a481 100644 --- a/docs/en/configuration.rst +++ b/docs/en/configuration.rst @@ -304,9 +304,9 @@ specified directly as connection options. default_migration_table: phinxlog default_environment: development development: - dsn: %%DATABASE_URL%% + dsn: '%%DATABASE_URL%%' production: - dsn: %%DATABASE_URL%% + dsn: '%%DATABASE_URL%%' name: production_database If the supplied DSN is invalid, then it is completely ignored. diff --git a/docs/en/index.rst b/docs/en/index.rst index aebe734e8..530c8c965 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -1,3 +1,5 @@ +:orphan: + Phinx Documentation =================== diff --git a/docs/en/namespaces.rst b/docs/en/namespaces.rst index c679687be..b7496fac7 100644 --- a/docs/en/namespaces.rst +++ b/docs/en/namespaces.rst @@ -1,3 +1,5 @@ +:orphan: + .. index:: single: Supporting namespaces From 7573f85a8f094dd0f37310feca428916f14d0be5 Mon Sep 17 00:00:00 2001 From: ndm2 Date: Sat, 19 Mar 2022 21:33:56 +0100 Subject: [PATCH 45/59] Remove base TOC tree limits. This will generate a fully expanded table of contents (in the `contents.html` file only) that can be used for figuring which files to index for the search. --- docs/en/contents.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/en/contents.rst b/docs/en/contents.rst index 4723181b2..900f6ed2e 100644 --- a/docs/en/contents.rst +++ b/docs/en/contents.rst @@ -2,7 +2,6 @@ Contents ######## .. toctree:: - :maxdepth: 2 :caption: Phinx intro From b21d590397b973851aa839fb455e3461b5d12c8f Mon Sep 17 00:00:00 2001 From: saeideng Date: Mon, 21 Mar 2022 17:49:28 +0330 Subject: [PATCH 46/59] Remove faker example from seeding docs (#2077) --- docs/en/seeding.rst | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/docs/en/seeding.rst b/docs/en/seeding.rst index 9569b9cc6..3658512a1 100644 --- a/docs/en/seeding.rst +++ b/docs/en/seeding.rst @@ -152,47 +152,6 @@ within your seed class and then use the `insert()` method to insert data: You must call the `saveData()` method to commit your data to the table. Phinx will buffer data until you do so. -Integrating with the Faker library -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It's trivial to use the awesome -`Faker library `_ in your seed classes. -Simply install it using Composer: - -.. code-block:: bash - - $ composer require fzaninotto/faker - -Then use it in your seed classes: - -.. code-block:: php - - $faker->userName, - 'password' => sha1($faker->password), - 'password_salt' => sha1('foo'), - 'email' => $faker->email, - 'first_name' => $faker->firstName, - 'last_name' => $faker->lastName, - 'created' => date('Y-m-d H:i:s'), - ]; - } - - $this->table('users')->insert($data)->saveData(); - } - } - Truncating Tables ----------------- From 2683c41d962ee6a92b872b054e70eeed3822bd60 Mon Sep 17 00:00:00 2001 From: Oliver Nowak Date: Wed, 23 Mar 2022 17:47:23 +0100 Subject: [PATCH 47/59] Update source files path. --- docs.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs.Dockerfile b/docs.Dockerfile index e41aed21d..f08ad3832 100644 --- a/docs.Dockerfile +++ b/docs.Dockerfile @@ -13,7 +13,7 @@ FROM markstory/cakephp-docs-builder:runtime as runtime # Configure search index script ENV LANGS="en" -ENV SEARCH_SOURCE="/data/docs" +ENV SEARCH_SOURCE="/usr/share/nginx/html" ENV SEARCH_URL_PREFIX="/phinx/0" COPY --from=builder /data/docs /data/docs From ebfbf9706f3e657302a1bfd0ecf131edba9dcfb9 Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Sat, 26 Mar 2022 12:39:23 +0100 Subject: [PATCH 48/59] update to PHPStan 1.5 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3be47a368..3802f3f6b 100644 --- a/composer.json +++ b/composer.json @@ -73,7 +73,7 @@ "cs-check": "phpcs -np app/ src/ tests/", "cs-fix": "phpcbf -np app/ src/ tests/", "stan": "phpstan analyse src/", - "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:~1.4.0 && mv composer.backup composer.json", + "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:~1.5.0 && mv composer.backup composer.json", "test": "phpunit --colors=always" }, "bin": [ From dd5fc8c1ccd7b7014e4ce13e1c2f302f63a019e6 Mon Sep 17 00:00:00 2001 From: Harald Ernst Date: Sat, 26 Mar 2022 17:50:28 +0100 Subject: [PATCH 49/59] Add missing save call to renameColumn doc examples (#2080) --- docs/en/migrations.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/en/migrations.rst b/docs/en/migrations.rst index 37e3e6b53..de23d4747 100644 --- a/docs/en/migrations.rst +++ b/docs/en/migrations.rst @@ -1126,7 +1126,8 @@ To rename a column, access an instance of the Table object then call the public function up() { $table = $this->table('users'); - $table->renameColumn('bio', 'biography'); + $table->renameColumn('bio', 'biography') + ->save(); } /** @@ -1135,7 +1136,8 @@ To rename a column, access an instance of the Table object then call the public function down() { $table = $this->table('users'); - $table->renameColumn('biography', 'bio'); + $table->renameColumn('biography', 'bio') + ->save(); } } From b2452d36463826615ec7d6eea544531fe310b2c8 Mon Sep 17 00:00:00 2001 From: Matthias Wirtz <2990373+swiffer@users.noreply.github.com> Date: Tue, 29 Mar 2022 12:06:56 +0200 Subject: [PATCH 50/59] Update SQLiteAdapter.php --- src/Phinx/Db/Adapter/SQLiteAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Phinx/Db/Adapter/SQLiteAdapter.php b/src/Phinx/Db/Adapter/SQLiteAdapter.php index 3521d22bf..55d3125b4 100644 --- a/src/Phinx/Db/Adapter/SQLiteAdapter.php +++ b/src/Phinx/Db/Adapter/SQLiteAdapter.php @@ -167,7 +167,7 @@ public function connect() if (!empty($options['mode'])) { $params[] = 'mode=' . $options['mode']; } - $dsn = 'sqlite:file:' . $options['name'] ?? '' . '?' . implode('&', $params); + $dsn = 'sqlite:file:' . ($options['name'] ?? '') . '?' . implode('&', $params); } else { // use a memory database if the option was specified if (!empty($options['memory']) || $options['name'] === static::MEMORY) { From 6d469fca92d90a805a9db47c211241da7c6bbc13 Mon Sep 17 00:00:00 2001 From: Matthias Wirtz <2990373+swiffer@users.noreply.github.com> Date: Tue, 29 Mar 2022 12:48:54 +0200 Subject: [PATCH 51/59] Update phpstan-baseline.neon update baseline to reflect latest code correction --- phpstan-baseline.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1ada84a96..b4cecf28e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -15,11 +15,6 @@ parameters: count: 1 path: src/Phinx/Db/Adapter/PostgresAdapter.php - - - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" - count: 1 - path: src/Phinx/Db/Adapter/SQLiteAdapter.php - - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" count: 1 From 69f3ca4b0affeda17c70ffb54591f659afa5b229 Mon Sep 17 00:00:00 2001 From: Corey Taylor Date: Thu, 21 Apr 2022 08:19:42 -0500 Subject: [PATCH 52/59] Update dependabot config --- .github/dependabot.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c630ffa6b..6647c4286 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,5 +3,10 @@ updates: - package-ecosystem: composer directory: "/" schedule: - interval: daily + interval: weekly + open-pull-requests-limit: 10 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly open-pull-requests-limit: 10 From ee97f9f4180fe24d285700223852f201e37fbde1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Apr 2022 13:22:09 +0000 Subject: [PATCH 53/59] Bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/deploy_docs_0x.yml | 2 +- .github/workflows/phar.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d52730175..9cbb62863 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: if: matrix.db-type == 'pgsql' && matrix.php-version == '7.2' run: docker run --rm --name=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=cakephp -p 5432:5432 -d postgres:9.4 - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -112,7 +112,7 @@ jobs: PHP_VERSION: '7.4' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Get date part for cache key id: key-date @@ -176,7 +176,7 @@ jobs: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/deploy_docs_0x.yml b/.github/workflows/deploy_docs_0x.yml index 65585333b..9a06695c4 100644 --- a/.github/workflows/deploy_docs_0x.yml +++ b/.github/workflows/deploy_docs_0x.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Cloning repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 diff --git a/.github/workflows/phar.yml b/.github/workflows/phar.yml index dc625be68..ba5a06d2d 100644 --- a/.github/workflows/phar.yml +++ b/.github/workflows/phar.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 From 93272dc7ed519c15a471e9849352478f39ccfef5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Apr 2022 13:22:13 +0000 Subject: [PATCH 54/59] Bump actions/cache from 1 to 3 Bumps [actions/cache](https://github.com/actions/cache) from 1 to 3. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v1...v3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/phar.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d52730175..616e5e340 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: run: echo "::set-output name=date::$(date +'%Y-%m')" - name: Cache composer dependencies - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }} @@ -127,7 +127,7 @@ jobs: key: ${{ steps.key-date.outputs.date }} - name: Cache PHP extensions - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ${{ steps.php-ext-cache.outputs.dir }} key: ${{ runner.os }}-php-ext-${{ steps.php-ext-cache.outputs.key }} @@ -153,7 +153,7 @@ jobs: run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache composer dependencies - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }} @@ -193,7 +193,7 @@ jobs: run: echo "::set-output name=date::$(date +'%Y-%m')" - name: Cache composer dependencies - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }} diff --git a/.github/workflows/phar.yml b/.github/workflows/phar.yml index dc625be68..65123952c 100644 --- a/.github/workflows/phar.yml +++ b/.github/workflows/phar.yml @@ -22,7 +22,7 @@ jobs: run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} From 38391274feb6a7ab86c6a8182c1147bf205ef54a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Apr 2022 13:22:19 +0000 Subject: [PATCH 55/59] Bump codecov/codecov-action from 1 to 3 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1 to 3. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v1...v3) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d52730175..d9aedcf58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -101,7 +101,7 @@ jobs: - name: Submit code coverage if: matrix.php-version == '8.0' - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 testsuite-windows: runs-on: windows-2019 @@ -169,7 +169,7 @@ jobs: vendor/bin/phpunit --verbose --coverage-clover=coverage.xml - name: Submit code coverage - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 cs-stan: name: Coding Standard & Static Analysis From 2046c447b1a4425956555118200138e22ebd680c Mon Sep 17 00:00:00 2001 From: ingLomeland <87584165+ingLomeland@users.noreply.github.com> Date: Sun, 3 Jul 2022 18:41:43 +0200 Subject: [PATCH 56/59] Add setting DSN options for SqlServerAdapter (#2094) Co-authored-by: ingLomeland --- src/Phinx/Db/Adapter/SqlServerAdapter.php | 8 ++++++++ tests/Phinx/Db/Adapter/SqlServerAdapterTest.php | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Phinx/Db/Adapter/SqlServerAdapter.php b/src/Phinx/Db/Adapter/SqlServerAdapter.php index d9751087e..4c3f5fff9 100644 --- a/src/Phinx/Db/Adapter/SqlServerAdapter.php +++ b/src/Phinx/Db/Adapter/SqlServerAdapter.php @@ -77,6 +77,14 @@ public function connect() } $dsn .= ';database=' . $options['name'] . ';MultipleActiveResultSets=false'; + // option to add additional connection options + // https://docs.microsoft.com/en-us/sql/connect/php/connection-options?view=sql-server-ver15 + if (isset($options['dsn_options'])) { + foreach ($options['dsn_options'] as $key => $option) { + $dsn .= ';' . $key . '=' . $option; + } + } + $driverOptions = []; // charset support diff --git a/tests/Phinx/Db/Adapter/SqlServerAdapterTest.php b/tests/Phinx/Db/Adapter/SqlServerAdapterTest.php index e1dc21e69..4497207a1 100644 --- a/tests/Phinx/Db/Adapter/SqlServerAdapterTest.php +++ b/tests/Phinx/Db/Adapter/SqlServerAdapterTest.php @@ -50,6 +50,14 @@ public function testConnection() $this->assertSame(\PDO::ERRMODE_EXCEPTION, $this->adapter->getConnection()->getAttribute(\PDO::ATTR_ERRMODE)); } + public function testConnectionWithDsnOptions() + { + $options = $this->adapter->getOptions(); + $options['dsn_options'] = ['TrustServerCertificate' => 'true']; + $this->adapter->setOptions($options); + $this->assertInstanceOf('PDO', $this->adapter->getConnection()); + } + public function testConnectionWithFetchMode() { $options = $this->adapter->getOptions(); From 8ad008e86804836160f7bd8e4933f3d7a1ced770 Mon Sep 17 00:00:00 2001 From: Corey Taylor Date: Sun, 3 Jul 2022 23:54:54 -0500 Subject: [PATCH 57/59] Add php 8.2 to github actions and update versions --- .github/workflows/ci.yml | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f68974b63..a02f2be85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,14 @@ name: CI -on: ['push', 'pull_request'] +on: + push: + branches: + - '0.x' + - '0.next' + - '1.x' + pull_request: + branches: + - '*' jobs: testsuite: @@ -8,13 +16,15 @@ jobs: strategy: fail-fast: false matrix: - php-version: ['7.2', '8.0', '8.1'] + php-version: ['7.2', '7.4', '8.0', '8.1'] db-type: [sqlite, mysql, pgsql] prefer-lowest: [''] include: + - php-version: '8.2' + db-type: mysql - php-version: '7.2' - db-type: 'mysql' - prefer-lowest: 'prefer-lowest' + db-type: mysql + prefer-lowest: prefer-lowest steps: - name: Setup MySQL latest @@ -57,7 +67,7 @@ jobs: - name: Composer install run: | - if [[ ${{ matrix.php-version }} == '8.1' ]]; then + if [[ ${{ matrix.php-version }} == '8.2' ]]; then composer install --ignore-platform-req=php elif ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then composer update --prefer-lowest --prefer-stable @@ -89,7 +99,7 @@ jobs: if [[ ${{ matrix.db-type }} == 'mysql' ]]; then export MYSQL_DSN='mysql://root:root@127.0.0.1/phinx'; fi if [[ ${{ matrix.db-type }} == 'pgsql' ]]; then export PGSQL_DSN='pgsql://postgres:postgres@127.0.0.1/phinx'; fi - if [[ ${{ matrix.php-version }} == '8.0' ]]; then + if [[ ${{ matrix.php-version }} == '8.1' ]]; then export CODECOVERAGE=1 && vendor/bin/phpunit --verbose --coverage-clover=coverage.xml else vendor/bin/phpunit @@ -97,19 +107,19 @@ jobs: - name: Prefer lowest check if: matrix.prefer-lowest == 'prefer-lowest' - run: composer require --dev dereuromark/composer-prefer-lowest && vendor/bin/validate-prefer-lowest -m + run: composer require --dev dereuromark/composer-prefer-lowest && vendor/bin/validate-prefer-lowest -m - name: Submit code coverage - if: matrix.php-version == '8.0' + if: matrix.php-version == '8.1' uses: codecov/codecov-action@v3 testsuite-windows: runs-on: windows-2019 - name: Windows - PHP 7.4 & SQL Server + name: Windows - PHP 8.1 & SQL Server env: EXTENSIONS: pdo_sqlsrv - PHP_VERSION: '7.4' + PHP_VERSION: '8.1' steps: - uses: actions/checkout@v3 @@ -181,7 +191,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.2' + php-version: '7.4' coverage: none - name: Get composer cache directory @@ -205,4 +215,5 @@ jobs: run: vendor/bin/phpcs --report=checkstyle -np app/ src/ tests/ - name: Run phpstan + if: always() run: vendor/bin/phpstan.phar analyse --error-format=github From 11ec6ee38217626203065c66d5879c97801aeab8 Mon Sep 17 00:00:00 2001 From: Pavel Kachurka <91262244+paulermo@users.noreply.github.com> Date: Mon, 4 Jul 2022 17:36:12 +0200 Subject: [PATCH 58/59] Fix setting persistent option for PDO connection (#2092) --- src/Phinx/Db/Adapter/MysqlAdapter.php | 5 +++++ src/Phinx/Db/Adapter/PostgresAdapter.php | 5 +++++ src/Phinx/Db/Adapter/SQLiteAdapter.php | 5 +++++ src/Phinx/Db/Adapter/SqlServerAdapter.php | 3 +++ tests/Phinx/Db/Adapter/MysqlAdapterTest.php | 12 ++++++++++++ tests/Phinx/Db/Adapter/PostgresAdapterTest.php | 12 ++++++++++++ tests/Phinx/Db/Adapter/SQLiteAdapterTest.php | 12 ++++++++++++ 7 files changed, 54 insertions(+) diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 921933a50..009994fcb 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -132,6 +132,11 @@ public function connect() $driverOptions[PDO::ATTR_DEFAULT_FETCH_MODE] = constant('\PDO::FETCH_' . strtoupper($options['fetch_mode'])); } + // pass \PDO::ATTR_PERSISTENT to driver options instead of useless setting it after instantiation + if (isset($options['attr_persistent'])) { + $driverOptions[PDO::ATTR_PERSISTENT] = $options['attr_persistent']; + } + // support arbitrary \PDO::MYSQL_ATTR_* driver options and pass them to PDO // http://php.net/manual/en/ref.pdo-mysql.php#pdo-mysql.constants foreach ($options as $key => $option) { diff --git a/src/Phinx/Db/Adapter/PostgresAdapter.php b/src/Phinx/Db/Adapter/PostgresAdapter.php index f510ba97d..7dafad7a2 100644 --- a/src/Phinx/Db/Adapter/PostgresAdapter.php +++ b/src/Phinx/Db/Adapter/PostgresAdapter.php @@ -80,6 +80,11 @@ public function connect() $driverOptions[PDO::ATTR_DEFAULT_FETCH_MODE] = constant('\PDO::FETCH_' . strtoupper($options['fetch_mode'])); } + // pass \PDO::ATTR_PERSISTENT to driver options instead of useless setting it after instantiation + if (isset($options['attr_persistent'])) { + $driverOptions[PDO::ATTR_PERSISTENT] = $options['attr_persistent']; + } + $db = $this->createPdoConnection($dsn, $options['user'] ?? null, $options['pass'] ?? null, $driverOptions); try { diff --git a/src/Phinx/Db/Adapter/SQLiteAdapter.php b/src/Phinx/Db/Adapter/SQLiteAdapter.php index 55d3125b4..2d1e33e4f 100644 --- a/src/Phinx/Db/Adapter/SQLiteAdapter.php +++ b/src/Phinx/Db/Adapter/SQLiteAdapter.php @@ -184,6 +184,11 @@ public function connect() $driverOptions[PDO::ATTR_DEFAULT_FETCH_MODE] = constant('\PDO::FETCH_' . strtoupper($options['fetch_mode'])); } + // pass \PDO::ATTR_PERSISTENT to driver options instead of useless setting it after instantiation + if (isset($options['attr_persistent'])) { + $driverOptions[PDO::ATTR_PERSISTENT] = $options['attr_persistent']; + } + $db = $this->createPdoConnection($dsn, null, null, $driverOptions); $this->setConnection($db); diff --git a/src/Phinx/Db/Adapter/SqlServerAdapter.php b/src/Phinx/Db/Adapter/SqlServerAdapter.php index 4c3f5fff9..c2670a2c8 100644 --- a/src/Phinx/Db/Adapter/SqlServerAdapter.php +++ b/src/Phinx/Db/Adapter/SqlServerAdapter.php @@ -97,6 +97,9 @@ public function connect() $driverOptions[PDO::ATTR_DEFAULT_FETCH_MODE] = constant('\PDO::FETCH_' . strtoupper($options['fetch_mode'])); } + // Note, the PDO::ATTR_PERSISTENT attribute is not supported for sqlsrv and will throw an error when used + // See https://github.com/Microsoft/msphpsql/issues/65 + // support arbitrary \PDO::SQLSRV_ATTR_* driver options and pass them to PDO // http://php.net/manual/en/ref.pdo-sqlsrv.php#pdo-sqlsrv.constants foreach ($options as $key => $option) { diff --git a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php index 26d21df9d..4842760c3 100644 --- a/tests/Phinx/Db/Adapter/MysqlAdapterTest.php +++ b/tests/Phinx/Db/Adapter/MysqlAdapterTest.php @@ -2214,4 +2214,16 @@ public function testGetPhinxTypeFromSQLDefinition(string $sqlDefinition, array $ $this->assertSame($expectedResponse['name'], $result['name'], "Type mismatch - got '{$result['name']}' when expecting '{$expectedResponse['name']}'"); $this->assertSame($expectedResponse['limit'], $result['limit'], "Field upper boundary mismatch - got '{$result['limit']}' when expecting '{$expectedResponse['limit']}'"); } + + public function testPdoPersistentConnection() + { + $adapter = new MysqlAdapter(MYSQL_DB_CONFIG + ['attr_persistent' => true]); + $this->assertTrue($adapter->getConnection()->getAttribute(\PDO::ATTR_PERSISTENT)); + } + + public function testPdoNotPersistentConnection() + { + $adapter = new MysqlAdapter(MYSQL_DB_CONFIG); + $this->assertFalse($adapter->getConnection()->getAttribute(\PDO::ATTR_PERSISTENT)); + } } diff --git a/tests/Phinx/Db/Adapter/PostgresAdapterTest.php b/tests/Phinx/Db/Adapter/PostgresAdapterTest.php index 47eded3cb..a8baa8c2c 100644 --- a/tests/Phinx/Db/Adapter/PostgresAdapterTest.php +++ b/tests/Phinx/Db/Adapter/PostgresAdapterTest.php @@ -2310,4 +2310,16 @@ public function testInvalidPdoAttribute() $this->expectExceptionMessage('Invalid PDO attribute: attr_invalid (\PDO::ATTR_INVALID)'); $adapter->connect(); } + + public function testPdoPersistentConnection() + { + $adapter = new PostgresAdapter(PGSQL_DB_CONFIG + ['attr_persistent' => true]); + $this->assertTrue($adapter->getConnection()->getAttribute(\PDO::ATTR_PERSISTENT)); + } + + public function testPdoNotPersistentConnection() + { + $adapter = new PostgresAdapter(PGSQL_DB_CONFIG); + $this->assertFalse($adapter->getConnection()->getAttribute(\PDO::ATTR_PERSISTENT)); + } } diff --git a/tests/Phinx/Db/Adapter/SQLiteAdapterTest.php b/tests/Phinx/Db/Adapter/SQLiteAdapterTest.php index 08c94bee3..b92e45878 100644 --- a/tests/Phinx/Db/Adapter/SQLiteAdapterTest.php +++ b/tests/Phinx/Db/Adapter/SQLiteAdapterTest.php @@ -2306,4 +2306,16 @@ public function testPdoExceptionUpdateNonExistingTable() $table = new \Phinx\Db\Table('non_existing_table', [], $this->adapter); $table->addColumn('column', 'string')->update(); } + + public function testPdoPersistentConnection() + { + $adapter = new SQLiteAdapter(SQLITE_DB_CONFIG + ['attr_persistent' => true]); + $this->assertTrue($adapter->getConnection()->getAttribute(\PDO::ATTR_PERSISTENT)); + } + + public function testPdoNotPersistentConnection() + { + $adapter = new SQLiteAdapter(SQLITE_DB_CONFIG); + $this->assertFalse($adapter->getConnection()->getAttribute(\PDO::ATTR_PERSISTENT)); + } } From e9804ca06bb634ca2b4559333ba67b963bd147e5 Mon Sep 17 00:00:00 2001 From: Mark Scherer Date: Mon, 4 Jul 2022 18:40:54 +0200 Subject: [PATCH 59/59] Update ci.yml --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a02f2be85..15038f19d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,8 +7,6 @@ on: - '0.next' - '1.x' pull_request: - branches: - - '*' jobs: testsuite: