0 follower

Final Class Yiisoft\Db\Sqlite\Schema

InheritanceYiisoft\Db\Sqlite\Schema » Yiisoft\Db\Driver\Pdo\AbstractPdoSchema

Implements the SQLite Server specific schema, supporting SQLite 3.3.0 or higher.

Public Methods

Hide inherited methods

Method Description Defined By
getSchemaDefaultValues() Yiisoft\Db\Sqlite\Schema

Method Details

Hide inherited methods

findColumns() protected method

Collects the table column metadata.

protected boolean findColumns ( \Yiisoft\Db\Schema\TableSchemaInterface $table )
$table \Yiisoft\Db\Schema\TableSchemaInterface

The table metadata.

return boolean

Whether the table exists in the database.

                protected function findColumns(TableSchemaInterface $table): bool
{
    $tableName = $table->getName();
    $columns = $this->loadTableColumnsInfo($tableName);
    $jsonColumns = $this->getJsonColumns($table);
    $checks = $this->getTableChecks($tableName);
    foreach ($columns as $info) {
        if (in_array($info['name'], $jsonColumns, true)) {
            $info['type'] = ColumnType::JSON;
        }
        $info['schema'] = $table->getSchemaName();
        $info['table'] = $tableName;
        $column = $this->loadColumn($info, $checks);
        $table->column($info['name'], $column);
    }
    $column = count($table->getPrimaryKey()) === 1 ? $table->getColumn($table->getPrimaryKey()[0]) : null;
    if ($column !== null && !strncasecmp($column->getDbType() ?? '', 'int', 3)) {
        $table->sequenceName('');
        $column->autoIncrement();
    }
    return !empty($columns);
}

            
findConstraints() protected method

protected void findConstraints ( \Yiisoft\Db\Schema\TableSchemaInterface $table )
$table \Yiisoft\Db\Schema\TableSchemaInterface

                protected function findConstraints(TableSchemaInterface $table): void
{
    $tableName = $this->resolveFullName($table->getName(), $table->getSchemaName());
    $table->checks(...$this->getTableMetadata($tableName, SchemaInterface::CHECKS));
    $table->foreignKeys(...$this->getTableMetadata($tableName, SchemaInterface::FOREIGN_KEYS));
    $table->indexes(...$this->getTableMetadata($tableName, SchemaInterface::INDEXES));
}

            
findTableNames() protected method

protected array findTableNames ( string $schema '' )
$schema string

                protected function findTableNames(string $schema = ''): array
{
    /** @var string[] */
    return $this->db->createCommand(
        "SELECT DISTINCT tbl_name FROM sqlite_master WHERE tbl_name<>'sqlite_sequence' ORDER BY tbl_name",
    )->queryColumn();
}

            
findViewNames() protected method

protected array findViewNames ( string $schema '' )
$schema string

                protected function findViewNames(string $schema = ''): array
{
    /** @var string[] */
    return $this->db->createCommand(
        <<<SQL
        SELECT name FROM sqlite_master WHERE type = 'view' AND name NOT LIKE 'sqlite_%'
        SQL,
    )->queryColumn();
}

            
getSchemaDefaultValues() public method

public array getSchemaDefaultValues ( string $schema '', boolean $refresh false )
$schema string
$refresh boolean
throws \Yiisoft\Db\Exception\NotSupportedException

                public function getSchemaDefaultValues(string $schema = '', bool $refresh = false): array
{
    throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.');
}

            
loadResultColumn() protected method

protected ?\Yiisoft\Db\Schema\Column\ColumnInterface loadResultColumn ( array $metadata )
$metadata array

                protected function loadResultColumn(array $metadata): ?ColumnInterface
{
    if (empty($metadata['sqlite:decl_type']) && (empty($metadata['native_type']) || $metadata['native_type'] === 'null')) {
        return null;
    }
    $dbType = $metadata['sqlite:decl_type'] ?? $metadata['native_type'];
    $columnInfo = ['source' => ColumnInfoSource::QUERY_RESULT];
    if (!empty($metadata['table'])) {
        $columnInfo['table'] = $metadata['table'];
        $columnInfo['name'] = $metadata['name'];
    } elseif (!empty($metadata['name'])) {
        $columnInfo['name'] = $metadata['name'];
    }
    return $this->db->getColumnFactory()->fromDefinition($dbType, $columnInfo);
}

            
loadTableChecks() protected method

