diff --git a/composer.json b/composer.json index 45ecf846..e0d84c48 100644 --- a/composer.json +++ b/composer.json @@ -46,6 +46,7 @@ } }, "config": { + "process-timeout": 0, "allow-plugins": { "phpstan/extension-installer": true, "pestphp/pest-plugin": true diff --git a/phpstan.neon b/phpstan.neon index 407209e2..eea61ca0 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,7 +3,7 @@ includes: - phpstan-baseline.neon parameters: - level: 5 + level: 6 paths: - src - tests diff --git a/src/Connection.php b/src/Connection.php index e6db4a19..bdd94b65 100755 --- a/src/Connection.php +++ b/src/Connection.php @@ -26,6 +26,7 @@ use Artemeon\Database\Schema\TableIndex; use Generator; use InvalidArgumentException; +use Override; use Psr\Log\LoggerInterface; /** @@ -42,9 +43,14 @@ class Connection implements ConnectionInterface { /** * Array to cache queries. + * + * @var array> */ private array $queryCache = []; + /** + * @var array> + */ private array $tablesCache = []; /** @@ -52,6 +58,9 @@ class Connection implements ConnectionInterface */ private int $number = 0; + /** + * @var list + */ private array $queries = []; /** @@ -131,7 +140,7 @@ protected function dbconnect(): void * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function multiInsert(string $tableName, array $columns, array $valueSets, ?array $escapes = null): bool { if (!$this->connected) { @@ -164,7 +173,7 @@ public function multiInsert(string $tableName, array $columns, array $valueSets, * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function insert(string $tableName, array $values, ?array $escapes = null): int { $this->multiInsert($tableName, array_keys($values), [array_values($values)], $escapes); @@ -175,7 +184,7 @@ public function insert(string $tableName, array $values, ?array $escapes = null) /** * @inheritDoc */ - #[\Override] + #[Override] public function selectRow( string $tableName, array $columns, @@ -214,7 +223,7 @@ public function selectRow( * @inheritDoc * @throws QueryException */ - #[\Override] + #[Override] public function update(string $tableName, array $values, array $identifier, ?array $escapes = null): int { if (empty($identifier)) { @@ -245,7 +254,7 @@ public function update(string $tableName, array $values, array $identifier, ?arr * @inheritDoc * @throws QueryException */ - #[\Override] + #[Override] public function delete(string $tableName, array $identifier): int { if (empty($identifier)) { @@ -270,7 +279,7 @@ public function delete(string $tableName, array $identifier): int * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function insertOrUpdate(string $tableName, array $columns, array $values, array $primaryColumns): bool { if (!$this->connected) { @@ -289,7 +298,7 @@ public function insertOrUpdate(string $tableName, array $columns, array $values, * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function _pQuery(string $query, array $params = [], array $escapes = []): bool { if (!$this->connected) { @@ -328,7 +337,7 @@ public function _pQuery(string $query, array $params = [], array $escapes = []): * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function executeStatement(string $query, array $params = []): int { $this->_pQuery($query, $params); @@ -339,7 +348,7 @@ public function executeStatement(string $query, array $params = []): int /** * @inheritDoc */ - #[\Override] + #[Override] public function getAffectedRowsCount(): int { return $this->dbDriver->getAffectedRowsCount(); @@ -349,7 +358,7 @@ public function getAffectedRowsCount(): int * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function getPRow(string $query, array $params = [], int $number = 0, bool $cache = true, array $escapes = []): array { if (!$this->connected) { @@ -374,7 +383,7 @@ public function getPRow(string $query, array $params = [], int $number = 0, bool * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function getPArray( string $query, array $params = [], @@ -434,7 +443,7 @@ public function getPArray( * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function getGenerator(string $query, array $params = [], int $chunkSize = 2048, bool $paging = true): Generator { if (!$this->connected) { @@ -465,7 +474,7 @@ public function getGenerator(string $query, array $params = [], int $chunkSize = * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function fetchAllAssociative(string $query, array $params = []): array { if (!$this->connected) { @@ -488,7 +497,7 @@ public function fetchAllAssociative(string $query, array $params = []): array * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function fetchAssociative(string $query, array $params = []): array | false { if (!$this->connected) { @@ -515,7 +524,7 @@ public function fetchAssociative(string $query, array $params = []): array | fal * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function fetchFirstColumn(string $query, array $params = []): array { if (!$this->connected) { @@ -538,7 +547,7 @@ public function fetchFirstColumn(string $query, array $params = []): array * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function fetchOne(string $query, array $params = []): mixed { if (!$this->connected) { @@ -558,7 +567,7 @@ public function fetchOne(string $query, array $params = []): mixed * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function iterateAssociative(string $query, array $params = []): Generator { if (!$this->connected) { @@ -575,7 +584,7 @@ public function iterateAssociative(string $query, array $params = []): Generator * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function iterateColumn(string $query, array $params = []): Generator { if (!$this->connected) { @@ -593,6 +602,8 @@ public function iterateColumn(string $query, array $params = []): Generator /** * Writes the last DB-Error to the screen. * + * @param list $params + * * @throws QueryException * @throws ConnectionException */ @@ -642,7 +653,7 @@ private function getError(string $query, array $params): void * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function beginTransaction(): void { if (!$this->connected) { @@ -666,7 +677,7 @@ public function beginTransaction(): void * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function transactionBegin(): void { $this->beginTransaction(); @@ -677,7 +688,7 @@ public function transactionBegin(): void * @throws CommitException * @throws ConnectionException */ - #[\Override] + #[Override] public function commit(): void { if (!$this->connected) { @@ -710,7 +721,7 @@ public function commit(): void * @throws ConnectionException * @throws CommitException */ - #[\Override] + #[Override] public function transactionCommit(): void { $this->commit(); @@ -720,7 +731,7 @@ public function transactionCommit(): void * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function rollBack(): void { if (!$this->connected) { @@ -744,13 +755,13 @@ public function rollBack(): void * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function transactionRollback(): void { $this->rollBack(); } - #[\Override] + #[Override] public function hasOpenTransactions(): bool { return $this->numberOfOpenTransactions > 0; @@ -759,7 +770,7 @@ public function hasOpenTransactions(): bool /** * @inheritDoc */ - #[\Override] + #[Override] public function hasDriver(string $class): bool { return $this->dbDriver instanceof $class; @@ -769,7 +780,7 @@ public function hasDriver(string $class): bool * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function getTables(?string $prefix = null): array { if ($prefix === null) { @@ -811,7 +822,7 @@ public function getTables(?string $prefix = null): array * @throws ConnectionException * @deprecated */ - #[\Override] + #[Override] public function getColumnsOfTable(string $tableName): array { if (!$this->hasTable($tableName)) { @@ -841,7 +852,7 @@ public function getColumnsOfTable(string $tableName): array * @throws TableNotFoundException * @throws ConnectionException */ - #[\Override] + #[Override] public function getTableInformation(string $tableName): Table { if (!$this->hasTable($tableName)) { @@ -858,7 +869,7 @@ public function getTableInformation(string $tableName): Table /** * @inheritDoc */ - #[\Override] + #[Override] public function getDatatype(DataType $type): string { return $this->dbDriver->getDatatype($type); @@ -868,7 +879,7 @@ public function getDatatype(DataType $type): string * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function createTable(string $tableName, array $columns, array $keys, array $indices = []): bool { if (!$this->connected) { @@ -912,7 +923,7 @@ public function createTable(string $tableName, array $columns, array $keys, arra * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function dropTable(string $tableName): void { if (!$this->hasTable($tableName)) { @@ -928,7 +939,7 @@ public function dropTable(string $tableName): void * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function generateTableFromMetadata(Table $table): void { $columns = []; @@ -952,7 +963,7 @@ public function generateTableFromMetadata(Table $table): void * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function createIndex(string $tableName, string $name, array $columns, bool $unique = false): bool { if (!$this->connected) { @@ -974,7 +985,7 @@ public function createIndex(string $tableName, string $name, array $columns, boo * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function deleteIndex(string $table, string $index): bool { if (!$this->connected) { @@ -988,7 +999,7 @@ public function deleteIndex(string $table, string $index): bool * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function addIndex(string $table, TableIndex $index): bool { if (!$this->connected) { @@ -1002,7 +1013,7 @@ public function addIndex(string $table, TableIndex $index): bool * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function hasIndex(string $tableName, string $name): bool { if (!$this->connected) { @@ -1016,7 +1027,7 @@ public function hasIndex(string $tableName, string $name): bool * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function renameTable(string $oldName, string $newName): bool { if (!$this->connected) { @@ -1034,7 +1045,7 @@ public function renameTable(string $oldName, string $newName): bool * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function changeColumn(string $tableName, string $oldColumnName, string $newColumnName, DataType $newDataType): bool { if (!$this->connected) { @@ -1065,7 +1076,7 @@ public function changeColumn(string $tableName, string $oldColumnName, string $n * @throws ConnectionException * @throws QueryException */ - #[\Override] + #[Override] public function addColumn(string $table, string $column, DataType $dataType, ?bool $nullable = null, ?string $default = null): bool { if (!$this->connected) { @@ -1100,7 +1111,7 @@ public function addColumn(string $table, string $column, DataType $dataType, ?bo * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function removeColumn(string $tableName, string $column): bool { if (!$this->connected) { @@ -1123,7 +1134,7 @@ public function removeColumn(string $tableName, string $column): bool /** * @inheritDoc */ - #[\Override] + #[Override] public function hasColumn(string $tableName, string $column): bool { return $this->dbDriver->hasColumn($tableName, $column); @@ -1133,7 +1144,7 @@ public function hasColumn(string $tableName, string $column): bool * @inheritDoc * @throws ConnectionException */ - #[\Override] + #[Override] public function hasTable(string $tableName): bool { return in_array($tableName, $this->getTables(), true); @@ -1151,6 +1162,9 @@ private function processQuery(string $query): string return str_replace($search, $replace, $query); } + /** + * @param list $params + */ private function addQueryToList(string $query, array $params, bool $cached, float $startTime): void { if ($this->debugLevel !== 100) { @@ -1169,7 +1183,7 @@ private function addQueryToList(string $query, array $params, bool $cached, floa * * @throws ConnectionException */ - #[\Override] + #[Override] public function getDbInfo(): array { if (!$this->connected) { @@ -1186,7 +1200,7 @@ public function getDbInfo(): array /** * Returns an array of all queries. */ - #[\Override] + #[Override] public function getQueries(): array { return $this->queries; @@ -1196,7 +1210,7 @@ public function getQueries(): array * Returns the number of queries sent to the database * including those solved by the cache. */ - #[\Override] + #[Override] public function getNumber(): int { return $this->number; @@ -1205,7 +1219,7 @@ public function getNumber(): int /** * Returns the number of queries solved by the cache. */ - #[\Override] + #[Override] public function getNumberCache(): int { return $this->numberCache; @@ -1214,7 +1228,7 @@ public function getNumberCache(): int /** * Returns the number of items currently in the query-cache. */ - #[\Override] + #[Override] public function getCacheSize(): int { return count($this->queryCache); @@ -1224,8 +1238,13 @@ public function getCacheSize(): int * An internal wrapper to dbsafeString, used to process a complete array of parameters * as used by prepared statements. * - * @param array|false $escapes An array of boolean for each param, used to block the escaping of html-special chars. - * If not passed, all params will be cleaned. + * @template TKey of array-key + * + * @param array $params + * @param list|false $escapes An array of boolean for each param, used to block the escaping of html-special chars. + * If not passed, all params will be cleaned. + * + * @return array * * @see Db::dbsafeString($string, $htmlSpecialChars = true) */ @@ -1300,7 +1319,7 @@ public function dbsafeString(mixed $input, bool $htmlSpecialChars = true, bool $ /** * Method to flush the query-cache. */ - #[\Override] + #[Override] public function flushQueryCache(): void { $this->queryCache = []; @@ -1311,7 +1330,7 @@ public function flushQueryCache(): void * Since the tables won't change during regular operations, * flushing the tables cache is only required during package updates / installations. */ - #[\Override] + #[Override] public function flushTablesCache(): void { $this->tablesCache = []; @@ -1323,7 +1342,7 @@ public function flushTablesCache(): void * * @throws ConnectionException */ - #[\Override] + #[Override] public function flushPreparedStatementsCache(): void { if (!$this->connected) { @@ -1336,7 +1355,7 @@ public function flushPreparedStatementsCache(): void /** * @inheritDoc */ - #[\Override] + #[Override] public function encloseColumnName(string $column): string { return $this->dbDriver->encloseColumnName($column); @@ -1345,7 +1364,7 @@ public function encloseColumnName(string $column): string /** * @inheritDoc */ - #[\Override] + #[Override] public function encloseTableName(string $tableName): string { return $this->dbDriver->encloseTableName($tableName); @@ -1369,7 +1388,7 @@ public function validateDatabaseConnectionData(ConnectionParameters $config): bo return false; } - #[\Override] + #[Override] public function isConnected(): bool { return $this->connected; @@ -1380,7 +1399,7 @@ public function isConnected(): bool * method unifies the behaviour. In order to select a column, which contains a backslash you need to escape the value * with this method. */ - #[\Override] + #[Override] public function escape(mixed $value): mixed { return $this->dbDriver->escape($value); @@ -1389,7 +1408,7 @@ public function escape(mixed $value): mixed /** * @inheritDoc */ - #[\Override] + #[Override] public function prettifyQuery(string $query, array $params): string { foreach ($params as $param) { @@ -1415,13 +1434,13 @@ public function prettifyQuery(string $query, array $params): string /** * @inheritDoc */ - #[\Override] + #[Override] public function appendLimitExpression(string $query, int $start, int $end): string { return $this->dbDriver->appendLimitExpression($query, $start, $end); } - #[\Override] + #[Override] public function getConcatExpression(array $parts): string { return $this->dbDriver->getConcatExpression($parts); @@ -1430,37 +1449,37 @@ public function getConcatExpression(array $parts): string /** * @inheritDoc */ - #[\Override] + #[Override] public function convertToDatabaseValue(mixed $value, DataType $type): mixed { return $this->dbDriver->convertToDatabaseValue($value, $type); } - #[\Override] + #[Override] public function getLeastExpression(array $parts): string { return $this->dbDriver->getLeastExpression($parts); } - #[\Override] + #[Override] public function getSubstringExpression(string $value, int $offset, ?int $length): string { return $this->dbDriver->getSubstringExpression($value, $offset, $length); } - #[\Override] + #[Override] public function getStringLengthExpression(string $targetString): string { return $this->dbDriver->getStringLengthExpression($targetString); } - #[\Override] + #[Override] public function getJsonColumnExpression(string $column, string $key): string { return $this->dbDriver->getJsonColumnExpression($column, $key); } - #[\Override] + #[Override] public function getNthLastElementFromSlug(string $column, int $position): string { return $this->dbDriver->getNthLastElementFromSlug($column, $position); diff --git a/src/ConnectionInterface.php b/src/ConnectionInterface.php index 44c5ef92..021ca7b5 100755 --- a/src/ConnectionInterface.php +++ b/src/ConnectionInterface.php @@ -36,7 +36,12 @@ interface ConnectionInterface extends DoctrineConnectionInterface * Method to get an array of rows for a given query from the database. * Makes use of prepared statements. * + * @param list $params + * @param list $escapes + * * @throws QueryException + * @return array> + * * @see fetchAllAssociative */ public function getPArray(string $query, array $params = [], ?int $start = null, ?int $end = null, bool $cache = true, array $escapes = []): array; @@ -49,7 +54,12 @@ public function getPArray(string $query, array $params = [], ?int $start = null, * Returns one row from a result-set. * Makes use of prepared statements. * + * @param list $params + * @param list $escapes + * * @throws QueryException + * @return array + * * @see fetchAssociative */ public function getPRow(string $query, array $params = [], int $number = 0, bool $cache = true, array $escapes = []): array; @@ -58,11 +68,13 @@ public function getPRow(string $query, array $params = [], int $number = 0, bool * Retrieves a single row of the referenced table, returning the requested columns and filtering by the given identifier(s). * * @param string $tableName the table name from which to select the row - * @param array $columns a flat list of column names to select - * @param array $identifiers mapping of column name to value to search for (e.g. ["id" => 1]) + * @param list $columns a flat list of column names to select + * @param array $identifiers mapping of column name to value to search for (e.g. ["id" => 1]) * @param bool $cached whether a previously selected result can be reused - * @param array|null $escapes which parameters to escape (described in {@see dbsafeParams}) + * @param list|null $escapes which parameters to escape (described in {@see dbsafeParams}) * @throws QueryException + * + * @return array|null */ public function selectRow(string $tableName, array $columns, array $identifiers, bool $cached = true, ?array $escapes = []): ?array; @@ -79,6 +91,8 @@ public function selectRow(string $tableName, array $columns, array $identifiers, * false and don't modify the result set you will get an endless loop, so you must get sure that in the end the * result set will be empty. * + * @param list $params + * * @throws QueryException * @see iterateAssociative */ @@ -89,8 +103,9 @@ public function getGenerator(string $query, array $params = [], int $chunkSize = * * Sending a prepared statement to the database * - * @param array $escapes An array of booleans for each param, used to block the escaping of html-special chars. - * If not passed, all params will be cleaned. + * @param list $params + * @param list $escapes An array of booleans for each param, used to block the escaping of html-special chars. + * If not passed, all params will be cleaned. * @throws QueryException * @see executeStatement */ @@ -106,7 +121,9 @@ public function getAffectedRowsCount(): int; * For most databases, this will create s.th. like * INSERT INTO $table ($columns) VALUES (?, ?), (?, ?)... * - * @param string[] $columns + * @param list $columns + * @param list $valueSets + * @param list|null $escapes * @throws QueryException */ public function multiInsert(string $tableName, array $columns, array $valueSets, ?array $escapes = null): bool; @@ -117,6 +134,10 @@ public function multiInsert(string $tableName, array $columns, array $valueSets, * Please note: since some DBRMs fire a delete && insert, make sure to pass ALL columns and values, * otherwise data might be lost. And: params are sent to the database unescaped. * + * @param list $columns + * @param list $values + * @param list $primaryColumns + * * @throws QueryException */ public function insertOrUpdate(string $tableName, array $columns, array $values, array $primaryColumns): bool; @@ -155,6 +176,7 @@ public function hasDriver(string $class): bool; * Returns all tables used by the project. * * @throws QueryException + * @return list */ public function getTables(): array; @@ -174,7 +196,9 @@ public function getDatatype(DataType $type): string; * Used to send a `CREATE TABLE` statement to the database. * By passing the query through this method, the driver can add db-specific commands. * - * @param array $columns + * @param array $columns + * @param list $keys + * @param list|string> $indices * * @throws QueryException */ @@ -199,6 +223,8 @@ public function generateTableFromMetadata(Table $table): void; * Creates a new index on the provided table over the given columns. If unique is true we create a unique index * where each index can only occur once in the table. * + * @param list $columns + * * @throws QueryException */ public function createIndex(string $tableName, string $name, array $columns, bool $unique = false): bool; @@ -285,6 +311,8 @@ public function encloseTableName(string $tableName): string; /** * Helper to replace all param-placeholder with the matching value, only to be used * to render a debuggable-statement. + * + * @param list $params */ public function prettifyQuery(string $query, array $params): string; @@ -293,8 +321,14 @@ public function prettifyQuery(string $query, array $params): string; */ public function appendLimitExpression(string $query, int $start, int $end): string; + /** + * @param list $parts + */ public function getConcatExpression(array $parts): string; + /** + * @param list $parts + */ public function getLeastExpression(array $parts): string; /** @@ -320,11 +354,15 @@ public function convertToDatabaseValue(mixed $value, DataType $type): mixed; /** * Queries the current db-driver about common information. + * + * @return array */ public function getDbInfo(): array; /** * Returns an array of all queries. + * + * @return list */ public function getQueries(): array; diff --git a/src/ConnectionParameters.php b/src/ConnectionParameters.php index 0ce37488..edd25232 100644 --- a/src/ConnectionParameters.php +++ b/src/ConnectionParameters.php @@ -20,6 +20,9 @@ final class ConnectionParameters { public const string SQLITE3_BASE_PATH = 'sqlite3_base_path'; + /** + * @var array + */ private array $attributes = []; public function __construct( @@ -74,6 +77,16 @@ public function getAttribute(string $key): mixed return $this->attributes[$key] ?? null; } + /** + * @param array{ + * dbhost?:string|null, + * dbusername?:string|null, + * dbpassword?:string|null, + * dbname?:string|null, + * dbport?:int|string|null, + * dbdriver?:string|null, + * } $data + */ public static function fromArray(array $data): self { return new self( diff --git a/src/DoctrineConnectionInterface.php b/src/DoctrineConnectionInterface.php index 63c0e3f2..e9fbfa71 100644 --- a/src/DoctrineConnectionInterface.php +++ b/src/DoctrineConnectionInterface.php @@ -26,33 +26,51 @@ interface DoctrineConnectionInterface { /** * Prepares and executes an SQL query and returns the result as an array of associative arrays. + * + * @param list $params + * + * @return list> */ public function fetchAllAssociative(string $query, array $params = []): array; /** * Prepares and executes an SQL query and returns the first row of the result * as an associative array. + * + * @param list $params + * + * @return array|false */ public function fetchAssociative(string $query, array $params = []): array | false; /** * Prepares and executes an SQL query and returns the result as an array of the first column values. + * + * @param list $params + * + * @return list */ public function fetchFirstColumn(string $query, array $params = []): array; /** * Prepares and executes an SQL query and returns the value of a single column of the first row of the result. + * + * @param list $params */ public function fetchOne(string $query, array $params = []): mixed; /** * Prepares and executes an SQL query and returns the result as an iterator over rows represented * as associative arrays. + * + * @param list $params */ public function iterateAssociative(string $query, array $params = []): Generator; /** * Prepares and executes an SQL query and returns the result as an iterator over the first column values. + * + * @param list $params */ public function iterateColumn(string $query, array $params = []): Generator; @@ -65,22 +83,33 @@ public function iterateColumn(string $query, array $params = []): Generator; * - DCL statements: GRANT, REVOKE, etc. * - Session control statements: ALTER SESSION, SET, DECLARE, etc. * - Other statements that don't yield a row set. + * + * @param list $params */ public function executeStatement(string $query, array $params = []): int; /** * Creates a simple insert for a single row where the values parameter is an associative array with column names to * value mapping. + * + * @param array $values + * @param list|null $escapes */ public function insert(string $tableName, array $values, ?array $escapes = null): int; /** * Updates a row on the provided table by the identifier columns. + * + * @param array $values + * @param array $identifier + * @param list|null $escapes */ public function update(string $tableName, array $values, array $identifier, ?array $escapes = null): int; /** * Deletes a row on the provided table by the identifier columns. + * + * @param array $identifier */ public function delete(string $tableName, array $identifier): int; diff --git a/src/Driver/DriverAbstract.php b/src/Driver/DriverAbstract.php index ffd44176..0a246e17 100644 --- a/src/Driver/DriverAbstract.php +++ b/src/Driver/DriverAbstract.php @@ -19,6 +19,7 @@ use Artemeon\Database\Exception\QueryException; use Artemeon\Database\Schema\DataType; use Artemeon\Database\Schema\TableIndex; +use Override; use Symfony\Component\Process\Process; /** @@ -28,6 +29,9 @@ */ abstract class DriverAbstract implements DriverInterface { + /** + * @var array + */ protected array $statementsCache = []; protected int $affectedRowsCount = 0; @@ -50,7 +54,7 @@ protected function isWinOs(): bool /** * @inheritDoc */ - #[\Override] + #[Override] public function handlesDumpCompression(): bool { return !$this->isWinOs(); @@ -59,7 +63,7 @@ public function handlesDumpCompression(): bool /** * @inheritDoc */ - #[\Override] + #[Override] public function hasColumn(string $tableName, string $columnName): bool { $table = $this->getTableInformation($tableName); @@ -70,7 +74,7 @@ public function hasColumn(string $tableName, string $columnName): bool /** * @inheritDoc */ - #[\Override] + #[Override] public function renameTable(string $oldName, string $newName): bool { $enclosedOldName = $this->encloseTableName($oldName); @@ -82,7 +86,7 @@ public function renameTable(string $oldName, string $newName): bool /** * @inheritDoc */ - #[\Override] + #[Override] public function changeColumn(string $table, string $oldColumnName, string $newColumnName, DataType $newDataType): bool { $enclosedTableName = $this->encloseTableName($table); @@ -96,7 +100,7 @@ public function changeColumn(string $table, string $oldColumnName, string $newCo /** * @inheritDoc */ - #[\Override] + #[Override] public function addColumn(string $table, string $column, DataType $dataType, ?bool $nullable = null, ?string $default = null): bool { $enclosedTableName = $this->encloseTableName($table); @@ -119,7 +123,7 @@ public function addColumn(string $table, string $column, DataType $dataType, ?bo /** * @inheritDoc */ - #[\Override] + #[Override] public function createIndex(string $table, string $name, array $columns, bool $unique = false): bool { return $this->_pQuery( @@ -131,7 +135,7 @@ public function createIndex(string $table, string $name, array $columns, bool $u /** * @inheritDoc */ - #[\Override] + #[Override] public function deleteIndex(string $table, string $index): bool { return $this->_pQuery("DROP INDEX $index", []); @@ -140,7 +144,7 @@ public function deleteIndex(string $table, string $index): bool /** * @inheritDoc */ - #[\Override] + #[Override] public function addIndex(string $table, TableIndex $index): bool { return $this->createIndex($table, $index->getName(), explode(',', $index->getDescription())); @@ -149,7 +153,7 @@ public function addIndex(string $table, TableIndex $index): bool /** * @inheritDoc */ - #[\Override] + #[Override] public function removeColumn(string $table, string $column): bool { $enclosedTableName = $this->encloseTableName($table); @@ -162,7 +166,7 @@ public function removeColumn(string $table, string $column): bool * @inheritDoc * @throws QueryException */ - #[\Override] + #[Override] public function triggerMultiInsert(string $table, array $columns, array $valueSets, ConnectionInterface $database, ?array $escapes): bool { $safeColumns = array_map(fn (string $column) => $this->encloseColumnName($column), $columns); @@ -186,7 +190,7 @@ public function triggerMultiInsert(string $table, array $columns, array $valueSe * @inheritDoc * @throws QueryException */ - #[\Override] + #[Override] public function insertOrUpdate(string $table, array $columns, array $values, array $primaryColumns): bool { $placeholders = []; @@ -243,7 +247,7 @@ public function insertOrUpdate(string $table, array $columns, array $values, arr /** * @inheritDoc */ - #[\Override] + #[Override] public function encloseColumnName(string $column): string { return $column; @@ -252,7 +256,7 @@ public function encloseColumnName(string $column): string /** * @inheritDoc */ - #[\Override] + #[Override] public function encloseTableName(string $table): string { return $table; @@ -261,13 +265,13 @@ public function encloseTableName(string $table): string /** * @inheritDoc */ - #[\Override] + #[Override] public function flushQueryCache(): void { $this->statementsCache = []; } - #[\Override] + #[Override] public function escape(mixed $value): mixed { return $value; @@ -276,7 +280,7 @@ public function escape(mixed $value): mixed /** * @inheritDoc */ - #[\Override] + #[Override] public function getAffectedRowsCount(): int { return $this->affectedRowsCount; @@ -285,7 +289,7 @@ public function getAffectedRowsCount(): int /** * @inheritDoc */ - #[\Override] + #[Override] public function appendLimitExpression(string $query, int $start, int $end): string { // Calculate the end-value: mysql limit: start, nr of records, so: @@ -298,7 +302,7 @@ public function appendLimitExpression(string $query, int $start, int $end): stri /** * @inheritDoc */ - #[\Override] + #[Override] public function getConcatExpression(array $parts): string { return 'CONCAT(' . implode(', ', $parts) . ')'; @@ -307,7 +311,7 @@ public function getConcatExpression(array $parts): string /** * @inheritDoc */ - #[\Override] + #[Override] public function convertToDatabaseValue(mixed $value, DataType $type): mixed { return match ($type) { @@ -323,13 +327,13 @@ public function convertToDatabaseValue(mixed $value, DataType $type): mixed /** * @inheritDoc */ - #[\Override] + #[Override] public function getLeastExpression(array $parts): string { return 'LEAST(' . implode(', ', $parts) . ')'; } - #[\Override] + #[Override] public function getSubstringExpression(string $value, int $offset, ?int $length): string { $parameters = [$value, $offset]; @@ -340,7 +344,7 @@ public function getSubstringExpression(string $value, int $offset, ?int $length) return 'SUBSTRING(' . implode(', ', $parameters) . ')'; } - #[\Override] + #[Override] public function getStringLengthExpression(string $targetString): string { return 'LENGTH(' . $targetString . ')'; diff --git a/src/Driver/MysqliDriver.php b/src/Driver/MysqliDriver.php index b8309776..0fed968b 100755 --- a/src/Driver/MysqliDriver.php +++ b/src/Driver/MysqliDriver.php @@ -300,6 +300,8 @@ public function getTableInformation(string $tableName): Table /** * Tries to convert a column provided by the database back to the Kajona internal type constant. + * + * @param array{Type:string} $infoSchemaRow */ private function getCoreTypeForDbType(array $infoSchemaRow): ?DataType { diff --git a/src/Driver/PostgresDriver.php b/src/Driver/PostgresDriver.php index 7bfebe46..709796f5 100755 --- a/src/Driver/PostgresDriver.php +++ b/src/Driver/PostgresDriver.php @@ -37,6 +37,9 @@ class PostgresDriver extends DriverAbstract private string $dumpBin = 'pg_dump'; // Binary to dump db (if not in path, add the path here) private string $restoreBin = 'psql'; // Binary to restore db (if not in path, add the path here) + /** + * @var array + */ private array $cxInfo = []; /** @@ -275,6 +278,8 @@ public function getTableInformation(string $tableName): Table /** * Tries to convert a column provided by the database back to the Kajona internal type constant. + * + * @param array{data_type:string,character_maximum_length:int|numeric-string} $infoSchemaRow */ private function getCoreTypeForDbType(array $infoSchemaRow): ?DataType { @@ -293,13 +298,21 @@ private function getCoreTypeForDbType(array $infoSchemaRow): ?DataType if ($infoSchemaRow['data_type'] === 'character varying') { if ($infoSchemaRow['character_maximum_length'] == '10') { return DataType::CHAR10; - } elseif ($infoSchemaRow['character_maximum_length'] == '20') { + } + + if ($infoSchemaRow['character_maximum_length'] == '20') { return DataType::CHAR20; - } elseif ($infoSchemaRow['character_maximum_length'] == '100') { + } + + if ($infoSchemaRow['character_maximum_length'] == '100') { return DataType::CHAR100; - } elseif ($infoSchemaRow['character_maximum_length'] == '254') { + } + + if ($infoSchemaRow['character_maximum_length'] == '254') { return DataType::CHAR254; - } elseif ($infoSchemaRow['character_maximum_length'] == '500') { + } + + if ($infoSchemaRow['character_maximum_length'] == '500') { return DataType::CHAR500; } } elseif ($infoSchemaRow['data_type'] === 'text') { diff --git a/src/Driver/Sqlite3Driver.php b/src/Driver/Sqlite3Driver.php index 504a2f0e..3e18bcc2 100755 --- a/src/Driver/Sqlite3Driver.php +++ b/src/Driver/Sqlite3Driver.php @@ -87,6 +87,9 @@ public function dbclose(): void } /** + * @param list $sourceTableInfo + * @param list $targetTableInfo + * * @throws QueryException */ private function buildAndCopyTempTables(string $targetTableName, array $sourceTableInfo, array $targetTableInfo): bool @@ -404,6 +407,8 @@ public function getTableInformation(string $tableName): Table /** * Tries to convert a column provided by the database back to the Kajona internal type constant. + * + * @param array{type:string} $infoSchemaRow */ private function getCoreTypeForDbType(array $infoSchemaRow): ?DataType { diff --git a/src/DriverInterface.php b/src/DriverInterface.php index 2f373bed..a79ea4c2 100755 --- a/src/DriverInterface.php +++ b/src/DriverInterface.php @@ -44,6 +44,10 @@ public function dbclose(): void; * INSERT INTO $table ($columns) VALUES (?, ?), (?, ?)... * Please note that this method is used to create the query itself, based on the Kajona-internal syntax. * The query is fired to the database by Database. + * + * @param list $columns + * @param list> $valueSets + * @param list $escapes */ public function triggerMultiInsert(string $table, array $columns, array $valueSets, ConnectionInterface $database, ?array $escapes): bool; @@ -52,6 +56,10 @@ public function triggerMultiInsert(string $table, array $columns, array $valueSe * to detect whether a row is already present or not. * Please note: since some dbrms fire a delete && insert, make sure to pass ALL colums and values, * otherwise data might be lost. + * + * @param list $columns + * @param list $values + * @param list $primaryColumns */ public function insertOrUpdate(string $table, array $columns, array $values, array $primaryColumns): bool; @@ -59,6 +67,8 @@ public function insertOrUpdate(string $table, array $columns, array $values, arr * Sends a prepared statement to the database. All params must be represented by the "?" char. * The params themselves are stored using the second params using the matching order. * + * @param list $params + * * @throws QueryException */ public function _pQuery(string $query, array $params): bool; @@ -67,6 +77,8 @@ public function _pQuery(string $query, array $params): bool; * This method is used to retrieve an array of result-sets from the database using * a prepared statement. * + * @param list $params + * * @throws QueryException */ public function getPArray(string $query, array $params): Generator; @@ -81,6 +93,8 @@ public function getError(): string; * Returns ALL tables in the database currently connected to. * The method should return an array using the following keys: * name => Table name. + * + * @return list */ public function getTables(): array; @@ -93,13 +107,16 @@ public function getTableInformation(string $tableName): Table; * Used to send a CREATE table statement to the database * By passing the query through this method, the driver can add db-specific commands. * - * @param array $columns + * @param array $columns + * @param list $primaryKeys */ public function createTable(string $name, array $columns, array $primaryKeys): bool; /** * Creates a new index on the provided table over the given columns. If unique is true we create a unique index * where each index can only occur once in the table. + * + * @param list $columns */ public function createIndex(string $table, string $name, array $columns, bool $unique = false): bool; @@ -183,6 +200,8 @@ public function transactionRollback(): void; * Returns an array of key value pairs with infos about the current database * The array returned should have tho following structure: * property name => value. + * + * @return array */ public function getDbInfo(): array; @@ -191,6 +210,7 @@ public function getDbInfo(): array; * The dump must include, and ONLY include the pass tables. * * @param string &$fileName passed by reference so that the driver is able to update the filename, e.g. in order to add a .gz suffix. + * @param list $tables */ public function dbExport(string &$fileName, array $tables): bool; @@ -238,6 +258,8 @@ public function appendLimitExpression(string $query, int $start, int $end): stri * * $connection->getConcatExpression(['user_kajona.user_forename', '\' \'', 'user_kajona.user_name']) * . + * + * @param list $parts */ public function getConcatExpression(array $parts): string; @@ -264,6 +286,8 @@ public function convertToDatabaseValue(mixed $value, DataType $type): mixed; * * $connection->getLeastExpression(['column1','column2', ...]) * . + * + * @param list $parts */ public function getLeastExpression(array $parts): string; diff --git a/src/Exception/QueryException.php b/src/Exception/QueryException.php index 5410356f..dd26dd8f 100644 --- a/src/Exception/QueryException.php +++ b/src/Exception/QueryException.php @@ -18,6 +18,9 @@ class QueryException extends Exception { + /** + * @param list $params + */ public function __construct(string $message, private readonly string $query, private readonly array $params, ?Throwable $previous = null) { parent::__construct($message, 0, $previous); @@ -28,6 +31,9 @@ public function getQuery(): string return $this->query; } + /** + * @return list + */ public function getParams(): array { return $this->params; diff --git a/src/MockConnection.php b/src/MockConnection.php index 95015445..574ca753 100644 --- a/src/MockConnection.php +++ b/src/MockConnection.php @@ -43,11 +43,16 @@ */ class MockConnection implements ConnectionInterface { + /** + * @var list> + */ private array $rows = []; /** * Adds a row to unconditionally be returned from {@see getPArray()} and {@see getGenerator()}. It will also be * returned from {@see getPRow()} and {@see selectRow()} _if it's the first row added_. + * + * @param array $row */ public function addRow(array $row): void { diff --git a/src/Schema/Table.php b/src/Schema/Table.php index 70c458e1..1a6bb820 100644 --- a/src/Schema/Table.php +++ b/src/Schema/Table.php @@ -14,6 +14,7 @@ namespace Artemeon\Database\Schema; use JsonSerializable; +use Override; /** * Base information about a database table. @@ -35,8 +36,10 @@ public function __construct(private string $name) /** * @inheritDoc + * + * @return array{name:string,indexes:TableIndex[],keys:TableKey[],columns:TableColumn[]} */ - #[\Override] + #[Override] public function jsonSerialize(): array { return [ @@ -148,6 +151,9 @@ public function setPrimaryKeys(array $primaryKeys): self return $this; } + /** + * @return string[] + */ public function getColumnNames(): array { return array_map(static fn (TableColumn $column) => $column->getName(), $this->columns); diff --git a/src/Schema/TableColumn.php b/src/Schema/TableColumn.php index 2f612d91..a9b612cd 100644 --- a/src/Schema/TableColumn.php +++ b/src/Schema/TableColumn.php @@ -14,6 +14,7 @@ namespace Artemeon\Database\Schema; use JsonSerializable; +use Override; /** * Base information about a table's column. @@ -35,8 +36,15 @@ public function __construct(private string $name) /** * @inheritDoc + * + * @return array{ + * name: string, + * internalType: string, + * databaseType: string, + * nullable: bool, + * } */ - #[\Override] + #[Override] public function jsonSerialize(): array { return [ diff --git a/src/Schema/TableIndex.php b/src/Schema/TableIndex.php index f37b0968..d754a0cd 100644 --- a/src/Schema/TableIndex.php +++ b/src/Schema/TableIndex.php @@ -14,6 +14,7 @@ namespace Artemeon\Database\Schema; use JsonSerializable; +use Override; /** * Base information about a table's index. @@ -28,8 +29,10 @@ public function __construct(private string $name) /** * @inheritDoc + * + * @return array{name:string, description:string} */ - #[\Override] + #[Override] public function jsonSerialize(): array { return [ diff --git a/src/Schema/TableKey.php b/src/Schema/TableKey.php index 2a2e3ee7..f1278f36 100644 --- a/src/Schema/TableKey.php +++ b/src/Schema/TableKey.php @@ -14,6 +14,7 @@ namespace Artemeon\Database\Schema; use JsonSerializable; +use Override; /** * Base information about a tables primary key. @@ -26,8 +27,10 @@ public function __construct(private string $name) /** * @inheritDoc + * + * @return array{name: string} */ - #[\Override] + #[Override] public function jsonSerialize(): array { return ['name' => $this->getName()]; diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php index 34b739a0..826bb27d 100644 --- a/tests/ConnectionTest.php +++ b/tests/ConnectionTest.php @@ -405,7 +405,7 @@ public function testGetAffectedRows(): void * @throws \ReflectionException */ #[DataProvider('dataPostgresProcessQueryProvider')] - public function testPostgresProcessQuery($expected, $query): void + public function testPostgresProcessQuery(string $expected, string $query): void { $dbPostgres = new PostgresDriver(); $reflection = new ReflectionClass(PostgresDriver::class); @@ -418,6 +418,9 @@ public function testPostgresProcessQuery($expected, $query): void $this->assertEquals($expected, $actual); } + /** + * @return array{string,string}[] + */ public static function dataPostgresProcessQueryProvider(): array { return [ @@ -639,7 +642,7 @@ public function testDelete(): void * @throws QueryException */ #[DataProvider('intComparisonDataProvider')] - public function testIntComparison($id, $date, $expected): void + public function testIntComparison(string $id, int $date, int $expected): void { // note calculation does not work if we cross a year border. $objLeftDate = DateTime::createFromFormat('YmdHis', '' . $date); @@ -660,6 +663,9 @@ public function testIntComparison($id, $date, $expected): void $this->assertEquals($expected, $row['result_2']); } + /** + * @return array{string,int,int}[] + */ public static function intComparisonDataProvider(): array { return [ @@ -701,7 +707,7 @@ public function testSqlConcat(): void * @throws QueryException */ #[DataProvider('databaseValueProvider')] - public function testConvertToDatabaseValue($value, DataType $type): void + public function testConvertToDatabaseValue(mixed $value, DataType $type): void { $connection = $this->getConnection(); $systemId = $this->generateSystemid(); @@ -741,6 +747,9 @@ public function testConvertToDatabaseValue($value, DataType $type): void $this->assertEquals($expect, $actual); } + /** + * @return array{mixed, DataType}[] + */ public static function databaseValueProvider(): array { return [ diff --git a/tests/ConnectionTestCase.php b/tests/ConnectionTestCase.php index a06879a7..c0d7b61e 100644 --- a/tests/ConnectionTestCase.php +++ b/tests/ConnectionTestCase.php @@ -85,6 +85,9 @@ private function setupFixture(): void } } + /** + * @return array + */ protected function getTestTableColumns(): array { return [ @@ -107,6 +110,9 @@ protected function generateSystemid(): string return substr(sha1(uniqid()), 0, 20); } + /** + * @return ($assoc is true ? list> : list>) + */ protected function getRows(int $count, bool $assoc = true): array { $rows = []; @@ -131,6 +137,9 @@ protected function getRows(int $count, bool $assoc = true): array return $rows; } + /** + * @return list + */ protected function getColumnNames(): array { return [ diff --git a/tests/Driver/MysqliDriverTest.php b/tests/Driver/MysqliDriverTest.php index 50b8e36b..fc3ed58e 100644 --- a/tests/Driver/MysqliDriverTest.php +++ b/tests/Driver/MysqliDriverTest.php @@ -26,22 +26,30 @@ public function testBuildsDatabaseSpecificSubstringExpression(): void self::assertEquals('SUBSTRING("test value", 1, 1)', $mysqliDriver->getSubstringExpression('"test value"', 1, 1)); } - public static function provideValidExportFilenameAndPasswordAndExpectedCommandLine() + /** + * @return array{string,list,string,string}[] + */ + public static function provideValidExportFilenameAndPasswordAndExpectedCommandLine(): array { return [ [ - '/path/to/dump.sql', [], + '/path/to/dump.sql', + [], 'securepassword', "'bash' '-c' '/usr/bin/mysqldump -h '\''localhost'\'' -u '\''sebastian_bergmann'\'' -p'\''securepassword'\'' -P 3306 '\''testdb'\'' | gzip > '\''/path/to/dump.sql.gz'\'''", ], [ - '/path/to/dump.sql', ['agp_user', 'agp_tours'], + '/path/to/dump.sql', + ['agp_user', 'agp_tours'], 'securepassword', "'bash' '-c' '/usr/bin/mysqldump -h '\''localhost'\'' -u '\''sebastian_bergmann'\'' -p'\''securepassword'\'' -P 3306 '\''testdb'\'' '\''agp_user'\'' '\''agp_tours'\'' | gzip > '\''/path/to/dump.sql.gz'\'''", ], ]; } + /** + * @param list $tables + */ #[DataProvider('provideValidExportFilenameAndPasswordAndExpectedCommandLine')] public function testDbExportWillRunProcess(string $fileName, array $tables, string $password, string $expectedCommandLine): void { @@ -73,23 +81,30 @@ public function testDbExportWillRunProcess(string $fileName, array $tables, stri $this->assertTrue($result); } - public static function provideValidImportFilenameAndPasswordAndExpectedCommandLine() + /** + * @return array{string,string,string}[] + */ + public static function provideValidImportFilenameAndPasswordAndExpectedCommandLine(): array { return [ [ - '/path/to/dump.sql', 'securepassword', + '/path/to/dump.sql', + 'securepassword', "'bash' '-c' 'cat '\''/path/to/dump.sql'\'' | /usr/bin/mysql -h '\''localhost'\'' -u '\''sebastian_bergmann'\'' -p'\''securepassword'\'' -P 3306 '\''testdb'\'''", ], [ - '/path/to/dump.sql.gz', 'securepassword', + '/path/to/dump.sql.gz', + 'securepassword', "'bash' '-c' 'gunzip -c '\''/path/to/dump.sql.gz'\'' | /usr/bin/mysql -h '\''localhost'\'' -u '\''sebastian_bergmann'\'' -p'\''securepassword'\'' -P 3306 '\''testdb'\'''", ], [ - '/path/to/dump.sql', '', + '/path/to/dump.sql', + '', "'bash' '-c' 'cat '\''/path/to/dump.sql'\'' | /usr/bin/mysql -h '\''localhost'\'' -u '\''sebastian_bergmann'\'' -P 3306 '\''testdb'\'''", ], [ - '/path/to/dump.sql.gz', '', + '/path/to/dump.sql.gz', + '', "'bash' '-c' 'gunzip -c '\''/path/to/dump.sql.gz'\'' | /usr/bin/mysql -h '\''localhost'\'' -u '\''sebastian_bergmann'\'' -P 3306 '\''testdb'\'''", ], ]; diff --git a/tests/Driver/PostgresDriverTest.php b/tests/Driver/PostgresDriverTest.php index 5f625f52..d6817e31 100644 --- a/tests/Driver/PostgresDriverTest.php +++ b/tests/Driver/PostgresDriverTest.php @@ -26,22 +26,30 @@ public function testBuildsDatabaseSpecificSubstringExpression(): void self::assertEquals('SUBSTRING(cast ("test value" as text), 1, 1)', $postgresDriver->getSubstringExpression('"test value"', 1, 1)); } - public static function provideValidExportFilenameAndPasswordAndExpectedCommandLine() + /** + * @return array{string,list,string,string}[] + */ + public static function provideValidExportFilenameAndPasswordAndExpectedCommandLine(): array { return [ [ - '/path/to/dump.sql', ['agp_user', 'agp_tours'], + '/path/to/dump.sql', + ['agp_user', 'agp_tours'], 'securepassword', "'bash' '-c' '/usr/bin/pg_dump --clean --no-owner -h '\''localhost'\'' -U '\''sebastian_bergmann'\'' -p '\''5432'\'' -d '\''testdb'\'' -t '\''agp_user'\'' -t '\''agp_tours'\'' | gzip > '\''/path/to/dump.sql.gz'\'''", ], [ - '/path/to/dump.sql', [], + '/path/to/dump.sql', + [], 'securepassword', "'bash' '-c' '/usr/bin/pg_dump --clean --no-owner -h '\''localhost'\'' -U '\''sebastian_bergmann'\'' -p '\''5432'\'' -d '\''testdb'\'' | gzip > '\''/path/to/dump.sql.gz'\'''", ], ]; } + /** + * @param list $tables + */ #[DataProvider('provideValidExportFilenameAndPasswordAndExpectedCommandLine')] public function testDbExportWillRunProcess(string $fileName, array $tables, string $password, string $expectedCommandLine): void { @@ -77,23 +85,30 @@ public function testDbExportWillRunProcess(string $fileName, array $tables, stri self::assertTrue($result); } - public static function provideValidImportFilenameAndPasswordAndExpectedCommandLine() + /** + * @return array{string,string,string}[] + */ + public static function provideValidImportFilenameAndPasswordAndExpectedCommandLine(): array { return [ [ - '/path/to/dump.sql', 'securepassword', + '/path/to/dump.sql', + 'securepassword', "'/usr/bin/psql' '-q' '-h' 'localhost' '-U' 'sebastian_bergmann' '-p5432' '-d' 'testdb' '-f' '/path/to/dump.sql'", ], [ - '/path/to/dump.sql.gz', 'securepassword', + '/path/to/dump.sql.gz', + 'securepassword', "'bash' '-c' 'gunzip -c '\''/path/to/dump.sql.gz'\'' | /usr/bin/psql -q -h '\''localhost'\'' -U '\''sebastian_bergmann'\'' -p5432 -d '\''testdb'\'''", ], [ - '/path/to/dump.sql', '', + '/path/to/dump.sql', + '', "'/usr/bin/psql' '-q' '-h' 'localhost' '-U' 'sebastian_bergmann' '-p5432' '-d' 'testdb' '-f' '/path/to/dump.sql'", ], [ - '/path/to/dump.sql.gz', '', + '/path/to/dump.sql.gz', + '', "'bash' '-c' 'gunzip -c '\''/path/to/dump.sql.gz'\'' | /usr/bin/psql -q -h '\''localhost'\'' -U '\''sebastian_bergmann'\'' -p5432 -d '\''testdb'\'''", ], ];