diff --git a/composer.json b/composer.json index db3fe75..58a8791 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "require-dev": { "ext-sqlite3": "*", - "phpstan/phpstan": "^v1.10", + "phpstan/phpstan": "^v1.10 || ^2.0", "phpunit/phpunit": "^10.1 || ^12.0", "phpmd/phpmd": "^2.13", "squizlabs/php_codesniffer": "^3.7 || ^4.0" diff --git a/composer.lock b/composer.lock index bdefa3f..cc92e71 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9550657384725499f5d4d13f02fa6727", + "content-hash": "93bc42531787d8ef4154e3511c04bd99", "packages": [ { "name": "greenlion/php-sql-parser", @@ -908,15 +908,15 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.34", + "version": "2.3.0", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/4dd89ca7aa30fdc6760be21550d583bcc32e8476", - "reference": "4dd89ca7aa30fdc6760be21550d583bcc32e8476", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b1f9890d9af53a25c58129e78f0aadd31f90d7f4", + "reference": "b1f9890d9af53a25c58129e78f0aadd31f90d7f4", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -935,6 +935,17 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ "dev", @@ -957,7 +968,7 @@ "type": "github" } ], - "time": "2026-07-28T10:04:39+00:00" + "time": "2026-10-06T06:15:36+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/src/Connection/DefaultSettings.php b/src/Connection/DefaultSettings.php index 1a70378..ca2d2ea 100644 --- a/src/Connection/DefaultSettings.php +++ b/src/Connection/DefaultSettings.php @@ -92,7 +92,7 @@ public function getConnectionName():string { return $this->connectionName; } - /** @return array */ + /** @return array> */ public function getConnectionSettings():array { // NOTE: It's not possible to test the 'port' values returned by this method // because the DefaultSettings can only ever return the DEFAULT_DRIVER port diff --git a/src/Migration/AbstractMigrator.php b/src/Migration/AbstractMigrator.php index 5f085ed..43be791 100644 --- a/src/Migration/AbstractMigrator.php +++ b/src/Migration/AbstractMigrator.php @@ -3,6 +3,7 @@ use GT\Database\Connection\Settings; use GT\Database\Database; +use LogicException; use SplFileInfo; use SplFileObject; @@ -15,7 +16,7 @@ abstract class AbstractMigrator { protected ?SplFileObject $streamOut = null; protected string $driver; - protected Database $dbClient; + protected ?Database $dbClient; protected string $path; protected string $tableName; protected Settings $settings; @@ -39,6 +40,10 @@ public function __construct( $this->dbClient = new Database($settings); } + protected function getDatabase():Database { + return $this->dbClient ?? throw new LogicException("Migration database is disconnected"); + } + abstract protected function getDefaultTableName():string; public function setOutput( @@ -104,7 +109,7 @@ public function extractNumberFromFilename(string $pathName):int { protected function executeSqlFile(string $file):string { $md5 = md5_file($file); foreach($this->splitSqlFile($file) as $sql) { - $this->dbClient->executeSql($sql); + $this->getDatabase()->executeSql($sql); } return $md5; @@ -123,7 +128,7 @@ protected function countSqlStatements(string $file):int { protected function tableHasColumn(string $columnName):bool { switch($this->driver) { case Settings::DRIVER_SQLITE: - $result = $this->dbClient->executeSql( + $result = $this->getDatabase()->executeSql( "PRAGMA table_info(`{$this->tableName}`)" ); foreach($result->fetchAll() as $row) { @@ -135,7 +140,7 @@ protected function tableHasColumn(string $columnName):bool { default: // @codeCoverageIgnoreStart - $result = $this->dbClient->executeSql( + $result = $this->getDatabase()->executeSql( "show columns from `{$this->tableName}` like ?", [$columnName] ); @@ -152,7 +157,7 @@ protected function ensureColumnExists( return; } - $this->dbClient->executeSql( + $this->getDatabase()->executeSql( "alter table `{$this->tableName}` add `$columnName` $definition" ); } diff --git a/src/Migration/Migrator.php b/src/Migration/Migrator.php index 4084d13..aa48c8c 100644 --- a/src/Migration/Migrator.php +++ b/src/Migration/Migrator.php @@ -7,7 +7,7 @@ use GT\Database\DatabaseException; /** - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * @SuppressWarnings("PHPMD.ExcessiveClassComplexity") */ class Migrator extends AbstractMigrator { const COLUMN_QUERY_NUMBER = "queryNumber"; @@ -36,7 +36,7 @@ protected function getDefaultTableName():string { public function checkMigrationTableExists():bool { switch($this->driver) { case Settings::DRIVER_SQLITE: - $result = $this->dbClient->executeSql( + $result = $this->getDatabase()->executeSql( "select name from sqlite_master " . "where type=? " . "and name like ?", [ @@ -48,7 +48,7 @@ public function checkMigrationTableExists():bool { default: // @codeCoverageIgnoreStart - $result = $this->dbClient->executeSql( + $result = $this->getDatabase()->executeSql( "show tables like ?", [ $this->tableName @@ -62,7 +62,7 @@ public function checkMigrationTableExists():bool { } public function createMigrationTable():void { - $this->dbClient->executeSql(implode("\n", [ + $this->getDatabase()->executeSql(implode("\n", [ "create table if not exists `{$this->tableName}` (", "`" . self::COLUMN_QUERY_NUMBER . "` int primary key,", "`" . self::COLUMN_QUERY_HASH . "` varchar(32) null,", @@ -74,7 +74,7 @@ public function createMigrationTable():void { public function getMigrationCount():int { try { - $result = $this->dbClient->executeSql("select `" + $result = $this->getDatabase()->executeSql("select `" . self::COLUMN_QUERY_NUMBER . "` from `{$this->tableName}` " . "order by `" . self::COLUMN_QUERY_NUMBER . "` desc" @@ -191,7 +191,7 @@ public function performMigration( continue; } - $this->dbClient->executeSql($sql); + $this->getDatabase()->executeSql($sql); $this->recordMigrationProgress($fileNumber, $md5, $statementNumber); } @@ -219,10 +219,10 @@ public function selectSchema():void { $schema = $this->schema; try { - $this->dbClient->executeSql( + $this->getDatabase()->executeSql( "create schema if not exists `$schema` default character set {$this->charset} default collate {$this->collate}" ); - $this->dbClient->executeSql( + $this->getDatabase()->executeSql( "use `$schema`" ); } @@ -249,7 +249,7 @@ protected function recordMigrationProgress( $existingState = $this->getMigrationProgress($number); if($existingState) { - $this->dbClient->executeSql(implode("\n", [ + $this->getDatabase()->executeSql(implode("\n", [ "update `{$this->tableName}`", "set `" . self::COLUMN_QUERY_HASH . "` = ?,", "`" . self::COLUMN_LAST_STATEMENT . "` = ?,", @@ -259,7 +259,7 @@ protected function recordMigrationProgress( return; } - $this->dbClient->executeSql(implode("\n", [ + $this->getDatabase()->executeSql(implode("\n", [ "insert into `{$this->tableName}` (", "`" . self::COLUMN_QUERY_NUMBER . "`, ", "`" . self::COLUMN_QUERY_HASH . "`, ", @@ -293,7 +293,7 @@ protected function getMigrationProgress(int $fileNumber):?array { $selectList .= ", null as `" . self::COLUMN_LAST_STATEMENT . "`"; } - $result = $this->dbClient->executeSql(implode("\n", [ + $result = $this->getDatabase()->executeSql(implode("\n", [ "select $selectList", "from `{$this->tableName}`", "where `" . self::COLUMN_QUERY_NUMBER . "` = ?", @@ -331,7 +331,7 @@ protected function resolveLastCompletedStatement( */ public function deleteAndRecreateSchema():void { if($this->driver === Settings::DRIVER_SQLITE) { - unset($this->dbClient); + $this->dbClient = null; if($this->schema !== Settings::SCHEMA_IN_MEMORY && is_file($this->schema)) { @@ -343,10 +343,10 @@ public function deleteAndRecreateSchema():void { } try { - $this->dbClient->executeSql( + $this->getDatabase()->executeSql( "drop schema if exists `{$this->schema}`" ); - $this->dbClient->executeSql( + $this->getDatabase()->executeSql( "create schema if not exists " . $this->schema . " default character set " diff --git a/src/PlaceholderValidator.php b/src/PlaceholderValidator.php index 067bb1b..676dcb5 100644 --- a/src/PlaceholderValidator.php +++ b/src/PlaceholderValidator.php @@ -2,7 +2,7 @@ namespace GT\Database; /** - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * @SuppressWarnings("PHPMD.ExcessiveClassComplexity") */ class PlaceholderValidator { /** @param array|array $bindings */ diff --git a/src/Query/Query.php b/src/Query/Query.php index 1aba62b..6c75576 100644 --- a/src/Query/Query.php +++ b/src/Query/Query.php @@ -12,7 +12,7 @@ /** - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * @SuppressWarnings("PHPMD.ExcessiveClassComplexity") */ abstract class Query { const SPECIAL_BINDINGS = [ @@ -165,7 +165,7 @@ public function injectSpecialBindings( return $sql; } - /** @param array> $data */ + /** @param array $data */ public function injectDynamicBindings(string $sql, array &$data):string { $sql = $this->injectDynamicBindingsValueSet($sql, $data); $sql = $this->injectDynamicIn($sql, $data); @@ -173,7 +173,7 @@ public function injectDynamicBindings(string $sql, array &$data):string { return trim($sql); } - /** @param array>> $data */ + /** @param array $data */ private function injectDynamicBindingsValueSet(string $sql, array &$data):string { $pattern = '/\(\s*:__dynamicValueSet\s\)/'; if(!preg_match($pattern, $sql, $matches)) { @@ -215,7 +215,7 @@ private function injectDynamicBindingsValueSet(string $sql, array &$data):string return str_replace($matches[0], $replacementString, $sql); } - /** @param array> $data */ + /** @param array $data */ private function injectDynamicIn(string $sql, array &$data):string { $pattern = '/\(\s*:__dynamicIn\s\)/'; if(!preg_match($pattern, $sql, $matches)) { @@ -237,7 +237,7 @@ private function injectDynamicIn(string $sql, array &$data):string { return str_replace($matches[0], "( $replacementString )", $sql); } - /** @param array>> $data */ + /** @param array $data */ private function injectDynamicOr(string $sql, array &$data):string { $pattern = '/:__dynamicOr/'; if(!preg_match($pattern, $sql, $matches)) { diff --git a/src/Result/ResultSet.php b/src/Result/ResultSet.php index 5fc85c4..c338710 100644 --- a/src/Result/ResultSet.php +++ b/src/Result/ResultSet.php @@ -14,7 +14,7 @@ */ class ResultSet implements Iterator, Countable { protected ?Row $currentRow; - protected int $rowIndex; + protected ?int $rowIndex = null; protected int $iteratorIndex; public function __construct( @@ -114,7 +114,7 @@ public function getFieldList():array { public function rewind():void { $this->statement->execute(); $this->currentRow = null; - unset($this->rowIndex); + $this->rowIndex = null; $this->iteratorIndex = 0; }