diff --git a/libraries/classes/DatabaseInterface.php b/libraries/classes/DatabaseInterface.php index 89d2b97a48..e95e23b7ac 100644 --- a/libraries/classes/DatabaseInterface.php +++ b/libraries/classes/DatabaseInterface.php @@ -10,8 +10,9 @@ namespace PhpMyAdmin; use mysqli_result; use PhpMyAdmin\Database\DatabaseList; -use PhpMyAdmin\Dbi\DbiExtension; -use PhpMyAdmin\Dbi\DbiMysqli; +use PhpMyAdmin\Dbal\DbalInterface; +use PhpMyAdmin\Dbal\DbiExtension; +use PhpMyAdmin\Dbal\DbiMysqli; use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Html\MySQLDocumentation; use PhpMyAdmin\SqlParser\Context; @@ -21,7 +22,7 @@ use PhpMyAdmin\SqlParser\Context; * * @package PhpMyAdmin-DBI */ -class DatabaseInterface +class DatabaseInterface implements DbalInterface { /** * Force STORE_RESULT method, ignored by classic MySQL. diff --git a/libraries/classes/Dbal/DbalInterface.php b/libraries/classes/Dbal/DbalInterface.php new file mode 100644 index 0000000000..62abd5eecb --- /dev/null +++ b/libraries/classes/Dbal/DbalInterface.php @@ -0,0 +1,938 @@ + + * $dbi->getTablesFull('my_database'); + * $dbi->getTablesFull('my_database', 'my_table')); + * $dbi->getTablesFull('my_database', 'my_tables_', true)); + * + * + * @param string $database database + * @param string|array $table table name(s) + * @param boolean $tbl_is_group $table is a table group + * @param integer $limit_offset zero-based offset for the count + * @param boolean|integer $limit_count number of tables to return + * @param string $sort_by table attribute to sort by + * @param string $sort_order direction to sort (ASC or DESC) + * @param string $table_type whether table or view + * @param mixed $link link type + * + * @return array list of tables in given db(s) + * @todo move into Table + * + */ + public function getTablesFull( + string $database, + $table = '', + bool $tbl_is_group = false, + int $limit_offset = 0, + $limit_count = false, + string $sort_by = 'Name', + string $sort_order = 'ASC', + ?string $table_type = null, + $link = DatabaseInterface::CONNECT_USER + ): array; + + /** + * Get VIEWs in a particular database + * + * @param string $db Database name to look in + * + * @return array Set of VIEWs inside the database + */ + public function getVirtualTables(string $db): array; + + /** + * returns array with databases containing extended infos about them + * + * @param string $database database + * @param boolean $force_stats retrieve stats also for MySQL < 5 + * @param integer $link link type + * @param string $sort_by column to order by + * @param string $sort_order ASC or DESC + * @param integer $limit_offset starting offset for LIMIT + * @param bool|int $limit_count row count for LIMIT or true + * for + * $GLOBALS['cfg']['MaxDbList'] + * + * @return array + * @todo move into ListDatabase? + * + */ + public function getDatabasesFull( + ?string $database = null, + bool $force_stats = false, + $link = DatabaseInterface::CONNECT_USER, + string $sort_by = 'SCHEMA_NAME', + string $sort_order = 'ASC', + int $limit_offset = 0, + $limit_count = false + ): array; + + /** + * returns detailed array with all columns for sql + * + * @param string $sql_query target SQL query to get columns + * @param array $view_columns alias for columns + * + * @return array + */ + public function getColumnMapFromSql(string $sql_query, array $view_columns = []): array; + + /** + * returns detailed array with all columns for given table in database, + * or all tables/databases + * + * @param string $database name of database + * @param string $table name of table to retrieve columns from + * @param string $column name of specific column + * @param mixed $link mysql link resource + * + * @return array + */ + public function getColumnsFull( + ?string $database = null, + ?string $table = null, + ?string $column = null, + $link = DatabaseInterface::CONNECT_USER + ): array; + + /** + * Returns SQL query for fetching columns for a table + * + * The 'Key' column is not calculated properly, use $dbi->getColumns() + * to get correct values. + * + * @param string $database name of database + * @param string $table name of table to retrieve columns from + * @param string $column name of column, null to show all columns + * @param boolean $full whether to return full info or only column names + * + * @return string + * @see getColumns() + * + */ + public function getColumnsSql( + string $database, + string $table, + ?string $column = null, + bool $full = false + ): string; + + /** + * Returns descriptions of columns in given table (all or given by $column) + * + * @param string $database name of database + * @param string $table name of table to retrieve columns from + * @param string $column name of column, null to show all columns + * @param boolean $full whether to return full info or only column names + * @param integer $link link type + * + * @return array array indexed by column names or, + * if $column is given, flat array description + */ + public function getColumns( + string $database, + string $table, + ?string $column = null, + bool $full = false, + $link = DatabaseInterface::CONNECT_USER + ): array; + + /** + * Returns all column names in given table + * + * @param string $database name of database + * @param string $table name of table to retrieve columns from + * @param mixed $link mysql link resource + * + * @return null|array + */ + public function getColumnNames( + string $database, + string $table, + $link = DatabaseInterface::CONNECT_USER + ): ?array; + + /** + * Returns SQL for fetching information on table indexes (SHOW INDEXES) + * + * @param string $database name of database + * @param string $table name of the table whose indexes are to be retrieved + * @param string $where additional conditions for WHERE + * + * @return string SQL for getting indexes + */ + public function getTableIndexesSql(string $database, string $table, ?string $where = null): string; + + /** + * Returns indexes of a table + * + * @param string $database name of database + * @param string $table name of the table whose indexes are to be retrieved + * @param mixed $link mysql link resource + * + * @return array + */ + public function getTableIndexes( + string $database, + string $table, + $link = DatabaseInterface::CONNECT_USER + ): array; + + /** + * returns value of given mysql server variable + * + * @param string $var mysql server variable name + * @param int $type DatabaseInterface::GETVAR_SESSION | + * DatabaseInterface::GETVAR_GLOBAL + * @param mixed $link mysql link resource|object + * + * @return mixed value for mysql server variable + */ + public function getVariable( + string $var, + int $type = DatabaseInterface::GETVAR_SESSION, + $link = DatabaseInterface::CONNECT_USER + ); + + /** + * Sets new value for a variable if it is different from the current value + * + * @param string $var variable name + * @param string $value value to set + * @param mixed $link mysql link resource|object + * + * @return bool whether query was a successful + */ + public function setVariable(string $var, string $value, $link = DatabaseInterface::CONNECT_USER): bool; + + /** + * Function called just after a connection to the MySQL database server has + * been established. It sets the connection collation, and determines the + * version of MySQL which is running. + * + * @return void + */ + public function postConnect(): void; + + /** + * Sets collation connection for user link + * + * @param string $collation collation to set + * + * @return void + */ + public function setCollation(string $collation): void; + + /** + * Function called just after a connection to the MySQL database server has + * been established. It sets the connection collation, and determines the + * version of MySQL which is running. + * + * @return void + */ + public function postConnectControl(): void; + + /** + * returns a single value from the given result or query, + * if the query or the result has more than one row or field + * the first field of the first row is returned + * + * + * $sql = 'SELECT `name` FROM `user` WHERE `id` = 123'; + * $user_name = $dbi->fetchValue($sql); + * // produces + * // $user_name = 'John Doe' + * + * + * @param string $query The query to execute + * @param integer $row_number row to fetch the value from, + * starting at 0, with 0 being + * default + * @param integer|string $field field to fetch the value from, + * starting at 0, with 0 being + * default + * @param integer $link link type + * + * @return mixed value of first field in first row from result + * or false if not found + */ + public function fetchValue( + string $query, + int $row_number = 0, + $field = 0, + $link = DatabaseInterface::CONNECT_USER + ); + + /** + * returns only the first row from the result + * + * + * $sql = 'SELECT * FROM `user` WHERE `id` = 123'; + * $user = $dbi->fetchSingleRow($sql); + * // produces + * // $user = array('id' => 123, 'name' => 'John Doe') + * + * + * @param string $query The query to execute + * @param string $type NUM|ASSOC|BOTH returned array should either numeric + * associative or both + * @param integer $link link type + * + * @return array|boolean first row from result + * or false if result is empty + */ + public function fetchSingleRow( + string $query, + string $type = 'ASSOC', + $link = DatabaseInterface::CONNECT_USER + ); + + /** + * returns all rows in the resultset in one array + * + * + * $sql = 'SELECT * FROM `user`'; + * $users = $dbi->fetchResult($sql); + * // produces + * // $users[] = array('id' => 123, 'name' => 'John Doe') + * + * $sql = 'SELECT `id`, `name` FROM `user`'; + * $users = $dbi->fetchResult($sql, 'id'); + * // produces + * // $users['123'] = array('id' => 123, 'name' => 'John Doe') + * + * $sql = 'SELECT `id`, `name` FROM `user`'; + * $users = $dbi->fetchResult($sql, 0); + * // produces + * // $users['123'] = array(0 => 123, 1 => 'John Doe') + * + * $sql = 'SELECT `id`, `name` FROM `user`'; + * $users = $dbi->fetchResult($sql, 'id', 'name'); + * // or + * $users = $dbi->fetchResult($sql, 0, 1); + * // produces + * // $users['123'] = 'John Doe' + * + * $sql = 'SELECT `name` FROM `user`'; + * $users = $dbi->fetchResult($sql); + * // produces + * // $users[] = 'John Doe' + * + * $sql = 'SELECT `group`, `name` FROM `user`' + * $users = $dbi->fetchResult($sql, array('group', null), 'name'); + * // produces + * // $users['admin'][] = 'John Doe' + * + * $sql = 'SELECT `group`, `name` FROM `user`' + * $users = $dbi->fetchResult($sql, array('group', 'name'), 'id'); + * // produces + * // $users['admin']['John Doe'] = '123' + * + * + * @param string $query query to execute + * @param string|integer|array $key field-name or offset + * used as key for + * array or array of + * those + * @param string|integer $value value-name or offset + * used as value for + * array + * @param integer $link link type + * @param integer $options query options + * + * @return array resultrows or values indexed by $key + */ + public function fetchResult( + string $query, + $key = null, + $value = null, + $link = DatabaseInterface::CONNECT_USER, + int $options = 0 + ); + + /** + * Get supported SQL compatibility modes + * + * @return array supported SQL compatibility modes + */ + public function getCompatibilities(): array; + + /** + * returns warnings for last query + * + * @param integer $link link type + * + * @return array warnings + */ + public function getWarnings($link = DatabaseInterface::CONNECT_USER): array; + + /** + * returns an array of PROCEDURE or FUNCTION names for a db + * + * @param string $db db name + * @param string $which PROCEDURE | FUNCTION + * @param integer $link link type + * + * @return array the procedure names or function names + */ + public function getProceduresOrFunctions( + string $db, + string $which, + $link = DatabaseInterface::CONNECT_USER + ): array; + + /** + * returns the definition of a specific PROCEDURE, FUNCTION, EVENT or VIEW + * + * @param string $db db name + * @param string $which PROCEDURE | FUNCTION | EVENT | VIEW + * @param string $name the procedure|function|event|view name + * @param integer $link link type + * + * @return string|null the definition + */ + public function getDefinition( + string $db, + string $which, + string $name, + $link = DatabaseInterface::CONNECT_USER + ): ?string; + + /** + * returns details about the PROCEDUREs or FUNCTIONs for a specific database + * or details about a specific routine + * + * @param string $db db name + * @param string $which PROCEDURE | FUNCTION or null for both + * @param string $name name of the routine (to fetch a specific routine) + * + * @return array information about ROCEDUREs or FUNCTIONs + */ + public function getRoutines(string $db, ?string $which = null, string $name = ''): array; + + /** + * returns details about the EVENTs for a specific database + * + * @param string $db db name + * @param string $name event name + * + * @return array information about EVENTs + */ + public function getEvents(string $db, string $name = ''): array; + + /** + * returns details about the TRIGGERs for a specific table or database + * + * @param string $db db name + * @param string $table table name + * @param string $delimiter the delimiter to use (may be empty) + * + * @return array information about triggers (may be empty) + */ + public function getTriggers(string $db, string $table = '', $delimiter = '//'); + + /** + * gets the current user with host + * + * @return string the current user i.e. user@host + */ + public function getCurrentUser(): string; + + /** + * Checks if current user is superuser + * + * @return bool Whether user is a superuser + */ + public function isSuperuser(): bool; + + /** + * Checks if current user has global create user/grant privilege + * or is a superuser (i.e. SELECT on mysql.users) + * while caching the result in session. + * + * @param string $type type of user to check for + * i.e. 'create', 'grant', 'super' + * + * @return bool Whether user is a given type of user + */ + public function isUserType(string $type): bool; + + /** + * Get the current user and host + * + * @return array array of username and hostname + */ + public function getCurrentUserAndHost(): array; + + /** + * Returns value for lower_case_table_names variable + * + * @return string|bool + */ + public function getLowerCaseNames(); + + /** + * Get the list of system schemas + * + * @return array list of system schemas + */ + public function getSystemSchemas(): array; + + /** + * Checks whether given schema is a system schema + * + * @param string $schema_name Name of schema (database) to test + * @param bool $testForMysqlSchema Whether 'mysql' schema should + * be treated the same as IS and + * DD + * + * @return bool + */ + public function isSystemSchema(string $schema_name, bool $testForMysqlSchema = false): bool; + + /** + * Return connection parameters for the database server + * + * @param integer $mode Connection mode on of CONNECT_USER, CONNECT_CONTROL + * or CONNECT_AUXILIARY. + * @param array|null $server Server information like host/port/socket/persistent + * + * @return array user, host and server settings array + */ + public function getConnectionParams(int $mode, ?array $server = null): array; + + /** + * connects to the database server + * + * @param integer $mode Connection mode on of CONNECT_USER, CONNECT_CONTROL + * or CONNECT_AUXILIARY. + * @param array|null $server Server information like host/port/socket/persistent + * @param integer $target How to store connection link, defaults to $mode + * + * @return mixed false on error or a connection object on success + */ + public function connect(int $mode, ?array $server = null, ?int $target = null); + + /** + * selects given database + * + * @param string $dbname database name to select + * @param integer $link link type + * + * @return boolean + */ + public function selectDb(string $dbname, $link = DatabaseInterface::CONNECT_USER): bool; + + /** + * returns array of rows with associative and numeric keys from $result + * + * @param object $result result set identifier + * + * @return array + */ + public function fetchArray($result); + + /** + * returns array of rows with associative keys from $result + * + * @param object $result result set identifier + * + * @return array|bool + */ + public function fetchAssoc($result); + + /** + * returns array of rows with numeric keys from $result + * + * @param object $result result set identifier + * + * @return array|bool + */ + public function fetchRow($result); + + /** + * Adjusts the result pointer to an arbitrary row in the result + * + * @param object $result database result + * @param integer $offset offset to seek + * + * @return bool true on success, false on failure + */ + public function dataSeek($result, int $offset): bool; + + /** + * Frees memory associated with the result + * + * @param object $result database result + * + * @return void + */ + public function freeResult($result): void; + + /** + * Check if there are any more query results from a multi query + * + * @param integer $link link type + * + * @return bool true or false + */ + public function moreResults($link = DatabaseInterface::CONNECT_USER): bool; + + /** + * Prepare next result from multi_query + * + * @param integer $link link type + * + * @return bool true or false + */ + public function nextResult($link = DatabaseInterface::CONNECT_USER): bool; + + /** + * Store the result returned from multi query + * + * @param integer $link link type + * + * @return mixed false when empty results / result set when not empty + */ + public function storeResult($link = DatabaseInterface::CONNECT_USER); + + /** + * Returns a string representing the type of connection used + * + * @param integer $link link type + * + * @return string|bool type of connection used + */ + public function getHostInfo($link = DatabaseInterface::CONNECT_USER); + + /** + * Returns the version of the MySQL protocol used + * + * @param integer $link link type + * + * @return int|bool version of the MySQL protocol used + */ + public function getProtoInfo($link = DatabaseInterface::CONNECT_USER); + + /** + * returns a string that represents the client library version + * + * @param integer $link link type + * + * @return string MySQL client library version + */ + public function getClientInfo($link = DatabaseInterface::CONNECT_USER): string; + + /** + * returns last error message or false if no errors occurred + * + * @param integer $link link type + * + * @return string|bool error or false + */ + public function getError($link = DatabaseInterface::CONNECT_USER); + + /** + * returns the number of rows returned by last query + * + * @param object $result result set identifier + * + * @return string|int + */ + public function numRows($result); + + /** + * returns last inserted auto_increment id for given $link + * or $GLOBALS['userlink'] + * + * @param integer $link link type + * + * @return int|boolean + */ + public function insertId($link = DatabaseInterface::CONNECT_USER); + + /** + * returns the number of rows affected by last query + * + * @param integer $link link type + * @param bool $get_from_cache whether to retrieve from cache + * + * @return int|boolean + */ + public function affectedRows($link = DatabaseInterface::CONNECT_USER, bool $get_from_cache = true); + + /** + * returns metainfo for fields in $result + * + * @param object $result result set identifier + * + * @return mixed meta info for fields in $result + */ + public function getFieldsMeta($result); + + /** + * return number of fields in given $result + * + * @param object $result result set identifier + * + * @return int field count + */ + public function numFields($result): int; + + /** + * returns the length of the given field $i in $result + * + * @param object $result result set identifier + * @param int $i field + * + * @return int|bool length of field + */ + public function fieldLen($result, int $i); + + /** + * returns name of $i. field in $result + * + * @param object $result result set identifier + * @param int $i field + * + * @return string name of $i. field in $result + */ + public function fieldName($result, int $i): string; + + /** + * returns concatenated string of human readable field flags + * + * @param object $result result set identifier + * @param int $i field + * + * @return string field flags + */ + public function fieldFlags($result, $i): string; + + /** + * returns properly escaped string for use in MySQL queries + * + * @param string $str string to be escaped + * @param mixed $link optional database link to use + * + * @return string a MySQL escaped string + */ + public function escapeString(string $str, $link = DatabaseInterface::CONNECT_USER); + + /** + * Checks if this database server is running on Amazon RDS. + * + * @return boolean + */ + public function isAmazonRds(): bool; + + /** + * Gets SQL for killing a process. + * + * @param int $process Process ID + * + * @return string + */ + public function getKillQuery(int $process): string; + + /** + * Get the phpmyadmin database manager + * + * @return SystemDatabase + */ + public function getSystemDatabase(): SystemDatabase; + + /** + * Get a table with database name and table name + * + * @param string $db_name DB name + * @param string $table_name Table name + * + * @return Table + */ + public function getTable(string $db_name, string $table_name): Table; + + /** + * returns collation of given db + * + * @param string $db name of db + * + * @return string collation of $db + */ + public function getDbCollation(string $db): string; + + /** + * returns default server collation from show variables + * + * @return string + */ + public function getServerCollation(): string; + + /** + * Server version as number + * + * @return integer + */ + public function getVersion(): int; + + /** + * Server version + * + * @return string + */ + public function getVersionString(): string; + + /** + * Server version comment + * + * @return string + */ + public function getVersionComment(): string; + + /** + * Whether connection is MariaDB + * + * @return boolean + */ + public function isMariaDB(): bool; + + /** + * Whether connection is Percona + * + * @return boolean + */ + public function isPercona(): bool; + + /** + * Prepare an SQL statement for execution. + * + * @param string $query The query, as a string. + * @param int $link Link type. + * + * @return object|false A statement object or false. + */ + public function prepare(string $query, $link = DatabaseInterface::CONNECT_USER); +} diff --git a/libraries/classes/Dbi/DbiExtension.php b/libraries/classes/Dbal/DbiExtension.php similarity index 99% rename from libraries/classes/Dbi/DbiExtension.php rename to libraries/classes/Dbal/DbiExtension.php index 2c464cf57d..114b9c1aba 100644 --- a/libraries/classes/Dbi/DbiExtension.php +++ b/libraries/classes/Dbal/DbiExtension.php @@ -6,7 +6,7 @@ */ declare(strict_types=1); -namespace PhpMyAdmin\Dbi; +namespace PhpMyAdmin\Dbal; /** * Contract for every database extension supported by phpMyAdmin diff --git a/libraries/classes/Dbi/DbiMysqli.php b/libraries/classes/Dbal/DbiMysqli.php similarity index 99% rename from libraries/classes/Dbi/DbiMysqli.php rename to libraries/classes/Dbal/DbiMysqli.php index de07db1896..1318a0b5b7 100644 --- a/libraries/classes/Dbi/DbiMysqli.php +++ b/libraries/classes/Dbal/DbiMysqli.php @@ -7,7 +7,7 @@ */ declare(strict_types=1); -namespace PhpMyAdmin\Dbi; +namespace PhpMyAdmin\Dbal; use mysqli; use mysqli_result; diff --git a/test/classes/Dbi/DbiDummyTest.php b/test/classes/Dbal/DbiDummyTest.php similarity index 98% rename from test/classes/Dbi/DbiDummyTest.php rename to test/classes/Dbal/DbiDummyTest.php index 1860fbfc40..0cb11d3440 100644 --- a/test/classes/Dbi/DbiDummyTest.php +++ b/test/classes/Dbal/DbiDummyTest.php @@ -6,7 +6,7 @@ */ declare(strict_types=1); -namespace PhpMyAdmin\Tests\Dbi; +namespace PhpMyAdmin\Tests\Dbal; use PHPUnit\Framework\TestCase; diff --git a/test/classes/Dbi/DbiMysqliTest.php b/test/classes/Dbal/DbiMysqliTest.php similarity index 98% rename from test/classes/Dbi/DbiMysqliTest.php rename to test/classes/Dbal/DbiMysqliTest.php index 4d1d818ecc..6468240a2d 100644 --- a/test/classes/Dbi/DbiMysqliTest.php +++ b/test/classes/Dbal/DbiMysqliTest.php @@ -6,11 +6,11 @@ */ declare(strict_types=1); -namespace PhpMyAdmin\Tests\Dbi; +namespace PhpMyAdmin\Tests\Dbal; use mysqli; use mysqli_result; -use PhpMyAdmin\Dbi\DbiMysqli; +use PhpMyAdmin\Dbal\DbiMysqli; use PHPUnit\Framework\TestCase; /** diff --git a/test/classes/Stubs/DbiDummy.php b/test/classes/Stubs/DbiDummy.php index 67fa6d80bd..1ca678f577 100644 --- a/test/classes/Stubs/DbiDummy.php +++ b/test/classes/Stubs/DbiDummy.php @@ -13,7 +13,7 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Stubs; -use PhpMyAdmin\Dbi\DbiExtension; +use PhpMyAdmin\Dbal\DbiExtension; /** * Fake database driver for testing purposes