diff --git a/.appveyor.yml b/.appveyor.yml index ddc5093abc..e4ed5ce841 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -40,15 +40,15 @@ init: ## Install PHP and composer, and run the appropriate composer command install: - # Upgrade to 0.10.16-beta to benefit from a bugfix for - # https://github.com/chocolatey/choco/issues/1843 - - ps: choco upgrade chocolatey --pre + - sc config wuauserv start=auto + - net start wuauserv - ps: | # Check if installation is cached if (!(Test-Path c:\tools\php)) { - appveyor-retry choco install --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') + choco upgrade chocolatey + appveyor-retry choco install --no-progress --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') # install sqlite - appveyor-retry choco install -y sqlite + appveyor-retry choco install --no-progress -y sqlite Get-ChildItem -Path c:\tools\php cd c:\tools\php diff --git a/src/Schema/SQLiteSchemaManager.php b/src/Schema/SQLiteSchemaManager.php index 54da7c1006..47eabd6f25 100644 --- a/src/Schema/SQLiteSchemaManager.php +++ b/src/Schema/SQLiteSchemaManager.php @@ -13,6 +13,7 @@ use Doctrine\DBAL\Types\Type; use function array_change_key_case; +use function array_map; use function array_merge; use function assert; use function count; @@ -359,9 +360,8 @@ protected function _getPortableTableForeignKeyDefinition(array $tableForeignKey) private function parseColumnCollationFromSQL(string $column, string $sql): ?string { - $pattern = '{(?:\W' . preg_quote($column) . '\W|\W' - . preg_quote($this->platform->quoteSingleIdentifier($column)) - . '\W)[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}is'; + $pattern = '{' . $this->buildIdentifierPattern($column) + . '[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}is'; if (preg_match($pattern, $sql, $match) !== 1) { return null; @@ -373,9 +373,7 @@ private function parseColumnCollationFromSQL(string $column, string $sql): ?stri private function parseTableCommentFromSQL(string $table, string $sql): ?string { $pattern = '/\s* # Allow whitespace characters at start of line -CREATE\sTABLE # Match "CREATE TABLE" -(?:\W"' . preg_quote($this->platform->quoteSingleIdentifier($table), '/') . '"\W|\W' . preg_quote($table, '/') - . '\W) # Match table name (quoted and unquoted) +CREATE\sTABLE' . $this->buildIdentifierPattern($table) . ' ( # Start capture (?:\s*--[^\n]*\n?)+ # Capture anything that starts with whitespaces followed by -- until the end of the line(s) )/ix'; @@ -391,8 +389,8 @@ private function parseTableCommentFromSQL(string $table, string $sql): ?string private function parseColumnCommentFromSQL(string $column, string $sql): string { - $pattern = '{[\s(,](?:\W' . preg_quote($this->platform->quoteSingleIdentifier($column)) - . '\W|\W' . preg_quote($column) . '\W)(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i'; + $pattern = '{[\s(,]' . $this->buildIdentifierPattern($column) + . '(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i'; if (preg_match($pattern, $sql, $match) !== 1) { return ''; @@ -404,6 +402,22 @@ private function parseColumnCommentFromSQL(string $column, string $sql): string return $comment; } + /** + * Returns a regular expression pattern that matches the given unquoted or quoted identifier. + */ + private function buildIdentifierPattern(string $identifier): string + { + return '(?:' . implode('|', array_map( + static function (string $sql): string { + return '\W' . preg_quote($sql, '/') . '\W'; + }, + [ + $identifier, + $this->platform->quoteSingleIdentifier($identifier), + ], + )) . ')'; + } + /** @throws Exception */ private function getCreateTableSQL(string $table): string { diff --git a/tests/Functional/Schema/SQLiteSchemaManagerTest.php b/tests/Functional/Schema/SQLiteSchemaManagerTest.php index 14f5f917e9..d9d57f4a1f 100644 --- a/tests/Functional/Schema/SQLiteSchemaManagerTest.php +++ b/tests/Functional/Schema/SQLiteSchemaManagerTest.php @@ -392,4 +392,25 @@ public function testShorthandInForeignKeyReferenceWithMultipleColumns(): void $createTableTrackSql, ); } + + /** + * This test duplicates {@see parent::testCommentInTable()} with the only difference that the name of the table + * being created is quoted. It is only meant to cover the logic of parsing the SQLite CREATE TABLE statement + * when the table name is quoted. + * + * Running the same test for all platforms, on the one hand, won't produce additional coverage, and on the other, + * is not feasible due to the differences in case sensitivity depending on whether the name is quoted. + * + * Once all identifiers are quoted by default, this test can be removed. + */ + public function testCommentInQuotedTable(): void + { + $table = new Table('"table_with_comment"'); + $table->addColumn('id', Types::INTEGER); + $table->setComment('This is a comment'); + $this->dropAndCreateTable($table); + + $table = $this->schemaManager->introspectTable('table_with_comment'); + self::assertSame('This is a comment', $table->getComment()); + } }