diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 3cd706fdc296..727c15566d74 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6684,7 +6684,7 @@ parameters: - message: '#^Only booleans are allowed in a negated boolean, PhpMyAdmin\\Dbal\\ResultInterface\|false given\.$#' identifier: booleanNot.exprNotBoolean - count: 3 + count: 2 path: src/Dbal/DatabaseInterface.php - @@ -10170,7 +10170,7 @@ parameters: Use dependency injection instead\.$# ''' identifier: staticMethod.deprecated - count: 7 + count: 8 path: src/Navigation/Nodes/Node.php - diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 23b1cae8f96c..6f0f66278ac3 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -5993,6 +5993,7 @@ + diff --git a/src/Dbal/DatabaseInterface.php b/src/Dbal/DatabaseInterface.php index 4a6a87e9da06..e95258ad8451 100644 --- a/src/Dbal/DatabaseInterface.php +++ b/src/Dbal/DatabaseInterface.php @@ -1711,25 +1711,6 @@ public function getError(ConnectionType $connectionType = ConnectionType::User): return $this->extension->getError($this->connections[$connectionType->value]); } - /** - * returns the number of rows returned by last query - * used with tryQuery as it accepts false - * - * @param string $query query to run - * - * @psalm-return int|numeric-string - */ - public function queryAndGetNumRows(string $query): string|int - { - $result = $this->tryQuery($query); - - if (! $result) { - return 0; - } - - return $result->numRows(); - } - /** * returns last inserted auto_increment id for given $link */ @@ -1970,14 +1951,13 @@ public function setVersion(array $version): void $this->isPercona = stripos($this->versionComment, 'percona') !== false; } - /** - * Prepare an SQL statement for execution. - * - * @param string $query The query, as a string. - */ - public function prepare(string $query, ConnectionType $connectionType = ConnectionType::User): Statement|null - { - return $this->extension->prepare($this->connections[$connectionType->value], $query); + /** @param list $params */ + public function executeQuery( + string $query, + array $params, + ConnectionType $connectionType = ConnectionType::User, + ): ResultInterface|null { + return $this->extension->executeQuery($this->connections[$connectionType->value], $query, $params); } public function getDatabaseList(): ListDatabase diff --git a/src/Dbal/DbiExtension.php b/src/Dbal/DbiExtension.php index 619f831b541d..2c7e4ad33bcb 100644 --- a/src/Dbal/DbiExtension.php +++ b/src/Dbal/DbiExtension.php @@ -91,11 +91,11 @@ public function affectedRows(Connection $connection): int|string; public function escapeString(Connection $connection, string $string): string; /** - * Prepare an SQL statement for execution. + * Execute a prepared statement and return the result. * - * @param string $query The query, as a string. + * @param list $params */ - public function prepare(Connection $connection, string $query): Statement|null; + public function executeQuery(Connection $connection, string $query, array $params): ResultInterface|null; /** * Returns the number of warnings from the last query. diff --git a/src/Dbal/DbiMysqli.php b/src/Dbal/DbiMysqli.php index dd993d4b3bdd..f7a8946167e9 100644 --- a/src/Dbal/DbiMysqli.php +++ b/src/Dbal/DbiMysqli.php @@ -284,20 +284,21 @@ public function escapeString(Connection $connection, string $string): string } /** - * Prepare an SQL statement for execution. + * Execute a prepared statement and return the result. * - * @param string $query The query, as a string. + * @param list $params */ - public function prepare(Connection $connection, string $query): Statement|null + public function executeQuery(Connection $connection, string $query, array $params): MysqliResult|null { /** @var mysqli $mysqli */ $mysqli = $connection->connection; - $statement = $mysqli->prepare($query); - if ($statement === false) { + $result = $mysqli->execute_query($query, $params); + + if ($result === false) { return null; } - return new MysqliStatement($statement); + return new MysqliResult($result); } /** diff --git a/src/Dbal/MysqliStatement.php b/src/Dbal/MysqliStatement.php deleted file mode 100644 index 1e8557c3c800..000000000000 --- a/src/Dbal/MysqliStatement.php +++ /dev/null @@ -1,39 +0,0 @@ - $params - */ - public function execute(array $params): bool - { - $paramCount = $this->statement->param_count; - if (count($params) !== $paramCount) { - return false; - } - - return $this->statement->execute($params); - } - - /** - * Gets a result set from a prepared statement. - */ - public function getResult(): ResultInterface - { - return new MysqliResult($this->statement->get_result()); - } -} diff --git a/src/Dbal/Statement.php b/src/Dbal/Statement.php deleted file mode 100644 index 721206bba554..000000000000 --- a/src/Dbal/Statement.php +++ /dev/null @@ -1,20 +0,0 @@ - $params - */ - public function execute(array $params): bool; - - /** - * Gets a result set from a prepared statement. - */ - public function getResult(): ResultInterface; -} diff --git a/src/Navigation/Nodes/Node.php b/src/Navigation/Nodes/Node.php index 8e03d0c7db1c..3041f162ad56 100644 --- a/src/Navigation/Nodes/Node.php +++ b/src/Navigation/Nodes/Node.php @@ -379,13 +379,13 @@ public function getPresence(UserPrivileges $userPrivileges, string $type = '', s $query = 'SHOW DATABASES '; $query .= $this->getWhereClause('Database', $searchClause); - return (int) $dbi->queryAndGetNumRows($query); + return $this->queryAndGetNumRows($query); } $retval = 0; foreach ($this->getDatabasesToSearch($userPrivileges, $searchClause) as $db) { $query = 'SHOW DATABASES LIKE ' . $dbi->quoteString($db); - $retval += (int) $dbi->queryAndGetNumRows($query); + $retval += $this->queryAndGetNumRows($query); } return $retval; @@ -831,4 +831,20 @@ private function getDataFromShowDatabasesLike(UserPrivileges $userPrivileges, in return $retval; } + + /** + * returns the number of rows returned by last query + * used with tryQuery as it accepts false + */ + protected function queryAndGetNumRows(string $query): int + { + $dbi = DatabaseInterface::getInstance(); + $result = $dbi->tryQuery($query); + + if ($result === false) { + return 0; + } + + return (int) $result->numRows(); + } } diff --git a/src/Navigation/Nodes/NodeTable.php b/src/Navigation/Nodes/NodeTable.php index 246baabe230d..14632669d76e 100644 --- a/src/Navigation/Nodes/NodeTable.php +++ b/src/Navigation/Nodes/NodeTable.php @@ -94,7 +94,7 @@ public function getPresence(UserPrivileges $userPrivileges, string $type = '', s $db = Util::backquote($db); $table = Util::backquote($table); $query = 'SHOW COLUMNS FROM ' . $table . ' FROM ' . $db; - $retval = (int) $dbi->queryAndGetNumRows($query); + $retval = $this->queryAndGetNumRows($query); } break; @@ -102,7 +102,7 @@ public function getPresence(UserPrivileges $userPrivileges, string $type = '', s $db = Util::backquote($db); $table = Util::backquote($table); $query = 'SHOW INDEXES FROM ' . $table . ' FROM ' . $db; - $retval = (int) $dbi->queryAndGetNumRows($query); + $retval = $this->queryAndGetNumRows($query); break; case 'triggers': if (! $this->config->selectedServer['DisableIS']) { @@ -116,7 +116,7 @@ public function getPresence(UserPrivileges $userPrivileges, string $type = '', s } else { $db = Util::backquote($db); $query = 'SHOW TRIGGERS FROM ' . $db . ' WHERE `Table` = ' . $dbi->quoteString($table); - $retval = (int) $dbi->queryAndGetNumRows($query); + $retval = $this->queryAndGetNumRows($query); } break; diff --git a/src/Server/Privileges.php b/src/Server/Privileges.php index 6f94a08294d3..e157c69cf2d1 100644 --- a/src/Server/Privileges.php +++ b/src/Server/Privileges.php @@ -1196,12 +1196,12 @@ private function getTablePrivileges(DatabaseName $db, TableName $table): array NOT (`Table_priv` = \'\' AND Column_priv = \'\') ORDER BY `User` ASC, `Host` ASC, `Db` ASC, `Table_priv` ASC; '; - $statement = $this->dbi->prepare($query); - if ($statement === null || ! $statement->execute([$db->getName(), $table->getName()])) { + $result = $this->dbi->executeQuery($query, [$db->getName(), $table->getName()]); + if ($result === null) { return []; } - return $statement->getResult()->fetchAllAssoc(); + return $result->fetchAllAssoc(); } /** @return array> */ @@ -3171,12 +3171,11 @@ public function getFormForChangePassword( private function getUserPrivileges(string $user, string $host, bool $hasAccountLocking): array|null { $query = 'SELECT * FROM `mysql`.`user` WHERE `User` = ? AND `Host` = ?;'; - $statement = $this->dbi->prepare($query); - if ($statement === null || ! $statement->execute([$user, $host])) { + $result = $this->dbi->executeQuery($query, [$user, $host]); + if ($result === null) { return null; } - $result = $statement->getResult(); /** @var array|null $userPrivileges */ $userPrivileges = $result->fetchAssoc(); if ($userPrivileges === []) { @@ -3190,12 +3189,11 @@ private function getUserPrivileges(string $user, string $host, bool $hasAccountL $userPrivileges['account_locked'] = 'N'; $query = 'SELECT * FROM `mysql`.`global_priv` WHERE `User` = ? AND `Host` = ?;'; - $statement = $this->dbi->prepare($query); - if ($statement === null || ! $statement->execute([$user, $host])) { + $result = $this->dbi->executeQuery($query, [$user, $host]); + if ($result === null) { return $userPrivileges; } - $result = $statement->getResult(); /** @var array|null $globalPrivileges */ $globalPrivileges = $result->fetchAssoc(); if ($globalPrivileges === []) { diff --git a/tests/unit/DatabaseInterfaceTest.php b/tests/unit/DatabaseInterfaceTest.php index 81da15ca991d..81b481295d61 100644 --- a/tests/unit/DatabaseInterfaceTest.php +++ b/tests/unit/DatabaseInterfaceTest.php @@ -13,7 +13,6 @@ use PhpMyAdmin\Dbal\DatabaseInterface; use PhpMyAdmin\Dbal\DbiExtension; use PhpMyAdmin\Dbal\ResultInterface; -use PhpMyAdmin\Dbal\Statement; use PhpMyAdmin\I18n\LanguageManager; use PhpMyAdmin\Index; use PhpMyAdmin\Query\Utilities; @@ -758,17 +757,17 @@ public function testGetDatabasesFullDisabledISAndSortIntColumn(): void $dummyDbi->assertAllQueriesConsumed(); } - public function testPrepare(): void + public function testExecuteQuery(): void { $query = 'SELECT * FROM `mysql`.`user` WHERE `User` = ? AND `Host` = ?;'; - $stmtStub = self::createStub(Statement::class); + $resultStub = self::createStub(ResultInterface::class); $dummyDbi = $this->createMock(DbiExtension::class); - $dummyDbi->expects(self::once())->method('prepare') - ->with(self::isType('object'), self::equalTo($query)) - ->willReturn($stmtStub); + $dummyDbi->expects(self::once())->method('executeQuery') + ->with(self::isType('object'), self::equalTo($query), self::equalTo(['root', 'localhost'])) + ->willReturn($resultStub); $dbi = $this->createDatabaseInterface($dummyDbi); - $stmt = $dbi->prepare($query, ConnectionType::ControlUser); - self::assertSame($stmtStub, $stmt); + $stmt = $dbi->executeQuery($query, ['root', 'localhost'], ConnectionType::ControlUser); + self::assertSame($resultStub, $stmt); } /** diff --git a/tests/unit/Dbal/MysqliStatementTest.php b/tests/unit/Dbal/MysqliStatementTest.php deleted file mode 100644 index 7cc19b689dbe..000000000000 --- a/tests/unit/Dbal/MysqliStatementTest.php +++ /dev/null @@ -1,25 +0,0 @@ -expects(self::once())->method('get_result')->willReturn(false); - $statement = new MysqliStatement($mysqliStmt); - $result = $statement->getResult(); - self::assertInstanceOf(MysqliResult::class, $result); - } -} diff --git a/tests/unit/Server/PrivilegesTest.php b/tests/unit/Server/PrivilegesTest.php index 4762ff8efc52..5ac3996cf121 100644 --- a/tests/unit/Server/PrivilegesTest.php +++ b/tests/unit/Server/PrivilegesTest.php @@ -12,7 +12,6 @@ use PhpMyAdmin\Dbal\ConnectionType; use PhpMyAdmin\Dbal\DatabaseInterface; use PhpMyAdmin\Dbal\ResultInterface; -use PhpMyAdmin\Dbal\Statement; use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Http\Factory\ServerRequestFactory; use PhpMyAdmin\Message; @@ -1896,18 +1895,15 @@ public function testGetFormForChangePassword(): void public function testGetUserPrivileges(): void { $mysqliResultStub = $this->createMock(ResultInterface::class); - $mysqliStmtStub = $this->createMock(Statement::class); - $mysqliStmtStub->expects(self::exactly(2))->method('execute')->willReturn(true); - $mysqliStmtStub->expects(self::exactly(2))->method('getResult')->willReturn($mysqliResultStub); $dbi = $this->createMock(DatabaseInterface::class); $dbi->expects(self::once())->method('isMariaDB')->willReturn(true); $userQuery = 'SELECT * FROM `mysql`.`user` WHERE `User` = ? AND `Host` = ?;'; $globalPrivQuery = 'SELECT * FROM `mysql`.`global_priv` WHERE `User` = ? AND `Host` = ?;'; - $dbi->expects(self::exactly(2))->method('prepare')->willReturnMap([ - [$userQuery, ConnectionType::User, $mysqliStmtStub], - [$globalPrivQuery, ConnectionType::User, $mysqliStmtStub], + $dbi->expects(self::exactly(2))->method('executeQuery')->willReturnMap([ + [$userQuery, ['test.user', 'test.host'], ConnectionType::User, $mysqliResultStub], + [$globalPrivQuery,['test.user', 'test.host'], ConnectionType::User, $mysqliResultStub], ]); $mysqliResultStub->expects(self::exactly(2)) diff --git a/tests/unit/Stubs/DbiDummy.php b/tests/unit/Stubs/DbiDummy.php index ca334e25c0ab..d62157788ca4 100644 --- a/tests/unit/Stubs/DbiDummy.php +++ b/tests/unit/Stubs/DbiDummy.php @@ -15,7 +15,6 @@ use PhpMyAdmin\Dbal\Connection; use PhpMyAdmin\Dbal\DbiExtension; use PhpMyAdmin\Dbal\ResultInterface; -use PhpMyAdmin\Dbal\Statement; use PhpMyAdmin\FieldMetadata; use PhpMyAdmin\Identifiers\DatabaseName; use PhpMyAdmin\Tests\FieldHelper; @@ -314,7 +313,12 @@ public function removeDefaultResults(): void $this->dummyQueries = []; } - public function prepare(Connection $connection, string $query): Statement|null + /** + * Execute a prepared statement and return the result. + * + * @param list $params + */ + public function executeQuery(Connection $connection, string $query, array $params): ResultInterface|null { return null; }