Final Class Yiisoft\Db\Sqlite\Schema
| Inheritance | Yiisoft\Db\Sqlite\Schema » Yiisoft\Db\Driver\Pdo\AbstractPdoSchema |
|---|
Implements the SQLite Server specific schema, supporting SQLite 3.3.0 or higher.
Psalm Types
| Name | Value |
|---|---|
| ForeignKeyInfo | array{id: string, cid: string, seq: string, table: string, from: string, to: string|null, on_update: \Yiisoft\Db\Constant\ReferentialAction::*, on_delete: \Yiisoft\Db\Constant\ReferentialAction::*} |
| GroupedForeignKeyInfo | array<string, list<\Yiisoft\Db\Sqlite\ForeignKeyInfo>> |
| IndexInfo | array{seqno: string, cid: string, name: string} |
| IndexListInfo | array{seq: string, name: string, unique: string, origin: string, partial: string} |
| ColumnInfo | array{cid: string, name: string, type: string, notnull: string, dflt_value: string|null, pk: string, size?: integer, scale?: integer, schema: string|null, table: string} |
Public Methods
| Method | Description | Defined By |
|---|---|---|
| getSchemaDefaultValues() | Yiisoft\Db\Sqlite\Schema |
Protected Methods
Method Details
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);
}
| 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));
}
| 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();
}
| 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();
}
| 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.');
}
| protected \Yiisoft\Db\Schema\Column\ColumnInterface|null 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);
}
| 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;
}
| protected array loadTableDefaultValues ( string $tableName ) | ||
| $tableName | string | |
protected function loadTableDefaultValues(string $tableName): array
{
throw new NotSupportedException('SQLite does not support default value constraints.');
}
| 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;
}
| 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;
}
| protected \Yiisoft\Db\Schema\TableSchemaInterface|null 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;
}
Signup or Login in order to comment.