From a4df6985d4d2f51f810137ac788f3a43983195a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Zaj=C3=ADc?= Date: Mon, 29 Dec 2025 21:25:51 +0100 Subject: [PATCH 1/7] phpstan2 --- Dockerfile | 10 ---------- composer.json | 6 +++--- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index 12c34ca8c..2ae2b0de5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,9 +18,6 @@ COPY docker/php/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini RUN apt-get update -q \ && apt-get install gnupg -y --no-install-recommends \ - && curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \ - && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg \ - && curl https://packages.microsoft.com/config/debian/11/prod.list > /etc/apt/sources.list.d/mssql-release.list \ && echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list \ && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - \ && apt-get update -q \ @@ -37,7 +34,6 @@ RUN apt-get update -q \ debsig-verify \ dirmngr \ gpg-agent \ - msodbcsql17 \ libonig-dev \ libxml2-dev \ awscli \ @@ -87,12 +83,6 @@ ARG SQLSRV_VERSION=5.10.1 ARG SNOWFLAKE_ODBC_VERSION=2.25.12 ARG SNOWFLAKE_GPG_KEY=630D9F3CAB551AF3 -#Synapse ODBC -RUN set -ex; \ - pecl install sqlsrv-$SQLSRV_VERSION pdo_sqlsrv-$SQLSRV_VERSION; \ - docker-php-ext-enable sqlsrv pdo_sqlsrv; \ - docker-php-source delete - ## Snowflake COPY ./docker/snowflake/generic.pol /etc/debsig/policies/$SNOWFLAKE_GPG_KEY/generic.pol COPY ./docker/snowflake/simba.snowflake.ini /usr/lib/snowflake/odbc/lib/simba.snowflake.ini diff --git a/composer.json b/composer.json index 257c622cf..6f3895c92 100755 --- a/composer.json +++ b/composer.json @@ -34,9 +34,9 @@ "php-parallel-lint/php-parallel-lint": "^1.3", "phpstan/extension-installer": "^1.1", "phpstan/phpdoc-parser": "^1.6", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpstan/phpstan-symfony": "^1.1", + "phpstan/phpstan": "^2", + "phpstan/phpstan-phpunit": "^2", + "phpstan/phpstan-symfony": "^2", "phpunit/phpunit": "^9", "react/async": "^4||^3", "squizlabs/php_codesniffer": "^3", From 0178fe23079c9797b173c3e9aa7a0210c0c4924b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Zaj=C3=ADc?= Date: Mon, 29 Dec 2025 21:54:20 +0100 Subject: [PATCH 2/7] datatypes phpstan2 --- packages/php-datatypes/composer.json | 5 ++--- packages/php-datatypes/phpstan-baseline.neon | 19 +++++++++++++++++++ packages/php-datatypes/phpstan.neon | 5 ++++- .../src/Definition/GenericStorage.php | 2 +- .../php-datatypes/src/Definition/MySQL.php | 4 ++-- .../php-datatypes/src/Definition/Redshift.php | 6 +++--- .../src/Definition/Snowflake.php | 2 +- 7 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 packages/php-datatypes/phpstan-baseline.neon diff --git a/packages/php-datatypes/composer.json b/packages/php-datatypes/composer.json index c323f4fe2..14e286efd 100644 --- a/packages/php-datatypes/composer.json +++ b/packages/php-datatypes/composer.json @@ -14,10 +14,9 @@ "require-dev": { "phpunit/phpunit": "^9", "squizlabs/php_codesniffer": "^3", - "phpstan/phpstan": "^1.4", + "phpstan/phpstan": "^2", "php-parallel-lint/php-parallel-lint": "^1.3", - "keboola/coding-standard": "^15", - "phpstan/phpdoc-parser": "^1.6" + "keboola/coding-standard": "^15" }, "autoload": { "psr-4": { diff --git a/packages/php-datatypes/phpstan-baseline.neon b/packages/php-datatypes/phpstan-baseline.neon new file mode 100644 index 000000000..fda548d3e --- /dev/null +++ b/packages/php-datatypes/phpstan-baseline.neon @@ -0,0 +1,19 @@ +parameters: + ignoreErrors: + - + message: '#^Parameter \#1 \$lengthOptions of method Keboola\\Datatype\\Definition\\MySQL\:\:getLengthFromArray\(\) expects array\{character_maximum\?\: int\|string\|null, numeric_precision\?\: int\|string\|null, numeric_scale\?\: int\|string\|null\}, array given\.$#' + identifier: argument.type + count: 1 + path: src/Definition/MySQL.php + + - + message: '#^Parameter \#1 \$lengthOptions of method Keboola\\Datatype\\Definition\\Redshift\:\:getLengthFromArray\(\) expects array\{character_maximum\?\: int\|string\|null, numeric_precision\?\: int\|string\|null, numeric_scale\?\: int\|string\|null\}, array given\.$#' + identifier: argument.type + count: 1 + path: src/Definition/Redshift.php + + - + message: '#^Parameter \#1 \$lengthOptions of method Keboola\\Datatype\\Definition\\Snowflake\:\:getLengthFromArray\(\) expects array\{character_maximum\?\: int\|string\|null, numeric_precision\?\: int\|string\|null, numeric_scale\?\: int\|string\|null\}, array given\.$#' + identifier: argument.type + count: 1 + path: src/Definition/Snowflake.php diff --git a/packages/php-datatypes/phpstan.neon b/packages/php-datatypes/phpstan.neon index 9a2fbd304..40031f5e1 100644 --- a/packages/php-datatypes/phpstan.neon +++ b/packages/php-datatypes/phpstan.neon @@ -1,5 +1,8 @@ parameters: - checkMissingIterableValueType: false ignoreErrors: - '#^Parameter \#. \$options of class Keboola\\Datatype\\.* constructor expects array\{length\?\: string\|null, nullable\?\: bool, default\?\: string\|null.*}, .*array.* given\.$#' - '#^Parameter \#. \$options of class Keboola\\Datatype\\.* constructor expects array\{length\?\: array\|string\|null, nullable\?\: bool, default\?\: string\|null.*}, .*array.* given\.$#' + - identifier: missingType.iterableValue + treatPhpDocTypesAsCertain: false +includes: + - phpstan-baseline.neon diff --git a/packages/php-datatypes/src/Definition/GenericStorage.php b/packages/php-datatypes/src/Definition/GenericStorage.php index 261956c2f..15cf1a006 100644 --- a/packages/php-datatypes/src/Definition/GenericStorage.php +++ b/packages/php-datatypes/src/Definition/GenericStorage.php @@ -57,7 +57,7 @@ public function __construct(string $type, array $options = []) public function getSQLDefinition(): string { $sql = $this->getType(); - if ($this->getLength() && $this->getLength() !== '') { + if (!$this->isEmpty($this->getLength())) { $sql .= '(' . $this->getLength() . ')'; } $sql .= ($this->isNullable()) ? ' NULL' : ' NOT NULL'; diff --git a/packages/php-datatypes/src/Definition/MySQL.php b/packages/php-datatypes/src/Definition/MySQL.php index aae4e106b..c3a6f6fac 100644 --- a/packages/php-datatypes/src/Definition/MySQL.php +++ b/packages/php-datatypes/src/Definition/MySQL.php @@ -53,7 +53,7 @@ public function __construct(string $type, array $options = []) public function getSQLDefinition(): string { $definition = $this->getType(); - if ($this->getLength() && $this->getLength() !== '') { + if (!$this->isEmpty($this->getLength())) { $definition .= '(' . $this->getLength() . ')'; } if (!$this->isNullable()) { @@ -123,7 +123,7 @@ private function getLengthFromArray(array $lengthOptions): ?string */ private function validateType(string $type): void { - if (!in_array(strtoupper($type), $this::TYPES)) { + if (!in_array(strtoupper($type), self::TYPES, true)) { throw new InvalidTypeException("'{$type}' is not a valid type"); } } diff --git a/packages/php-datatypes/src/Definition/Redshift.php b/packages/php-datatypes/src/Definition/Redshift.php index 7e4d80259..10b07144e 100644 --- a/packages/php-datatypes/src/Definition/Redshift.php +++ b/packages/php-datatypes/src/Definition/Redshift.php @@ -59,13 +59,13 @@ public function getCompression(): ?string public function getSQLDefinition(): string { $definition = $this->getType(); - if ($this->getLength() && $this->getLength() !== '') { + if (!$this->isEmpty($this->getLength())) { $definition .= '(' . $this->getLength() . ')'; } if (!$this->isNullable()) { $definition .= ' NOT NULL'; } - if ($this->getCompression() && $this->getCompression() !== '') { + if (!$this->isEmpty($this->getCompression())) { $definition .= ' ENCODE ' . $this->getCompression(); } return $definition; @@ -133,7 +133,7 @@ private function getLengthFromArray(array $lengthOptions): ?string */ private function validateType(string $type): void { - if (!in_array(strtoupper($type), $this::TYPES)) { + if (!in_array(strtoupper($type), self::TYPES, true)) { throw new InvalidTypeException("'{$type}' is not a valid type"); } } diff --git a/packages/php-datatypes/src/Definition/Snowflake.php b/packages/php-datatypes/src/Definition/Snowflake.php index bc2e8bc2e..e3cbf29d2 100644 --- a/packages/php-datatypes/src/Definition/Snowflake.php +++ b/packages/php-datatypes/src/Definition/Snowflake.php @@ -255,7 +255,7 @@ public function isTypeWithComplexLength(): bool */ private function validateType(string $type): void { - if (!in_array(strtoupper($type), $this::TYPES)) { + if (!in_array(strtoupper($type), self::TYPES, true)) { throw new InvalidTypeException("'{$type}' is not a valid type"); } } From d0cd01cf84aaf3d78d2f22a1944d36814d3e4e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Zaj=C3=ADc?= Date: Mon, 29 Dec 2025 21:59:20 +0100 Subject: [PATCH 3/7] utils phpstan2 --- .../php-table-backend-utils/composer.json | 4 +- .../phpstan-baseline.neon | 87 +++++++++++++++++-- packages/php-table-backend-utils/phpstan.neon | 3 + .../Bigquery/BigQueryClientWrapper.php | 3 +- .../Connection/Exception/DriverException.php | 2 - .../Bigquery/BigqueryTableReflection.php | 39 +++++++-- .../Snowflake/SnowflakeTableQueryBuilder.php | 3 - .../Functional/Bigquery/BigqueryBaseCase.php | 1 - .../Bigquery/Connection/QueryTagsTest.php | 2 + .../Bigquery/Connection/SessionTest.php | 4 +- .../Table/BigqueryTableReflectionTest.php | 17 +++- 11 files changed, 132 insertions(+), 33 deletions(-) diff --git a/packages/php-table-backend-utils/composer.json b/packages/php-table-backend-utils/composer.json index b40580959..6237ef57f 100644 --- a/packages/php-table-backend-utils/composer.json +++ b/packages/php-table-backend-utils/composer.json @@ -23,8 +23,8 @@ "require-dev": { "keboola/coding-standard": "^15", "php-parallel-lint/php-parallel-lint": "^1.3", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan": "^2", + "phpstan/phpstan-phpunit": "^2", "phpunit/phpunit": "^9" }, "autoload": { diff --git a/packages/php-table-backend-utils/phpstan-baseline.neon b/packages/php-table-backend-utils/phpstan-baseline.neon index ff3bb2c22..3d38eb6e6 100644 --- a/packages/php-table-backend-utils/phpstan-baseline.neon +++ b/packages/php-table-backend-utils/phpstan-baseline.neon @@ -1,46 +1,115 @@ parameters: ignoreErrors: - - message: "#^Method Keboola\\\\TableBackendUtils\\\\Connection\\\\ConnectionRetryWrapper\\:\\:beginTransaction\\(\\) should return bool but returns mixed\\.$#" + message: '#^Cannot access offset ''jobId'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: src/Connection/Bigquery/BigQueryClientWrapper.php + + - + message: '#^Anonymous function should return bool\|Closure but returns mixed\.$#' + identifier: return.type + count: 1 + path: src/Connection/Bigquery/Retry.php + + - + message: '#^Parameter \#2 \$array of function array_key_exists expects array, mixed given\.$#' + identifier: argument.type + count: 2 + path: src/Connection/Bigquery/Retry.php + + - + message: '#^Method Keboola\\TableBackendUtils\\Connection\\ConnectionRetryWrapper\:\:beginTransaction\(\) should return bool but returns mixed\.$#' + identifier: return.type count: 1 path: src/Connection/ConnectionRetryWrapper.php - - message: "#^Method Keboola\\\\TableBackendUtils\\\\Connection\\\\ConnectionRetryWrapper\\:\\:commit\\(\\) should return bool but returns mixed\\.$#" + message: '#^Method Keboola\\TableBackendUtils\\Connection\\ConnectionRetryWrapper\:\:commit\(\) should return bool but returns mixed\.$#' + identifier: return.type count: 1 path: src/Connection/ConnectionRetryWrapper.php - - message: "#^Method Keboola\\\\TableBackendUtils\\\\Connection\\\\ConnectionRetryWrapper\\:\\:exec\\(\\) should return int but returns mixed\\.$#" + message: '#^Method Keboola\\TableBackendUtils\\Connection\\ConnectionRetryWrapper\:\:exec\(\) should return int but returns mixed\.$#' + identifier: return.type count: 1 path: src/Connection/ConnectionRetryWrapper.php - - message: "#^Method Keboola\\\\TableBackendUtils\\\\Connection\\\\ConnectionRetryWrapper\\:\\:lastInsertId\\(\\) should return int\\|string\\|false but returns mixed\\.$#" + message: '#^Method Keboola\\TableBackendUtils\\Connection\\ConnectionRetryWrapper\:\:lastInsertId\(\) should return int\|string\|false but returns mixed\.$#' + identifier: return.type count: 1 path: src/Connection/ConnectionRetryWrapper.php - - message: "#^Method Keboola\\\\TableBackendUtils\\\\Connection\\\\ConnectionRetryWrapper\\:\\:prepare\\(\\) should return Doctrine\\\\DBAL\\\\Driver\\\\Statement but returns mixed\\.$#" + message: '#^Method Keboola\\TableBackendUtils\\Connection\\ConnectionRetryWrapper\:\:prepare\(\) should return Doctrine\\DBAL\\Driver\\Statement but returns mixed\.$#' + identifier: return.type count: 1 path: src/Connection/ConnectionRetryWrapper.php - - message: "#^Method Keboola\\\\TableBackendUtils\\\\Connection\\\\ConnectionRetryWrapper\\:\\:query\\(\\) should return Doctrine\\\\DBAL\\\\Driver\\\\Result but returns mixed\\.$#" + message: '#^Method Keboola\\TableBackendUtils\\Connection\\ConnectionRetryWrapper\:\:query\(\) should return Doctrine\\DBAL\\Driver\\Result but returns mixed\.$#' + identifier: return.type count: 1 path: src/Connection/ConnectionRetryWrapper.php - - message: "#^Method Keboola\\\\TableBackendUtils\\\\Connection\\\\ConnectionRetryWrapper\\:\\:rollBack\\(\\) should return bool but returns mixed\\.$#" + message: '#^Method Keboola\\TableBackendUtils\\Connection\\ConnectionRetryWrapper\:\:rollBack\(\) should return bool but returns mixed\.$#' + identifier: return.type count: 1 path: src/Connection/ConnectionRetryWrapper.php - - message: "#^Parameter \\#1 \\$params of static method Doctrine\\\\DBAL\\\\DriverManager\\:\\:getConnection\\(\\) expects array\\{application_name\\?\\: string, charset\\?\\: string, dbname\\?\\: string, defaultTableOptions\\?\\: array\\, default_dbname\\?\\: string, driver\\?\\: 'ibm_db2'\\|'mysqli'\\|'oci8'\\|'pdo_mysql'\\|'pdo_oci'\\|'pdo_pgsql'\\|'pdo_sqlite'\\|'pdo_sqlsrv'\\|'pgsql'\\|'sqlite3'\\|'sqlsrv', driverClass\\?\\: class\\-string\\, driverOptions\\?\\: array, \\.\\.\\.\\}, array\\{port\\?\\: string, warehouse\\?\\: string, database\\?\\: string, schema\\?\\: string, tracing\\?\\: int, loginTimeout\\?\\: int, networkTimeout\\?\\: int, queryTimeout\\?\\: int, \\.\\.\\.\\} given\\.$#" + message: '#^Method Keboola\\TableBackendUtils\\Connection\\Snowflake\\Result\:\:fetchAssociative\(\) should return array\\|false but returns array\\|false\.$#' + identifier: return.type + count: 1 + path: src/Connection/Snowflake/Result.php + + - + message: '#^Method Keboola\\TableBackendUtils\\Connection\\Snowflake\\Result\:\:fetchNumeric\(\) should return list\\|false but returns array\\|false\.$#' + identifier: return.type + count: 1 + path: src/Connection/Snowflake/Result.php + + - + message: '#^PHPDoc tag @var for variable \$params contains unknown class Keboola\\TableBackendUtils\\Connection\\Snowflake\\Doctrine\\DBAL\\Driver\.$#' + identifier: class.notFound count: 2 path: src/Connection/Snowflake/SnowflakeConnectionFactory.php - - message: "#^Parameter \\#1 \\$params \\(array\\{host\\: string, user\\: string, password\\?\\: string, privateKey\\?\\: string, port\\?\\: string, warehouse\\?\\: string, database\\?\\: string, schema\\?\\: string, \\.\\.\\.\\}\\) of method Keboola\\\\TableBackendUtils\\\\Connection\\\\Snowflake\\\\SnowflakeDriver\\:\\:connect\\(\\) should be compatible with parameter \\$params \\(array\\{application_name\\?\\: string, charset\\?\\: string, dbname\\?\\: string, defaultTableOptions\\?\\: array\\, default_dbname\\?\\: string, driver\\?\\: 'ibm_db2'\\|'mysqli'\\|'oci8'\\|'pdo_mysql'\\|'pdo_oci'\\|'pdo_pgsql'\\|'pdo_sqlite'\\|'pdo_sqlsrv'\\|'pgsql'\\|'sqlite3'\\|'sqlsrv', driverClass\\?\\: class\\-string\\, driverOptions\\?\\: array, \\.\\.\\.\\}\\) of method Doctrine\\\\DBAL\\\\Driver\\:\\:connect\\(\\)$#" + message: '#^Parameter \#1 \$params of static method Doctrine\\DBAL\\DriverManager\:\:getConnection\(\) expects array\{application_name\?\: string, charset\?\: string, dbname\?\: string, defaultTableOptions\?\: array\, default_dbname\?\: string, driver\?\: ''ibm_db2''\|''mysqli''\|''oci8''\|''pdo_mysql''\|''pdo_oci''\|''pdo_pgsql''\|''pdo_sqlite''\|''pdo_sqlsrv''\|''pgsql''\|''sqlite3''\|''sqlsrv'', driverClass\?\: class\-string\, driverOptions\?\: array\, \.\.\.\}, array\{port\?\: string, warehouse\?\: string, database\?\: string, schema\?\: string, tracing\?\: int, loginTimeout\?\: int, networkTimeout\?\: int, queryTimeout\?\: int, \.\.\.\} given\.$#' + identifier: argument.type + count: 2 + path: src/Connection/Snowflake/SnowflakeConnectionFactory.php + + - + message: '#^Parameter \#1 \$params \(array\{host\: string, user\: string, password\?\: string, privateKey\?\: string, port\?\: string, warehouse\?\: string, database\?\: string, schema\?\: string, \.\.\.\}\) of method Keboola\\TableBackendUtils\\Connection\\Snowflake\\SnowflakeDriver\:\:connect\(\) should be compatible with parameter \$params \(array\{application_name\?\: string, charset\?\: string, dbname\?\: string, defaultTableOptions\?\: array\, default_dbname\?\: string, driver\?\: ''ibm_db2''\|''mysqli''\|''oci8''\|''pdo_mysql''\|''pdo_oci''\|''pdo_pgsql''\|''pdo_sqlite''\|''pdo_sqlsrv''\|''pgsql''\|''sqlite3''\|''sqlsrv'', driverClass\?\: class\-string\, driverOptions\?\: array\, \.\.\.\}\) of method Doctrine\\DBAL\\Driver\:\:connect\(\)$#' + identifier: method.childParameterType count: 1 path: src/Connection/Snowflake/SnowflakeDriver.php + + - + message: '#^Parameter \#1 \$tableName of method Keboola\\TableBackendUtils\\Schema\\Snowflake\\SnowflakeSchemaReflection\:\:fallbackColumnType\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Schema/Snowflake/SnowflakeSchemaReflection.php + + - + message: '#^Parameter \#2 \$columnName of method Keboola\\TableBackendUtils\\Schema\\Snowflake\\SnowflakeSchemaReflection\:\:fallbackColumnType\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Schema/Snowflake/SnowflakeSchemaReflection.php + + - + message: '#^Parameter \#1 \$dbResponse of static method Keboola\\TableBackendUtils\\Column\\Bigquery\\Parser\\RESTtoSQLDatatypeConverter\:\:convertColumnToSQLFormat\(\) expects array\{name\: string, type\: string, mode\?\: ''NULLABLE''\|''REPEATED''\|''REQUIRED'', fields\?\: array\, description\?\: string, maxLength\?\: string, precision\?\: string, scale\?\: string, \.\.\.\}, array\ given\.$#' + identifier: argument.type + count: 1 + path: tests/Functional/Bigquery/Table/BigqueryTableReflectionTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertIsIterable\(\) with Keboola\\TableBackendUtils\\Column\\ColumnCollection will always evaluate to true\.$#' + identifier: method.alreadyNarrowedType + count: 1 + path: tests/Unit/Column/ColumnCollectionTest.php diff --git a/packages/php-table-backend-utils/phpstan.neon b/packages/php-table-backend-utils/phpstan.neon index 195f74b59..2caa709c2 100644 --- a/packages/php-table-backend-utils/phpstan.neon +++ b/packages/php-table-backend-utils/phpstan.neon @@ -1,4 +1,7 @@ parameters: + ignoreErrors: + - identifier: function.alreadyNarrowedType + includes: - vendor/phpstan/phpstan-phpunit/extension.neon - phpstan-baseline.neon diff --git a/packages/php-table-backend-utils/src/Connection/Bigquery/BigQueryClientWrapper.php b/packages/php-table-backend-utils/src/Connection/Bigquery/BigQueryClientWrapper.php index 5a702e6ba..1bb1936d8 100644 --- a/packages/php-table-backend-utils/src/Connection/Bigquery/BigQueryClientWrapper.php +++ b/packages/php-table-backend-utils/src/Connection/Bigquery/BigQueryClientWrapper.php @@ -65,7 +65,7 @@ public function __construct( */ public function runQuery(JobConfigurationInterface $query, array $options = []): QueryResults { - if (count($this->queryTags->toArray()) !== 0 && method_exists($query, 'labels')) { + if (count($this->queryTags->toArray()) !== 0) { $query = $query->labels($this->queryTags->toArray()); } @@ -102,6 +102,7 @@ public function runJob(JobConfigurationInterface $config, array $options = []): // this should never happen as ['jobReference']['jobId'] is assigned in the JobConfigurationTrait throw $e; } + assert(is_string($jobConfig['jobReference']['jobId'])); $job = $this->job($jobConfig['jobReference']['jobId']); } else { throw $e; diff --git a/packages/php-table-backend-utils/src/Connection/Exception/DriverException.php b/packages/php-table-backend-utils/src/Connection/Exception/DriverException.php index daaf95c3c..30f870239 100644 --- a/packages/php-table-backend-utils/src/Connection/Exception/DriverException.php +++ b/packages/php-table-backend-utils/src/Connection/Exception/DriverException.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Driver\AbstractException; use Throwable; -use function assert; class DriverException extends AbstractException { @@ -16,7 +15,6 @@ class DriverException extends AbstractException public static function newFromHandle($resource): self { $errorCode = odbc_error($resource); - assert($errorCode !== false); $errorMsg = odbc_errormsg($resource); return new self($errorMsg, null, (int) $errorCode); diff --git a/packages/php-table-backend-utils/src/Table/Bigquery/BigqueryTableReflection.php b/packages/php-table-backend-utils/src/Table/Bigquery/BigqueryTableReflection.php index c8fa20d3c..732727661 100644 --- a/packages/php-table-backend-utils/src/Table/Bigquery/BigqueryTableReflection.php +++ b/packages/php-table-backend-utils/src/Table/Bigquery/BigqueryTableReflection.php @@ -49,10 +49,12 @@ public function getColumnsNames(): array $this->throwIfNotExists(); $columns = []; + /** @var array{schema: array{fields: array}} $info */ + $info = $this->table->info(); /** * @phpstan-var BigqueryTableFieldSchema $row */ - foreach ($this->table->info()['schema']['fields'] as $row) { + foreach ($info['schema']['fields'] as $row) { $columns[] = $row['name']; } return $columns; @@ -62,10 +64,12 @@ public function getColumnsDefinitions(): ColumnCollection { $this->throwIfNotExists(); $columns = []; + /** @var array{schema: array{fields: array}} $info */ + $info = $this->table->info(); /** * @phpstan-var BigqueryTableFieldSchema $row */ - foreach ($this->table->info()['schema']['fields'] as $row) { + foreach ($info['schema']['fields'] as $row) { $columns[] = BigqueryColumn::createFromDB($row); } @@ -75,27 +79,36 @@ public function getColumnsDefinitions(): ColumnCollection public function getRowsCount(): int { $this->throwIfNotExists(); - return (int) $this->table->info()['numRows']; + /** @var array{numRows: int|string} $info */ + $info = $this->table->info(); + return (int) $info['numRows']; } /** @return array */ public function getPrimaryKeysNames(): array { $this->throwIfNotExists(); + /** @var array $info */ $info = $this->table->info(); if (!array_key_exists('tableConstraints', $info)) { return []; } - if (!array_key_exists('primaryKey', $info['tableConstraints'])) { + /** @var array $tableConstraints */ + $tableConstraints = $info['tableConstraints']; + if (!array_key_exists('primaryKey', $tableConstraints)) { return []; } - return $info['tableConstraints']['primaryKey']['columns']; + /** @var array{columns: array} $primaryKey */ + $primaryKey = $tableConstraints['primaryKey']; + return $primaryKey['columns']; } public function getTableStats(): TableStatsInterface { $this->throwIfNotExists(); - return new TableStats((int) $this->table->info()['numBytes'], $this->getRowsCount()); + /** @var array{numBytes: int|string} $info */ + $info = $this->table->info(); + return new TableStats((int) $info['numBytes'], $this->getRowsCount()); } public function isTemporary(): bool @@ -139,9 +152,11 @@ public function refresh(): void public function getPartitioningConfiguration(): PartitioningConfig|null { $this->throwIfNotExists(); + /** @var array $info */ $info = $this->table->info(); $timePartitioning = null; if (array_key_exists('timePartitioning', $info)) { + /** @var array{type: string, expirationMs?: string|null, field?: string|null} $data */ $data = $info['timePartitioning']; $timePartitioning = new TimePartitioningConfig( $data['type'], @@ -151,6 +166,7 @@ public function getPartitioningConfiguration(): PartitioningConfig|null } $rangePartitioning = null; if (array_key_exists('rangePartitioning', $info)) { + /** @var array{field: string, range: array{start: string, end: string, interval: string}} $data */ $data = $info['rangePartitioning']; $rangePartitioning = new RangePartitioningConfig( $data['field'], @@ -162,7 +178,7 @@ public function getPartitioningConfiguration(): PartitioningConfig|null $requirePartitionFilter = false; if (array_key_exists('requirePartitionFilter', $info)) { - $requirePartitionFilter = $info['requirePartitionFilter']; + $requirePartitionFilter = (bool) $info['requirePartitionFilter']; } return new PartitioningConfig( @@ -175,11 +191,14 @@ public function getPartitioningConfiguration(): PartitioningConfig|null public function getClusteringConfiguration(): ClusteringConfig|null { $this->throwIfNotExists(); + /** @var array $info */ $info = $this->table->info(); if (!array_key_exists('clustering', $info)) { return null; } - return new ClusteringConfig($info['clustering']['fields']); + /** @var array{fields: array} $clustering */ + $clustering = $info['clustering']; + return new ClusteringConfig($clustering['fields']); } /** @@ -225,6 +244,8 @@ public function getPartitionsList(): array public function getTableType(): TableType { - return ($this->table->info()['type'] === 'EXTERNAL') ? TableType::BIGQUERY_EXTERNAL : TableType::TABLE; + /** @var array{type: string} $info */ + $info = $this->table->info(); + return ($info['type'] === 'EXTERNAL') ? TableType::BIGQUERY_EXTERNAL : TableType::TABLE; } } diff --git a/packages/php-table-backend-utils/src/Table/Snowflake/SnowflakeTableQueryBuilder.php b/packages/php-table-backend-utils/src/Table/Snowflake/SnowflakeTableQueryBuilder.php index 58300dfdd..a7a43ec62 100644 --- a/packages/php-table-backend-utils/src/Table/Snowflake/SnowflakeTableQueryBuilder.php +++ b/packages/php-table-backend-utils/src/Table/Snowflake/SnowflakeTableQueryBuilder.php @@ -149,9 +149,6 @@ public function getCreateTableCommand( ); } - /** - * @param SnowflakeTableDefinition $definition - */ public function getCreateTableCommandFromDefinition( TableDefinitionInterface $definition, bool $definePrimaryKeys = self::CREATE_TABLE_WITHOUT_PRIMARY_KEYS, diff --git a/packages/php-table-backend-utils/tests/Functional/Bigquery/BigqueryBaseCase.php b/packages/php-table-backend-utils/tests/Functional/Bigquery/BigqueryBaseCase.php index 02ee2b48f..dc4de94b1 100644 --- a/packages/php-table-backend-utils/tests/Functional/Bigquery/BigqueryBaseCase.php +++ b/packages/php-table-backend-utils/tests/Functional/Bigquery/BigqueryBaseCase.php @@ -61,7 +61,6 @@ protected function getCredentials(): array /** @var array $credentials */ $credentials = json_decode($keyFile, true, 512, JSON_THROW_ON_ERROR); - assert($credentials !== false); return $credentials; } diff --git a/packages/php-table-backend-utils/tests/Functional/Bigquery/Connection/QueryTagsTest.php b/packages/php-table-backend-utils/tests/Functional/Bigquery/Connection/QueryTagsTest.php index a44f03dbc..52d2f38ba 100644 --- a/packages/php-table-backend-utils/tests/Functional/Bigquery/Connection/QueryTagsTest.php +++ b/packages/php-table-backend-utils/tests/Functional/Bigquery/Connection/QueryTagsTest.php @@ -40,7 +40,9 @@ public function testRunIdAndBranchIdQueryTagExists(): void $info = $job->info(); $this->assertArrayHasKey('configuration', $info); + $this->assertIsArray($info['configuration']); $this->assertArrayHasKey('labels', $info['configuration']); + $this->assertIsArray($info['configuration']['labels']); $this->assertArrayHasKey('run_id', $info['configuration']['labels']); $this->assertEquals('e2e-utils-lib', $info['configuration']['labels']['run_id']); diff --git a/packages/php-table-backend-utils/tests/Functional/Bigquery/Connection/SessionTest.php b/packages/php-table-backend-utils/tests/Functional/Bigquery/Connection/SessionTest.php index 04364bfca..9eadabc8e 100644 --- a/packages/php-table-backend-utils/tests/Functional/Bigquery/Connection/SessionTest.php +++ b/packages/php-table-backend-utils/tests/Functional/Bigquery/Connection/SessionTest.php @@ -20,9 +20,9 @@ public function testCreateSession(): void $s = new SessionFactory($this->bqClient); $session = $s->createSession(); - $sessionIdDecoded = base64_decode($session->getSessionId()); // session id is base64 string which contains $ - $this->assertIsString($sessionIdDecoded); + $sessionIdDecoded = base64_decode($session->getSessionId()); + $this->assertStringContainsString('$', $sessionIdDecoded); // plain session use $job = $this->bqClient->runJob($this->bqClient->query('SELECT 1', [ diff --git a/packages/php-table-backend-utils/tests/Functional/Bigquery/Table/BigqueryTableReflectionTest.php b/packages/php-table-backend-utils/tests/Functional/Bigquery/Table/BigqueryTableReflectionTest.php index 1d91c8a01..7517ea26b 100644 --- a/packages/php-table-backend-utils/tests/Functional/Bigquery/Table/BigqueryTableReflectionTest.php +++ b/packages/php-table-backend-utils/tests/Functional/Bigquery/Table/BigqueryTableReflectionTest.php @@ -79,12 +79,21 @@ public function testColumnDefinition( self::assertEquals($expectedSqlDefinition, $definition->getSQLDefinition(), 'SQL definition doesnt match'); // check that SQLtoRestDatatypeConverter returns same definition as BQ REST API + $tableInfo = $this->bqClient + ->dataset(self::TEST_SCHEMA) + ->table(self::TABLE_GENERIC) + ->info(); + assert(is_array($tableInfo)); + assert(array_key_exists('schema', $tableInfo)); + assert(is_array($tableInfo['schema'])); + assert(array_key_exists('fields', $tableInfo['schema'])); + assert(is_array($tableInfo['schema']['fields'])); + assert(array_key_exists(1, $tableInfo['schema']['fields'])); + assert(is_array($tableInfo['schema']['fields'][1])); + self::assertEquals( RESTtoSQLDatatypeConverter::convertColumnToSQLFormat( - $this->bqClient - ->dataset(self::TEST_SCHEMA) - ->table(self::TABLE_GENERIC) - ->info()['schema']['fields'][1], + $tableInfo['schema']['fields'][1], ), RESTtoSQLDatatypeConverter::convertColumnToSQLFormat( SQLtoRestDatatypeConverter::convertColumnToRestFormat($column), From 084ed72e9271b2d9458e17f6e84f06d1ce1b966d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Zaj=C3=ADc?= Date: Mon, 29 Dec 2025 22:04:22 +0100 Subject: [PATCH 4/7] ie phpstan2 --- packages/php-db-import-export/composer.json | 6 +- .../phpstan-baseline-php-version.neon.php | 7 +- .../phpstan-baseline.neon | 447 ++++++++++++++++-- .../phpstan-baseline_v7.neon | 346 -------------- packages/php-db-import-export/phpstan.neon | 5 + .../Backend/Snowflake/MockConnectionTrait.php | 1 + .../unit/Storage/ABS/DestinationFileTest.php | 21 - 7 files changed, 424 insertions(+), 409 deletions(-) delete mode 100644 packages/php-db-import-export/phpstan-baseline_v7.neon delete mode 100644 packages/php-db-import-export/tests/unit/Storage/ABS/DestinationFileTest.php diff --git a/packages/php-db-import-export/composer.json b/packages/php-db-import-export/composer.json index 2161f211b..b8535fdac 100644 --- a/packages/php-db-import-export/composer.json +++ b/packages/php-db-import-export/composer.json @@ -31,9 +31,9 @@ "flow-php/types": "^0.21.0", "keboola/coding-standard": "^15", "php-parallel-lint/php-parallel-lint": "^1.3", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^2", + "phpstan/phpstan-phpunit": "^2", "phpunit/phpunit": "^9", "react/async": "^4||^3", "symfony/finder": "^5.4" diff --git a/packages/php-db-import-export/phpstan-baseline-php-version.neon.php b/packages/php-db-import-export/phpstan-baseline-php-version.neon.php index 66725c287..f502cb7b0 100644 --- a/packages/php-db-import-export/phpstan-baseline-php-version.neon.php +++ b/packages/php-db-import-export/phpstan-baseline-php-version.neon.php @@ -3,12 +3,7 @@ declare(strict_types=1); $includes = []; -if (PHP_VERSION_ID < 80000) { - $includes[] = __DIR__ . '/phpstan-baseline_v7.neon'; -} -if (PHP_VERSION_ID >= 80000) { - $includes[] = __DIR__ . '/phpstan-baseline.neon'; -} +$includes[] = __DIR__ . '/phpstan-baseline.neon'; $config = []; $config['includes'] = $includes; diff --git a/packages/php-db-import-export/phpstan-baseline.neon b/packages/php-db-import-export/phpstan-baseline.neon index 0ab0f7ab4..56b04bb49 100644 --- a/packages/php-db-import-export/phpstan-baseline.neon +++ b/packages/php-db-import-export/phpstan-baseline.neon @@ -1,166 +1,547 @@ parameters: ignoreErrors: - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Bigquery\\\\BigqueryException\\:\\:createExceptionFromJobResult\\(\\) has parameter \\$jobInfo with no value type specified in iterable type array\\.$#" + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable count: 1 path: src/Backend/Bigquery/BigqueryException.php - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Bigquery\\\\BigqueryException\\:\\:getErrorMessageForErrorList\\(\\) has parameter \\$parsingErrors with no value type specified in iterable type array\\.$#" + message: '#^Cannot access offset ''errorResult'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Cannot access offset ''errors'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Cannot access offset ''jobId'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Cannot access offset ''message'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 7 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Cannot access offset ''reason'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Method Keboola\\Db\\ImportExport\\Backend\\Bigquery\\BigqueryException\:\:createExceptionFromJobResult\(\) has parameter \$jobInfo with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Method Keboola\\Db\\ImportExport\\Backend\\Bigquery\\BigqueryException\:\:getErrorMessageForErrorList\(\) has parameter \$parsingErrors with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Parameter \#1 \$array of function array_filter expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Parameter \#1 \$haystack of function str_contains expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Parameter \#1 \$message of class Keboola\\Db\\ImportExport\\Backend\\Bigquery\\BigqueryException constructor expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Parameter \#1 \$message of class Keboola\\Db\\ImportExport\\Backend\\Bigquery\\BigqueryInputDataException constructor expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Parameter \#1 \$message of static method Keboola\\Db\\ImportExport\\Backend\\Bigquery\\BigqueryException\:\:isUserError\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Parameter \#2 \$reason of static method Keboola\\Db\\ImportExport\\Backend\\Bigquery\\BigqueryException\:\:isUserError\(\) expects string, mixed given\.$#' + identifier: argument.type count: 1 path: src/Backend/Bigquery/BigqueryException.php - - message: "#^Cannot access offset 'durationSeconds' on mixed\\.$#" + message: '#^Parameter \#3 \$jobId of static method Keboola\\Db\\ImportExport\\Backend\\Bigquery\\BigqueryException\:\:getErrorMessageForErrorList\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Bigquery/BigqueryException.php + + - + message: '#^Cannot access offset ''errorResult'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: src/Backend/Bigquery/ToStage/FromGCSCopyIntoAdapter.php + + - + message: '#^Cannot access offset ''durationSeconds'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible count: 1 path: src/Backend/ImportState.php - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Snowflake\\\\Exporter\\:\\:getAdapter\\(\\) should return Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Snowflake\\\\SnowflakeExportAdapterInterface but returns object\\.$#" + message: '#^Parameter \#2 \$params of method Doctrine\\DBAL\\Connection\:\:executeQuery\(\) expects array\\|string, mixed\>, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Snowflake/Export/AbsExportAdapter.php + + - + message: '#^Parameter \#2 \$params of method Doctrine\\DBAL\\Connection\:\:executeQuery\(\) expects array\\|string, mixed\>, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Snowflake/Export/GcsExportAdapter.php + + - + message: '#^Parameter \#2 \$params of method Doctrine\\DBAL\\Connection\:\:executeQuery\(\) expects array\\|string, mixed\>, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Snowflake/Export/S3ExportAdapter.php + + - + message: '#^Method Keboola\\Db\\ImportExport\\Backend\\Snowflake\\Exporter\:\:getAdapter\(\) should return Keboola\\Db\\ImportExport\\Backend\\Snowflake\\SnowflakeExportAdapterInterface but returns object\.$#' + identifier: return.type count: 1 path: src/Backend/Snowflake/Exporter.php - - message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" + message: '#^Parameter \#1 \$objectOrClass of class ReflectionClass constructor expects class\-string\\|T of object, string given\.$#' + identifier: argument.type count: 1 path: src/Backend/Snowflake/Exporter.php - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Snowflake\\\\Importer\\:\\:getAdapter\\(\\) should return Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Snowflake\\\\SnowflakeImportAdapterInterface but returns object\\.$#" + message: '#^Method Keboola\\Db\\ImportExport\\Backend\\Snowflake\\Importer\:\:getAdapter\(\) should return Keboola\\Db\\ImportExport\\Backend\\Snowflake\\SnowflakeImportAdapterInterface but returns object\.$#' + identifier: return.type count: 1 path: src/Backend/Snowflake/Importer.php - - message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" + message: '#^Parameter \#1 \$objectOrClass of class ReflectionClass constructor expects class\-string\\|T of object, string given\.$#' + identifier: argument.type count: 1 path: src/Backend/Snowflake/Importer.php - - message: "#^Dead catch \\- Error is never thrown in the try block\\.$#" + message: '#^Parameter \#2 \$params of method Doctrine\\DBAL\\Connection\:\:executeQuery\(\) expects array\\|string, mixed\>, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Backend/Snowflake/ToStage/FromTableInsertIntoAdapter.php + + - + message: '#^Dead catch \- Error is never thrown in the try block\.$#' + identifier: catch.neverThrown count: 1 path: src/Backend/SourceDestinationColumnMap.php - - message: "#^Class Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\ABS\\\\BlobIterator implements generic interface Iterator but does not specify its types\\: TKey, TValue$#" + message: '#^Class Keboola\\Db\\ImportExport\\Storage\\ABS\\BlobIterator implements generic interface Iterator but does not specify its types\: TKey, TValue$#' + identifier: missingType.generics count: 1 path: src/Storage/ABS/BlobIterator.php - - message: "#^Cannot access offset 'entries' on mixed\\.$#" + message: '#^PHPDoc tag @var with type string is not subtype of native type non\-empty\-string\|false\.$#' + identifier: varTag.nativeType + count: 1 + path: src/Storage/ABS/ManifestGenerator/AbsSlicedManifestFromFolderGenerator.php + + - + message: '#^PHPDoc tag @var with type string is not subtype of native type non\-empty\-string\|false\.$#' + identifier: varTag.nativeType + count: 1 + path: src/Storage/ABS/ManifestGenerator/AbsSlicedManifestFromUnloadQueryResultGenerator.php + + - + message: '#^Parameter \#2 \$bind of method Keboola\\Db\\Import\\Snowflake\\Connection\:\:query\(\) expects array\\|string, mixed\>, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Storage/ABS/SnowflakeExportAdapter.php + + - + message: '#^Cannot access offset ''entries'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible count: 2 path: src/Storage/ABS/SourceFile.php - - message: "#^Cannot access offset 'url' on mixed\\.$#" + message: '#^Cannot access offset ''url'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible count: 1 path: src/Storage/ABS/SourceFile.php - - message: "#^Cannot access offset 0 on mixed\\.$#" + message: '#^Cannot access offset 0 on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible count: 1 path: src/Storage/ABS/SourceFile.php - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: mixed given\\.$#" + message: '#^Parameter \#1 \$callback of function array_map expects \(callable\(mixed\)\: mixed\)\|null, Closure\(array\)\: mixed given\.$#' + identifier: argument.type count: 1 path: src/Storage/ABS/SourceFile.php - - message: "#^Parameter \\#1 \\$entryUrl of method Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\ABS\\\\SourceFile\\:\\:getBlobPath\\(\\) expects string, mixed given\\.$#" + message: '#^Parameter \#1 \$entries of method Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\:\:transformManifestEntries\(\) expects array\, array given\.$#' + identifier: argument.type count: 1 path: src/Storage/ABS/SourceFile.php - - message: "#^Parameter \\#1 \\$json of function GuzzleHttp\\\\json_decode expects string, string\\|false given\\.$#" + message: '#^Parameter \#1 \$entryUrl of method Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\:\:getBlobPath\(\) expects string, mixed given\.$#' + identifier: argument.type count: 1 path: src/Storage/ABS/SourceFile.php - - message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, mixed given\\.$#" + message: '#^Parameter \#1 \$value of function count expects array\|Countable, mixed given\.$#' + identifier: argument.type count: 1 path: src/Storage/ABS/SourceFile.php - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" + message: '#^Parameter \#2 \$array of function array_map expects array, mixed given\.$#' + identifier: argument.type count: 1 path: src/Storage/ABS/SourceFile.php - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(string\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: mixed given\\.$#" + message: '#^PHPDoc tag @var with type string is not subtype of native type non\-empty\-string\|false\.$#' + identifier: varTag.nativeType + count: 1 + path: src/Storage/GCS/ManifestGenerator/GcsSlicedManifestFromFolderGenerator.php + + - + message: '#^Parameter \#2 \$bind of method Keboola\\Db\\Import\\Snowflake\\Connection\:\:query\(\) expects array\\|string, mixed\>, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Storage/GCS/SnowflakeExportAdapter.php + + - + message: '#^Parameter \#1 \$callback of function array_map expects \(callable\(string\)\: mixed\)\|null, Closure\(array\)\: mixed given\.$#' + identifier: argument.type count: 1 path: src/Storage/GCS/SourceFile.php - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: mixed given\\.$#" + message: '#^Parameter \#1 \$entries of method Keboola\\Db\\ImportExport\\Storage\\GCS\\SourceFile\:\:transformManifestEntries\(\) expects array\, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Storage/GCS/SourceFile.php + + - + message: '#^Parameter \#2 \$bind of method Keboola\\Db\\Import\\Snowflake\\Connection\:\:query\(\) expects array\\|string, mixed\>, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Storage/S3/SnowflakeExportAdapter.php + + - + message: '#^Method Keboola\\Db\\ImportExport\\Storage\\S3\\SourceDirectory\:\:getManifestEntries\(\) should return array\ but returns array\.$#' + identifier: return.type count: 1 path: src/Storage/S3/SourceDirectory.php - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" + message: '#^Parameter \#1 \$callback of function array_map expects \(callable\(mixed\)\: mixed\)\|null, Closure\(array\)\: mixed given\.$#' + identifier: argument.type count: 1 path: src/Storage/S3/SourceDirectory.php - - message: "#^Cannot access offset 'entries' on mixed\\.$#" + message: '#^Parameter \#2 \$array of function array_map expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Storage/S3/SourceDirectory.php + + - + message: '#^Cannot access offset ''entries'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible count: 1 path: src/Storage/S3/SourceFile.php - - message: "#^Cannot access offset 'url' on mixed\\.$#" + message: '#^Cannot access offset ''url'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible count: 1 path: src/Storage/S3/SourceFile.php - - message: "#^Cannot cast mixed to string\\.$#" + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string count: 1 path: src/Storage/S3/SourceFile.php - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\S3\\\\SourceFile\\:\\:getManifestEntries\\(\\) should return array\\ but returns array\\.$#" + message: '#^Method Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile\:\:getManifestEntries\(\) should return array\ but returns array\\.$#' + identifier: return.type count: 1 path: src/Storage/S3/SourceFile.php - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" + message: '#^Parameter \#2 \$array of function array_map expects array, mixed given\.$#' + identifier: argument.type count: 1 path: src/Storage/S3/SourceFile.php - - message: "#^Cannot access offset 'Key' on mixed\\.$#" + message: '#^Parameter \#2 \$bind of method Keboola\\Db\\Import\\Snowflake\\Connection\:\:query\(\) expects array\\|string, mixed\>, array\ given\.$#' + identifier: argument.type + count: 1 + path: src/Storage/Snowflake/SnowflakeImportAdapter.php + + - + message: '#^Cannot access offset ''Key'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible count: 1 path: tests/Common/StubLoader/S3Loader.php - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" + message: '#^Parameter \#2 \$array of function array_map expects array, mixed given\.$#' + identifier: argument.type count: 1 path: tests/Common/StubLoader/S3Loader.php - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: array\\ given\\.$#" + message: '#^Parameter \#2 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\ImportExportBaseTest\:\:getSourceInstance\(\) expects array\, array given\.$#' + identifier: argument.type + count: 3 + path: tests/functional/Bigquery/Exporter/ExportTest.php + + - + message: '#^Parameter \#2 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\ImportExportBaseTest\:\:getSourceInstance\(\) expects array\, array given\.$#' + identifier: argument.type + count: 3 + path: tests/functional/Bigquery/Exporter/ParquetExportTest.php + + - + message: '#^Parameter \#1 \$callback of function array_map expects \(callable\(mixed\)\: mixed\)\|null, Closure\(array\)\: list given\.$#' + identifier: argument.type count: 2 path: tests/functional/Bigquery/SqlBuildTest.php - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" + message: '#^Cannot access offset int\|string on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 4 + path: tests/functional/ImportExportBaseTest.php + + - + message: '#^Method Tests\\Keboola\\Db\\ImportExportFunctional\\ImportExportBaseTest\:\:getBuildPrefix\(\) should return string but returns string\|false\.$#' + identifier: return.type + count: 1 + path: tests/functional/ImportExportBaseTest.php + + - + message: '#^Method Tests\\Keboola\\Db\\ImportExportFunctional\\ImportExportBaseTest\:\:getSourceInstance\(\) should return Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile but returns Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\GCS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile\.$#' + identifier: return.type count: 1 path: tests/functional/ImportExportBaseTest.php - - message: "#^Parameter \\#2 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Snowflake\\\\SnowflakeImportExportBaseTest\\:\\:getSourceInstance\\(\\) expects array\\, mixed given\\.$#" + message: '#^Method Tests\\Keboola\\Db\\ImportExportFunctional\\ImportExportBaseTest\:\:getSourceInstanceFromCsv\(\) should return Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile but returns Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\GCS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile\.$#' + identifier: return.type + count: 1 + path: tests/functional/ImportExportBaseTest.php + + - + message: '#^PHPDoc tag @var with type array\ is not subtype of native type list\\.$#' + identifier: varTag.nativeType + count: 1 + path: tests/functional/ImportExportBaseTest.php + + - + message: '#^Parameter \#1 \$array \(list\\) of array_values is already a list, call has no effect\.$#' + identifier: arrayValues.list + count: 2 + path: tests/functional/ImportExportBaseTest.php + + - + message: '#^Parameter \#2 \$array of function array_map expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: tests/functional/ImportExportBaseTest.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 3 + path: tests/functional/Snowflake/ExportLegacyTest.php + + - + message: '#^Parameter \#1 \$columns of static method Keboola\\Db\\ImportExport\\Backend\\Snowflake\\Helper\\ColumnsHelper\:\:getColumnsString\(\) expects array\, array given\.$#' + identifier: argument.type + count: 1 + path: tests/functional/Snowflake/ExportLegacyTest.php + + - + message: '#^Parameter \#2 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getSourceInstance\(\) expects array\, array given\.$#' + identifier: argument.type + count: 3 + path: tests/functional/Snowflake/ExportLegacyTest.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 4 + path: tests/functional/Snowflake/Exporter/ExportTest.php + + - + message: '#^Parameter \#1 \$columns of static method Keboola\\Db\\ImportExport\\Backend\\Snowflake\\Helper\\ColumnsHelper\:\:getColumnsString\(\) expects array\, array given\.$#' + identifier: argument.type + count: 2 + path: tests/functional/Snowflake/Exporter/ExportTest.php + + - + message: '#^Parameter \#2 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\ImportExportBaseTest\:\:getSourceInstance\(\) expects array\, array given\.$#' + identifier: argument.type + count: 4 + path: tests/functional/Snowflake/Exporter/ExportTest.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 3 + path: tests/functional/Snowflake/Exporter/ParquetExportTest.php + + - + message: '#^Parameter \#2 \$string of method PHPUnit\\Framework\\Assert\:\:assertStringEndsWith\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 3 + path: tests/functional/Snowflake/Exporter/ParquetExportTest.php + + - + message: '#^Parameter \#1 \$array \(list\\) of array_values is already a list, call has no effect\.$#' + identifier: arrayValues.list + count: 3 + path: tests/functional/Snowflake/FullImportTest.php + + - + message: '#^Parameter \#2 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getSourceInstance\(\) expects array\, array given\.$#' + identifier: argument.type + count: 1 + path: tests/functional/Snowflake/FullImportTest.php + + - + message: '#^Parameter \#2 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getSourceInstance\(\) expects array\, mixed given\.$#' + identifier: argument.type count: 10 path: tests/functional/Snowflake/FullImportTest.php - - message: "#^Parameter \\#3 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Snowflake\\\\SnowflakeImportExportBaseTest\\:\\:getSourceInstanceFromCsv\\(\\) expects array\\, mixed given\\.$#" + message: '#^Parameter \#3 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getSourceInstanceFromCsv\(\) expects array\, mixed given\.$#' + identifier: argument.type count: 2 path: tests/functional/Snowflake/FullImportTest.php - - message: "#^Parameter \\#3 \\$columnsNames of class Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\Snowflake\\\\Table constructor expects array\\, mixed given\\.$#" + message: '#^Parameter \#3 \$columnsNames of class Keboola\\Db\\ImportExport\\Storage\\Snowflake\\Table constructor expects array\, mixed given\.$#' + identifier: argument.type count: 1 path: tests/functional/Snowflake/FullImportTest.php - - message: "#^Parameter \\#2 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Snowflake\\\\SnowflakeImportExportBaseTest\\:\\:getSourceInstance\\(\\) expects array\\, mixed given\\.$#" + message: '#^Parameter \#1 \$array \(list\\) of array_values is already a list, call has no effect\.$#' + identifier: arrayValues.list + count: 2 + path: tests/functional/Snowflake/IncrementalImportTest.php + + - + message: '#^Parameter \#2 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getSourceInstance\(\) expects array\, mixed given\.$#' + identifier: argument.type count: 6 path: tests/functional/Snowflake/IncrementalImportTest.php + + - + message: '#^Parameter \#2 \$columns of method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getSourceInstance\(\) expects array\, array given\.$#' + identifier: argument.type + count: 1 + path: tests/functional/Snowflake/OtherImportTest.php + + - + message: '#^Method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getBuildPrefix\(\) should return string but returns string\|false\.$#' + identifier: return.type + count: 1 + path: tests/functional/Snowflake/SnowflakeImportExportBaseTest.php + + - + message: '#^Method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getSourceInstance\(\) should return Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile but returns Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\GCS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile\.$#' + identifier: return.type + count: 1 + path: tests/functional/Snowflake/SnowflakeImportExportBaseTest.php + + - + message: '#^Method Tests\\Keboola\\Db\\ImportExportFunctional\\Snowflake\\SnowflakeImportExportBaseTest\:\:getSourceInstanceFromCsv\(\) should return Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile but returns Keboola\\Db\\ImportExport\\Storage\\ABS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\GCS\\SourceFile\|Keboola\\Db\\ImportExport\\Storage\\S3\\SourceFile\.$#' + identifier: return.type + count: 1 + path: tests/functional/Snowflake/SnowflakeImportExportBaseTest.php + + - + message: '#^Cannot access offset ''name'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: tests/unit/Backend/ImportStateTest.php + + - + message: '#^Method Keboola\\Db\\ImportExport\\Storage\\SourceInterface@anonymous/tests/unit/Backend/Snowflake/SqlCommandBuilderTest\.php\:67\:\:getPrimaryKeysNames\(\) never returns null so it can be removed from the return type\.$#' + identifier: return.unusedType + count: 1 + path: tests/unit/Backend/Snowflake/SqlCommandBuilderTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\SlicedManifestGeneratorInterface'' and Keboola\\Db\\ImportExport\\Storage\\ABS\\ManifestGenerator\\AbsSlicedManifestFromFolderGenerator will always evaluate to true\.$#' + identifier: method.alreadyNarrowedType + count: 1 + path: tests/unit/Storage/ABS/ManifestGenerator/AbsSlicedManifestFromFolderGeneratorTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\SlicedManifestGeneratorInterface'' and Keboola\\Db\\ImportExport\\Storage\\ABS\\ManifestGenerator\\AbsSlicedManifestFromUnloadQueryResultGenerator will always evaluate to true\.$#' + identifier: method.alreadyNarrowedType + count: 1 + path: tests/unit/Storage/ABS/ManifestGenerator/AbsSlicedManifestFromUnloadQueryResultGeneratorTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\SlicedManifestGeneratorInterface'' and Keboola\\Db\\ImportExport\\Storage\\GCS\\ManifestGenerator\\GcsSlicedManifestFromFolderGenerator will always evaluate to true\.$#' + identifier: method.alreadyNarrowedType + count: 1 + path: tests/unit/Storage/GCS/ManifestGenerator/GCSSlicedManifestFromFolderGeneratorTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\SlicedManifestGeneratorInterface'' and Keboola\\Db\\ImportExport\\Storage\\GCS\\ManifestGenerator\\GcsSlicedManifestFromUnloadQueryResultGenerator will always evaluate to true\.$#' + identifier: method.alreadyNarrowedType + count: 1 + path: tests/unit/Storage/GCS/ManifestGenerator/GcsSlicedManifestFromUnloadQueryResultGeneratorTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\SlicedManifestGeneratorInterface'' and Keboola\\Db\\ImportExport\\Storage\\S3\\ManifestGenerator\\S3SlicedManifestFromFolderGenerator will always evaluate to true\.$#' + identifier: method.alreadyNarrowedType + count: 1 + path: tests/unit/Storage/S3/ManifestGenerator/S3SlicedManifestFromFolderGeneratorTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\SlicedManifestGeneratorInterface'' and Keboola\\Db\\ImportExport\\Storage\\S3\\ManifestGenerator\\S3SlicedManifestFromUnloadQueryResultGenerator will always evaluate to true\.$#' + identifier: method.alreadyNarrowedType + count: 1 + path: tests/unit/Storage/S3/ManifestGenerator/S3SlicedManifestFromUnloadQueryResultGeneratorTest.php diff --git a/packages/php-db-import-export/phpstan-baseline_v7.neon b/packages/php-db-import-export/phpstan-baseline_v7.neon deleted file mode 100644 index 404abb3e0..000000000 --- a/packages/php-db-import-export/phpstan-baseline_v7.neon +++ /dev/null @@ -1,346 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Cannot access offset 'durationSeconds' on mixed\\.$#" - count: 1 - path: src/Backend/ImportState.php - - - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Snowflake\\\\Exporter\\:\\:getAdapter\\(\\) should return Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Snowflake\\\\SnowflakeExportAdapterInterface but returns object\\.$#" - count: 1 - path: src/Backend/Snowflake/Exporter.php - - - - message: "#^Parameter \\#1 \\$argument of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" - count: 1 - path: src/Backend/Snowflake/Exporter.php - - - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Snowflake\\\\Importer\\:\\:getAdapter\\(\\) should return Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Snowflake\\\\SnowflakeImportAdapterInterface but returns object\\.$#" - count: 1 - path: src/Backend/Snowflake/Importer.php - - - - message: "#^Parameter \\#1 \\$argument of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" - count: 1 - path: src/Backend/Snowflake/Importer.php - - - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Synapse\\\\Exporter\\:\\:getAdapter\\(\\) should return Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Synapse\\\\SynapseExportAdapterInterface but returns object\\.$#" - count: 1 - path: src/Backend/Synapse/Exporter.php - - - - message: "#^Parameter \\#1 \\$argument of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" - count: 1 - path: src/Backend/Synapse/Exporter.php - - - - message: "#^Parameter \\#2 \\$callback of function array_filter expects callable\\(Keboola\\\\TableBackendUtils\\\\Column\\\\ColumnInterface\\)\\: mixed, Closure\\(Keboola\\\\TableBackendUtils\\\\Column\\\\SynapseColumn\\)\\: bool given\\.$#" - count: 1 - path: src/Backend/Synapse/ToFinalTable/SqlBuilder.php - - - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Teradata\\\\ToStage\\\\Exception\\\\FailedTPTLoadException\\:\\:getLogTableContent\\(\\) should return array\\\\|null but returns array\\|null\\.$#" - count: 1 - path: src/Backend/Teradata/ToStage/Exception/FailedTPTLoadException.php - - - - message: "#^Class Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\ABS\\\\BlobIterator implements generic interface Iterator but does not specify its types\\: TKey, TValue$#" - count: 1 - path: src/Storage/ABS/BlobIterator.php - - - - message: "#^Cannot access offset 'entries' on mixed\\.$#" - count: 3 - path: src/Storage/ABS/SourceFile.php - - - - message: "#^Cannot access offset 'url' on mixed\\.$#" - count: 1 - path: src/Storage/ABS/SourceFile.php - - - - message: "#^Cannot access offset 0 on mixed\\.$#" - count: 1 - path: src/Storage/ABS/SourceFile.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: mixed given\\.$#" - count: 1 - path: src/Storage/ABS/SourceFile.php - - - - message: "#^Parameter \\#1 \\$entryUrl of method Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\ABS\\\\SourceFile\\:\\:getBlobPath\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Storage/ABS/SourceFile.php - - - - message: "#^Parameter \\#1 \\$json of function GuzzleHttp\\\\json_decode expects string, string\\|false given\\.$#" - count: 1 - path: src/Storage/ABS/SourceFile.php - - - - message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, mixed given\\.$#" - count: 1 - path: src/Storage/ABS/SourceFile.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" - count: 1 - path: src/Storage/ABS/SourceFile.php - - - - message: "#^Parameter \\#1 \\$sql of method Doctrine\\\\DBAL\\\\Connection\\:\\:exec\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Storage/ABS/SynapseExportAdapter.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(string\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: mixed given\\.$#" - count: 1 - path: src/Storage/GCS/SourceFile.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: mixed given\\.$#" - count: 1 - path: src/Storage/S3/SourceDirectory.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" - count: 1 - path: src/Storage/S3/SourceDirectory.php - - - - message: "#^Cannot access offset 'entries' on mixed\\.$#" - count: 1 - path: src/Storage/S3/SourceFile.php - - - - message: "#^Cannot access offset 'url' on mixed\\.$#" - count: 1 - path: src/Storage/S3/SourceFile.php - - - - message: "#^Cannot cast mixed to string\\.$#" - count: 1 - path: src/Storage/S3/SourceFile.php - - - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\S3\\\\SourceFile\\:\\:getManifestEntries\\(\\) should return array\\ but returns array\\.$#" - count: 1 - path: src/Storage/S3/SourceFile.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" - count: 1 - path: src/Storage/S3/SourceFile.php - - - - message: "#^Method Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\Synapse\\\\SelectSource\\:\\:__construct\\(\\) has parameter \\$queryBindings with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Storage/Synapse/SelectSource.php - - - - message: "#^PHPDoc tag @param for parameter \\$queryBindings with type array\\|null is not subtype of native type array\\.$#" - count: 1 - path: src/Storage/Synapse/SelectSource.php - - - - message: "#^Cannot access offset 'Key' on mixed\\.$#" - count: 1 - path: tests/Common/StubLoader/S3Loader.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" - count: 1 - path: tests/Common/StubLoader/S3Loader.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: array\\ given\\.$#" - count: 2 - path: tests/functional/Bigquery/SqlBuildTest.php - - - - message: "#^Offset 0 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Exasol/FullImportTest.php - - - - message: "#^Offset 1 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Exasol/FullImportTest.php - - - - message: "#^Parameter \\#2 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Exasol\\\\FullImportTest\\:\\:createS3SourceInstance\\(\\) expects array\\, mixed given\\.$#" - count: 10 - path: tests/functional/Exasol/FullImportTest.php - - - - message: "#^Parameter \\#3 \\$columns of class Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\Exasol\\\\Table constructor expects array\\, mixed given\\.$#" - count: 1 - path: tests/functional/Exasol/FullImportTest.php - - - - message: "#^Parameter \\#3 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Exasol\\\\FullImportTest\\:\\:createS3SourceInstanceFromCsv\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: tests/functional/Exasol/FullImportTest.php - - - - message: "#^Offset 0 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Exasol/IncrementalImportTest.php - - - - message: "#^Offset 1 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Exasol/IncrementalImportTest.php - - - - message: "#^Parameter \\#2 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Exasol\\\\IncrementalImportTest\\:\\:createS3SourceInstance\\(\\) expects array\\, mixed given\\.$#" - count: 6 - path: tests/functional/Exasol/IncrementalImportTest.php - - - - message: "#^Parameter \\#1 \\$datetime of class DateTime constructor expects string, mixed given\\.$#" - count: 1 - path: tests/functional/Exasol/SqlBuilderTest.php - - - - message: "#^Parameter \\#3 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Exasol\\\\StageImportS3Test\\:\\:createS3SourceInstanceFromCsv\\(\\) expects array\\, array given\\.$#" - count: 1 - path: tests/functional/Exasol/StageImportS3Test.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" - count: 1 - path: tests/functional/ImportExportBaseTest.php - - - - message: "#^Parameter \\#2 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Snowflake\\\\SnowflakeImportExportBaseTest\\:\\:getSourceInstance\\(\\) expects array\\, mixed given\\.$#" - count: 10 - path: tests/functional/Snowflake/FullImportTest.php - - - - message: "#^Parameter \\#3 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Snowflake\\\\SnowflakeImportExportBaseTest\\:\\:getSourceInstanceFromCsv\\(\\) expects array\\, mixed given\\.$#" - count: 2 - path: tests/functional/Snowflake/FullImportTest.php - - - - message: "#^Parameter \\#3 \\$columnsNames of class Keboola\\\\Db\\\\ImportExport\\\\Storage\\\\Snowflake\\\\Table constructor expects array\\, mixed given\\.$#" - count: 1 - path: tests/functional/Snowflake/FullImportTest.php - - - - message: "#^Parameter \\#2 \\$columns of method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Snowflake\\\\SnowflakeImportExportBaseTest\\:\\:getSourceInstance\\(\\) expects array\\, mixed given\\.$#" - count: 6 - path: tests/functional/Snowflake/IncrementalImportTest.php - - - - message: "#^Parameter \\#1 \\$fileName of class Keboola\\\\Csv\\\\CsvFile constructor expects string, mixed given\\.$#" - count: 1 - path: tests/functional/Snowflake/SnowflakeImportExportBaseTest.php - - - - message: "#^Parameter \\#1 \\$keys of function array_combine expects array, mixed given\\.$#" - count: 1 - path: tests/functional/Snowflake/SnowflakeImportExportBaseTest.php - - - - message: "#^Parameter \\#2 \\$values of function array_combine expects array, mixed given\\.$#" - count: 1 - path: tests/functional/Snowflake/SnowflakeImportExportBaseTest.php - - - - message: "#^Offset 0 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Synapse/FullImportNoTypesTest.php - - - - message: "#^Offset 1 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Synapse/FullImportNoTypesTest.php - - - - message: "#^Offset 0 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Synapse/FullImportWithTypesTest.php - - - - message: "#^Offset 1 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Synapse/FullImportWithTypesTest.php - - - - message: "#^Offset 0 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Synapse/IncrementalImportNoTypesTest.php - - - - message: "#^Offset 1 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Synapse/IncrementalImportNoTypesTest.php - - - - message: "#^Offset 0 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Synapse/IncrementalImportWithTypesTest.php - - - - message: "#^Offset 1 does not exist on array\\\\.$#" - count: 1 - path: tests/functional/Synapse/IncrementalImportWithTypesTest.php - - - - message: "#^Parameter \\#2 \\$sourceColumnsNames of static method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Synapse\\\\ToStage\\\\StageTableDefinitionFactory\\:\\:createStagingTableDefinition\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: tests/functional/Synapse/OtherImports/StageImportTest.php - - - - message: "#^Parameter \\#1 \\$datetime of class DateTime constructor expects string, mixed given\\.$#" - count: 1 - path: tests/functional/Synapse/SqlBuilderTest.php - - - - message: "#^Parameter \\#2 \\$callback of function array_filter expects callable\\(Keboola\\\\TableBackendUtils\\\\Column\\\\ColumnInterface\\)\\: mixed, Closure\\(Keboola\\\\TableBackendUtils\\\\Column\\\\SynapseColumn\\)\\: bool given\\.$#" - count: 1 - path: tests/functional/Synapse/SqlBuilderTest.php - - - - message: "#^Parameter \\#2 \\$tableName of method Keboola\\\\Db\\\\ImportExport\\\\Backend\\\\Synapse\\\\ToFinalTable\\\\SqlBuilder\\:\\:getDropCommand\\(\\) expects string, mixed given\\.$#" - count: 1 - path: tests/functional/Synapse/SynapseBaseTestCase.php - - - - message: "#^PHPDoc tag @var for variable \\$files has no value type specified in iterable type array\\.$#" - count: 2 - path: tests/functional/Teradata/ExportTest.php - - - - message: "#^Parameter \\#1 \\$expectedFiles of static method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Teradata\\\\ExportTest\\:\\:assertFilesMatch\\(\\) expects array\\, array given\\.$#" - count: 1 - path: tests/functional/Teradata/ExportTest.php - - - - message: "#^Parameter \\#2 \\$files of static method Tests\\\\Keboola\\\\Db\\\\ImportExportFunctional\\\\Teradata\\\\ExportTest\\:\\:assertFilesMatch\\(\\) expects array\\, array\\ given\\.$#" - count: 1 - path: tests/functional/Teradata/ExportTest.php - - - - message: "#^Variable \\$destination in PHPDoc tag @var does not match assigned variable \\$options\\.$#" - count: 1 - path: tests/unit/Storage/ABS/SynapseExportAdapterTest.php - - - message: "#^Left side of && is always true\\.$#" - count: 1 - path: tests/functional/ImportExportBaseTest.php - - - - message: "#^Left side of && is always true\\.$#" - count: 1 - path: tests/functional/Snowflake/SnowflakeImportExportBaseTest.php - - - - message: "#^Left side of && is always true\\.$#" - count: 1 - path: tests/functional/Teradata/ToFinal/IncrementalImportTest.php - diff --git a/packages/php-db-import-export/phpstan.neon b/packages/php-db-import-export/phpstan.neon index e07177684..443b53d86 100644 --- a/packages/php-db-import-export/phpstan.neon +++ b/packages/php-db-import-export/phpstan.neon @@ -1,2 +1,7 @@ includes: - phpstan-baseline-php-version.neon.php +parameters: + treatPhpDocTypesAsCertain: false + ignoreErrors: + - identifier: staticMethod.alreadyNarrowedType + diff --git a/packages/php-db-import-export/tests/unit/Backend/Snowflake/MockConnectionTrait.php b/packages/php-db-import-export/tests/unit/Backend/Snowflake/MockConnectionTrait.php index ad27ee3d0..9eb3abb24 100644 --- a/packages/php-db-import-export/tests/unit/Backend/Snowflake/MockConnectionTrait.php +++ b/packages/php-db-import-export/tests/unit/Backend/Snowflake/MockConnectionTrait.php @@ -19,6 +19,7 @@ private function mockConnection() $mock = $this->createMock(Connection::class); $mock->expects(self::any())->method('quoteIdentifier')->willReturnCallback(static function ($input) { + assert(is_string($input)); return QuoteHelper::quoteIdentifier($input); }); diff --git a/packages/php-db-import-export/tests/unit/Storage/ABS/DestinationFileTest.php b/packages/php-db-import-export/tests/unit/Storage/ABS/DestinationFileTest.php deleted file mode 100644 index 80c3bf260..000000000 --- a/packages/php-db-import-export/tests/unit/Storage/ABS/DestinationFileTest.php +++ /dev/null @@ -1,21 +0,0 @@ -createABSSourceDestinationInstance('file.csv'); - self::assertInstanceOf(Storage\ABS\BaseFile::class, $source); - self::assertInstanceOf(Storage\DestinationInterface::class, $source); - } -} From c4aa2826c643bf8901ddff29fc3e326dab124123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Zaj=C3=ADc?= Date: Mon, 29 Dec 2025 22:16:49 +0100 Subject: [PATCH 5/7] driver-snflk phpstan2 --- packages/php-storage-driver-snowflake/composer.json | 4 ++-- packages/php-storage-driver-snowflake/phpstan.neon | 4 ++++ .../src/Handler/Bucket/CreateBucketHandler.php | 4 ++-- .../src/Handler/Project/CreateProjectHandler.php | 2 +- .../src/Handler/Project/DropDevBranchHandler.php | 3 +-- .../src/Handler/Table/ProfileTableHandler.php | 3 ++- .../src/SnowflakeDriverClient.php | 3 ++- 7 files changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/php-storage-driver-snowflake/composer.json b/packages/php-storage-driver-snowflake/composer.json index 9312e2629..3efcaa038 100644 --- a/packages/php-storage-driver-snowflake/composer.json +++ b/packages/php-storage-driver-snowflake/composer.json @@ -18,8 +18,8 @@ }, "require-dev": { "keboola/coding-standard": "^15", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan": "^2", + "phpstan/phpstan-phpunit": "^2", "phpunit/phpunit": "^9" }, "autoload": { diff --git a/packages/php-storage-driver-snowflake/phpstan.neon b/packages/php-storage-driver-snowflake/phpstan.neon index b6753bb36..9fa925254 100644 --- a/packages/php-storage-driver-snowflake/phpstan.neon +++ b/packages/php-storage-driver-snowflake/phpstan.neon @@ -1,3 +1,7 @@ parameters: + treatPhpDocTypesAsCertain: false + ignoreErrors: + - identifier: method.alreadyNarrowedType + includes: - vendor/phpstan/phpstan-phpunit/extension.neon diff --git a/packages/php-storage-driver-snowflake/src/Handler/Bucket/CreateBucketHandler.php b/packages/php-storage-driver-snowflake/src/Handler/Bucket/CreateBucketHandler.php index 8ccd051b5..40163de47 100644 --- a/packages/php-storage-driver-snowflake/src/Handler/Bucket/CreateBucketHandler.php +++ b/packages/php-storage-driver-snowflake/src/Handler/Bucket/CreateBucketHandler.php @@ -22,14 +22,14 @@ final class CreateBucketHandler extends BaseHandler * @inheritDoc * @param GenericBackendCredentials $credentials * @param CreateBucketCommand $command - * @return CreateBucketResponse|null + * @return CreateBucketResponse */ public function __invoke( Message $credentials, Message $command, array $features, Message $runtimeOptions, - ): Message|null { + ): Message { assert($credentials instanceof GenericBackendCredentials); assert($command instanceof CreateBucketCommand); diff --git a/packages/php-storage-driver-snowflake/src/Handler/Project/CreateProjectHandler.php b/packages/php-storage-driver-snowflake/src/Handler/Project/CreateProjectHandler.php index c6911d473..a4a2f7bcc 100644 --- a/packages/php-storage-driver-snowflake/src/Handler/Project/CreateProjectHandler.php +++ b/packages/php-storage-driver-snowflake/src/Handler/Project/CreateProjectHandler.php @@ -38,7 +38,7 @@ public function __invoke( Message $command, array $features, Message $runtimeOptions, - ): ?Message { + ): Message { assert($credentials instanceof GenericBackendCredentials); assert($command instanceof CreateProjectCommand); diff --git a/packages/php-storage-driver-snowflake/src/Handler/Project/DropDevBranchHandler.php b/packages/php-storage-driver-snowflake/src/Handler/Project/DropDevBranchHandler.php index ff43c0671..8fed86719 100644 --- a/packages/php-storage-driver-snowflake/src/Handler/Project/DropDevBranchHandler.php +++ b/packages/php-storage-driver-snowflake/src/Handler/Project/DropDevBranchHandler.php @@ -17,14 +17,13 @@ final class DropDevBranchHandler extends BaseHandler * @inheritDoc * @param GenericBackendCredentials $credentials * @param DropDevBranchCommand $command - * @return null */ public function __invoke( Message $credentials, Message $command, array $features, Message $runtimeOptions, - ): Message|null { + ): null { assert($credentials instanceof GenericBackendCredentials); assert($command instanceof DropDevBranchCommand); diff --git a/packages/php-storage-driver-snowflake/src/Handler/Table/ProfileTableHandler.php b/packages/php-storage-driver-snowflake/src/Handler/Table/ProfileTableHandler.php index d5dfa76b5..ee2b0a2df 100644 --- a/packages/php-storage-driver-snowflake/src/Handler/Table/ProfileTableHandler.php +++ b/packages/php-storage-driver-snowflake/src/Handler/Table/ProfileTableHandler.php @@ -32,13 +32,14 @@ final class ProfileTableHandler extends BaseHandler * @inheritDoc * @param GenericBackendCredentials $credentials * @param CreateProfileTableCommand $command + * @return CreateProfileTableResponse */ public function __invoke( Message $credentials, Message $command, array $features, Message $runtimeOptions, - ): Message|null { + ): Message { assert($credentials instanceof GenericBackendCredentials); assert($command instanceof CreateProfileTableCommand); diff --git a/packages/php-storage-driver-snowflake/src/SnowflakeDriverClient.php b/packages/php-storage-driver-snowflake/src/SnowflakeDriverClient.php index 1029900de..43de4e52e 100644 --- a/packages/php-storage-driver-snowflake/src/SnowflakeDriverClient.php +++ b/packages/php-storage-driver-snowflake/src/SnowflakeDriverClient.php @@ -28,13 +28,14 @@ public function __construct( /** * @param string[] $features + * @return DriverResponse */ public function runCommand( Message $credentials, Message $command, array $features, Message $runtimeOptions, - ): Message|null { + ): Message { $handler = HandlerFactory::create( $command, $this->internalLogger, From 18f39113274d992cd9d47d4dae249f2d1a6418cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Zaj=C3=ADc?= Date: Mon, 29 Dec 2025 22:19:14 +0100 Subject: [PATCH 6/7] driver-common phpstan2 --- .../Shared/Driver/Logger/UserInMemoryLogger.php | 2 +- packages/php-storage-driver-common/composer.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/php-storage-driver-common/Shared/Driver/Logger/UserInMemoryLogger.php b/packages/php-storage-driver-common/Shared/Driver/Logger/UserInMemoryLogger.php index b5c667e16..33c7df47d 100644 --- a/packages/php-storage-driver-common/Shared/Driver/Logger/UserInMemoryLogger.php +++ b/packages/php-storage-driver-common/Shared/Driver/Logger/UserInMemoryLogger.php @@ -43,7 +43,7 @@ public function __construct() /** * @throws \JsonException - * @param mixed $level + * @param string $level * @param Stringable|string $message * @param array $context */ diff --git a/packages/php-storage-driver-common/composer.json b/packages/php-storage-driver-common/composer.json index 2c3f401ff..206d09d7a 100644 --- a/packages/php-storage-driver-common/composer.json +++ b/packages/php-storage-driver-common/composer.json @@ -19,9 +19,9 @@ }, "require-dev": { "phpunit/phpunit": "^9", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpstan/phpstan-symfony": "^1.1", + "phpstan/phpstan": "^2", + "phpstan/phpstan-phpunit": "^2", + "phpstan/phpstan-symfony": "^2", "keboola/coding-standard": "^15", "php-parallel-lint/php-parallel-lint": "^1.3", "symfony/finder": "^5.4", From 66af596fca59d5cbf341a9a699726f90c32b8d3d Mon Sep 17 00:00:00 2001 From: zajca Date: Sun, 4 Jan 2026 20:48:46 +0100 Subject: [PATCH 7/7] fix dep --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6f3895c92..cec0d3edc 100755 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "keboola/coding-standard": "^15", "keboola/phpunit-retry-annotations": "^0.3.0", "php-parallel-lint/php-parallel-lint": "^1.3", - "phpstan/extension-installer": "^1.1", + "phpstan/extension-installer": "^1", "phpstan/phpdoc-parser": "^1.6", "phpstan/phpstan": "^2", "phpstan/phpstan-phpunit": "^2",