From 5d048d2582d781306393521d0e470dee1d812374 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:23:51 +0300 Subject: [PATCH 01/24] Update yiisoft/cache-file requirement from ^2.0 to ^3.1 (#275) Updates the requirements on [yiisoft/cache-file](https://github.com/yiisoft/cache-file) to permit the latest version. - [Release notes](https://github.com/yiisoft/cache-file/releases) - [Changelog](https://github.com/yiisoft/cache-file/blob/master/CHANGELOG.md) - [Commits](https://github.com/yiisoft/cache-file/compare/2.0.0...3.1.0) --- updated-dependencies: - dependency-name: yiisoft/cache-file dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index faaac763..96db4428 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "spatie/phpunit-watcher": "^1.23", "vimeo/psalm": "^4.3|^5.6", "yiisoft/aliases": "^2.0", - "yiisoft/cache-file": "^2.0", + "yiisoft/cache-file": "^3.1", "yiisoft/json": "^1.0", "yiisoft/var-dumper": "^1.5" }, From 6bf147fa1c4fc639d76798694a0efb08b14a4cc5 Mon Sep 17 00:00:00 2001 From: Sergei Tigrov Date: Sat, 14 Oct 2023 14:54:10 +0700 Subject: [PATCH 02/24] Fix tests according to main PR (#274) --- tests/QueryBuilderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php index f7934429..0730ee64 100644 --- a/tests/QueryBuilderTest.php +++ b/tests/QueryBuilderTest.php @@ -286,7 +286,7 @@ public function testBuildWithQuery(): void $this->assertSame( << Date: Wed, 1 Nov 2023 10:37:14 +0700 Subject: [PATCH 03/24] Refactor DMLQueryBuilder (#271) * Refactor DMLQueryBuilder * Apply fixes from StyleCI * Add line to CHANGELOG.md * Remove `Generator` from tests --------- Co-authored-by: StyleCI Bot --- CHANGELOG.md | 1 + src/DMLQueryBuilder.php | 41 ++++++++----------------- tests/Provider/QueryBuilderProvider.php | 5 +++ tests/QueryBuilderTest.php | 3 +- 4 files changed, 19 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1545601..86f60ce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Enh #263: Support json type (@Tigrov) - Bug #268: Fix foreign keys: support multiple foreign keys referencing to one table and possible null columns for reference (@Tigrov) +- Bug #271: Refactor `DMLQueryBuilder`, related with yiisoft/db#746 (@Tigrov) ## 1.0.1 July 24, 2023 diff --git a/src/DMLQueryBuilder.php b/src/DMLQueryBuilder.php index a3ef422e..798697a0 100644 --- a/src/DMLQueryBuilder.php +++ b/src/DMLQueryBuilder.php @@ -8,13 +8,10 @@ use Yiisoft\Db\Exception\InvalidArgumentException; use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Expression\Expression; -use Yiisoft\Db\Expression\ExpressionInterface; use Yiisoft\Db\Query\QueryInterface; use Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder; use function implode; -use function ltrim; -use function reset; /** * Implements a DML (Data Manipulation Language) SQL statements for SQLite Server. @@ -45,8 +42,8 @@ public function resetSequence(string $table, int|string $value = null): string if ($value !== null) { $value = "'" . ((int) $value - 1) . "'"; } else { - $pk = $tableSchema->getPrimaryKey(); - $key = $this->quoter->quoteColumnName(reset($pk)); + $key = $tableSchema->getPrimaryKey()[0]; + $key = $this->quoter->quoteColumnName($key); $value = '(SELECT MAX(' . $key . ') FROM ' . $tableName . ')'; } @@ -62,11 +59,6 @@ public function upsert( /** @psalm-var Constraint[] $constraints */ $constraints = []; - /** - * @psalm-var string[] $insertNames - * @psalm-var string[] $updateNames - * @psalm-var array|bool $updateColumns - */ [$uniqueNames, $insertNames, $updateNames] = $this->prepareUpsertColumns( $table, $insertColumns, @@ -78,20 +70,19 @@ public function upsert( return $this->insert($table, $insertColumns, $params); } - /** @psalm-var string[] $placeholders */ [, $placeholders, $values, $params] = $this->prepareInsertValues($table, $insertColumns, $params); - $insertSql = 'INSERT OR IGNORE INTO ' - . $this->quoter->quoteTableName($table) + $quotedTableName = $this->quoter->quoteTableName($table); + + $insertSql = 'INSERT OR IGNORE INTO ' . $quotedTableName . (!empty($insertNames) ? ' (' . implode(', ', $insertNames) . ')' : '') - . (!empty($placeholders) ? ' VALUES (' . implode(', ', $placeholders) . ')' : "$values"); + . (!empty($placeholders) ? ' VALUES (' . implode(', ', $placeholders) . ')' : ' ' . $values); if ($updateColumns === false) { return $insertSql; } $updateCondition = ['or']; - $quotedTableName = $this->quoter->quoteTableName($table); foreach ($constraints as $constraint) { $constraintCondition = ['and']; @@ -106,13 +97,9 @@ public function upsert( if ($updateColumns === true) { $updateColumns = []; - foreach ($updateNames as $name) { - $quotedName = $this->quoter->quoteColumnName($name); - - if (strrpos($quotedName, '.') === false) { - $quotedName = "(SELECT $quotedName FROM `EXCLUDED`)"; - } - $updateColumns[$name] = new Expression($quotedName); + /** @psalm-var string[] $updateNames */ + foreach ($updateNames as $quotedName) { + $updateColumns[$quotedName] = new Expression("(SELECT $quotedName FROM `EXCLUDED`)"); } } @@ -120,13 +107,9 @@ public function upsert( return $insertSql; } - /** @psalm-var array $params */ - $updateSql = 'WITH "EXCLUDED" (' - . implode(', ', $insertNames) - . ') AS (' . (!empty($placeholders) - ? 'VALUES (' . implode(', ', $placeholders) . ')' - : ltrim("$values", ' ')) . ') ' . - $this->update($table, $updateColumns, $updateCondition, $params); + $updateSql = 'WITH "EXCLUDED" (' . implode(', ', $insertNames) . ') AS (' + . (!empty($placeholders) ? 'VALUES (' . implode(', ', $placeholders) . ')' : $values) + . ') ' . $this->update($table, $updateColumns, $updateCondition, $params); return "$updateSql; $insertSql;"; } diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 6761ba42..f4d4e5d2 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -176,6 +176,11 @@ public static function upsert(): array WITH "EXCLUDED" (`email`, `address`, `status`, `profile_id`) AS (VALUES (:qp0, :qp1, :qp2, :qp3)) UPDATE `T_upsert` SET `address`=(SELECT `address` FROM `EXCLUDED`), `status`=(SELECT `status` FROM `EXCLUDED`), `profile_id`=(SELECT `profile_id` FROM `EXCLUDED`) WHERE `T_upsert`.`email`=(SELECT `email` FROM `EXCLUDED`); INSERT OR IGNORE INTO `T_upsert` (`email`, `address`, `status`, `profile_id`) VALUES (:qp0, :qp1, :qp2, :qp3); SQL, ], + 'regular values with unique at not the first position' => [ + 3 => << [ 3 => << Date: Tue, 7 Nov 2023 17:47:50 +0700 Subject: [PATCH 04/24] Move methods from command to abstract pdo command (#278) * Move methods from `Command` to `AbstractPdoCommand` class --------- Co-authored-by: StyleCI Bot --- CHANGELOG.md | 1 + src/Command.php | 45 --------------------------------------------- 2 files changed, 1 insertion(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86f60ce1..a3343f60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Enh #263: Support json type (@Tigrov) - Bug #268: Fix foreign keys: support multiple foreign keys referencing to one table and possible null columns for reference (@Tigrov) - Bug #271: Refactor `DMLQueryBuilder`, related with yiisoft/db#746 (@Tigrov) +- Enh #278: Move methods from `Command` to `AbstractPdoCommand` class (@Tigrov) ## 1.0.1 July 24, 2023 diff --git a/src/Command.php b/src/Command.php index f73ca139..aa8176dc 100644 --- a/src/Command.php +++ b/src/Command.php @@ -4,13 +4,10 @@ namespace Yiisoft\Db\Sqlite; -use PDOException; use Throwable; use Yiisoft\Db\Driver\Pdo\AbstractPdoCommand; -use Yiisoft\Db\Exception\ConvertException; use Yiisoft\Db\Exception\Exception; use Yiisoft\Db\Exception\InvalidArgumentException; -use Yiisoft\Db\QueryBuilder\QueryBuilderInterface; use function array_pop; use function count; @@ -60,11 +57,6 @@ public function showDatabases(): array return $this->setSql($sql)->queryColumn(); } - protected function getQueryBuilder(): QueryBuilderInterface - { - return $this->db->getQueryBuilder(); - } - /** * Executes the SQL statement. * @@ -105,43 +97,6 @@ public function execute(): int return $result; } - /** - * @psalm-suppress UnusedClosureParam - * - * @throws Throwable - */ - protected function internalExecute(string|null $rawSql): void - { - $attempt = 0; - - while (true) { - try { - if ( - ++$attempt === 1 - && $this->isolationLevel !== null - && $this->db->getTransaction() === null - ) { - $this->db->transaction( - function () use ($rawSql): void { - $this->internalExecute($rawSql); - }, - $this->isolationLevel, - ); - } else { - $this->pdoStatement?->execute(); - } - break; - } catch (PDOException $e) { - $rawSql = $rawSql ?: $this->getRawSql(); - $e = (new ConvertException($e, $rawSql))->run(); - - if ($this->retryHandler === null || !($this->retryHandler)($e, $attempt)) { - throw $e; - } - } - } - } - /** * Performs the actual DB query of an SQL statement. * From bc5f00e7e238712128e7f65db1128c34c9417b49 Mon Sep 17 00:00:00 2001 From: Sergei Tigrov Date: Sun, 12 Nov 2023 14:47:46 +0700 Subject: [PATCH 05/24] Enable BC test (#279) --- .github/workflows/bc.yml | 23 +++++++++++++++++++++++ .github/workflows/bc.yml_ | 15 --------------- 2 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/bc.yml delete mode 100644 .github/workflows/bc.yml_ diff --git a/.github/workflows/bc.yml b/.github/workflows/bc.yml new file mode 100644 index 00000000..5970206c --- /dev/null +++ b/.github/workflows/bc.yml @@ -0,0 +1,23 @@ +on: + pull_request: + paths: + - 'src/**' + - '.github/workflows/bc.yml' + - 'composer.json' + push: + branches: ['master'] + paths: + - 'src/**' + - '.github/workflows/bc.yml' + - 'composer.json' + +name: backwards compatibility + +jobs: + roave_bc_check: + uses: yiisoft/actions/.github/workflows/bc.yml@master + with: + os: >- + ['ubuntu-latest'] + php: >- + ['8.1'] diff --git a/.github/workflows/bc.yml_ b/.github/workflows/bc.yml_ deleted file mode 100644 index 35b3a862..00000000 --- a/.github/workflows/bc.yml_ +++ /dev/null @@ -1,15 +0,0 @@ -on: - - pull_request - - push - -name: backwards compatibility -jobs: - roave_bc_check: - name: Roave BC Check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: fetch tags - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - - name: Roave BC Check - uses: docker://nyholm/roave-bc-check-ga From a8d37cb1f4c717a060b6b42c2709f7fadc1abe19 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sun, 12 Nov 2023 19:11:11 +0300 Subject: [PATCH 06/24] Raise `yiisoft/db` to `^1.2` (#280) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 96db4428..4b35c3e1 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "php": "^8.0", "ext-mbstring": "*", "ext-pdo": "*", - "yiisoft/db": "^1.0", + "yiisoft/db": "^1.2", "yiisoft/json": "^1.0" }, "require-dev": { From de04d852907b3cfe80679edb4453ec9a8182bafb Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sun, 12 Nov 2023 16:12:15 +0000 Subject: [PATCH 07/24] Release version 1.1.0 --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3343f60..fd5aabb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,11 @@ # SQLite driver for Yii Database Change Log -## 1.0.2 under development +## 1.1.0 November 12, 2023 - Enh #263: Support json type (@Tigrov) +- Enh #278: Move methods from `Command` to `AbstractPdoCommand` class (@Tigrov) - Bug #268: Fix foreign keys: support multiple foreign keys referencing to one table and possible null columns for reference (@Tigrov) - Bug #271: Refactor `DMLQueryBuilder`, related with yiisoft/db#746 (@Tigrov) -- Enh #278: Move methods from `Command` to `AbstractPdoCommand` class (@Tigrov) ## 1.0.1 July 24, 2023 From 8b652d16595295b6e558619ae3b23b959ad3d285 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sun, 12 Nov 2023 16:12:19 +0000 Subject: [PATCH 08/24] Prepare for next release --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd5aabb3..f92de014 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # SQLite driver for Yii Database Change Log +## 1.1.1 under development + +- no changes in this release. + ## 1.1.0 November 12, 2023 - Enh #263: Support json type (@Tigrov) From e3d9164f5b166dceba4540411f335436e3e5b3cc Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 15 Nov 2023 16:07:51 +0300 Subject: [PATCH 09/24] Remove unused code in `Command` class + Cleanup psalm annotations (#281) --- CHANGELOG.md | 2 +- src/AbstractTokenizer.php | 1 - src/Builder/JsonExpressionBuilder.php | 1 - src/Command.php | 18 ------------------ src/DMLQueryBuilder.php | 2 +- src/DQLQueryBuilder.php | 2 -- src/QueryBuilder.php | 4 +--- src/Schema.php | 23 +++++++++++------------ 8 files changed, 14 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f92de014..99610dd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.1.1 under development -- no changes in this release. +- Enh #281: Remove unused code in `Command` class (@vjik) ## 1.1.0 November 12, 2023 diff --git a/src/AbstractTokenizer.php b/src/AbstractTokenizer.php index 7febb90b..effa5a31 100644 --- a/src/AbstractTokenizer.php +++ b/src/AbstractTokenizer.php @@ -101,7 +101,6 @@ public function tokenize(): SqlToken $token[] = (new SqlToken())->type(SqlToken::TYPE_STATEMENT); $this->tokenStack->push($token[0]); - /** @psalm-var SqlToken */ $this->currentToken = $this->tokenStack->top(); $length = 0; diff --git a/src/Builder/JsonExpressionBuilder.php b/src/Builder/JsonExpressionBuilder.php index 73ef7c91..219d88e0 100644 --- a/src/Builder/JsonExpressionBuilder.php +++ b/src/Builder/JsonExpressionBuilder.php @@ -41,7 +41,6 @@ public function __construct(private QueryBuilderInterface $queryBuilder) */ public function build(ExpressionInterface $expression, array &$params = []): string { - /** @psalm-var mixed $value */ $value = $expression->getValue(); if ($value instanceof QueryInterface) { diff --git a/src/Command.php b/src/Command.php index aa8176dc..6996cd7f 100644 --- a/src/Command.php +++ b/src/Command.php @@ -41,7 +41,6 @@ public function insertWithReturningPks(string $table, array $columns): bool|arra continue; } - /** @psalm-var mixed */ $result[$name] = $columns[$name] ?? $tableSchema?->getColumn($name)?->getDefaultValue(); } @@ -72,7 +71,6 @@ public function execute(): int { $sql = $this->getSql(); - /** @psalm-var array $params */ $params = $this->params; $statements = $this->splitStatements($sql, $params); @@ -83,11 +81,8 @@ public function execute(): int $result = 0; - /** @psalm-var array> $statements */ foreach ($statements as $statement) { [$statementSql, $statementParams] = $statement; - $statementSql = is_string($statementSql) ? $statementSql : ''; - $statementParams = is_array($statementParams) ? $statementParams : []; $this->setSql($statementSql)->bindValues($statementParams); $result = parent::execute(); } @@ -111,7 +106,6 @@ protected function queryInternal(int $queryMode): mixed { $sql = $this->getSql(); - /** @psalm-var array $params */ $params = $this->params; $statements = $this->splitStatements($sql, $params); @@ -122,14 +116,7 @@ protected function queryInternal(int $queryMode): mixed [$lastStatementSql, $lastStatementParams] = array_pop($statements); - /** - * @psalm-var array $statements - */ foreach ($statements as $statement) { - /** - * @psalm-var string $statementSql - * @psalm-var array $statementParams - */ [$statementSql, $statementParams] = $statement; $this->setSql($statementSql)->bindValues($statementParams); parent::execute(); @@ -137,7 +124,6 @@ protected function queryInternal(int $queryMode): mixed $this->setSql($lastStatementSql)->bindValues($lastStatementParams); - /** @psalm-var string $result */ $result = parent::queryInternal($queryMode); $this->setSql($sql)->bindValues($params); @@ -155,8 +141,6 @@ protected function queryInternal(int $queryMode): mixed * * @return array|bool List of SQL statements or `false` if there's a single statement. * - * @psalm-param array $params - * * @psalm-return false|list */ private function splitStatements(string $sql, array $params): bool|array @@ -186,8 +170,6 @@ private function splitStatements(string $sql, array $params): bool|array /** * Returns named bindings used in the specified statement token. - * - * @psalm-param array $params */ private function extractUsedParams(SqlToken $statement, array $params): array { diff --git a/src/DMLQueryBuilder.php b/src/DMLQueryBuilder.php index 798697a0..e772a598 100644 --- a/src/DMLQueryBuilder.php +++ b/src/DMLQueryBuilder.php @@ -56,7 +56,7 @@ public function upsert( bool|array $updateColumns, array &$params ): string { - /** @psalm-var Constraint[] $constraints */ + /** @var Constraint[] $constraints */ $constraints = []; [$uniqueNames, $insertNames, $updateNames] = $this->prepareUpsertColumns( diff --git a/src/DQLQueryBuilder.php b/src/DQLQueryBuilder.php index 753e9504..1faa2b0c 100644 --- a/src/DQLQueryBuilder.php +++ b/src/DQLQueryBuilder.php @@ -46,7 +46,6 @@ public function build(QueryInterface $query, array $params = []): array $sql = $this->buildOrderByAndLimit($sql, $orderBy, $query->getLimit(), $query->getOffset()); if (!empty($orderBy)) { - /** @psalm-var array $orderBy */ foreach ($orderBy as $expression) { if ($expression instanceof ExpressionInterface) { $this->buildExpression($expression, $params); @@ -57,7 +56,6 @@ public function build(QueryInterface $query, array $params = []): array $groupBy = $query->getGroupBy(); if (!empty($groupBy)) { - /** @psalm-var array $groupBy */ foreach ($groupBy as $expression) { if ($expression instanceof ExpressionInterface) { $this->buildExpression($expression, $params); diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 3aa810b1..4f867bd2 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -14,9 +14,7 @@ final class QueryBuilder extends AbstractQueryBuilder { /** - * @var array Mapping from abstract column types (keys) to physical column types (values). - * - * @psalm-var string[] $typeMap + * @var string[] Mapping from abstract column types (keys) to physical column types (values). */ protected array $typeMap = [ SchemaInterface::TYPE_PK => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL', diff --git a/src/Schema.php b/src/Schema.php index ef856721..57134f1a 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -72,9 +72,7 @@ final class Schema extends AbstractPdoSchema { /** - * @var array Mapping from physical column types (keys) to abstract column types (values). - * - * @psalm-var array $typeMap + * @var string[] Mapping from physical column types (keys) to abstract column types (values). */ private array $typeMap = [ 'tinyint' => self::TYPE_TINYINT, @@ -218,7 +216,6 @@ protected function loadTableForeignKeys(string $tableName): array $primaryKey = $this->getTablePrimaryKey($table); if ($primaryKey !== null) { - /** @psalm-var string $primaryKeyColumnName */ foreach ((array) $primaryKey->getColumnNames() as $i => $primaryKeyColumnName) { $foreignKey[$i]['to'] = $primaryKeyColumnName; } @@ -303,7 +300,6 @@ protected function loadTableChecks(string $tableName): array $sql = ($sql === false || $sql === null) ? '' : (string) $sql; - /** @psalm-var SqlToken[]|SqlToken[][]|SqlToken[][][] $code */ $code = (new SqlTokenizer($sql))->tokenize(); $pattern = (new SqlTokenizer('any CREATE any TABLE any()'))->tokenize(); $result = []; @@ -363,7 +359,6 @@ protected function loadTableDefaultValues(string $tableName): array */ protected function findColumns(TableSchemaInterface $table): bool { - /** @psalm-var ColumnInfo[] $columns */ $columns = $this->getPragmaTableInfo($table->getName()); $jsonColumns = $this->getJsonColumns($table); @@ -444,7 +439,6 @@ public function findUniqueIndexes(TableSchemaInterface $table): array foreach ($indexList as $index) { $indexName = $index['name']; - /** @psalm-var IndexInfo[] $indexInfo */ $indexInfo = $this->getPragmaIndexInfo($index['name']); if ($index['unique']) { @@ -551,6 +545,8 @@ private function normalizeDefaultValue(string|null $defaultValue, ColumnSchemaIn * @throws Throwable * * @return array The table columns info. + * + * @psalm-return ColumnInfo[] $tableColumns; */ private function loadTableColumnsInfo(string $tableName): array { @@ -558,6 +554,7 @@ private function loadTableColumnsInfo(string $tableName): array /** @psalm-var ColumnInfo[] $tableColumns */ $tableColumns = $this->normalizeRowKeyCase($tableColumns, true); + /** @psalm-var ColumnInfo[] */ return DbArrayHelper::index($tableColumns, 'cid'); } @@ -585,7 +582,6 @@ private function loadTableConstraints(string $tableName, string $returnType): Co ]; foreach ($indexes as $index) { - /** @psalm-var IndexInfo[] $columns */ $columns = $this->getPragmaIndexInfo($index['name']); if ($index['origin'] === 'pk') { @@ -611,8 +607,6 @@ private function loadTableConstraints(string $tableName, string $returnType): Co * Extra check for PK in case of `INTEGER PRIMARY KEY` with ROWID. * * @link https://www.sqlite.org/lang_createtable.html#primkeyconst - * - * @psalm-var ColumnInfo[] $tableColumns */ $tableColumns = $this->loadTableColumnsInfo($tableName); @@ -659,16 +653,18 @@ private function getPragmaForeignKeyList(string $tableName): array * @throws Exception * @throws InvalidConfigException * @throws Throwable + * + * @psalm-return IndexInfo[] */ private function getPragmaIndexInfo(string $name): array { $column = $this->db ->createCommand('PRAGMA INDEX_INFO(' . (string) $this->db->getQuoter()->quoteValue($name) . ')') ->queryAll(); - /** @psalm-var IndexInfo[] $column */ $column = $this->normalizeRowKeyCase($column, true); DbArrayHelper::multisort($column, 'seqno'); + /** @psalm-var IndexInfo[] $column */ return $column; } @@ -688,9 +684,12 @@ private function getPragmaIndexList(string $tableName): array * @throws Exception * @throws InvalidConfigException * @throws Throwable + * + * @psalm-return ColumnInfo[] */ private function getPragmaTableInfo(string $tableName): array { + /** @psalm-var ColumnInfo[] */ return $this->db->createCommand( 'PRAGMA TABLE_INFO(' . $this->db->getQuoter()->quoteSimpleTableName($tableName) . ')' )->queryAll(); @@ -703,7 +702,7 @@ private function getPragmaTableInfo(string $tableName): array */ protected function findViewNames(string $schema = ''): array { - /** @psalm-var string[][] $views */ + /** @var string[][] $views */ $views = $this->db->createCommand( << Date: Thu, 16 Nov 2023 13:09:43 +0700 Subject: [PATCH 10/24] Change property `Schema::$typeMap` to constant `Schema::TYPE_MAP` (#282) --- CHANGELOG.md | 1 + src/Schema.php | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99610dd1..24aa252d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 1.1.1 under development - Enh #281: Remove unused code in `Command` class (@vjik) +- Enh #282: Change property `Schema::$typeMap` to constant `Schema::TYPE_MAP` (@Tigrov) ## 1.1.0 November 12, 2023 diff --git a/src/Schema.php b/src/Schema.php index 57134f1a..cc88fcd4 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -72,9 +72,11 @@ final class Schema extends AbstractPdoSchema { /** - * @var string[] Mapping from physical column types (keys) to abstract column types (values). + * Mapping from physical column types (keys) to abstract column types (values). + * + * @var string[] */ - private array $typeMap = [ + private const TYPE_MAP = [ 'tinyint' => self::TYPE_TINYINT, 'bit' => self::TYPE_SMALLINT, 'boolean' => self::TYPE_BOOLEAN, @@ -481,8 +483,8 @@ protected function loadColumnSchema(array $info): ColumnSchemaInterface if (preg_match('/^(\w+)(?:\(([^)]+)\))?/', $column->getDbType() ?? '', $matches)) { $type = strtolower($matches[1]); - if (isset($this->typeMap[$type])) { - $column->type($this->typeMap[$type]); + if (isset(self::TYPE_MAP[$type])) { + $column->type(self::TYPE_MAP[$type]); } if (!empty($matches[2])) { From 0992809d21d41f18b0b173ef47ffb041f80ff7a0 Mon Sep 17 00:00:00 2001 From: Sergei Tigrov Date: Thu, 7 Dec 2023 16:03:13 +0700 Subject: [PATCH 11/24] Fix `QueryBuilderTest::testBatchInsert()` (#283) Co-authored-by: Sergei Predvoditelev --- CHANGELOG.md | 1 + src/Schema.php | 7 +++---- tests/QueryBuilderTest.php | 11 ++++++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24aa252d..b78d56f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Enh #281: Remove unused code in `Command` class (@vjik) - Enh #282: Change property `Schema::$typeMap` to constant `Schema::TYPE_MAP` (@Tigrov) +- Enh #283: Remove unnecessary check for array type in `Schema::loadTableIndexes()` (@Tigrov) ## 1.1.0 November 12, 2023 diff --git a/src/Schema.php b/src/Schema.php index cc88fcd4..23d46723 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -251,13 +251,12 @@ protected function loadTableForeignKeys(string $tableName): array * * @return array Indexes for the given table. * - * @psalm-return array|IndexConstraint[] + * @psalm-return IndexConstraint[] */ protected function loadTableIndexes(string $tableName): array { - $tableIndexes = $this->loadTableConstraints($tableName, self::INDEXES); - - return is_array($tableIndexes) ? $tableIndexes : []; + /** @var IndexConstraint[] */ + return $this->loadTableConstraints($tableName, self::INDEXES); } /** diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php index f5adf0b5..a54377ea 100644 --- a/tests/QueryBuilderTest.php +++ b/tests/QueryBuilderTest.php @@ -181,9 +181,14 @@ public function testAlterColumn(): void * @throws NotSupportedException * @throws Throwable */ - public function testBatchInsert(string $table, array $columns, iterable $rows, string $expected): void - { - parent::testBatchInsert($table, $columns, $rows, $expected); + public function testBatchInsert( + string $table, + array $columns, + iterable $rows, + string $expected, + array $expectedParams = [], + ): void { + parent::testBatchInsert($table, $columns, $rows, $expected, $expectedParams); } /** From 05ebf547949bc34e72dd55efdab4c18aa7a9aa19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:25:17 +0300 Subject: [PATCH 12/24] Update rector/rector requirement from ^0.18 to ^0.19 (#285) Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version. - [Release notes](https://github.com/rectorphp/rector/releases) - [Commits](https://github.com/rectorphp/rector/compare/0.18.0...0.19.0) --- updated-dependencies: - dependency-name: rector/rector dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4b35c3e1..c2223a5a 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-json": "*", "maglnet/composer-require-checker": "^4.2", "phpunit/phpunit": "^9.6|^10.0", - "rector/rector": "^0.18", + "rector/rector": "^0.19", "roave/infection-static-analysis-plugin": "^1.16", "spatie/phpunit-watcher": "^1.23", "vimeo/psalm": "^4.3|^5.6", From f0acbe53160fe5dd32cf9a535f83e5fb4818c150 Mon Sep 17 00:00:00 2001 From: Sergei Tigrov Date: Sat, 3 Feb 2024 20:25:26 +0700 Subject: [PATCH 13/24] Fix psalm issues (#288) Co-authored-by: Sergei Predvoditelev --- .github/workflows/static.yml | 6 ++++++ CHANGELOG.md | 1 + composer.json | 2 +- psalm.xml | 1 + psalm4.xml | 19 +++++++++++++++++++ src/DDLQueryBuilder.php | 4 ++-- src/Schema.php | 2 +- 7 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 psalm4.xml diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 0b170765..b7778798 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -39,6 +39,7 @@ jobs: - '8.0' - '8.1' - '8.2' + - '8.3' steps: - name: Checkout. @@ -70,4 +71,9 @@ jobs: run: composer update --no-interaction --no-progress --optimize-autoloader --ansi - name: Static analysis. + if: ${{ matrix.php != '8.0' }} run: vendor/bin/psalm --config=${{ inputs.psalm-config }} --shepherd --stats --output-format=github --php-version=${{ matrix.php }} + + - name: Static analysis. + if: ${{ matrix.php == '8.0' }} + run: vendor/bin/psalm --config=psalm4.xml --shepherd --stats --output-format=github --php-version=${{ matrix.php }} diff --git a/CHANGELOG.md b/CHANGELOG.md index b78d56f3..3dc7d3b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Enh #281: Remove unused code in `Command` class (@vjik) - Enh #282: Change property `Schema::$typeMap` to constant `Schema::TYPE_MAP` (@Tigrov) - Enh #283: Remove unnecessary check for array type in `Schema::loadTableIndexes()` (@Tigrov) +- Enh #288: Minor refactoring of `DDLQueryBuilder` and `Schema` (@Tigrov) ## 1.1.0 November 12, 2023 diff --git a/composer.json b/composer.json index c2223a5a..5e57c922 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "rector/rector": "^0.19", "roave/infection-static-analysis-plugin": "^1.16", "spatie/phpunit-watcher": "^1.23", - "vimeo/psalm": "^4.3|^5.6", + "vimeo/psalm": "^4.30|^5.20", "yiisoft/aliases": "^2.0", "yiisoft/cache-file": "^3.1", "yiisoft/json": "^1.0", diff --git a/psalm.xml b/psalm.xml index 10d319ae..906206a6 100644 --- a/psalm.xml +++ b/psalm.xml @@ -15,5 +15,6 @@ + diff --git a/psalm4.xml b/psalm4.xml new file mode 100644 index 00000000..10d319ae --- /dev/null +++ b/psalm4.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + diff --git a/src/DDLQueryBuilder.php b/src/DDLQueryBuilder.php index 84a9c89b..15b8cd92 100644 --- a/src/DDLQueryBuilder.php +++ b/src/DDLQueryBuilder.php @@ -105,8 +105,8 @@ public function createIndex( [$schema, $table] = $tableParts; } - return 'CREATE ' . ($indexType ? ($indexType . ' ') : '') . 'INDEX ' - . $this->quoter->quoteTableName(($schema ? $schema . '.' : '') . $name) + return 'CREATE ' . (!empty($indexType) ? $indexType . ' ' : '') . 'INDEX ' + . $this->quoter->quoteTableName((!empty($schema) ? $schema . '.' : '') . $name) . ' ON ' . $this->quoter->quoteTableName($table) . ' (' . $this->queryBuilder->buildColumns($columns) . ')'; diff --git a/src/Schema.php b/src/Schema.php index 23d46723..3d2853c1 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -752,7 +752,7 @@ private function getJsonColumns(TableSchemaInterface $table): array $regexp = '/\bjson_valid\(\s*["`\[]?(.+?)["`\]]?\s*\)/i'; foreach ($checks as $check) { - if (preg_match_all($regexp, $check->getExpression(), $matches, PREG_SET_ORDER)) { + if (preg_match_all($regexp, $check->getExpression(), $matches, PREG_SET_ORDER) > 0) { foreach ($matches as $match) { $result[] = $match[1]; } From 36aa01a178ccf45b604ad14078870e7a238951b1 Mon Sep 17 00:00:00 2001 From: Sergei Tigrov Date: Sat, 10 Feb 2024 17:56:02 +0700 Subject: [PATCH 14/24] Resolve deprecated methods (#287) * Resolve deprecated methods * Add line to CHANGELOG.md * Fix test * Fix psalm issues --------- Co-authored-by: Sergei Predvoditelev --- CHANGELOG.md | 1 + src/Schema.php | 17 +++++++++++++---- tests/SchemaTest.php | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dc7d3b3..dc02fd4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Enh #282: Change property `Schema::$typeMap` to constant `Schema::TYPE_MAP` (@Tigrov) - Enh #283: Remove unnecessary check for array type in `Schema::loadTableIndexes()` (@Tigrov) - Enh #288: Minor refactoring of `DDLQueryBuilder` and `Schema` (@Tigrov) +- Enh #287: Resolve deprecated methods (@Tigrov) ## 1.1.0 November 12, 2023 diff --git a/src/Schema.php b/src/Schema.php index 3d2853c1..beecabc4 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -21,6 +21,7 @@ use Yiisoft\Db\Schema\TableSchemaInterface; use function array_column; +use function array_map; use function array_merge; use function count; use function explode; @@ -201,7 +202,7 @@ protected function loadTableForeignKeys(string $tableName): array $foreignKeysList = $this->getPragmaForeignKeyList($tableName); /** @psalm-var ForeignKeyInfo[] $foreignKeysList */ - $foreignKeysList = $this->normalizeRowKeyCase($foreignKeysList, true); + $foreignKeysList = array_map('array_change_key_case', $foreignKeysList); $foreignKeysList = DbArrayHelper::index($foreignKeysList, null, ['table']); DbArrayHelper::multisort($foreignKeysList, 'seq'); @@ -553,7 +554,7 @@ private function loadTableColumnsInfo(string $tableName): array { $tableColumns = $this->getPragmaTableInfo($tableName); /** @psalm-var ColumnInfo[] $tableColumns */ - $tableColumns = $this->normalizeRowKeyCase($tableColumns, true); + $tableColumns = array_map('array_change_key_case', $tableColumns); /** @psalm-var ColumnInfo[] */ return DbArrayHelper::index($tableColumns, 'cid'); @@ -575,7 +576,7 @@ private function loadTableConstraints(string $tableName, string $returnType): Co { $indexList = $this->getPragmaIndexList($tableName); /** @psalm-var IndexListInfo[] $indexes */ - $indexes = $this->normalizeRowKeyCase($indexList, true); + $indexes = array_map('array_change_key_case', $indexList); $result = [ self::PRIMARY_KEY => null, self::INDEXES => [], @@ -642,9 +643,12 @@ private function createColumnSchema(string $name): ColumnSchemaInterface * @throws Exception * @throws InvalidConfigException * @throws Throwable + * + * @psalm-return ForeignKeyInfo[] */ private function getPragmaForeignKeyList(string $tableName): array { + /** @psalm-var ForeignKeyInfo[] */ return $this->db->createCommand( 'PRAGMA FOREIGN_KEY_LIST(' . $this->db->getQuoter()->quoteSimpleTableName($tableName) . ')' )->queryAll(); @@ -662,7 +666,7 @@ private function getPragmaIndexInfo(string $name): array $column = $this->db ->createCommand('PRAGMA INDEX_INFO(' . (string) $this->db->getQuoter()->quoteValue($name) . ')') ->queryAll(); - $column = $this->normalizeRowKeyCase($column, true); + $column = array_map('array_change_key_case', $column); DbArrayHelper::multisort($column, 'seqno'); /** @psalm-var IndexInfo[] $column */ @@ -673,9 +677,12 @@ private function getPragmaIndexInfo(string $name): array * @throws Exception * @throws InvalidConfigException * @throws Throwable + * + * @psalm-return IndexListInfo[] */ private function getPragmaIndexList(string $tableName): array { + /** @psalm-var IndexListInfo[] */ return $this->db ->createCommand('PRAGMA INDEX_LIST(' . (string) $this->db->getQuoter()->quoteValue($tableName) . ')') ->queryAll(); @@ -723,6 +730,8 @@ protected function findViewNames(string $schema = ''): array * @param string $name the table name. * * @return array The cache key. + * + * @psalm-suppress DeprecatedMethod */ protected function getCacheKey(string $name): array { diff --git a/tests/SchemaTest.php b/tests/SchemaTest.php index e15c3f1b..2a171127 100644 --- a/tests/SchemaTest.php +++ b/tests/SchemaTest.php @@ -352,11 +352,11 @@ public function testWorkWithPrimaryKeyConstraint(): void public function testNotConnectionPDO(): void { $db = $this->createMock(ConnectionInterface::class); - $schema = new Schema($db, DbHelper::getSchemaCache(), 'system'); + $schema = new Schema($db, DbHelper::getSchemaCache()); $this->expectException(NotSupportedException::class); $this->expectExceptionMessage('Only PDO connections are supported.'); - $schema->refreshTableSchema('customer'); + $schema->refresh(); } } From f0ccbfaa95eeef93eb109b04ec03aa84a80a43a7 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Sun, 11 Feb 2024 17:17:19 -0300 Subject: [PATCH 15/24] Fix workflow mutation. (#291) --- .github/workflows/mutation.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/mutation.yml b/.github/workflows/mutation.yml index cc226299..c9d07e45 100644 --- a/.github/workflows/mutation.yml +++ b/.github/workflows/mutation.yml @@ -35,7 +35,6 @@ jobs: - ubuntu-latest php: - - 8.0 - 8.1 steps: @@ -71,6 +70,6 @@ jobs: - name: Run infection. run: | - vendor/bin/roave-infection-static-analysis-plugin -j2 --ignore-msi-with-no-mutations --only-covered + vendor/bin/roave-infection-static-analysis-plugin --threads=2 --ignore-msi-with-no-mutations --only-covered env: STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }} From 9d30cf96a3273a6e2d4c52be7ed23647b7ed46cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 10:24:12 +0300 Subject: [PATCH 16/24] Update rector/rector requirement from ^0.19 to ^1.0 (#290) Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version. - [Release notes](https://github.com/rectorphp/rector/releases) - [Commits](https://github.com/rectorphp/rector/compare/0.19.0...1.0.0) --- updated-dependencies: - dependency-name: rector/rector dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sergei Predvoditelev --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5e57c922..1130051a 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-json": "*", "maglnet/composer-require-checker": "^4.2", "phpunit/phpunit": "^9.6|^10.0", - "rector/rector": "^0.19", + "rector/rector": "^1.0", "roave/infection-static-analysis-plugin": "^1.16", "spatie/phpunit-watcher": "^1.23", "vimeo/psalm": "^4.30|^5.20", From d8222a0ccd0b2b431f253bfb13af1f79e6d341d9 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 21 Mar 2024 07:30:14 +0000 Subject: [PATCH 17/24] Release version 1.2.0 --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc02fd4a..ec8fc9db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,12 @@ # SQLite driver for Yii Database Change Log -## 1.1.1 under development +## 1.2.0 March 21, 2024 - Enh #281: Remove unused code in `Command` class (@vjik) - Enh #282: Change property `Schema::$typeMap` to constant `Schema::TYPE_MAP` (@Tigrov) - Enh #283: Remove unnecessary check for array type in `Schema::loadTableIndexes()` (@Tigrov) +- Enh #287: Resolve deprecated methods (@Tigrov) - Enh #288: Minor refactoring of `DDLQueryBuilder` and `Schema` (@Tigrov) -- Enh #287: Resolve deprecated methods (@Tigrov) ## 1.1.0 November 12, 2023 From 3bf7df5f5b4b2a3a2334f8e67711e8ab0b2f1bd1 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 21 Mar 2024 07:30:15 +0000 Subject: [PATCH 18/24] Prepare for next release --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec8fc9db..39a530e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # SQLite driver for Yii Database Change Log +## 1.2.1 under development + +- no changes in this release. + ## 1.2.0 March 21, 2024 - Enh #281: Remove unused code in `Command` class (@vjik) From 2389210625d91213d105494ce198aa216f6f41ff Mon Sep 17 00:00:00 2001 From: Luiz Marin <67489841+luizcmarin@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:06:28 -0300 Subject: [PATCH 19/24] Translate into Brazilian Portuguese (#293) --- docs/pt-BR/testing.md | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 docs/pt-BR/testing.md diff --git a/docs/pt-BR/testing.md b/docs/pt-BR/testing.md new file mode 100644 index 00000000..7d20dbe5 --- /dev/null +++ b/docs/pt-BR/testing.md @@ -0,0 +1,51 @@ +# Testes + +## Ações do Github + +Todos os nossos pacotes possuem ações do github por padrão, então você pode testar sua [contribuição](https://github.com/yiisoft/db-sqlite/blob/master/.github/CONTRIBUTING.md) na nuvem. + +> Observação: recomendamos a solicitação pull no modo rascunho até que todos os testes sejam aprovados. + +## Teste de unidade + +O pacote é testado com [PHPUnit](https://phpunit.de/). + +```shell +vendor/bin/phpunit +``` + +### Teste de mutação + +Os testes do pacote são verificados com a estrutura de mutação [Infection](https://infection.github.io/) e com +[plugin de análise estática de infecção](https://github.com/Roave/infection-static-analysis-plugin). Para executá-lo: + +```shell +./vendor/bin/roave-infection-static-analysis-plugin +``` + +## Análise estática + +O código é analisado estaticamente com [Psalm](https://psalm.dev/). Para executar a análise estática: + +```shell +./vendor/bin/psalm +``` + +## Reitor + +Use [Rector](https://github.com/rectorphp/rector) para fazer a base de código seguir algumas regras específicas ou +use a versão mais recente ou qualquer versão específica do PHP: + +```shell +./vendor/bin/rector +``` + +## Composer requer verificador + +Este pacote usa [composer-require-checker](https://github.com/maglnet/ComposerRequireChecker) para verificar se todas as dependências estão definidas corretamente em `composer.json`. + +Para executar o verificador, execute o seguinte comando: + +```shell +./vendor/bin/composer-require-checker +``` From 4a95c6bea300ed44088f787e9fa646111e747297 Mon Sep 17 00:00:00 2001 From: Sergei Tigrov Date: Fri, 12 Apr 2024 18:44:49 +0700 Subject: [PATCH 20/24] Update test according to main PR (#289) Co-authored-by: Sergei Predvoditelev --- CHANGELOG.md | 4 +-- rector.php | 5 +++- src/Builder/ExpressionBuilder.php | 16 ++++++++++ src/DQLQueryBuilder.php | 3 ++ src/SqlParser.php | 45 ++++++++++++++++++++++++++++ tests/CommandTest.php | 5 ++-- tests/Provider/SqlParserProvider.php | 30 +++++++++++++++++++ tests/QueryBuilderTest.php | 7 +++-- tests/SqlParserTest.php | 25 ++++++++++++++++ 9 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 src/Builder/ExpressionBuilder.php create mode 100644 src/SqlParser.php create mode 100644 tests/Provider/SqlParserProvider.php create mode 100644 tests/SqlParserTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 39a530e9..abb54123 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # SQLite driver for Yii Database Change Log -## 1.2.1 under development +## 2.0.0 under development -- no changes in this release. +- Enh #289: Implement `SqlParser` and `ExpressionBuilder` driver classes (@Tigrov) ## 1.2.0 March 21, 2024 diff --git a/rector.php b/rector.php index 6d4e4d49..8cbdabbd 100644 --- a/rector.php +++ b/rector.php @@ -11,7 +11,10 @@ $rectorConfig->paths([ __DIR__ . '/src', - __DIR__ . '/tests', + /** + * Disabled ./tests directory due to different branches with main package when testing + */ + // __DIR__ . '/tests', ]); // register a single rule diff --git a/src/Builder/ExpressionBuilder.php b/src/Builder/ExpressionBuilder.php new file mode 100644 index 00000000..96ac22ee --- /dev/null +++ b/src/Builder/ExpressionBuilder.php @@ -0,0 +1,16 @@ + LikeConditionBuilder::class, InCondition::class => InConditionBuilder::class, JsonExpression::class => JsonExpressionBuilder::class, + Expression::class => ExpressionBuilder::class, ]); } } diff --git a/src/SqlParser.php b/src/SqlParser.php new file mode 100644 index 00000000..9698d6d6 --- /dev/null +++ b/src/SqlParser.php @@ -0,0 +1,45 @@ +length - 1; + + while ($this->position < $length) { + $pos = $this->position++; + + match ($this->sql[$pos]) { + ':' => ($word = $this->parseWord()) === '' + ? $this->skipChars(':') + : $result = ':' . $word, + '"', "'", '`' => $this->skipQuotedWithoutEscape($this->sql[$pos]), + '[' => $this->sql[$this->position] === '[' + ? $this->skipToAfterString(']]') + : $this->skipQuotedWithoutEscape(']'), + '-' => $this->sql[$this->position] === '-' + ? ++$this->position && $this->skipToAfterChar("\n") + : null, + '/' => $this->sql[$this->position] === '*' + ? ++$this->position && $this->skipToAfterString('*/') + : null, + default => null, + }; + + if ($result !== null) { + $position = $pos; + + return $result; + } + } + + return null; + } +} diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 7f3dbd4d..32486c27 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -465,9 +465,10 @@ public function testUpdate( array $columns, array|string $conditions, array $params, - string $expected + array $expectedValues, + int $expectedCount, ): void { - parent::testUpdate($table, $columns, $conditions, $params, $expected); + parent::testUpdate($table, $columns, $conditions, $params, $expectedValues, $expectedCount); } /** diff --git a/tests/Provider/SqlParserProvider.php b/tests/Provider/SqlParserProvider.php new file mode 100644 index 00000000..77912c60 --- /dev/null +++ b/tests/Provider/SqlParserProvider.php @@ -0,0 +1,30 @@ + Date: Sat, 13 Apr 2024 15:02:56 +0700 Subject: [PATCH 21/24] Allow scalar values for `Query::select()` (#292) * Update tests according main PR * Apply Rector changes (CI) * Revert "Apply Rector changes (CI)" This reverts commit 132fef749da5ee8327a5d91101aa49286539fcaf. * Disable Rector for tests * Add type string to test --------- Co-authored-by: Tigrov Co-authored-by: Sergei Predvoditelev --- tests/QueryBuilderTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php index a14c9116..42e51121 100644 --- a/tests/QueryBuilderTest.php +++ b/tests/QueryBuilderTest.php @@ -770,4 +770,10 @@ public function testJsonColumn() $qb->insert('json_table', ['json_col' => new JsonExpression(['a' => 1, 'b' => 2])]), ); } + + /** @dataProvider \Yiisoft\Db\Sqlite\Tests\Provider\QueryBuilderProvider::selectScalar */ + public function testSelectScalar(array|bool|float|int|string $columns, string $expected): void + { + parent::testSelectScalar($columns, $expected); + } } From ad1b1e4a18173cfce0e8d3ca828ee3e1f87a6235 Mon Sep 17 00:00:00 2001 From: Luiz Marin <67489841+luizcmarin@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:48:22 -0300 Subject: [PATCH 22/24] Docs folder standardization and other fixes (#296) --- README.md | 4 +-- docs/{en/testing.md => internals.md} | 17 +++++----- docs/pt-BR/testing.md | 51 ---------------------------- phpunit.xml.dist | 2 +- psalm.xml | 2 +- psalm4.xml | 2 +- src/DQLQueryBuilder.php | 2 +- src/Dsn.php | 2 +- src/SqlTokenizer.php | 2 +- src/Transaction.php | 2 +- 10 files changed, 18 insertions(+), 68 deletions(-) rename docs/{en/testing.md => internals.md} (70%) delete mode 100644 docs/pt-BR/testing.md diff --git a/README.md b/README.md index 8b66401e..8ee37330 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,11 @@ perform advanced database operations such as joins and aggregates. The package could be installed via composer: -```php +```shell composer require yiisoft/db-sqlite ``` -## Usage +## Usage For config connection to SQLite database check [Connecting SQLite](https://github.com/yiisoft/db/blob/master/docs/en/connection/sqlite.md). diff --git a/docs/en/testing.md b/docs/internals.md similarity index 70% rename from docs/en/testing.md rename to docs/internals.md index 49d60d0e..30ec7ee4 100644 --- a/docs/en/testing.md +++ b/docs/internals.md @@ -1,4 +1,4 @@ -# Testing +# Internals ## Github actions @@ -8,13 +8,13 @@ All our packages have github actions by default, so you can test your [contribut ## Unit testing -The package is tested with [PHPUnit](https://phpunit.de/). +The package is tested with [PHPUnit](https://phpunit.de/). To run tests: ```shell -vendor/bin/phpunit +./vendor/bin/phpunit ``` -### Mutation testing +## Mutation testing The package tests are checked with [Infection](https://infection.github.io/) mutation framework with [Infection Static Analysis Plugin](https://github.com/Roave/infection-static-analysis-plugin). To run it: @@ -33,16 +33,17 @@ The code is statically analyzed with [Psalm](https://psalm.dev/). To run static ## Rector -Use [Rector](https://github.com/rectorphp/rector) to make codebase follow some specific rules or -use either newest or any specific version of PHP: +Use [Rector](https://github.com/rectorphp/rector) to make codebase follow some specific rules or +use either newest or any specific version of PHP: ```shell ./vendor/bin/rector ``` -## Composer require checker +## Dependencies -This package uses [composer-require-checker](https://github.com/maglnet/ComposerRequireChecker) to check if all dependencies are correctly defined in `composer.json`. +Use [ComposerRequireChecker](https://github.com/maglnet/ComposerRequireChecker) to detect transitive +[Composer](https://getcomposer.org/) dependencies. To run the checker, execute the following command: diff --git a/docs/pt-BR/testing.md b/docs/pt-BR/testing.md deleted file mode 100644 index 7d20dbe5..00000000 --- a/docs/pt-BR/testing.md +++ /dev/null @@ -1,51 +0,0 @@ -# Testes - -## Ações do Github - -Todos os nossos pacotes possuem ações do github por padrão, então você pode testar sua [contribuição](https://github.com/yiisoft/db-sqlite/blob/master/.github/CONTRIBUTING.md) na nuvem. - -> Observação: recomendamos a solicitação pull no modo rascunho até que todos os testes sejam aprovados. - -## Teste de unidade - -O pacote é testado com [PHPUnit](https://phpunit.de/). - -```shell -vendor/bin/phpunit -``` - -### Teste de mutação - -Os testes do pacote são verificados com a estrutura de mutação [Infection](https://infection.github.io/) e com -[plugin de análise estática de infecção](https://github.com/Roave/infection-static-analysis-plugin). Para executá-lo: - -```shell -./vendor/bin/roave-infection-static-analysis-plugin -``` - -## Análise estática - -O código é analisado estaticamente com [Psalm](https://psalm.dev/). Para executar a análise estática: - -```shell -./vendor/bin/psalm -``` - -## Reitor - -Use [Rector](https://github.com/rectorphp/rector) para fazer a base de código seguir algumas regras específicas ou -use a versão mais recente ou qualquer versão específica do PHP: - -```shell -./vendor/bin/rector -``` - -## Composer requer verificador - -Este pacote usa [composer-require-checker](https://github.com/maglnet/ComposerRequireChecker) para verificar se todas as dependências estão definidas corretamente em `composer.json`. - -Para executar o verificador, execute o seguinte comando: - -```shell -./vendor/bin/composer-require-checker -``` diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c65978bb..b4003563 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,5 @@ - + diff --git a/psalm.xml b/psalm.xml index 906206a6..0a53528c 100644 --- a/psalm.xml +++ b/psalm.xml @@ -3,7 +3,7 @@ errorLevel="1" findUnusedBaselineEntry="true" findUnusedCode="false" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" > diff --git a/psalm4.xml b/psalm4.xml index 10d319ae..36d7a96e 100644 --- a/psalm4.xml +++ b/psalm4.xml @@ -3,7 +3,7 @@ errorLevel="1" findUnusedBaselineEntry="true" findUnusedCode="false" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" > diff --git a/src/DQLQueryBuilder.php b/src/DQLQueryBuilder.php index 6d41350e..7723feb9 100644 --- a/src/DQLQueryBuilder.php +++ b/src/DQLQueryBuilder.php @@ -94,7 +94,7 @@ public function buildLimit(ExpressionInterface|int|null $limit, ExpressionInterf /** * Limit isn't optional in SQLite. * - * {@see http://www.sqlite.org/syntaxdiagrams.html#select-stmt} + * {@see https://www.sqlite.org/syntaxdiagrams.html#select-stmt} */ $sql = 'LIMIT 9223372036854775807 OFFSET ' . // 2^63-1 ($offset instanceof ExpressionInterface ? $this->buildExpression($offset) : (string)$offset); diff --git a/src/Dsn.php b/src/Dsn.php index 37f0c1cf..8806397a 100644 --- a/src/Dsn.php +++ b/src/Dsn.php @@ -24,7 +24,7 @@ public function __construct(private string $driver, private string|null $databas /** * @return string The Data Source Name, or DSN, has the information required to connect to the database. * - * Please refer to the [PHP manual](http://php.net/manual/en/pdo.construct.php) on the format of the DSN string. + * Please refer to the [PHP manual](https://php.net/manual/en/pdo.construct.php) on the format of the DSN string. * * The `driver` array key is used as the driver prefix of the DSN, all further key-value pairs are rendered as * `key=value` and concatenated by `;`. For example: diff --git a/src/SqlTokenizer.php b/src/SqlTokenizer.php index 54a4154a..7db891d2 100644 --- a/src/SqlTokenizer.php +++ b/src/SqlTokenizer.php @@ -12,7 +12,7 @@ * * It's used to obtain `CHECK` constraint information from a `CREATE TABLE` SQL code. * - * @link http://www.sqlite.org/draft/tokenreq.html + * @link https://www.sqlite.org/draft/tokenreq.html * @link https://sqlite.org/lang.html */ final class SqlTokenizer extends AbstractTokenizer diff --git a/src/Transaction.php b/src/Transaction.php index 2256e473..15731a29 100644 --- a/src/Transaction.php +++ b/src/Transaction.php @@ -29,7 +29,7 @@ final class Transaction extends AbstractPdoTransaction * @throws Throwable When unsupported isolation levels are used. SQLite only supports `SERIALIZABLE` * and `READ UNCOMMITTED`. * - * @link http://www.sqlite.org/pragma.html#pragma_read_uncommitted + * @link https://www.sqlite.org/pragma.html#pragma_read_uncommitted */ protected function setTransactionIsolationLevel(string $level): void { From f92c99f85e4c5d3593c5d5ff70747e9cb9d800ed Mon Sep 17 00:00:00 2001 From: Sergei Tigrov Date: Mon, 22 Apr 2024 21:51:09 +0700 Subject: [PATCH 23/24] Fix test configs (#298) --- phpunit.xml.dist | 2 +- psalm.xml | 2 +- psalm4.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b4003563..c65978bb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,5 @@ - + diff --git a/psalm.xml b/psalm.xml index 0a53528c..906206a6 100644 --- a/psalm.xml +++ b/psalm.xml @@ -3,7 +3,7 @@ errorLevel="1" findUnusedBaselineEntry="true" findUnusedCode="false" - xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" > diff --git a/psalm4.xml b/psalm4.xml index 36d7a96e..10d319ae 100644 --- a/psalm4.xml +++ b/psalm4.xml @@ -3,7 +3,7 @@ errorLevel="1" findUnusedBaselineEntry="true" findUnusedCode="false" - xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" > From 6710681af7f7e2c212c931b320cfaaab306c62f8 Mon Sep 17 00:00:00 2001 From: Luiz Marin <67489841+luizcmarin@users.noreply.github.com> Date: Mon, 22 Apr 2024 18:17:19 -0300 Subject: [PATCH 24/24] Docs folder standardization and other fixes (#297) --- LICENSE.md | 8 ++++---- README.md | 21 ++++++++++++++++----- composer.json | 2 +- docs/internals.md | 31 +++++++++++++++++++++++++++++-- phpunit.xml.dist | 2 +- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index bc5674fe..6a920d60 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,17 +1,17 @@ -Copyright © 2008 by Yii Software (https://www.yiiframework.com/) +Copyright © 2008 by Yii Software () All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Yii Software nor the names of its +* Neither the name of Yii Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/README.md b/README.md index 8ee37330..b1342bea 100644 --- a/README.md +++ b/README.md @@ -40,15 +40,26 @@ The package could be installed via composer: composer require yiisoft/db-sqlite ``` -## Usage +## Documentation -For config connection to SQLite database check [Connecting SQLite](https://github.com/yiisoft/db/blob/master/docs/en/connection/sqlite.md). +English: -[Check the documentation docs](https://github.com/yiisoft/db/blob/master/docs/en/README.md) to learn about usage. +- For config connection to SQLite database check [Connecting SQLite](https://github.com/yiisoft/db/blob/master/docs/en/connection/sqlite.md) +- [Check the yiisoft/db docs](https://github.com/yiisoft/db/blob/master/docs/en/README.md) to learn about usage. -## Testing +Português - Brasil: -[Check the documentation](/docs/en/testing.md) to learn about testing. +- Para configurar a conexão com o SQLite leia [Connecting SQLite](https://github.com/yiisoft/db/blob/master/docs/pt-BR/connection/sqlite.md). +- [Confira a documentação](https://github.com/yiisoft/db/blob/master/docs/pt-BR/README.md) para aprender como usar. + +Testing: + +- [Internals](docs/internals.md) + +## Support + +If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that. +You may also check out other [Yii Community Resources](https://www.yiiframework.com/community). ## Support the project diff --git a/composer.json b/composer.json index 1130051a..94622861 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "forum": "https://www.yiiframework.com/forum/", "wiki": "https://www.yiiframework.com/wiki/", "chat": "https://t.me/yii3en", - "irc": "irc://irc.freenode.net/yii" + "irc": "ircs://irc.libera.chat:6697/yii" }, "require": { "php": "^8.0", diff --git a/docs/internals.md b/docs/internals.md index 30ec7ee4..4966a62b 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -6,12 +6,39 @@ All our packages have github actions by default, so you can test your [contribut > Note: We recommend pull requesting in draft mode until all tests pass. +## Docker image + +For greater ease it is recommended to use docker containers, for this you can use the [docker-compose.yml](https://docs.docker.com/compose/compose-file/) file that is in the docs folder. + +1. [MySQL 8](../../../docker-compose.yml) +2. [MariaDB 10.11](../../../docker-compose-mariadb.yml) + +For running the docker containers you can use the following command: + +MySQL 8.0. + +```dockerfile +docker compose up -d +``` + +MariaDB 10.11. + +```dockerfile +docker compose -f docker-compose-mariadb.yml up -d +``` + ## Unit testing -The package is tested with [PHPUnit](https://phpunit.de/). To run tests: +The package is tested with [PHPUnit](https://phpunit.de/). + +The following steps are required to run the tests: + +1. Run the docker container for the dbms. +2. Install the dependencies of the project with composer. +3. Run the tests. ```shell -./vendor/bin/phpunit +vendor/bin/phpunit ``` ## Mutation testing diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c65978bb..368ef3ec 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,5 @@ - +