From b259119a211a3855c4d3c34ddfe2bed7e4fe9907 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Sat, 23 Sep 2023 14:10:32 +0700 Subject: [PATCH] Refactor `Quoter` --- src/Schema/Quoter.php | 32 ++++++++++++++++++++++---------- tests/Db/Schema/QuoterTest.php | 15 +++++++++++++++ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/Schema/Quoter.php b/src/Schema/Quoter.php index 10a559222..edc913625 100644 --- a/src/Schema/Quoter.php +++ b/src/Schema/Quoter.php @@ -8,11 +8,16 @@ use Yiisoft\Db\Expression\ExpressionInterface; use function addcslashes; +use function array_slice; +use function count; use function explode; use function implode; use function is_string; +use function preg_match; +use function preg_replace; use function preg_replace_callback; use function str_contains; +use function str_ends_with; use function str_replace; use function str_starts_with; use function strrpos; @@ -44,7 +49,7 @@ public function cleanUpTableNames(array $tableNames): array { $cleanedUpTableNames = []; $pattern = << $tableNames */ @@ -104,7 +109,7 @@ public function ensureColumnName(string $name): string $name = $parts[count($parts) - 1]; } - return preg_replace('|^\[\[([_\w\-. ]+)\]\]$|', '\1', $name); + return preg_replace('|^\[\[([\w\-. ]+)]]$|', '\1', $name); } public function quoteColumnName(string $name): string @@ -135,8 +140,9 @@ public function quoteSimpleColumnName(string $name): string [$startingCharacter, $endingCharacter] = $this->columnQuoteCharacter; } - return $name === '*' || str_contains($name, $startingCharacter) ? $name : $startingCharacter . $name - . $endingCharacter; + return $name === '*' || str_starts_with($name, $startingCharacter) + ? $name + : $startingCharacter . $name . $endingCharacter; } public function quoteSimpleTableName(string $name): string @@ -147,13 +153,15 @@ public function quoteSimpleTableName(string $name): string [$startingCharacter, $endingCharacter] = $this->tableQuoteCharacter; } - return str_contains($name, $startingCharacter) ? $name : $startingCharacter . $name . $endingCharacter; + return str_starts_with($name, $startingCharacter) + ? $name + : $startingCharacter . $name . $endingCharacter; } public function quoteSql(string $sql): string { return preg_replace_callback( - '/({{(%?[\w\-. ]+%?)}}|\\[\\[([\w\-. ]+)]])/', + '/({{(%?[\w\-. ]+)%?}}|\\[\\[([\w\-. ]+)]])/', function ($matches) { if (isset($matches[3])) { return $this->quoteColumnName($matches[3]); @@ -194,7 +202,7 @@ public function quoteValue(mixed $value): mixed return $value; } - return '\'' . str_replace('\'', '\'\'', addcslashes($value, "\000\032")) . '\''; + return "'" . str_replace("'", "''", addcslashes($value, "\000\032")) . "'"; } public function unquoteSimpleColumnName(string $name): string @@ -205,7 +213,9 @@ public function unquoteSimpleColumnName(string $name): string $startingCharacter = $this->columnQuoteCharacter[0]; } - return !str_contains($name, $startingCharacter) ? $name : substr($name, 1, -1); + return !str_starts_with($name, $startingCharacter) + ? $name + : substr($name, 1, -1); } public function unquoteSimpleTableName(string $name): string @@ -216,7 +226,9 @@ public function unquoteSimpleTableName(string $name): string $startingCharacter = $this->tableQuoteCharacter[0]; } - return !str_contains($name, $startingCharacter) ? $name : substr($name, 1, -1); + return !str_starts_with($name, $startingCharacter) + ? $name + : substr($name, 1, -1); } /** @@ -229,7 +241,7 @@ protected function unquoteParts(array $parts, bool $withColumn): array $lastKey = count($parts) - 1; foreach ($parts as $k => &$part) { - $part = ($withColumn || $lastKey === $k) ? + $part = ($withColumn && $lastKey === $k) ? $this->unquoteSimpleColumnName($part) : $this->unquoteSimpleTableName($part); } diff --git a/tests/Db/Schema/QuoterTest.php b/tests/Db/Schema/QuoterTest.php index 0841dca80..a98d1dbba 100644 --- a/tests/Db/Schema/QuoterTest.php +++ b/tests/Db/Schema/QuoterTest.php @@ -87,4 +87,19 @@ public function testCleanUpTableNamesWithCastException(): void ['tableAlias' => 123], ); } + + public function testGetTableNamePartsWithDifferentQuotes(): void + { + $quoter = new Quoter('`', '"'); + + $this->assertSame(['schema', 'table'], $quoter->getTableNameParts('"schema"."table"')); + } + + public function testQuoteSqlWithTablePrefix(): void + { + $quoter = new Quoter('`', '`', 'prefix_'); + $sql = 'SELECT * FROM {{%table%}}'; + + $this->assertSame('SELECT * FROM `prefix_table`', $quoter->quoteSql($sql)); + } }