2121use Yiisoft \Db \Schema \ColumnSchema ;
2222use Yiisoft \Db \Schema \Schema as AbstractSchema ;
2323use Yiisoft \Db \Transaction \Transaction ;
24- use Yiisoft \Db \Transaction \TransactionInterface ;
2524
2625use function count ;
2726use function explode ;
2827use function preg_match ;
2928use function strncasecmp ;
30- use function strncmp ;
3129use function strpos ;
3230use function strtolower ;
3331use function trim ;
3634 * Schema is the class for retrieving metadata from a SQLite (2/3) database.
3735 *
3836 * @property string $transactionIsolationLevel The transaction isolation level to use for this transaction. This can be
39- * either {@see TransactionInterface ::READ_UNCOMMITTED} or {@see TransactionInterface ::SERIALIZABLE}.
37+ * either {@see Transaction ::READ_UNCOMMITTED} or {@see Transaction ::SERIALIZABLE}.
4038 */
4139final class Schema extends AbstractSchema implements ConstraintFinderInterface
4240{
@@ -112,7 +110,7 @@ protected function findTableNames(string $schema = ''): array
112110 *
113111 * @param string $name table name.
114112 *
115- * @throws Exception|InvalidArgumentException|InvalidConfigException
113+ * @throws Exception|InvalidArgumentException|InvalidConfigException|Throwable
116114 *
117115 * @return TableSchema|null DBMS-dependent table metadata, `null` if the table does not exist.
118116 */
@@ -137,7 +135,7 @@ protected function loadTableSchema(string $name): ?TableSchema
137135 *
138136 * @param string $tableName table name.
139137 *
140- * @throws Exception|InvalidArgumentException|InvalidConfigException
138+ * @throws Exception|InvalidArgumentException|InvalidConfigException|Throwable
141139 *
142140 * @return Constraint|null primary key for the given table, `null` if the table has no primary key.
143141 */
@@ -188,7 +186,7 @@ protected function loadTableForeignKeys(string $tableName): array
188186 *
189187 * @param string $tableName table name.
190188 *
191- * @throws Exception|InvalidArgumentException|InvalidConfigException
189+ * @throws Exception|InvalidArgumentException|InvalidConfigException|Throwable
192190 *
193191 * @return IndexConstraint[] indexes for the given table.
194192 */
@@ -202,7 +200,7 @@ protected function loadTableIndexes(string $tableName): array
202200 *
203201 * @param string $tableName table name.
204202 *
205- * @throws Exception|InvalidArgumentException|InvalidConfigException
203+ * @throws Exception|InvalidArgumentException|InvalidConfigException|Throwable
206204 *
207205 * @return Constraint[] unique constraints for the given table.
208206 */
@@ -471,7 +469,7 @@ protected function loadColumnSchema(array $info): ColumnSchema
471469 * Sets the isolation level of the current transaction.
472470 *
473471 * @param string $level The transaction isolation level to use for this transaction. This can be either
474- * {@see TransactionInterface ::READ_UNCOMMITTED} or {@see TransactionInterface ::SERIALIZABLE}.
472+ * {@see Transaction ::READ_UNCOMMITTED} or {@see Transaction ::SERIALIZABLE}.
475473 *
476474 * @throws Exception|InvalidConfigException|NotSupportedException|Throwable when unsupported isolation levels are
477475 * used. SQLite only supports SERIALIZABLE and READ UNCOMMITTED.
@@ -527,24 +525,10 @@ private function loadTableColumnsInfo(string $tableName): array
527525 private function loadTableConstraints (string $ tableName , string $ returnType )
528526 {
529527 $ tableColumns = null ;
530-
531- $ index = $ this ->getDb ()->createCommand (
528+ $ indexList = $ this ->getDb ()->createCommand (
532529 'PRAGMA INDEX_LIST ( ' . $ this ->quoteValue ($ tableName ) . ') '
533530 )->queryAll ();
534-
535- $ unique = $ this ->getDb ()->createCommand (
536- "SELECT
537- '0' as 'seq',
538- name,
539- '1' as 'unique',
540- 'u' as 'origin',
541- '0' as 'partial'
542- FROM sqlite_master
543- WHERE type='index' AND sql LIKE 'CREATE UNIQUE INDEX%' AND tbl_name=' $ tableName' "
544- )->queryAll ();
545-
546- $ indexes = array_merge ($ index , $ unique );
547- $ indexes = $ this ->normalizePdoRowKeyCase ($ indexes , true );
531+ $ indexes = $ this ->normalizePdoRowKeyCase ($ indexList , true );
548532
549533 if (!empty ($ indexes ) && !isset ($ indexes [0 ]['origin ' ])) {
550534 /**
@@ -562,22 +546,14 @@ private function loadTableConstraints(string $tableName, string $returnType)
562546 ];
563547
564548 foreach ($ indexes as $ index ) {
565- $ columns = $ this ->getDb ()->createCommand (
566- 'PRAGMA INDEX_INFO ( ' . $ this ->quoteValue ($ index ['name ' ]) . ') '
567- )->queryAll ();
568-
569- $ columns = $ this ->normalizePdoRowKeyCase ($ columns , true );
570-
571- ArraySorter::multisort ($ columns , 'seqno ' , SORT_ASC , SORT_NUMERIC );
549+ $ columns = $ this ->getPragmaIndexInfo ($ index ['name ' ]);
572550
573551 if ($ tableColumns !== null ) {
574552 /** SQLite may not have an "origin" column in INDEX_LIST */
575553 $ index ['origin ' ] = 'c ' ;
576554
577555 if (!empty ($ columns ) && $ tableColumns [$ columns [0 ]['cid ' ]]['pk ' ] > 0 ) {
578556 $ index ['origin ' ] = 'pk ' ;
579- } elseif ($ index ['unique ' ] && $ this ->isSystemIdentifier ($ index ['name ' ])) {
580- $ index ['origin ' ] = 'u ' ;
581557 }
582558 }
583559
@@ -589,17 +565,17 @@ private function loadTableConstraints(string $tableName, string $returnType)
589565
590566 $ result ['indexes ' ][] = $ ic ;
591567
592- if ($ index ['origin ' ] === 'u ' ) {
568+ if ($ index ['origin ' ] === 'pk ' ) {
593569 $ ct = (new Constraint ())
594- ->name ($ index ['name ' ])
595570 ->columnNames (ArrayHelper::getColumn ($ columns , 'name ' ));
596571
597- $ result ['uniques ' ][ ] = $ ct ;
598- } elseif ($ index ['origin ' ] === ' pk ' ) {
572+ $ result ['primaryKey ' ] = $ ct ;
573+ } elseif ($ index ['unique ' ] ) {
599574 $ ct = (new Constraint ())
575+ ->name ($ index ['name ' ])
600576 ->columnNames (ArrayHelper::getColumn ($ columns , 'name ' ));
601577
602- $ result ['primaryKey ' ] = $ ct ;
578+ $ result ['uniques ' ][ ] = $ ct ;
603579 }
604580 }
605581
@@ -632,20 +608,6 @@ private function loadTableConstraints(string $tableName, string $returnType)
632608 return $ result [$ returnType ];
633609 }
634610
635- /**
636- * Return whether the specified identifier is a SQLite system identifier.
637- *
638- * @param string $identifier
639- *
640- * @return bool
641- *
642- * {@see https://www.sqlite.org/src/artifact/74108007d286232f}
643- */
644- private function isSystemIdentifier (string $ identifier ): bool
645- {
646- return strncmp ($ identifier , 'sqlite_ ' , 7 ) === 0 ;
647- }
648-
649611 /**
650612 * Creates a column schema for the database.
651613 *
@@ -657,4 +619,16 @@ private function createColumnSchema(): ColumnSchema
657619 {
658620 return new ColumnSchema ();
659621 }
622+
623+ /**
624+ * @throws Exception|InvalidConfigException|Throwable
625+ */
626+ private function getPragmaIndexInfo (string $ name ): array
627+ {
628+ $ column = $ this ->getDb ()->createCommand ('PRAGMA INDEX_INFO ( ' . $ this ->quoteValue ($ name ) . ') ' )->queryAll ();
629+ $ columns = $ this ->normalizePdoRowKeyCase ($ column , true );
630+ ArraySorter::multisort ($ columns , 'seqno ' , SORT_ASC , SORT_NUMERIC );
631+
632+ return $ columns ;
633+ }
660634}
0 commit comments