diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 70b834ebe1..631b18876b 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -2028,6 +2028,12 @@ parameters:
count: 1
path: src/Controllers/Database/RoutinesController.php
+ -
+ message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Database\\RoutineType\:\:tryFrom\(\) expects int\|string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: src/Controllers/Database/RoutinesController.php
+
-
message: '#^Parameter \#2 \$type of method PhpMyAdmin\\Database\\Routines\:\:getDataFromName\(\) expects string, mixed given\.$#'
identifier: argument.type
@@ -2046,12 +2052,6 @@ parameters:
count: 1
path: src/Controllers/Database/RoutinesController.php
- -
- message: '#^Parameter \#3 \$which of static method PhpMyAdmin\\Database\\Routines\:\:getDetails\(\) expects string\|null, mixed given\.$#'
- identifier: argument.type
- count: 1
- path: src/Controllers/Database/RoutinesController.php
-
-
message: '#^Parameter \#4 \$name of static method PhpMyAdmin\\Database\\Routines\:\:getDetails\(\) expects string, mixed given\.$#'
identifier: argument.type
@@ -5193,12 +5193,6 @@ parameters:
count: 2
path: src/Database/Routines.php
- -
- message: '#^Binary operation "\.\=" between non\-falsy\-string and mixed results in an error\.$#'
- identifier: assignOp.invalid
- count: 1
- path: src/Database/Routines.php
-
-
message: '''
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Config\:
@@ -5259,7 +5253,7 @@ parameters:
-
message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#'
identifier: empty.notAllowed
- count: 21
+ count: 13
path: src/Database/Routines.php
-
@@ -5292,12 +5286,6 @@ parameters:
count: 1
path: src/Database/Routines.php
- -
- message: '#^Parameter \#1 \$haystack of function str_contains expects string, mixed given\.$#'
- identifier: argument.type
- count: 1
- path: src/Database/Routines.php
-
-
message: '#^Parameter \#1 \$haystack of function stripos expects string, mixed given\.$#'
identifier: argument.type
@@ -5307,7 +5295,7 @@ parameters:
-
message: '#^Parameter \#1 \$identifier of static method PhpMyAdmin\\Util\:\:backquote\(\) expects string\|Stringable\|null, mixed given\.$#'
identifier: argument.type
- count: 9
+ count: 8
path: src/Database/Routines.php
-
@@ -5325,7 +5313,7 @@ parameters:
-
message: '#^Parameter \#1 \$str of method PhpMyAdmin\\Dbal\\DatabaseInterface\:\:quoteString\(\) expects string, mixed given\.$#'
identifier: argument.type
- count: 7
+ count: 6
path: src/Database/Routines.php
-
@@ -5337,7 +5325,7 @@ parameters:
-
message: '#^Parameter \#1 \$string of function htmlspecialchars expects string, mixed given\.$#'
identifier: argument.type
- count: 2
+ count: 1
path: src/Database/Routines.php
-
@@ -5370,12 +5358,6 @@ parameters:
count: 1
path: src/Database/Routines.php
- -
- message: '#^Parameter \#2 \$string of function explode expects string, mixed given\.$#'
- identifier: argument.type
- count: 1
- path: src/Database/Routines.php
-
-
message: '#^Parameter \#2 \$subject of function preg_match expects string, mixed given\.$#'
identifier: argument.type
@@ -5413,7 +5395,7 @@ parameters:
path: src/Database/Routines.php
-
- message: '#^Parameter \#7 \$itemType of method PhpMyAdmin\\Database\\Routines\:\:processParamsAndBuild\(\) expects string, mixed given\.$#'
+ message: '#^Parameter \#7 \$itemType of method PhpMyAdmin\\Database\\Routines\:\:processParamsAndBuild\(\) expects PhpMyAdmin\\Database\\RoutineType, PhpMyAdmin\\Database\\RoutineType\|null given\.$#'
identifier: argument.type
count: 1
path: src/Database/Routines.php
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 34e2e439d9..e461f30da8 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -973,8 +973,8 @@
-
+
@@ -3468,10 +3468,6 @@
-
-
-
-
@@ -3500,6 +3496,8 @@
+
+
@@ -3546,6 +3544,9 @@
+
+
+
@@ -3565,7 +3566,6 @@
-
@@ -3579,17 +3579,12 @@
-
-
-
-
-
@@ -3603,7 +3598,6 @@
-
@@ -3611,10 +3605,10 @@
-
+
type->parameters]]>
@@ -3648,20 +3642,12 @@
-
-
-
-
-
-
-
-
diff --git a/src/Controllers/Database/RoutinesController.php b/src/Controllers/Database/RoutinesController.php
index a0befa26bd..c788d76ac9 100644
--- a/src/Controllers/Database/RoutinesController.php
+++ b/src/Controllers/Database/RoutinesController.php
@@ -9,6 +9,7 @@ use PhpMyAdmin\Config;
use PhpMyAdmin\Controllers\InvocableController;
use PhpMyAdmin\Current;
use PhpMyAdmin\Database\Routines;
+use PhpMyAdmin\Database\RoutineType;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\DbTableExists;
use PhpMyAdmin\Html\Generator;
@@ -55,7 +56,7 @@ final readonly class RoutinesController implements InvocableController
{
$this->response->addScriptFiles(['database/routines.js', 'sql.js']);
- $type = $_REQUEST['type'] ?? null;
+ $type = RoutineType::tryFrom($_REQUEST['type'] ?? '');
$userPrivileges = $this->userPrivilegesFactory->getPrivileges();
@@ -104,7 +105,7 @@ final readonly class RoutinesController implements InvocableController
}
if (! empty($_POST['editor_process_add']) || ! empty($_POST['editor_process_edit'])) {
- $output = $this->routines->handleRequestCreateOrEdit($userPrivileges, Current::$database);
+ $output = $this->routines->handleRequestCreateOrEdit($userPrivileges, Current::$database, $request);
if ($request->isAjax()) {
if (! (Current::$message instanceof Message && Current::$message->isSuccess())) {
$this->response->setRequestStatus(false);
@@ -116,7 +117,7 @@ final readonly class RoutinesController implements InvocableController
$routines = Routines::getDetails(
$this->dbi,
Current::$database,
- $_POST['item_type'],
+ RoutineType::tryFrom($request->getParsedBodyParamAsString('item_type', '')),
$_POST['item_name'],
);
$routine = $routines[0];
@@ -451,10 +452,6 @@ final readonly class RoutinesController implements InvocableController
}
}
- if (! isset($type) || ! in_array($type, ['FUNCTION', 'PROCEDURE'], true)) {
- $type = null;
- }
-
$totalNumRoutines = Routines::getRoutineCount($this->dbi, Current::$database, $type);
$pageSize = $this->config->settings['MaxRoutineList'];
$pos = (int) $request->getParam('pos');
diff --git a/src/Database/RoutineType.php b/src/Database/RoutineType.php
new file mode 100644
index 0000000000..8bba2c5f24
--- /dev/null
+++ b/src/Database/RoutineType.php
@@ -0,0 +1,11 @@
+getQueryFromRequest();
+ $routineQuery = $this->getQueryFromRequest($request);
// set by getQueryFromRequest()
if ($this->errors === []) {
@@ -627,7 +631,6 @@ class Routines
* @param mixed[] $itemParamLength A length or not for the parameter
* @param mixed[] $itemParamOpsText An optional charset for the parameter
* @param mixed[] $itemParamOpsNum An optional parameter for a $itemParamType NUMBER
- * @param string $itemType The item type (PROCEDURE/FUNCTION)
* @param bool $warnedAboutLength A boolean that will be switched if a the length warning is given
*/
private function processParamsAndBuild(
@@ -637,7 +640,7 @@ class Routines
array $itemParamLength,
array $itemParamOpsText,
array $itemParamOpsNum,
- string $itemType,
+ RoutineType $itemType,
bool &$warnedAboutLength,
): string {
$params = '';
@@ -650,14 +653,14 @@ class Routines
}
if (
- $itemType === 'PROCEDURE'
+ $itemType === RoutineType::Procedure
&& ! empty($itemParamDir[$i])
&& in_array($itemParamDir[$i], $this->directions, true)
) {
$params .= $itemParamDir[$i] . ' '
. Util::backquote($itemParamName[$i])
. ' ' . $itemParamType[$i];
- } elseif ($itemType === 'FUNCTION') {
+ } elseif ($itemType === RoutineType::Function) {
$params .= Util::backquote($itemParamName[$i])
. ' ' . $itemParamType[$i];
} elseif (! $warnedAboutDir) {
@@ -775,14 +778,14 @@ class Routines
*
* @return string The CREATE [ROUTINE | PROCEDURE] query.
*/
- public function getQueryFromRequest(): string
+ public function getQueryFromRequest(ServerRequest $request): string
{
- $itemType = $_POST['item_type'] ?? '';
- $itemDefiner = $_POST['item_definer'] ?? '';
- $itemName = $_POST['item_name'] ?? '';
+ $itemType = RoutineType::tryFrom($request->getParsedBodyParamAsString('item_type', ''));
+ $itemDefiner = $request->getParsedBodyParamAsString('item_definer', '');
+ $itemName = $request->getParsedBodyParamAsString('item_name', '');
$query = 'CREATE ';
- if (! empty($itemDefiner)) {
+ if ($itemDefiner !== '') {
if (str_contains($itemDefiner, '@')) {
$arr = explode('@', $itemDefiner);
@@ -804,16 +807,13 @@ class Routines
}
}
- if ($itemType === 'FUNCTION' || $itemType === 'PROCEDURE') {
- $query .= $itemType . ' ';
+ if ($itemType !== null) {
+ $query .= $itemType->value . ' ';
} else {
- $this->errors[] = sprintf(
- __('Invalid routine type: "%s"'),
- htmlspecialchars($itemType),
- );
+ $this->errors[] = __('Invalid routine type!');
}
- if (! empty($itemName)) {
+ if ($itemName !== '') {
$query .= Util::backquote($itemName);
} else {
$this->errors[] = __('You must provide a routine name!');
@@ -821,18 +821,18 @@ class Routines
$warnedAboutLength = false;
- $itemParamName = $_POST['item_param_name'] ?? '';
- $itemParamType = $_POST['item_param_type'] ?? '';
- $itemParamLength = $_POST['item_param_length'] ?? '';
- $itemParamDir = (array) ($_POST['item_param_dir'] ?? []);
- $itemParamOpsText = (array) ($_POST['item_param_opts_text'] ?? []);
- $itemParamOpsNum = (array) ($_POST['item_param_opts_num'] ?? []);
+ $itemParamName = $request->getParsedBodyParam('item_param_name', '');
+ $itemParamType = $request->getParsedBodyParam('item_param_type', '');
+ $itemParamLength = $request->getParsedBodyParam('item_param_length', '');
+ $itemParamDir = (array) $request->getParsedBodyParam('item_param_dir', []);
+ $itemParamOpsText = (array) $request->getParsedBodyParam('item_param_opts_text', []);
+ $itemParamOpsNum = (array) $request->getParsedBodyParam('item_param_opts_num', []);
$params = '';
if (
- ! empty($itemParamName)
- && ! empty($itemParamType)
- && ! empty($itemParamLength)
+ $itemParamName !== []
+ && $itemParamType !== []
+ && $itemParamLength !== []
&& is_array($itemParamName)
&& is_array($itemParamType)
&& is_array($itemParamLength)
@@ -850,34 +850,33 @@ class Routines
}
$query .= '(' . $params . ') ';
- if ($itemType === 'FUNCTION') {
+ if ($itemType === RoutineType::Function) {
$query = $this->processFunctionSpecificParameters($query, $warnedAboutLength);
}
- if (! empty($_POST['item_comment'])) {
- $query .= 'COMMENT ' . $this->dbi->quoteString($_POST['item_comment']) . ' ';
+ $itemComment = $request->getParsedBodyParamAsString('item_comment', '');
+ if ($itemComment !== '') {
+ $query .= 'COMMENT ' . $this->dbi->quoteString($itemComment) . ' ';
}
- if (isset($_POST['item_isdeterministic'])) {
+ if ($request->hasBodyParam('item_isdeterministic')) {
$query .= 'DETERMINISTIC ';
} else {
$query .= 'NOT DETERMINISTIC ';
}
- $itemSqlDataAccess = $_POST['item_sqldataaccess'] ?? '';
+ $itemSqlDataAccess = $request->getParsedBodyParamAsString('item_sqldataaccess', '');
if (in_array($itemSqlDataAccess, $this->sqlDataAccess, true)) {
$query .= $itemSqlDataAccess . ' ';
}
- $itemSecurityType = $_POST['item_securitytype'] ?? '';
- if (! empty($itemSecurityType)) {
- if ($itemSecurityType === 'DEFINER' || $itemSecurityType === 'INVOKER') {
- $query .= 'SQL SECURITY ' . $itemSecurityType . ' ';
- }
+ $itemSecurityType = $request->getParsedBodyParamAsString('item_securitytype', '');
+ if ($itemSecurityType === 'DEFINER' || $itemSecurityType === 'INVOKER') {
+ $query .= 'SQL SECURITY ' . $itemSecurityType . ' ';
}
- $itemDefinition = $_POST['item_definition'] ?? '';
- if (! empty($itemDefinition)) {
+ $itemDefinition = $request->getParsedBodyParamAsString('item_definition', '');
+ if ($itemDefinition !== '') {
$query .= $itemDefinition;
} else {
$this->errors[] = __('You must provide a routine definition.');
@@ -1189,23 +1188,21 @@ class Routines
* returns details about the PROCEDUREs or FUNCTIONs for a specific database
* or details about a specific routine
*
- * @param string $db db name
- * @param string|null $which PROCEDURE | FUNCTION or null for both
- * @param string $name name of the routine (to fetch a specific routine)
+ * @param string $name name of the routine (to fetch a specific routine)
*
* @return Routine[]
*/
public static function getDetails(
DatabaseInterface $dbi,
string $db,
- string|null $which = null,
+ RoutineType|null $which = null,
string $name = '',
int $limit = 0,
int $offset = 0,
): array {
$query = QueryGenerator::getInformationSchemaRoutinesRequest(
$dbi->quoteString($db),
- in_array($which, ['FUNCTION', 'PROCEDURE'], true) ? $which : null,
+ $which,
$name === '' ? null : $dbi->quoteString($name),
$limit,
$offset,
@@ -1226,11 +1223,11 @@ class Routines
return $ret;
}
- public static function getRoutineCount(DatabaseInterface $dbi, string $db, string|null $which = null): int
+ public static function getRoutineCount(DatabaseInterface $dbi, string $db, RoutineType|null $which = null): int
{
$query = QueryGenerator::getInformationSchemaRoutinesCountRequest(
$dbi->quoteString($db),
- in_array($which, ['FUNCTION', 'PROCEDURE'], true) ? $which : null,
+ $which,
);
return (int) $dbi->fetchValue($query);
@@ -1260,38 +1257,14 @@ class Routines
* @return array
* @psalm-return list
*/
- public static function getFunctionNames(DatabaseInterface $dbi, string $db): array
+ public static function getNames(DatabaseInterface $dbi, string $db, RoutineType $type): array
{
- /** @psalm-var list $functions */
- $functions = $dbi->fetchResultSimple('SHOW FUNCTION STATUS;');
- $names = [];
- foreach ($functions as $function) {
- if ($function['Db'] !== $db || $function['Type'] !== 'FUNCTION' || $function['Name'] === '') {
- continue;
- }
-
- $names[] = $function['Name'];
- }
-
- return $names;
- }
-
- /**
- * @return array
- * @psalm-return list
- */
- public static function getProcedureNames(DatabaseInterface $dbi, string $db): array
- {
- /** @psalm-var list $procedures */
- $procedures = $dbi->fetchResultSimple('SHOW PROCEDURE STATUS;');
- $names = [];
- foreach ($procedures as $procedure) {
- if ($procedure['Db'] !== $db || $procedure['Type'] !== 'PROCEDURE' || $procedure['Name'] === '') {
- continue;
- }
-
- $names[] = $procedure['Name'];
- }
+ /** @var list $names */
+ $names = $dbi->fetchSingleColumn(
+ 'SELECT SPECIFIC_NAME FROM information_schema.ROUTINES'
+ . ' WHERE ROUTINE_SCHEMA = ' . $dbi->quoteString($db)
+ . " AND ROUTINE_TYPE = '" . $type->value . "' AND SPECIFIC_NAME != ''",
+ );
return $names;
}
diff --git a/src/Operations.php b/src/Operations.php
index 8199b30f90..f456c4b9a4 100644
--- a/src/Operations.php
+++ b/src/Operations.php
@@ -7,6 +7,7 @@ namespace PhpMyAdmin;
use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\Database\Events;
use PhpMyAdmin\Database\Routines;
+use PhpMyAdmin\Database\RoutineType;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Engines\Innodb;
use PhpMyAdmin\Identifiers\DatabaseName;
@@ -55,7 +56,7 @@ class Operations
*/
public function runProcedureAndFunctionDefinitions(string $db, DatabaseName $newDatabaseName): void
{
- foreach (Routines::getProcedureNames($this->dbi, $db) as $procedureName) {
+ foreach (Routines::getNames($this->dbi, $db, RoutineType::Procedure) as $procedureName) {
$this->dbi->selectDb($db);
$query = Routines::getProcedureDefinition($this->dbi, $db, $procedureName);
if ($query === null) {
@@ -68,7 +69,7 @@ class Operations
$this->dbi->query($query);
}
- foreach (Routines::getFunctionNames($this->dbi, $db) as $functionName) {
+ foreach (Routines::getNames($this->dbi, $db, RoutineType::Function) as $functionName) {
$this->dbi->selectDb($db);
$query = Routines::getFunctionDefinition($this->dbi, $db, $functionName);
if ($query === null) {
diff --git a/src/Plugins/Export/ExportSql.php b/src/Plugins/Export/ExportSql.php
index d7db94927a..f5fa3dc5c1 100644
--- a/src/Plugins/Export/ExportSql.php
+++ b/src/Plugins/Export/ExportSql.php
@@ -13,6 +13,7 @@ use PhpMyAdmin\Config;
use PhpMyAdmin\Current;
use PhpMyAdmin\Database\Events;
use PhpMyAdmin\Database\Routines;
+use PhpMyAdmin\Database\RoutineType;
use PhpMyAdmin\Dbal\ConnectionType;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Exceptions\ExportException;
@@ -617,8 +618,8 @@ class ExportSql extends ExportPlugin
$delimiter = '$$';
$dbi = DatabaseInterface::getInstance();
- $procedureNames = Routines::getProcedureNames($dbi, $db);
- $functionNames = Routines::getFunctionNames($dbi, $db);
+ $procedureNames = Routines::getNames($dbi, $db, RoutineType::Procedure);
+ $functionNames = Routines::getNames($dbi, $db, RoutineType::Function);
if ($procedureNames || $functionNames) {
$text .= "\n"
diff --git a/src/Plugins/Export/ExportXml.php b/src/Plugins/Export/ExportXml.php
index 814dce0728..8411a6e5d7 100644
--- a/src/Plugins/Export/ExportXml.php
+++ b/src/Plugins/Export/ExportXml.php
@@ -9,6 +9,7 @@ use PhpMyAdmin\Config;
use PhpMyAdmin\Current;
use PhpMyAdmin\Database\Events;
use PhpMyAdmin\Database\Routines;
+use PhpMyAdmin\Database\RoutineType;
use PhpMyAdmin\Dbal\ConnectionType;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Export\Export;
@@ -307,7 +308,7 @@ class ExportXml extends ExportPlugin
$head .= $this->exportDefinitions(
Current::$database,
'function',
- Routines::getFunctionNames($dbi, Current::$database),
+ Routines::getNames($dbi, Current::$database, RoutineType::Function),
);
}
@@ -315,7 +316,7 @@ class ExportXml extends ExportPlugin
$head .= $this->exportDefinitions(
Current::$database,
'procedure',
- Routines::getProcedureNames($dbi, Current::$database),
+ Routines::getNames($dbi, Current::$database, RoutineType::Procedure),
);
}
diff --git a/src/Query/Generator.php b/src/Query/Generator.php
index a22ca01995..090993e590 100644
--- a/src/Query/Generator.php
+++ b/src/Query/Generator.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace PhpMyAdmin\Query;
+use PhpMyAdmin\Database\RoutineType;
use PhpMyAdmin\Triggers\Trigger;
use PhpMyAdmin\Util;
@@ -175,7 +176,7 @@ class Generator
public static function getInformationSchemaRoutinesRequest(
string $quotedDbName,
- string|null $routineType,
+ RoutineType|null $routineType,
string|null $quotedRoutineName,
int $limit = 0,
int $offset = 0,
@@ -189,7 +190,7 @@ class Generator
. ' WHERE `ROUTINE_SCHEMA` ' . Util::getCollateForIS()
. ' = ' . $quotedDbName;
if ($routineType !== null) {
- $query .= " AND `ROUTINE_TYPE` = '" . $routineType . "'";
+ $query .= " AND `ROUTINE_TYPE` = '" . $routineType->value . "'";
}
if ($quotedRoutineName !== null) {
@@ -211,7 +212,7 @@ class Generator
public static function getInformationSchemaRoutinesCountRequest(
string $quotedDbName,
- string|null $routineType,
+ RoutineType|null $routineType,
string|null $quotedRoutineName = null,
): string {
$query = 'SELECT COUNT(*) AS `count`'
@@ -219,7 +220,7 @@ class Generator
. ' WHERE `ROUTINE_SCHEMA` ' . Util::getCollateForIS()
. ' = ' . $quotedDbName;
if ($routineType !== null) {
- $query .= " AND `ROUTINE_TYPE` = '" . $routineType . "'";
+ $query .= " AND `ROUTINE_TYPE` = '" . $routineType->value . "'";
}
if ($quotedRoutineName !== null) {
diff --git a/src/Server/Privileges.php b/src/Server/Privileges.php
index b6d107895d..953bfdd180 100644
--- a/src/Server/Privileges.php
+++ b/src/Server/Privileges.php
@@ -3082,16 +3082,13 @@ class Privileges
*/
public function getRoutineType(string $dbname, string $routineName): string
{
- $routineData = Routines::getDetails($this->dbi, $dbname);
- $routineName = mb_strtolower($routineName);
+ $routineData = Routines::getDetails($this->dbi, $dbname, name: $routineName);
- foreach ($routineData as $routine) {
- if (mb_strtolower($routine->name) === $routineName) {
- return $routine->type;
- }
+ if ($routineData === []) {
+ return '';
}
- return '';
+ return $routineData[0]->type;
}
/**
diff --git a/tests/unit/Database/RoutinesTest.php b/tests/unit/Database/RoutinesTest.php
index 10094f666f..93dae444f5 100644
--- a/tests/unit/Database/RoutinesTest.php
+++ b/tests/unit/Database/RoutinesTest.php
@@ -7,8 +7,10 @@ namespace PhpMyAdmin\Tests\Database;
use PhpMyAdmin\Config;
use PhpMyAdmin\Current;
use PhpMyAdmin\Database\Routines;
+use PhpMyAdmin\Database\RoutineType;
use PhpMyAdmin\Dbal\ConnectionType;
use PhpMyAdmin\Dbal\DatabaseInterface;
+use PhpMyAdmin\Http\Factory\ServerRequestFactory;
use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Types;
use PHPUnit\Framework\Attributes\CoversClass;
@@ -253,7 +255,9 @@ class RoutinesTest extends AbstractTestCase
unset($_POST);
$_POST = $request;
- self::assertSame($query, $routines->getQueryFromRequest());
+ $request = ServerRequestFactory::create()->createServerRequest('POST', 'https://example.com/')
+ ->withParsedBody($request);
+ self::assertSame($query, $routines->getQueryFromRequest($request));
self::assertSame($numErr, $routines->getErrorCount());
// reset
@@ -476,18 +480,16 @@ class RoutinesTest extends AbstractTestCase
{
$dbiDummy = $this->createDbiDummy();
$dbiDummy->addResult(
- 'SHOW FUNCTION STATUS;',
+ 'SELECT SPECIFIC_NAME FROM information_schema.ROUTINES '
+ . "WHERE ROUTINE_SCHEMA = 'test_db' AND ROUTINE_TYPE = 'FUNCTION' AND SPECIFIC_NAME != ''",
[
- ['db_test', 'test_func', 'FUNCTION'],
- ['test_db', 'test_func1', 'FUNCTION'],
- ['test_db', '', 'FUNCTION'],
- ['test_db', 'test_func2', 'FUNCTION'],
- ['test_db', 'test_func', 'PROCEDURE'],
+ ['test_func1'],
+ ['test_func2'],
],
- ['Db', 'Name', 'Type'],
+ ['Name'],
);
- $names = Routines::getFunctionNames($this->createDatabaseInterface($dbiDummy), 'test_db');
+ $names = Routines::getNames($this->createDatabaseInterface($dbiDummy), 'test_db', RoutineType::Function);
self::assertSame(['test_func1', 'test_func2'], $names);
$dbiDummy->assertAllQueriesConsumed();
@@ -497,12 +499,13 @@ class RoutinesTest extends AbstractTestCase
{
$dbiDummy = $this->createDbiDummy();
$dbiDummy->addResult(
- 'SHOW FUNCTION STATUS;',
- [['db_test', 'test_func', 'FUNCTION'], ['test_db', '', 'FUNCTION'], ['test_db', 'test_func', 'PROCEDURE']],
+ 'SELECT SPECIFIC_NAME FROM information_schema.ROUTINES '
+ . "WHERE ROUTINE_SCHEMA = 'test_db' AND ROUTINE_TYPE = 'FUNCTION' AND SPECIFIC_NAME != ''",
+ [],
['Db', 'Name', 'Type'],
);
- $names = Routines::getFunctionNames($this->createDatabaseInterface($dbiDummy), 'test_db');
+ $names = Routines::getNames($this->createDatabaseInterface($dbiDummy), 'test_db', RoutineType::Function);
self::assertSame([], $names);
$dbiDummy->assertAllQueriesConsumed();
@@ -512,18 +515,16 @@ class RoutinesTest extends AbstractTestCase
{
$dbiDummy = $this->createDbiDummy();
$dbiDummy->addResult(
- 'SHOW PROCEDURE STATUS;',
+ 'SELECT SPECIFIC_NAME FROM information_schema.ROUTINES '
+ . "WHERE ROUTINE_SCHEMA = 'test_db' AND ROUTINE_TYPE = 'PROCEDURE' AND SPECIFIC_NAME != ''",
[
- ['db_test', 'test_proc', 'PROCEDURE'],
- ['test_db', 'test_proc1', 'PROCEDURE'],
- ['test_db', '', 'PROCEDURE'],
- ['test_db', 'test_proc2', 'PROCEDURE'],
- ['test_db', 'test_proc', 'FUNCTION'],
+ ['test_proc1', 'PROCEDURE'],
+ ['test_proc2', 'PROCEDURE'],
],
- ['Db', 'Name', 'Type'],
+ ['Name'],
);
- $names = Routines::getProcedureNames($this->createDatabaseInterface($dbiDummy), 'test_db');
+ $names = Routines::getNames($this->createDatabaseInterface($dbiDummy), 'test_db', RoutineType::Procedure);
self::assertSame(['test_proc1', 'test_proc2'], $names);
$dbiDummy->assertAllQueriesConsumed();
@@ -533,16 +534,13 @@ class RoutinesTest extends AbstractTestCase
{
$dbiDummy = $this->createDbiDummy();
$dbiDummy->addResult(
- 'SHOW PROCEDURE STATUS;',
- [
- ['db_test', 'test_proc', 'PROCEDURE'],
- ['test_db', '', 'PROCEDURE'],
- ['test_db', 'test_proc', 'FUNCTION'],
- ],
+ 'SELECT SPECIFIC_NAME FROM information_schema.ROUTINES '
+ . "WHERE ROUTINE_SCHEMA = 'test_db' AND ROUTINE_TYPE = 'PROCEDURE' AND SPECIFIC_NAME != ''",
+ [],
['Db', 'Name', 'Type'],
);
- $names = Routines::getProcedureNames($this->createDatabaseInterface($dbiDummy), 'test_db');
+ $names = Routines::getNames($this->createDatabaseInterface($dbiDummy), 'test_db', RoutineType::Procedure);
self::assertSame([], $names);
$dbiDummy->assertAllQueriesConsumed();
diff --git a/tests/unit/Plugins/Export/ExportXmlTest.php b/tests/unit/Plugins/Export/ExportXmlTest.php
index 2fcebe2cee..da7ac09aa6 100644
--- a/tests/unit/Plugins/Export/ExportXmlTest.php
+++ b/tests/unit/Plugins/Export/ExportXmlTest.php
@@ -179,8 +179,8 @@ class ExportXmlTest extends AbstractTestCase
$config->selectedServer['DisableIS'] = false;
Current::$database = 'd<"b';
- $functions = [['d<"b', 'fn', 'FUNCTION']];
- $procedures = [['d<"b', 'pr', 'PROCEDURE']];
+ $functions = [['fn']];
+ $procedures = [['pr']];
$dbiDummy = $this->createDbiDummy();
$dbi = $this->createDatabaseInterface($dbiDummy);
@@ -191,8 +191,18 @@ class ExportXmlTest extends AbstractTestCase
[['utf-8', 'utf8_general_ci']],
['DEFAULT_CHARACTER_SET_NAME', 'DEFAULT_COLLATION_NAME'],
);
- $dbiDummy->addResult('SHOW FUNCTION STATUS;', $functions, ['Db', 'Name', 'Type']);
- $dbiDummy->addResult('SHOW PROCEDURE STATUS;', $procedures, ['Db', 'Name', 'Type']);
+ $dbiDummy->addResult(
+ 'SELECT SPECIFIC_NAME FROM information_schema.ROUTINES '
+ . "WHERE ROUTINE_SCHEMA = 'd<\\\"b' AND ROUTINE_TYPE = 'FUNCTION' AND SPECIFIC_NAME != ''",
+ $functions,
+ ['Name'],
+ );
+ $dbiDummy->addResult(
+ 'SELECT SPECIFIC_NAME FROM information_schema.ROUTINES '
+ . "WHERE ROUTINE_SCHEMA = 'd<\\\"b' AND ROUTINE_TYPE = 'PROCEDURE' AND SPECIFIC_NAME != ''",
+ $procedures,
+ ['Name'],
+ );
$dbiDummy->addResult('SHOW CREATE TABLE `d<"b`.`table`', [['table', '"tbl"']]);
$dbiDummy->addResult(
'SELECT 1 FROM information_schema.VIEWS WHERE TABLE_SCHEMA = \'d<\"b\' AND TABLE_NAME = \'table\'',
@@ -327,6 +337,7 @@ class ExportXmlTest extends AbstractTestCase
' </pma:structure_schemas>',
$result,
);
+ $dbiDummy->assertAllQueriesConsumed();
}
public function testExportFooter(): void
diff --git a/tests/unit/Stubs/DbiDummy.php b/tests/unit/Stubs/DbiDummy.php
index c75f01523f..15ff21fc0a 100644
--- a/tests/unit/Stubs/DbiDummy.php
+++ b/tests/unit/Stubs/DbiDummy.php
@@ -1780,14 +1780,14 @@ class DbiDummy implements DbiExtension
],
],
[
- 'query' => 'SHOW PROCEDURE STATUS;',
- 'columns' => ['Db', 'Name', 'Type'],
- 'result' => [['test_db', 'test_proc1', 'PROCEDURE'], ['test_db', 'test_proc2', 'PROCEDURE']],
+ 'query' => "SELECT SPECIFIC_NAME FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = 'test_db' AND ROUTINE_TYPE = 'PROCEDURE' AND SPECIFIC_NAME != ''",
+ 'columns' => ['Name'],
+ 'result' => [['test_proc1'], ['test_proc2']],
],
[
- 'query' => 'SHOW FUNCTION STATUS;',
- 'columns' => ['Db', 'Name', 'Type'],
- 'result' => [['test_db', 'test_func', 'FUNCTION']],
+ 'query' => "SELECT SPECIFIC_NAME FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = 'test_db' AND ROUTINE_TYPE = 'FUNCTION' AND SPECIFIC_NAME != ''",
+ 'columns' => ['Name'],
+ 'result' => [['test_func']],
],
[
'query' => 'SHOW CREATE PROCEDURE `test_db`.`test_proc1`',