protected array loadTableChecks ( string $tableName )
$tableName string

                protected function loadTableChecks(string $tableName): array
{
    $sql = $this->db->createCommand(
        'SELECT "sql" FROM "sqlite_master" WHERE name = :tableName',
        [':tableName' => $tableName],
    )->queryScalar();
    $sql = ($sql === false || $sql === null) ? '' : (string) $sql;
    $code = (new SqlTokenizer($sql))->tokenize();
    $pattern = (new SqlTokenizer('any CREATE any TABLE any()'))->tokenize();
    $result = [];
    if ($code[0] instanceof SqlToken && $code[0]->matches($pattern, 0, $firstMatchIndex, $lastMatchIndex)) {
        $offset = 0;
        $createTableToken = $code[0][(int) $lastMatchIndex - 1];
        $sqlTokenizerAnyCheck = new SqlTokenizer('any CHECK()');
        while (
            $createTableToken instanceof SqlToken
            && $createTableToken->matches($sqlTokenizerAnyCheck->tokenize(), (int) $offset, $firstMatchIndex, $offset)
        ) {
            $name = '';
            $checkSql = (string) $createTableToken[(int) $offset - 1];
            $pattern = (new SqlTokenizer('CONSTRAINT any'))->tokenize();
            if (
                isset($createTableToken[(int) $firstMatchIndex - 2])
                && $createTableToken->matches($pattern, (int) $firstMatchIndex - 2)
            ) {
                $sqlToken = $createTableToken[(int) $firstMatchIndex - 1];
                $name = $sqlToken?->getContent() ?? '';
            }
            $result[] = new Check($name, expression: $checkSql);
        }
    }
    return $result;
}

            
loadTableDefaultValues() protected method

protected array loadTableDefaultValues ( string $tableName )
$tableName string

                protected function loadTableDefaultValues(string $tableName): array
{
    throw new NotSupportedException('SQLite does not support default value constraints.');
}

            
loadTableForeignKeys() protected method

protected array loadTableForeignKeys ( string $tableName )
$tableName string

                protected function loadTableForeignKeys(string $tableName): array
{
    $result = [];
    $foreignKeysList = $this->getPragmaForeignKeyList($tableName);
    /** @psalm-var GroupedForeignKeyInfo $foreignKeysList */
    $foreignKeysList = DbArrayHelper::arrange($foreignKeysList, ['table', 'id']);
    foreach ($foreignKeysList as $table => $foreignKeysById) {
        /**
         * @psalm-var GroupedForeignKeyInfo $foreignKeysById
         * @psalm-var int $id
         */
        foreach ($foreignKeysById as $id => $foreignKey) {
            if ($foreignKey[0]['to'] === null) {
                /** @var Index $primaryKey */
                $primaryKey = $this->getTablePrimaryKey($table);
                $foreignColumnNames = $primaryKey->columnNames;
            } else {
                /** @var string[] $foreignColumnNames */
                $foreignColumnNames = array_column($foreignKey, 'to');
            }
            $result[] = new ForeignKey(
                (string) $id,
                array_column($foreignKey, 'from'),
                '',
                $table,
                $foreignColumnNames,
                $foreignKey[0]['on_delete'],
                $foreignKey[0]['on_update'],
            );
        }
    }
    return $result;
}

            
loadTableIndexes() protected method

protected array loadTableIndexes ( string $tableName )
$tableName string

                protected function loadTableIndexes(string $tableName): array
{
    $indexList = $this->db
        ->createCommand('PRAGMA INDEX_LIST(' . $this->db->getQuoter()->quoteValue($tableName) . ')')
        ->queryAll();
    /** @psalm-var IndexListInfo[] $indexes */
    $indexes = array_map(array_change_key_case(...), $indexList);
    $result = [];
    $hasPrimaryKey = false;
    foreach ($indexes as $index) {
        $columns = $this->getPragmaIndexInfo($index['name']);
        $result[$index['name']] = new Index(
            $index['name'],
            array_column($columns, 'name'),
            (bool) $index['unique'],
            $index['origin'] === 'pk',
        );
        $hasPrimaryKey = $hasPrimaryKey || $index['origin'] === 'pk';
    }
    if (!$hasPrimaryKey) {
        /**
         * Extra check for PK in case of `INTEGER PRIMARY KEY` with ROWID.
         *
         * @link https://www.sqlite.org/lang_createtable.html#primkeyconst
         */
        $tableColumns = $this->loadTableColumnsInfo($tableName);
        foreach ($tableColumns as $tableColumn) {
            if ($tableColumn['pk'] > 0) {
                $result[''] = new Index('', [$tableColumn['name']], true, true);
                break;
            }
        }
    }
    return $result;
}

            
loadTableSchema() protected method

protected ?\Yiisoft\Db\Schema\TableSchemaInterface loadTableSchema ( string $name )
$name string

                protected function loadTableSchema(string $name): ?TableSchemaInterface
{
    $table = new TableSchema($name);
    if ($this->findColumns($table)) {
        $this->findConstraints($table);
        return $table;
    }
    return null;
}