Skip to content

Commit e44b52f

Browse files
TigrovStyleCIBotvjik
authored
Move and deprecate Schema methods (#801)
* Move and deprecate `Schema` methods * Add tests * Add lines to CHANGELOG.md [skip ci] * Apply review suggestions * Fix bug with `Quoter` * Move `quoter->setTablePrefix()` to `AbstractPdoConnection` * Fix setTablePrefix() * Remove `QuoterInterface::getRawTableName()` due to BC issue * Update doc [skip ci] * Rearrange tests * Apply fixes from StyleCI * Fix psalm issues * Update CHANGELOG.md [skip ci] --------- Co-authored-by: StyleCI Bot <[email protected]> Co-authored-by: Sergei Predvoditelev <[email protected]>
1 parent 89e1003 commit e44b52f

10 files changed

+107
-14
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
- Enh #795: Allow to use `DMLQueryBuilderInterface::batchInsert()` method with empty columns (@Tigrov)
2020
- Enh #794: Add message type to log context (@darkdef)
2121
- Enh #802: Minor refactoring of `SchemaCache`, `AbstractPdoCommand` and `AbstractDDLQueryBuilder` (@Tigrov)
22+
- Enh #801: Deprecate `AbstractSchema::normalizeRowKeyCase()` method (@Tigrov)
23+
- Enh #801: Deprecate `SchemaInterface::getRawTableName()` and add `Quoter::getRawTableName()` method (@Tigrov)
24+
- Enh #801: Deprecate `SchemaInterface::isReadQuery()` and add `DbStringHelper::isReadQuery()` method (@Tigrov)
25+
- Enh #801: Remove unnecessary symbol `\\` from `rtrim()` function inside `DbStringHelper::baseName()` method (@Tigrov)
26+
- Bug #801: Fix bug with `Quoter::$tablePrefix` when change `AbstractConnection::$tablePrefix` property (@Tigrov)
2227

2328
## 1.2.0 November 12, 2023
2429

src/Driver/Pdo/AbstractPdoConnection.php

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

2626
use function array_keys;
2727
use function is_string;
28+
use function method_exists;
2829

2930
/**
3031
* Represents a connection to a database using the PDO (PHP Data Objects) extension.
@@ -198,6 +199,14 @@ public function setEmulatePrepare(bool $value): void
198199
$this->emulatePrepare = $value;
199200
}
200201

202+
public function setTablePrefix(string $value): void
203+
{
204+
parent::setTablePrefix($value);
205+
if ($this->quoter !== null && method_exists($this->quoter, 'setTablePrefix')) {
206+
$this->quoter->setTablePrefix($value);
207+
}
208+
}
209+
201210
/**
202211
* Initializes the DB connection.
203212
*

src/Helper/DbStringHelper.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use function mb_strrpos;
1010
use function mb_strtolower;
1111
use function mb_substr;
12+
use function preg_match;
1213
use function preg_replace;
1314
use function rtrim;
1415
use function str_replace;
@@ -38,7 +39,7 @@ final class DbStringHelper
3839
*/
3940
public static function baseName(string $path): string
4041
{
41-
$path = rtrim(str_replace('\\', '/', $path), '/\\');
42+
$path = rtrim(str_replace('\\', '/', $path), '/');
4243
$position = mb_strrpos($path, '/');
4344

4445
if ($position !== false) {
@@ -48,6 +49,20 @@ public static function baseName(string $path): string
4849
return $path;
4950
}
5051

52+
/**
53+
* Returns a value indicating whether an SQL statement is for read purpose.
54+
*
55+
* @param string $sql The SQL statement.
56+
*
57+
* @return bool Whether an SQL statement is for read purpose.
58+
*/
59+
public static function isReadQuery(string $sql): bool
60+
{
61+
$pattern = '/^\s*(SELECT|SHOW|DESCRIBE)\b/i';
62+
63+
return preg_match($pattern, $sql) === 1;
64+
}
65+
5166
/**
5267
* Returns string representation of a number value without a thousand separators and with dot as decimal separator.
5368
*

src/Schema/AbstractSchema.php

+11-1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public function getDataType(mixed $data): int
144144
};
145145
}
146146

147+
/** @deprecated Use {@see Quoter::getRawTableName()}. Will be removed in version 2.0.0. */
147148
public function getRawTableName(string $name): string
148149
{
149150
if (str_contains($name, '{{')) {
@@ -315,6 +316,7 @@ public function getTableUniques(string $name, bool $refresh = false): array
315316
return is_array($tableUniques) ? $tableUniques : [];
316317
}
317318

319+
/** @deprecated Use {@see DbStringHelper::isReadQuery()}. Will be removed in version 2.0.0. */
318320
public function isReadQuery(string $sql): bool
319321
{
320322
$pattern = '/^\s*(SELECT|SHOW|DESCRIBE)\b/i';
@@ -340,6 +342,7 @@ public function refresh(): void
340342
*/
341343
public function refreshTableSchema(string $name): void
342344
{
345+
/** @psalm-suppress DeprecatedMethod */
343346
$rawName = $this->getRawTableName($name);
344347

345348
unset($this->tableMetadata[$rawName]);
@@ -470,6 +473,7 @@ protected function getSchemaMetadata(string $schema, string $type, bool $refresh
470473
*/
471474
protected function getTableMetadata(string $name, string $type, bool $refresh = false): mixed
472475
{
476+
/** @psalm-suppress DeprecatedMethod */
473477
$rawName = $this->getRawTableName($name);
474478

475479
if (!isset($this->tableMetadata[$rawName])) {
@@ -532,6 +536,9 @@ protected function getTableTypeMetadata(
532536
* @param bool $multiple Whether many rows or a single row passed.
533537
*
534538
* @return array The normalized row or rows.
539+
*
540+
* @deprecated Use `array_change_key_case($row)` or `array_map('array_change_key_case', $row)`.
541+
* Will be removed in version 2.0.0.
535542
*/
536543
protected function normalizeRowKeyCase(array $row, bool $multiple): array
537544
{
@@ -567,7 +574,10 @@ protected function resolveTableName(string $name): TableSchemaInterface
567574
*/
568575
protected function setTableMetadata(string $name, string $type, mixed $data): void
569576
{
570-
/** @psalm-suppress MixedArrayAssignment */
577+
/**
578+
* @psalm-suppress MixedArrayAssignment
579+
* @psalm-suppress DeprecatedMethod
580+
*/
571581
$this->tableMetadata[$this->getRawTableName($name)][$type] = $data;
572582
}
573583

src/Schema/Quoter.php

+26
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,27 @@ public function cleanUpTableNames(array $tableNames): array
8383
return $cleanedUpTableNames;
8484
}
8585

86+
/**
87+
* Returns the actual name of a given table name.
88+
*
89+
* This method will strip off curly brackets from the given table name and replace the percentage character '%' with
90+
* {@see ConnectionInterface::tablePrefix}.
91+
*
92+
* @param string $name The table name to convert.
93+
*
94+
* @return string The real name of the given table name.
95+
*/
96+
public function getRawTableName(string $name): string
97+
{
98+
if (str_contains($name, '{{')) {
99+
$name = preg_replace('/{{(.*?)}}/', '\1', $name);
100+
101+
return str_replace('%', $this->tablePrefix, $name);
102+
}
103+
104+
return $name;
105+
}
106+
86107
public function getTableNameParts(string $name, bool $withColumn = false): array
87108
{
88109
$parts = array_slice(explode('.', $name), -2, 2);
@@ -204,6 +225,11 @@ public function quoteValue(mixed $value): mixed
204225
return "'" . str_replace("'", "''", addcslashes($value, "\000\032")) . "'";
205226
}
206227

228+
public function setTablePrefix(string $value): void
229+
{
230+
$this->tablePrefix = $value;
231+
}
232+
207233
public function unquoteSimpleColumnName(string $name): string
208234
{
209235
if (is_string($this->columnQuoteCharacter)) {

src/Schema/SchemaInterface.php

+4
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ public function getDataType(mixed $data): int;
284284
* @param string $name The table name to convert.
285285
*
286286
* @return string The real name of the given table name.
287+
*
288+
* @deprecated Use {@see Quoter::getRawTableName()}. Will be removed in version 2.0.0.
287289
*/
288290
public function getRawTableName(string $name): string;
289291

@@ -367,6 +369,8 @@ public function getTableSchemas(string $schema = '', bool $refresh = false): arr
367369
* @param string $sql The SQL statement.
368370
*
369371
* @return bool Whether an SQL statement is for read purpose.
372+
*
373+
* @deprecated Use {@see DbStringHelper::isReadQuery()}. Will be removed in version 2.0.0.
370374
*/
371375
public function isReadQuery(string $sql): bool;
372376

tests/AbstractQuoterTest.php

+12
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ public function testEnsureNameQuoted(string $name, string $expected): void
3131
$this->assertSame($expected, $db->getQuoter()->ensureNameQuoted($name));
3232
}
3333

34+
/**
35+
* @dataProvider \Yiisoft\Db\Tests\Provider\QuoterProvider::rawTableNames
36+
*/
37+
public function testGetRawTableName(string $tableName, string $expected, string $tablePrefix = ''): void
38+
{
39+
$db = $this->getConnection();
40+
41+
$db->setTablePrefix($tablePrefix);
42+
43+
$this->assertSame($expected, $db->getQuoter()->getRawTableName($tableName));
44+
}
45+
3446
/**
3547
* @dataProvider \Yiisoft\Db\Tests\Provider\QuoterProvider::tableNameParts
3648
*/

tests/AbstractSchemaTest.php

-12
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,6 @@ public function testGetDataType(): void
7474
fclose($fp);
7575
}
7676

77-
public function testIsReadQuery(): void
78-
{
79-
$db = $this->getConnection();
80-
81-
$schema = $db->getSchema();
82-
83-
$this->assertTrue($schema->isReadQuery('SELECT * FROM tbl'));
84-
$this->assertTrue($schema->isReadQuery('SELECT * FROM tbl WHERE id=1'));
85-
$this->assertTrue($schema->isReadQuery('SELECT * FROM tbl WHERE id=1 LIMIT 1'));
86-
$this->assertTrue($schema->isReadQuery('SELECT * FROM tbl WHERE id=1 LIMIT 1 OFFSET 1'));
87-
}
88-
8977
public function testRefresh(): void
9078
{
9179
$db = $this->getConnection();

tests/Db/Helper/DbStringHelperTest.php

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ public function testBaseName(): void
1818
$this->assertSame('TestCase', DbStringHelper::baseName('TestCase'));
1919
}
2020

21+
public function testIsReadQuery(): void
22+
{
23+
$this->assertTrue(DbStringHelper::isReadQuery('SELECT * FROM tbl'));
24+
$this->assertTrue(DbStringHelper::isReadQuery('SELECT * FROM tbl WHERE id=1'));
25+
$this->assertTrue(DbStringHelper::isReadQuery('SELECT * FROM tbl WHERE id=1 LIMIT 1'));
26+
$this->assertTrue(DbStringHelper::isReadQuery('SELECT * FROM tbl WHERE id=1 LIMIT 1 OFFSET 1'));
27+
}
28+
2129
public static function pascalCaseToIdProvider(): array
2230
{
2331
return [

tests/Provider/QuoterProvider.php

+16
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ public static function simpleTableNames(): array
7575
];
7676
}
7777

78+
/**
79+
* @return string[][]
80+
*/
81+
public static function rawTableNames(): array
82+
{
83+
return [
84+
['table', 'table'],
85+
['"table"', '"table"'],
86+
['public.table', 'public.table'],
87+
['{{table}}', 'table'],
88+
['{{public}}.{{table}}', 'public.table'],
89+
['{{%table}}', 'yii_table', 'yii_'],
90+
['{{public}}.{{%table}}', 'public.yii_table', 'yii_'],
91+
];
92+
}
93+
7894
/**
7995
* @return string[][]
8096
*/

0 commit comments

Comments
 (0)