Issues (43)

src/Schema/AbstractSchema.php (6 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Schema;
6
7
use Psr\SimpleCache\InvalidArgumentException;
8
use Throwable;
9
use Yiisoft\Db\Cache\SchemaCache;
10
use Yiisoft\Db\Command\DataType;
11
use Yiisoft\Db\Connection\ConnectionInterface;
12
use Yiisoft\Db\Constraint\Constraint;
13
use Yiisoft\Db\Constraint\IndexConstraint;
14
use Yiisoft\Db\Exception\NotSupportedException;
15
16
use function array_change_key_case;
17
use function array_map;
18
use function gettype;
19
use function is_array;
20
use function preg_match;
21
use function preg_replace;
22
use function str_contains;
23
use function str_replace;
24
25
/**
26
 * Provides a set of methods for working with database schemas such as creating, modifying, and inspecting tables,
27
 * columns, and other database objects.
28
 *
29
 * It's a powerful and flexible tool that allows you to perform a wide range of database operations in a
30
 * database-agnostic way.
31
 */
32
abstract class AbstractSchema implements SchemaInterface
33
{
34
    /**
35
     * Schema cache version, to detect incompatibilities in cached values when the data format of the cache changes.
36
     */
37
    protected const SCHEMA_CACHE_VERSION = 1;
38
    protected const CACHE_VERSION = 'cacheVersion';
39
    /**
40
     * @var string|null $defaultSchema The default schema name used for the current session.
41
     */
42
    protected string|null $defaultSchema = null;
43
    protected array $viewNames = [];
44
    private array $schemaNames = [];
45
    /** @psalm-var string[]|array */
46
    private array $tableNames = [];
47
    private array $tableMetadata = [];
48
49
    public function __construct(protected ConnectionInterface $db, private SchemaCache $schemaCache)
50
    {
51
    }
52
53
    /**
54
     * @param string $name The table name.
55
     *
56
     * @return array The cache key for the specified table name.
57
     */
58
    abstract protected function getCacheKey(string $name): array;
59
60
    /**
61
     * @return string The cache tag name.
62
     *
63
     * This allows {@see refresh()} to invalidate all cached table schemas.
64
     */
65
    abstract protected function getCacheTag(): string;
66
67
    /**
68
     * Loads all check constraints for the given table.
69
     *
70
     * @param string $tableName The table name.
71
     *
72
     * @return array The check constraints for the given table.
73
     */
74
    abstract protected function loadTableChecks(string $tableName): array;
75
76
    /**
77
     * Loads all default value constraints for the given table.
78
     *
79
     * @param string $tableName The table name.
80
     *
81
     * @return array The default value constraints for the given table.
82
     */
83
    abstract protected function loadTableDefaultValues(string $tableName): array;
84
85
    /**
86
     * Loads all foreign keys for the given table.
87
     *
88
     * @param string $tableName The table name.
89
     *
90
     * @return array The foreign keys for the given table.
91
     */
92
    abstract protected function loadTableForeignKeys(string $tableName): array;
93
94
    /**
95
     * Loads all indexes for the given table.
96
     *
97
     * @param string $tableName The table name.
98
     *
99
     * @return IndexConstraint[] The indexes for the given table.
100
     */
101
    abstract protected function loadTableIndexes(string $tableName): array;
102
103
    /**
104
     * Loads a primary key for the given table.
105
     *
106
     * @param string $tableName The table name.
107
     *
108
     * @return Constraint|null The primary key for the given table. `null` if the table has no primary key.
109
     */
110
    abstract protected function loadTablePrimaryKey(string $tableName): Constraint|null;
111
112
    /**
113
     * Loads all unique constraints for the given table.
114
     *
115
     * @param string $tableName The table name.
116
     *
117
     * @return array The unique constraints for the given table.
118
     */
119
    abstract protected function loadTableUniques(string $tableName): array;
120
121
    /**
122
     * Loads the metadata for the specified table.
123
     *
124
     * @param string $name The table name.
125
     *
126
     * @return TableSchemaInterface|null DBMS-dependent table metadata, `null` if the table doesn't exist.
127
     */
128
    abstract protected function loadTableSchema(string $name): TableSchemaInterface|null;
129
130
    public function getDefaultSchema(): string|null
131
    {
132
        return $this->defaultSchema;
133
    }
134
135
    public function getDataType(mixed $data): int
136
    {
137
        return match (gettype($data)) {
138
            // php type => SQL data type
139
            SchemaInterface::PHP_TYPE_BOOLEAN => DataType::BOOLEAN,
140
            SchemaInterface::PHP_TYPE_INTEGER => DataType::INTEGER,
141
            SchemaInterface::PHP_TYPE_RESOURCE => DataType::LOB,
142
            SchemaInterface::PHP_TYPE_NULL => DataType::NULL,
143
            default => DataType::STRING,
144
        };
145
    }
146
147
    /** @deprecated Use {@see Quoter::getRawTableName()}. Will be removed in version 2.0.0. */
148
    public function getRawTableName(string $name): string
149
    {
150
        if (str_contains($name, '{{')) {
151
            $name = preg_replace('/{{(.*?)}}/', '\1', $name);
152
153
            return str_replace('%', $this->db->getTablePrefix(), $name);
154
        }
155
156
        return $name;
157
    }
158
159
    /**
160
     * @throws InvalidArgumentException
161
     * @throws NotSupportedException
162
     */
163
    public function getSchemaChecks(string $schema = '', bool $refresh = false): array
164
    {
165
        return $this->getSchemaMetadata($schema, SchemaInterface::CHECKS, $refresh);
166
    }
167
168
    /**
169
     * @throws InvalidArgumentException
170
     * @throws NotSupportedException
171
     */
172
    public function getSchemaDefaultValues(string $schema = '', bool $refresh = false): array
173
    {
174
        return $this->getSchemaMetadata($schema, SchemaInterface::DEFAULT_VALUES, $refresh);
175
    }
176
177
    /**
178
     * @throws InvalidArgumentException
179
     * @throws NotSupportedException
180
     */
181
    public function getSchemaForeignKeys(string $schema = '', bool $refresh = false): array
182
    {
183
        return $this->getSchemaMetadata($schema, SchemaInterface::FOREIGN_KEYS, $refresh);
184
    }
185
186
    /**
187
     * @throws InvalidArgumentException
188
     * @throws NotSupportedException
189
     */
190
    public function getSchemaIndexes(string $schema = '', bool $refresh = false): array
191
    {
192
        return $this->getSchemaMetadata($schema, SchemaInterface::INDEXES, $refresh);
193
    }
194
195
    /**
196
     * @throws NotSupportedException If this method isn't supported by the underlying DBMS.
197
     */
198
    public function getSchemaNames(bool $refresh = false): array
199
    {
200
        if (empty($this->schemaNames) || $refresh) {
201
            $this->schemaNames = $this->findSchemaNames();
202
        }
203
204
        return $this->schemaNames;
205
    }
206
207
    /**
208
     * @throws InvalidArgumentException
209
     * @throws NotSupportedException
210
     */
211
    public function getSchemaPrimaryKeys(string $schema = '', bool $refresh = false): array
212
    {
213
        /** @psalm-var list<Constraint> */
214
        return $this->getSchemaMetadata($schema, SchemaInterface::PRIMARY_KEY, $refresh);
215
    }
216
217
    /**
218
     * @throws NotSupportedException
219
     * @throws InvalidArgumentException
220
     */
221
    public function getSchemaUniques(string $schema = '', bool $refresh = false): array
222
    {
223
        return $this->getSchemaMetadata($schema, SchemaInterface::UNIQUES, $refresh);
224
    }
225
226
    /**
227
     * @throws InvalidArgumentException
228
     */
229
    public function getTableChecks(string $name, bool $refresh = false): array
230
    {
231
        /** @psalm-var mixed $tableChecks */
232
        $tableChecks = $this->getTableMetadata($name, SchemaInterface::CHECKS, $refresh);
233
        return is_array($tableChecks) ? $tableChecks : [];
234
    }
235
236
    /**
237
     * @throws InvalidArgumentException
238
     */
239
    public function getTableDefaultValues(string $name, bool $refresh = false): array
240
    {
241
        /** @psalm-var mixed $tableDefaultValues */
242
        $tableDefaultValues = $this->getTableMetadata($name, SchemaInterface::DEFAULT_VALUES, $refresh);
243
        return is_array($tableDefaultValues) ? $tableDefaultValues : [];
244
    }
245
246
    /**
247
     * @throws InvalidArgumentException
248
     */
249
    public function getTableForeignKeys(string $name, bool $refresh = false): array
250
    {
251
        /** @psalm-var mixed $tableForeignKeys */
252
        $tableForeignKeys = $this->getTableMetadata($name, SchemaInterface::FOREIGN_KEYS, $refresh);
253
        return is_array($tableForeignKeys) ? $tableForeignKeys : [];
254
    }
255
256
    /**
257
     * @throws InvalidArgumentException
258
     */
259
    public function getTableIndexes(string $name, bool $refresh = false): array
260
    {
261
        /** @var IndexConstraint[] */
262
        return $this->getTableMetadata($name, SchemaInterface::INDEXES, $refresh);
263
    }
264
265
    /**
266
     * @throws NotSupportedException If this method isn't supported by the underlying DBMS.
267
     */
268
    public function getTableNames(string $schema = '', bool $refresh = false): array
269
    {
270
        if (!isset($this->tableNames[$schema]) || $refresh) {
271
            $this->tableNames[$schema] = $this->findTableNames($schema);
272
        }
273
274
        return is_array($this->tableNames[$schema]) ? $this->tableNames[$schema] : [];
275
    }
276
277
    /**
278
     * @throws InvalidArgumentException
279
     */
280
    public function getTablePrimaryKey(string $name, bool $refresh = false): Constraint|null
281
    {
282
        /** @psalm-var mixed $tablePrimaryKey */
283
        $tablePrimaryKey = $this->getTableMetadata($name, SchemaInterface::PRIMARY_KEY, $refresh);
284
        return $tablePrimaryKey instanceof Constraint ? $tablePrimaryKey : null;
285
    }
286
287
    /**
288
     * @throws InvalidArgumentException
289
     */
290
    public function getTableSchema(string $name, bool $refresh = false): TableSchemaInterface|null
291
    {
292
        /** @psalm-var mixed $tableSchema */
293
        $tableSchema = $this->getTableMetadata($name, SchemaInterface::SCHEMA, $refresh);
294
        return $tableSchema instanceof TableSchemaInterface ? $tableSchema : null;
295
    }
296
297
    /**
298
     * @throws NotSupportedException
299
     * @throws InvalidArgumentException
300
     */
301
    public function getTableSchemas(string $schema = '', bool $refresh = false): array
302
    {
303
        /** @psalm-var list<TableSchemaInterface> */
304
        return $this->getSchemaMetadata($schema, SchemaInterface::SCHEMA, $refresh);
305
    }
306
307
    /**
308
     * @throws InvalidArgumentException
309
     *
310
     * @return array The metadata for table unique constraints.
311
     */
312
    public function getTableUniques(string $name, bool $refresh = false): array
313
    {
314
        /** @psalm-var mixed $tableUniques */
315
        $tableUniques = $this->getTableMetadata($name, SchemaInterface::UNIQUES, $refresh);
316
        return is_array($tableUniques) ? $tableUniques : [];
317
    }
318
319
    /** @deprecated Use {@see DbStringHelper::isReadQuery()}. Will be removed in version 2.0.0. */
320
    public function isReadQuery(string $sql): bool
321
    {
322
        $pattern = '/^\s*(SELECT|SHOW|DESCRIBE)\b/i';
323
324
        return preg_match($pattern, $sql) > 0;
325
    }
326
327
    /**
328
     * @throws InvalidArgumentException
329
     */
330
    public function refresh(): void
331
    {
332
        if ($this->schemaCache->isEnabled()) {
333
            $this->schemaCache->invalidate($this->getCacheTag());
334
        }
335
336
        $this->tableNames = [];
337
        $this->tableMetadata = [];
338
    }
339
340
    /**
341
     * @throws InvalidArgumentException
342
     */
343
    public function refreshTableSchema(string $name): void
344
    {
345
        /** @psalm-suppress DeprecatedMethod */
346
        $rawName = $this->getRawTableName($name);
0 ignored issues
show
Deprecated Code introduced by
The function Yiisoft\Db\Schema\Abstra...hema::getRawTableName() has been deprecated: Use {@see Quoter::getRawTableName()}. Will be removed in version 2.0.0. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

346
        $rawName = /** @scrutinizer ignore-deprecated */ $this->getRawTableName($name);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
347
348
        unset($this->tableMetadata[$rawName]);
349
350
        $this->tableNames = [];
351
352
        if ($this->schemaCache->isEnabled()) {
353
            $this->schemaCache->remove($this->getCacheKey($rawName));
354
        }
355
    }
356
357
    public function enableCache(bool $value): void
358
    {
359
        $this->schemaCache->setEnabled($value);
360
    }
361
362
    /**
363
     * Returns all schema names in the database, including the default one but not system schemas.
364
     *
365
     * This method should be overridden by child classes to support this feature because the default
366
     * implementation simply throws an exception.
367
     *
368
     * @throws NotSupportedException If the DBMS doesn't support this method.
369
     *
370
     * @return array All schemas name in the database, except system schemas.
371
     */
372
    protected function findSchemaNames(): array
373
    {
374
        throw new NotSupportedException(static::class . ' does not support fetching all schema names.');
375
    }
376
377
    /**
378
     * Returns all table names in the database.
379
     *
380
     * This method should be overridden by child classes to support this feature because the default
381
     * implementation simply throws an exception.
382
     *
383
     * @param string $schema The schema of the tables. Defaults to empty string, meaning the current or default schema.
384
     *
385
     * @throws NotSupportedException If the DBMS doesn't support this method.
386
     *
387
     * @return array All tables name in the database. The names have NO schema name prefix.
388
     */
389
    protected function findTableNames(string $schema): array
0 ignored issues
show
The parameter $schema is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

389
    protected function findTableNames(/** @scrutinizer ignore-unused */ string $schema): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
390
    {
391
        throw new NotSupportedException(static::class . ' does not support fetching all table names.');
392
    }
393
394
    /**
395
     * Extracts the PHP type from an abstract DB type.
396
     *
397
     * @param ColumnSchemaInterface $column The column schema information.
398
     *
399
     * @return string The PHP type name.
400
     */
401
    protected function getColumnPhpType(ColumnSchemaInterface $column): string
402
    {
403
        return match ($column->getType()) {
404
            // abstract type => php type
405
            SchemaInterface::TYPE_TINYINT => SchemaInterface::PHP_TYPE_INTEGER,
406
            SchemaInterface::TYPE_SMALLINT => SchemaInterface::PHP_TYPE_INTEGER,
407
            SchemaInterface::TYPE_INTEGER => PHP_INT_SIZE === 4 && $column->isUnsigned()
408
                ? SchemaInterface::PHP_TYPE_STRING
409
                : SchemaInterface::PHP_TYPE_INTEGER,
410
            SchemaInterface::TYPE_BIGINT => PHP_INT_SIZE === 8 && !$column->isUnsigned()
411
                ? SchemaInterface::PHP_TYPE_INTEGER
412
                : SchemaInterface::PHP_TYPE_STRING,
413
            SchemaInterface::TYPE_BOOLEAN => SchemaInterface::PHP_TYPE_BOOLEAN,
414
            SchemaInterface::TYPE_DECIMAL => SchemaInterface::PHP_TYPE_DOUBLE,
415
            SchemaInterface::TYPE_FLOAT => SchemaInterface::PHP_TYPE_DOUBLE,
416
            SchemaInterface::TYPE_DOUBLE => SchemaInterface::PHP_TYPE_DOUBLE,
417
            SchemaInterface::TYPE_BINARY => SchemaInterface::PHP_TYPE_RESOURCE,
418
            SchemaInterface::TYPE_JSON => SchemaInterface::PHP_TYPE_ARRAY,
419
            default => SchemaInterface::PHP_TYPE_STRING,
420
        };
421
    }
422
423
    /**
424
     * Returns the metadata of the given type for all tables in the given schema.
425
     *
426
     * @param string $schema The schema of the metadata. Defaults to empty string, meaning the current or default schema
427
     * name.
428
     * @param string $type The metadata type.
429
     * @param bool $refresh Whether to fetch the latest available table metadata. If this is `false`, cached data may be
430
     * returned if available.
431
     *
432
     * @throws InvalidArgumentException
433
     * @throws NotSupportedException
434
     *
435
     * @return array The metadata of the given type for all tables in the given schema.
436
     *
437
     * @psalm-return list<Constraint|TableSchemaInterface|array>
438
     */
439
    protected function getSchemaMetadata(string $schema, string $type, bool $refresh): array
440
    {
441
        $metadata = [];
442
        /** @psalm-var string[] $tableNames */
443
        $tableNames = $this->getTableNames($schema, $refresh);
444
445
        foreach ($tableNames as $name) {
446
            $name = $this->db->getQuoter()->quoteSimpleTableName($name);
447
448
            if ($schema !== '') {
449
                $name = $schema . '.' . $name;
450
            }
451
452
            $tableMetadata = $this->getTableTypeMetadata($type, $name, $refresh);
453
454
            if ($tableMetadata !== null) {
455
                $metadata[] = $tableMetadata;
456
            }
457
        }
458
459
        return $metadata;
460
    }
461
462
    /**
463
     * Returns the metadata of the given type for the given table.
464
     *
465
     * @param string $name The table name. The table name may contain a schema name if any.
466
     * Don't quote the table name.
467
     * @param string $type The metadata type.
468
     * @param bool $refresh whether to reload the table metadata even if it's found in the cache.
469
     *
470
     * @throws InvalidArgumentException
471
     *
472
     * @return mixed The metadata of the given type for the given table.
473
     */
474
    protected function getTableMetadata(string $name, string $type, bool $refresh = false): mixed
475
    {
476
        /** @psalm-suppress DeprecatedMethod */
477
        $rawName = $this->getRawTableName($name);
0 ignored issues
show
Deprecated Code introduced by
The function Yiisoft\Db\Schema\Abstra...hema::getRawTableName() has been deprecated: Use {@see Quoter::getRawTableName()}. Will be removed in version 2.0.0. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

477
        $rawName = /** @scrutinizer ignore-deprecated */ $this->getRawTableName($name);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
478
479
        if (!isset($this->tableMetadata[$rawName])) {
480
            $this->loadTableMetadataFromCache($rawName);
481
        }
482
483
        if ($refresh || !isset($this->tableMetadata[$rawName][$type])) {
484
            /** @psalm-suppress MixedArrayAssignment */
485
            $this->tableMetadata[$rawName][$type] = $this->loadTableTypeMetadata($type, $rawName);
486
            $this->saveTableMetadataToCache($rawName);
487
        }
488
489
        /** @psalm-suppress MixedArrayAccess */
490
        return $this->tableMetadata[$rawName][$type];
491
    }
492
493
    /**
494
     * This method returns the desired metadata type for the table name.
495
     */
496
    protected function loadTableTypeMetadata(string $type, string $name): Constraint|array|TableSchemaInterface|null
497
    {
498
        return match ($type) {
499
            SchemaInterface::SCHEMA => $this->loadTableSchema($name),
500
            SchemaInterface::PRIMARY_KEY => $this->loadTablePrimaryKey($name),
501
            SchemaInterface::UNIQUES => $this->loadTableUniques($name),
502
            SchemaInterface::FOREIGN_KEYS => $this->loadTableForeignKeys($name),
503
            SchemaInterface::INDEXES => $this->loadTableIndexes($name),
504
            SchemaInterface::DEFAULT_VALUES => $this->loadTableDefaultValues($name),
505
            SchemaInterface::CHECKS => $this->loadTableChecks($name),
506
            default => null,
507
        };
508
    }
509
510
    /**
511
     * This method returns the desired metadata type for table name (with refresh if needed).
512
     *
513
     * @throws InvalidArgumentException
514
     */
515
    protected function getTableTypeMetadata(
516
        string $type,
517
        string $name,
518
        bool $refresh = false
519
    ): Constraint|array|null|TableSchemaInterface {
520
        return match ($type) {
521
            SchemaInterface::SCHEMA => $this->getTableSchema($name, $refresh),
522
            SchemaInterface::PRIMARY_KEY => $this->getTablePrimaryKey($name, $refresh),
523
            SchemaInterface::UNIQUES => $this->getTableUniques($name, $refresh),
524
            SchemaInterface::FOREIGN_KEYS => $this->getTableForeignKeys($name, $refresh),
525
            SchemaInterface::INDEXES => $this->getTableIndexes($name, $refresh),
526
            SchemaInterface::DEFAULT_VALUES => $this->getTableDefaultValues($name, $refresh),
527
            SchemaInterface::CHECKS => $this->getTableChecks($name, $refresh),
528
            default => null,
529
        };
530
    }
531
532
    /**
533
     * Change row's array key case to lower.
534
     *
535
     * @param array $row Thew row's array or an array of row arrays.
536
     * @param bool $multiple Whether many rows or a single row passed.
537
     *
538
     * @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.
542
     */
543
    protected function normalizeRowKeyCase(array $row, bool $multiple): array
544
    {
545
        if ($multiple) {
546
            return array_map(static fn (array $row) => array_change_key_case($row), $row);
547
        }
548
549
        return array_change_key_case($row);
550
    }
551
552
    /**
553
     * Resolves the table name and schema name (if any).
554
     *
555
     * @param string $name The table name.
556
     *
557
     * @throws NotSupportedException If the DBMS doesn't support this method.
558
     *
559
     * @return TableSchemaInterface The with resolved table, schema, etc. names.
560
     *
561
     * @see TableSchemaInterface
562
     */
563
    protected function resolveTableName(string $name): TableSchemaInterface
0 ignored issues
show
The parameter $name is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

563
    protected function resolveTableName(/** @scrutinizer ignore-unused */ string $name): TableSchemaInterface

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
564
    {
565
        throw new NotSupportedException(static::class . ' does not support resolving table names.');
566
    }
567
568
    /**
569
     * Sets the metadata of the given type for the given table.
570
     *
571
     * @param string $name The table name.
572
     * @param string $type The metadata type.
573
     * @param mixed $data The metadata to set.
574
     */
575
    protected function setTableMetadata(string $name, string $type, mixed $data): void
576
    {
577
        /**
578
         * @psalm-suppress MixedArrayAssignment
579
         * @psalm-suppress DeprecatedMethod
580
         */
581
        $this->tableMetadata[$this->getRawTableName($name)][$type] = $data;
0 ignored issues
show
Deprecated Code introduced by
The function Yiisoft\Db\Schema\Abstra...hema::getRawTableName() has been deprecated: Use {@see Quoter::getRawTableName()}. Will be removed in version 2.0.0. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

581
        $this->tableMetadata[/** @scrutinizer ignore-deprecated */ $this->getRawTableName($name)][$type] = $data;

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
582
    }
583
584
    /**
585
     * Tries to load and populate table metadata from cache.
586
     *
587
     * @throws InvalidArgumentException
588
     */
589
    private function loadTableMetadataFromCache(string $rawName): void
590
    {
591
        if (!$this->schemaCache->isEnabled() || $this->schemaCache->isExcluded($rawName)) {
592
            $this->tableMetadata[$rawName] = [];
593
            return;
594
        }
595
596
        $metadata = $this->schemaCache->get($this->getCacheKey($rawName));
597
598
        if (
599
            !is_array($metadata) ||
600
            !isset($metadata[self::CACHE_VERSION]) ||
601
            $metadata[self::CACHE_VERSION] !== static::SCHEMA_CACHE_VERSION
602
        ) {
603
            $this->tableMetadata[$rawName] = [];
604
            return;
605
        }
606
607
        unset($metadata[self::CACHE_VERSION]);
608
        $this->tableMetadata[$rawName] = $metadata;
609
    }
610
611
    /**
612
     * Saves table metadata to cache.
613
     *
614
     * @throws InvalidArgumentException
615
     */
616
    private function saveTableMetadataToCache(string $rawName): void
617
    {
618
        if ($this->schemaCache->isEnabled() === false || $this->schemaCache->isExcluded($rawName) === true) {
619
            return;
620
        }
621
622
        /** @psalm-var array<string, array<TableSchemaInterface|int>> $metadata */
623
        $metadata = $this->tableMetadata[$rawName];
624
        /** @psalm-var int */
625
        $metadata[self::CACHE_VERSION] = static::SCHEMA_CACHE_VERSION;
626
627
        $this->schemaCache->set($this->getCacheKey($rawName), $metadata, $this->getCacheTag());
628
    }
629
630
    /**
631
     * Find the view names for the database.
632
     *
633
     * @param string $schema The schema of the views.
634
     * Defaults to empty string, meaning the current or default schema.
635
     *
636
     * @return array The names of all views in the database.
637
     */
638
    protected function findViewNames(string $schema = ''): array
0 ignored issues
show
The parameter $schema is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

638
    protected function findViewNames(/** @scrutinizer ignore-unused */ string $schema = ''): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
639
    {
640
        return [];
641
    }
642
643
    /**
644
     * @throws Throwable
645
     *
646
     * @return array The view names for the database.
647
     */
648
    public function getViewNames(string $schema = '', bool $refresh = false): array
649
    {
650
        if (!isset($this->viewNames[$schema]) || $refresh) {
651
            $this->viewNames[$schema] = $this->findViewNames($schema);
652
        }
653
654
        return (array) $this->viewNames[$schema];
655
    }
656
}
657