2010-04-21 12:01:32 +00:00
< ? php
2010-10-29 13:24:06 +00:00
$drivers = array ( " server " => " MySQL " ) + $drivers ;
2010-04-21 12:01:32 +00:00
if ( ! defined ( " DRIVER " )) {
2010-10-29 13:24:06 +00:00
$possible_drivers = array ( " MySQLi " , " MySQL " , " PDO_MySQL " );
2010-04-21 12:01:32 +00:00
define ( " DRIVER " , " server " ); // server - backwards compatibility
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
if ( extension_loaded ( " mysqli " )) {
class Min_DB extends MySQLi {
var $extension = " MySQLi " ;
2013-07-24 23:26:41 +00:00
2015-08-15 15:04:21 +00:00
function __construct () {
2010-04-21 12:01:32 +00:00
parent :: init ();
}
2013-07-24 23:26:41 +00:00
2016-01-24 20:02:10 +00:00
function connect ( $server = " " , $username = " " , $password = " " , $database = null , $port = null , $socket = null ) {
2018-02-07 11:13:58 +00:00
global $adminer ;
2010-09-09 20:02:35 +00:00
mysqli_report ( MYSQLI_REPORT_OFF ); // stays between requests, not required since PHP 5.3.4
2010-04-21 12:01:32 +00:00
list ( $host , $port ) = explode ( " : " , $server , 2 ); // part after : is used for port or socket
2018-02-07 11:13:58 +00:00
$ssl = $adminer -> connectSsl ();
if ( $ssl ) {
$this -> ssl_set ( $ssl [ 'key' ], $ssl [ 'cert' ], $ssl [ 'ca' ], '' , '' );
}
2010-10-10 09:12:53 +00:00
$return = @ $this -> real_connect (
2010-04-21 12:01:32 +00:00
( $server != " " ? $host : ini_get ( " mysqli.default_host " )),
2011-06-22 13:06:46 +00:00
( $server . $username != " " ? $username : ini_get ( " mysqli.default_user " )),
( $server . $username . $password != " " ? $password : ini_get ( " mysqli.default_pw " )),
2016-01-24 20:02:10 +00:00
$database ,
2010-04-21 12:01:32 +00:00
( is_numeric ( $port ) ? $port : ini_get ( " mysqli.default_port " )),
2018-02-07 11:13:58 +00:00
( ! is_numeric ( $port ) ? $port : $socket ),
( $ssl ? 64 : 0 ) // 64 - MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT (not available before PHP 5.6.16)
2010-04-21 12:01:32 +00:00
);
2010-10-10 09:12:53 +00:00
return $return ;
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2015-03-08 20:06:45 +00:00
function set_charset ( $charset ) {
2015-03-10 16:21:30 +00:00
if ( parent :: set_charset ( $charset )) {
return true ;
}
2015-03-08 20:06:45 +00:00
// the client library may not support utf8mb4
parent :: set_charset ( 'utf8' );
return $this -> query ( " SET NAMES $charset " );
}
2010-04-21 12:01:32 +00:00
function result ( $query , $field = 0 ) {
$result = $this -> query ( $query );
if ( ! $result ) {
return false ;
}
$row = $result -> fetch_array ();
return $row [ $field ];
}
2015-03-08 20:06:45 +00:00
2010-04-21 12:01:32 +00:00
function quote ( $string ) {
return " ' " . $this -> escape_string ( $string ) . " ' " ;
}
}
2013-07-24 23:26:41 +00:00
2011-08-25 15:46:25 +00:00
} elseif ( extension_loaded ( " mysql " ) && ! ( ini_get ( " sql.safe_mode " ) && extension_loaded ( " pdo_mysql " ))) {
2010-04-21 12:01:32 +00:00
class Min_DB {
var
$extension = " MySQL " , ///< @var string extension name
$server_info , ///< @var string server version
$affected_rows , ///< @var int number of affected rows
2013-01-10 06:19:38 +00:00
$errno , ///< @var int last error code
2010-04-21 12:01:32 +00:00
$error , ///< @var string last error message
$_link , $_result ///< @access private
;
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Connect to server
* @ param string
* @ param string
* @ param string
* @ return bool
*/
function connect ( $server , $username , $password ) {
$this -> _link = @ mysql_connect (
( $server != " " ? $server : ini_get ( " mysql.default_host " )),
( " $server $username " != " " ? $username : ini_get ( " mysql.default_user " )),
( " $server $username $password " != " " ? $password : ini_get ( " mysql.default_password " )),
true ,
131072 // CLIENT_MULTI_RESULTS for CALL
);
if ( $this -> _link ) {
$this -> server_info = mysql_get_server_info ( $this -> _link );
} else {
$this -> error = mysql_error ();
}
return ( bool ) $this -> _link ;
}
2013-07-24 23:26:41 +00:00
2014-06-24 12:53:04 +00:00
/** Sets the client character set
* @ param string
* @ return bool
*/
function set_charset ( $charset ) {
if ( function_exists ( 'mysql_set_charset' )) {
2015-03-10 16:21:30 +00:00
if ( mysql_set_charset ( $charset , $this -> _link )) {
return true ;
}
2015-03-08 20:06:45 +00:00
// the client library may not support utf8mb4
mysql_set_charset ( 'utf8' , $this -> _link );
2014-06-24 12:53:04 +00:00
}
return $this -> query ( " SET NAMES $charset " );
}
2010-04-21 12:01:32 +00:00
/** Quote string to use in SQL
* @ param string
* @ return string escaped string enclosed in '
*/
function quote ( $string ) {
return " ' " . mysql_real_escape_string ( $string , $this -> _link ) . " ' " ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Select database
* @ param string
* @ return bool
*/
function select_db ( $database ) {
return mysql_select_db ( $database , $this -> _link );
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Send query
* @ param string
* @ param bool
* @ return mixed bool or Min_Result
*/
function query ( $query , $unbuffered = false ) {
$result = @ ( $unbuffered ? mysql_unbuffered_query ( $query , $this -> _link ) : mysql_query ( $query , $this -> _link )); // @ - mute mysql.trace_mode
2012-07-15 16:21:22 +00:00
$this -> error = " " ;
2010-04-21 12:01:32 +00:00
if ( ! $result ) {
2013-01-10 20:57:00 +00:00
$this -> errno = mysql_errno ( $this -> _link );
2010-04-21 12:01:32 +00:00
$this -> error = mysql_error ( $this -> _link );
return false ;
}
if ( $result === true ) {
$this -> affected_rows = mysql_affected_rows ( $this -> _link );
$this -> info = mysql_info ( $this -> _link );
return true ;
}
return new Min_Result ( $result );
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Send query with more resultsets
* @ param string
* @ return bool
*/
function multi_query ( $query ) {
return $this -> _result = $this -> query ( $query );
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Get current resultset
* @ return Min_Result
*/
function store_result () {
return $this -> _result ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Fetch next resultset
* @ return bool
*/
function next_result () {
// MySQL extension doesn't support multiple results
return false ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Get single field from result
* @ param string
* @ param int
* @ return string
*/
function result ( $query , $field = 0 ) {
$result = $this -> query ( $query );
2011-02-01 15:26:21 +00:00
if ( ! $result || ! $result -> num_rows ) {
2010-04-21 12:01:32 +00:00
return false ;
}
return mysql_result ( $result -> _result , 0 , $field );
}
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
class Min_Result {
var
$num_rows , ///< @var int number of rows in the result
2010-11-02 13:40:56 +00:00
$_result , $_offset = 0 ///< @access private
2010-04-21 12:01:32 +00:00
;
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Constructor
* @ param resource
*/
2015-08-15 15:04:21 +00:00
function __construct ( $result ) {
2010-04-21 12:01:32 +00:00
$this -> _result = $result ;
$this -> num_rows = mysql_num_rows ( $result );
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Fetch next row as associative array
* @ return array
*/
function fetch_assoc () {
return mysql_fetch_assoc ( $this -> _result );
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Fetch next row as numbered array
* @ return array
*/
function fetch_row () {
return mysql_fetch_row ( $this -> _result );
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Fetch next field
* @ return object properties : name , type , orgtable , orgname , charsetnr
*/
function fetch_field () {
2010-11-02 13:40:56 +00:00
$return = mysql_fetch_field ( $this -> _result , $this -> _offset ++ ); // offset required under certain conditions
2010-04-21 12:01:32 +00:00
$return -> orgtable = $return -> table ;
$return -> orgname = $return -> name ;
$return -> charsetnr = ( $return -> blob ? 63 : 0 );
return $return ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Free result set
*/
function __destruct () {
2013-08-09 00:16:04 +00:00
mysql_free_result ( $this -> _result );
2010-04-21 12:01:32 +00:00
}
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
} elseif ( extension_loaded ( " pdo_mysql " )) {
class Min_DB extends Min_PDO {
var $extension = " PDO_MySQL " ;
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
function connect ( $server , $username , $password ) {
2018-02-07 11:13:58 +00:00
global $adminer ;
$options = array ();
$ssl = $adminer -> connectSsl ();
if ( $ssl ) {
$options = array (
PDO :: MYSQL_ATTR_SSL_KEY => $ssl [ 'key' ],
PDO :: MYSQL_ATTR_SSL_CERT => $ssl [ 'cert' ],
PDO :: MYSQL_ATTR_SSL_CA => $ssl [ 'ca' ],
);
}
$this -> dsn (
2018-02-20 15:27:40 +00:00
" mysql:charset=utf8;host= " . str_replace ( " : " , " ;unix_socket= " , preg_replace ( '~:(\d)~' , ';port=\1' , $server )),
2018-02-07 11:13:58 +00:00
$username ,
$password ,
$options
);
2010-04-21 12:01:32 +00:00
return true ;
}
2013-07-24 23:26:41 +00:00
2014-06-24 12:53:04 +00:00
function set_charset ( $charset ) {
$this -> query ( " SET NAMES $charset " ); // charset in DSN is ignored before PHP 5.3.6
}
2010-04-21 12:01:32 +00:00
function select_db ( $database ) {
// database selection is separated from the connection so dbname in DSN can't be used
return $this -> query ( " USE " . idf_escape ( $database ));
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
function query ( $query , $unbuffered = false ) {
$this -> setAttribute ( 1000 , ! $unbuffered ); // 1000 - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
return parent :: query ( $query , $unbuffered );
}
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
}
2013-07-05 16:04:06 +00:00
class Min_Driver extends Min_SQL {
2013-07-24 23:26:41 +00:00
2013-07-05 16:04:06 +00:00
function insert ( $table , $set ) {
return ( $set ? parent :: insert ( $table , $set ) : queries ( " INSERT INTO " . table ( $table ) . " () \n VALUES () " ));
}
2013-07-24 23:26:41 +00:00
2013-07-09 18:34:12 +00:00
function insertUpdate ( $table , $rows , $primary ) {
$columns = array_keys ( reset ( $rows ));
$prefix = " INSERT INTO " . table ( $table ) . " ( " . implode ( " , " , $columns ) . " ) VALUES \n " ;
$values = array ();
foreach ( $columns as $key ) {
$values [ $key ] = " $key = VALUES( $key ) " ;
2013-07-05 16:04:06 +00:00
}
2013-07-09 18:34:12 +00:00
$suffix = " \n ON DUPLICATE KEY UPDATE " . implode ( " , " , $values );
$values = array ();
$length = 0 ;
foreach ( $rows as $set ) {
$value = " ( " . implode ( " , " , $set ) . " ) " ;
if ( $values && ( strlen ( $prefix ) + $length + strlen ( $value ) + strlen ( $suffix ) > 1e6 )) { // 1e6 - default max_allowed_packet
if ( ! queries ( $prefix . implode ( " , \n " , $values ) . $suffix )) {
return false ;
}
$values = array ();
$length = 0 ;
}
$values [] = $value ;
$length += strlen ( $value ) + 2 ; // 2 - strlen(",\n")
}
return queries ( $prefix . implode ( " , \n " , $values ) . $suffix );
2013-07-05 16:04:06 +00:00
}
2018-01-31 16:28:12 +00:00
2018-03-09 17:06:19 +00:00
function slowQuery ( $query , $timeout ) {
if ( min_version ( '5.7.8' , '10.1.2' )) {
if ( preg_match ( '~MariaDB~' , $this -> _conn -> server_info )) {
return " SET STATEMENT max_statement_time= $timeout FOR $query " ;
} elseif ( preg_match ( '~^(SELECT\b)(.+)~is' , $query , $match )) {
return " $match[1] /*+ MAX_EXECUTION_TIME( " . ( $timeout * 1000 ) . " ) */ $match[2] " ;
}
}
}
2018-02-06 12:39:44 +00:00
function convertSearch ( $idf , $val , $field ) {
2018-03-01 10:01:35 +00:00
return ( preg_match ( '~char|text|enum|set~' , $field [ " type " ]) && ! preg_match ( " ~^utf8~ " , $field [ " collation " ]) && preg_match ( '~[\x80-\xFF]~' , $val [ 'val' ])
2018-02-06 12:19:12 +00:00
? " CONVERT( $idf USING " . charset ( $this -> _conn ) . " ) "
: $idf
);
}
2018-01-31 16:28:12 +00:00
function warnings () {
2018-02-01 10:43:44 +00:00
$result = $this -> _conn -> query ( " SHOW WARNINGS " );
if ( $result && $result -> num_rows ) {
ob_start ();
select ( $result ); // select() usually needs to print a big table progressively
return ob_get_clean ();
}
2018-01-31 16:28:12 +00:00
}
2013-07-24 23:26:41 +00:00
2018-02-08 10:21:33 +00:00
function tableHelp ( $name ) {
2018-02-08 12:56:22 +00:00
$maria = preg_match ( '~MariaDB~' , $this -> _conn -> server_info );
2018-02-08 10:21:33 +00:00
if ( information_schema ( DB )) {
2018-02-08 12:56:22 +00:00
return strtolower (( $maria ? " information-schema- $name -table/ " : str_replace ( " _ " , " - " , $name ) . " -table.html " ));
2018-02-08 10:21:33 +00:00
}
if ( DB == " mysql " ) {
2018-02-08 12:56:22 +00:00
return ( $maria ? " mysql $name -table/ " : " system-database.html " ); //! more precise link
2018-02-08 10:21:33 +00:00
}
}
2013-07-05 16:04:06 +00:00
}
2010-04-21 12:01:32 +00:00
/** Escape database identifier
* @ param string
* @ return string
*/
function idf_escape ( $idf ) {
return " ` " . str_replace ( " ` " , " `` " , $idf ) . " ` " ;
}
2010-05-11 14:45:04 +00:00
/** Get escaped table name
* @ param string
* @ return string
*/
function table ( $idf ) {
return idf_escape ( $idf );
}
2010-04-21 12:01:32 +00:00
/** Connect to the database
* @ return mixed Min_DB or string for error
*/
function connect () {
2017-03-10 07:15:52 +00:00
global $adminer , $types , $structured_types ;
2010-04-21 12:01:32 +00:00
$connection = new Min_DB ;
$credentials = $adminer -> credentials ();
if ( $connection -> connect ( $credentials [ 0 ], $credentials [ 1 ], $credentials [ 2 ])) {
2014-06-26 11:22:35 +00:00
$connection -> set_charset ( charset ( $connection )); // available in MySQLi since PHP 5.0.5
2011-09-27 00:24:20 +00:00
$connection -> query ( " SET sql_quote_show_create = 1, autocommit = 1 " );
2018-01-30 15:42:13 +00:00
if ( min_version ( '5.7.8' , 10.2 , $connection )) {
2017-03-10 07:15:52 +00:00
$structured_types [ lang ( 'Strings' )][] = " json " ;
$types [ " json " ] = 4294967295 ;
}
2010-04-21 12:01:32 +00:00
return $connection ;
}
2011-08-09 09:51:18 +00:00
$return = $connection -> error ;
if ( function_exists ( 'iconv' ) && ! is_utf8 ( $return ) && strlen ( $s = iconv ( " windows-1250 " , " utf-8 " , $return )) > strlen ( $return )) { // windows-1250 - most common Windows encoding
$return = $s ;
}
return $return ;
2010-04-21 12:01:32 +00:00
}
/** Get cached list of databases
* @ param bool
* @ return array
*/
2012-08-19 16:43:31 +00:00
function get_databases ( $flush ) {
2010-04-21 12:01:32 +00:00
// SHOW DATABASES can take a very long time so it is cached
2012-08-20 00:12:19 +00:00
$return = get_session ( " dbs " );
2012-05-14 06:54:07 +00:00
if ( $return === null ) {
2018-01-29 18:49:52 +00:00
$query = ( min_version ( 5 )
2012-08-20 00:12:19 +00:00
? " SELECT SCHEMA_NAME FROM information_schema.SCHEMATA "
: " SHOW DATABASES "
2012-08-20 04:55:00 +00:00
); // SHOW DATABASES can be disabled by skip_show_database
$return = ( $flush ? slow_query ( $query ) : get_vals ( $query ));
2012-08-19 20:42:13 +00:00
restart_session ();
2012-08-20 00:12:19 +00:00
set_session ( " dbs " , $return );
2012-08-19 20:42:13 +00:00
stop_session ();
2010-04-21 12:01:32 +00:00
}
return $return ;
}
/** Formulate SQL query with limit
* @ param string everything after SELECT
2010-05-14 13:51:54 +00:00
* @ param string including WHERE
2010-04-21 12:01:32 +00:00
* @ param int
* @ param int
2010-04-26 16:19:26 +00:00
* @ param string
2010-04-21 12:01:32 +00:00
* @ return string
*/
2010-05-14 13:51:54 +00:00
function limit ( $query , $where , $limit , $offset = 0 , $separator = " " ) {
2012-05-14 06:54:07 +00:00
return " $query $where " . ( $limit !== null ? $separator . " LIMIT $limit " . ( $offset ? " OFFSET $offset " : " " ) : " " );
2010-04-21 12:01:32 +00:00
}
/** Formulate SQL modification query with limit 1
2018-02-01 15:56:50 +00:00
* @ param string
2010-04-21 12:01:32 +00:00
* @ param string everything after UPDATE or DELETE
2012-09-16 13:43:55 +00:00
* @ param string
2018-02-01 17:53:53 +00:00
* @ param string
2010-04-21 12:01:32 +00:00
* @ return string
*/
2018-02-01 17:53:53 +00:00
function limit1 ( $table , $query , $where , $separator = " \n " ) {
return limit ( $query , $where , 1 , 0 , $separator );
2010-04-21 12:01:32 +00:00
}
/** Get database collation
* @ param string
* @ param array result of collations ()
* @ return string
*/
function db_collation ( $db , $collations ) {
global $connection ;
$return = null ;
$create = $connection -> result ( " SHOW CREATE DATABASE " . idf_escape ( $db ), 1 );
if ( preg_match ( '~ COLLATE ([^ ]+)~' , $create , $match )) {
$return = $match [ 1 ];
} elseif ( preg_match ( '~ CHARACTER SET ([^ ]+)~' , $create , $match )) {
// default collation
2011-02-25 09:49:19 +00:00
$return = $collations [ $match [ 1 ]][ - 1 ];
2010-04-21 12:01:32 +00:00
}
return $return ;
}
/** Get supported engines
* @ return array
*/
function engines () {
$return = array ();
2010-10-13 15:53:59 +00:00
foreach ( get_rows ( " SHOW ENGINES " ) as $row ) {
2013-07-24 23:26:41 +00:00
if ( preg_match ( " ~YES|DEFAULT~ " , $row [ " Support " ])) {
2010-04-21 12:01:32 +00:00
$return [] = $row [ " Engine " ];
}
}
return $return ;
}
/** Get logged user
* @ return string
*/
function logged_user () {
global $connection ;
return $connection -> result ( " SELECT USER() " );
}
/** Get tables list
2011-07-27 18:06:50 +00:00
* @ return array array ( $name => $type )
2010-04-21 12:01:32 +00:00
*/
function tables_list () {
2018-01-29 18:49:52 +00:00
return get_key_vals ( min_version ( 5 )
2013-12-21 03:18:19 +00:00
? " SELECT TABLE_NAME, TABLE_TYPE FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() ORDER BY TABLE_NAME "
: " SHOW TABLES "
);
2010-04-21 12:01:32 +00:00
}
/** Count tables in all databases
* @ param array
* @ return array array ( $db => $tables )
*/
function count_tables ( $databases ) {
$return = array ();
foreach ( $databases as $db ) {
$return [ $db ] = count ( get_vals ( " SHOW TABLES IN " . idf_escape ( $db )));
}
return $return ;
}
/** Get table status
* @ param string
2013-04-27 03:04:57 +00:00
* @ param bool return only " Name " , " Engine " and " Comment " fields
2011-07-29 14:41:52 +00:00
* @ return array array ( $name => array ( " Name " => , " Engine " => , " Comment " => , " Oid " => , " Rows " => , " Collation " => , " Auto_increment " => , " Data_length " => , " Index_length " => , " Data_free " => )) or only inner array with $name
2010-04-21 12:01:32 +00:00
*/
2013-04-27 03:04:57 +00:00
function table_status ( $name = " " , $fast = false ) {
2010-04-21 12:01:32 +00:00
$return = array ();
2018-01-29 18:49:52 +00:00
foreach ( get_rows ( $fast && min_version ( 5 )
2017-03-09 17:52:00 +00:00
? " SELECT TABLE_NAME AS Name, ENGINE AS Engine, TABLE_COMMENT AS Comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() " . ( $name != " " ? " AND TABLE_NAME = " . q ( $name ) : " ORDER BY Name " )
2013-04-27 03:04:57 +00:00
: " SHOW TABLE STATUS " . ( $name != " " ? " LIKE " . q ( addcslashes ( $name , " %_ \\ " )) : " " )
) as $row ) {
2010-04-21 12:01:32 +00:00
if ( $row [ " Engine " ] == " InnoDB " ) {
// ignore internal comment, unnecessary since MySQL 5.1.21
2018-02-20 15:27:40 +00:00
$row [ " Comment " ] = preg_replace ( '~(?:(.+); )?InnoDB free: .*~' , '\1' , $row [ " Comment " ]);
2010-04-21 12:01:32 +00:00
}
2013-05-08 18:53:53 +00:00
if ( ! isset ( $row [ " Engine " ])) {
2010-04-21 12:01:32 +00:00
$row [ " Comment " ] = " " ;
}
if ( $name != " " ) {
return $row ;
}
$return [ $row [ " Name " ]] = $row ;
}
return $return ;
}
2010-05-27 11:31:08 +00:00
/** Find out whether the identifier is view
* @ param array
* @ return bool
*/
function is_view ( $table_status ) {
2013-06-24 12:53:48 +00:00
return $table_status [ " Engine " ] === null ;
2010-05-27 11:31:08 +00:00
}
2010-04-21 12:01:32 +00:00
/** Check if table supports foreign keys
* @ param array result of table_status
* @ return bool
*/
function fk_support ( $table_status ) {
2014-11-12 18:13:40 +00:00
return preg_match ( '~InnoDB|IBMDB2I~i' , $table_status [ " Engine " ])
2018-01-29 18:49:52 +00:00
|| ( preg_match ( '~NDB~i' , $table_status [ " Engine " ]) && min_version ( 5.6 ));
2010-04-21 12:01:32 +00:00
}
/** Get information about fields
* @ param string
* @ return array array ( $name => array ( " field " => , " full_type " => , " type " => , " length " => , " unsigned " => , " default " => , " null " => , " auto_increment " => , " on_update " => , " collation " => , " privileges " => , " comment " => , " primary " => ))
*/
2010-11-11 09:47:32 +00:00
function fields ( $table ) {
2010-04-21 12:01:32 +00:00
$return = array ();
2010-10-13 15:53:59 +00:00
foreach ( get_rows ( " SHOW FULL COLUMNS FROM " . table ( $table )) as $row ) {
2018-02-20 15:27:40 +00:00
preg_match ( '~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~' , $row [ " Type " ], $match );
2010-10-13 15:53:59 +00:00
$return [ $row [ " Field " ]] = array (
" field " => $row [ " Field " ],
" full_type " => $row [ " Type " ],
" type " => $match [ 1 ],
" length " => $match [ 2 ],
" unsigned " => ltrim ( $match [ 3 ] . $match [ 4 ]),
2013-07-24 23:26:41 +00:00
" default " => ( $row [ " Default " ] != " " || preg_match ( " ~char|set~ " , $match [ 1 ]) ? $row [ " Default " ] : null ),
2010-10-13 15:53:59 +00:00
" null " => ( $row [ " Null " ] == " YES " ),
" auto_increment " => ( $row [ " Extra " ] == " auto_increment " ),
2013-07-24 23:26:41 +00:00
" on_update " => ( preg_match ( '~^on update (.+)~i' , $row [ " Extra " ], $match ) ? $match [ 1 ] : " " ), //! available since MySQL 5.1.23
2010-10-13 15:53:59 +00:00
" collation " => $row [ " Collation " ],
2013-12-20 22:10:26 +00:00
" privileges " => array_flip ( preg_split ( '~, *~' , $row [ " Privileges " ])),
2010-10-13 15:53:59 +00:00
" comment " => $row [ " Comment " ],
" primary " => ( $row [ " Key " ] == " PRI " ),
);
2010-04-21 12:01:32 +00:00
}
return $return ;
}
/** Get table indexes
* @ param string
* @ param string Min_DB to use
2013-07-03 17:32:31 +00:00
* @ return array array ( $key_name => array ( " type " => , " columns " => array (), " lengths " => array (), " descs " => array ()))
2010-04-21 12:01:32 +00:00
*/
function indexes ( $table , $connection2 = null ) {
$return = array ();
2010-10-13 15:53:59 +00:00
foreach ( get_rows ( " SHOW INDEX FROM " . table ( $table ), $connection2 ) as $row ) {
2017-02-20 16:25:59 +00:00
$name = $row [ " Key_name " ];
$return [ $name ][ " type " ] = ( $name == " PRIMARY " ? " PRIMARY " : ( $row [ " Index_type " ] == " FULLTEXT " ? " FULLTEXT " : ( $row [ " Non_unique " ] ? ( $row [ " Index_type " ] == " SPATIAL " ? " SPATIAL " : " INDEX " ) : " UNIQUE " )));
$return [ $name ][ " columns " ][] = $row [ " Column_name " ];
$return [ $name ][ " lengths " ][] = ( $row [ " Index_type " ] == " SPATIAL " ? null : $row [ " Sub_part " ]);
$return [ $name ][ " descs " ][] = null ;
2010-04-21 12:01:32 +00:00
}
return $return ;
}
/** Get foreign keys in table
* @ param string
2011-07-12 14:03:39 +00:00
* @ return array array ( $name => array ( " db " => , " ns " => , " table " => , " source " => array (), " target " => array (), " on_delete " => , " on_update " => ))
2010-04-21 12:01:32 +00:00
*/
function foreign_keys ( $table ) {
global $connection , $on_actions ;
static $pattern = '`(?:[^`]|``)+`' ;
$return = array ();
2010-05-11 14:45:04 +00:00
$create_table = $connection -> result ( " SHOW CREATE TABLE " . table ( $table ), 1 );
2010-04-21 12:01:32 +00:00
if ( $create_table ) {
2014-11-15 22:06:46 +00:00
preg_match_all ( " ~CONSTRAINT ( $pattern ) FOREIGN KEY ? \\ (((?: $pattern ,? ?)+) \\ ) REFERENCES ( $pattern )(?: \\ .( $pattern ))? \\ (((?: $pattern ,? ?)+) \\ )(?: ON DELETE ( $on_actions ))?(?: ON UPDATE ( $on_actions ))?~ " , $create_table , $matches , PREG_SET_ORDER );
2010-04-21 12:01:32 +00:00
foreach ( $matches as $match ) {
preg_match_all ( " ~ $pattern ~ " , $match [ 2 ], $source );
preg_match_all ( " ~ $pattern ~ " , $match [ 5 ], $target );
$return [ idf_unescape ( $match [ 1 ])] = array (
" db " => idf_unescape ( $match [ 4 ] != " " ? $match [ 3 ] : $match [ 4 ]),
" table " => idf_unescape ( $match [ 4 ] != " " ? $match [ 4 ] : $match [ 3 ]),
" source " => array_map ( 'idf_unescape' , $source [ 0 ]),
" target " => array_map ( 'idf_unescape' , $target [ 0 ]),
2011-08-29 11:21:02 +00:00
" on_delete " => ( $match [ 6 ] ? $match [ 6 ] : " RESTRICT " ),
" on_update " => ( $match [ 7 ] ? $match [ 7 ] : " RESTRICT " ),
2010-04-21 12:01:32 +00:00
);
}
}
return $return ;
}
/** Get view SELECT
* @ param string
* @ return array array ( " select " => )
*/
function view ( $name ) {
global $connection ;
2018-02-20 15:27:40 +00:00
return array ( " select " => preg_replace ( '~^(?:[^`]|`[^`]*`)*\s+AS\s+~isU' , '' , $connection -> result ( " SHOW CREATE VIEW " . table ( $name ), 1 )));
2010-04-21 12:01:32 +00:00
}
/** Get sorted grouped list of collations
* @ return array
*/
function collations () {
$return = array ();
2010-10-13 15:53:59 +00:00
foreach ( get_rows ( " SHOW COLLATION " ) as $row ) {
2011-02-25 09:49:19 +00:00
if ( $row [ " Default " ]) {
$return [ $row [ " Charset " ]][ - 1 ] = $row [ " Collation " ];
} else {
$return [ $row [ " Charset " ]][] = $row [ " Collation " ];
}
2010-04-21 12:01:32 +00:00
}
ksort ( $return );
foreach ( $return as $key => $val ) {
2011-02-25 09:49:19 +00:00
asort ( $return [ $key ]);
2010-04-21 12:01:32 +00:00
}
return $return ;
}
/** Find out if database is information_schema
* @ param string
* @ return bool
*/
function information_schema ( $db ) {
2018-01-29 18:49:52 +00:00
return ( min_version ( 5 ) && $db == " information_schema " )
|| ( min_version ( 5.5 ) && $db == " performance_schema " );
2010-04-21 12:01:32 +00:00
}
/** Get escaped error message
* @ return string
*/
function error () {
global $connection ;
return h ( preg_replace ( '~^You have an error.*syntax to use~U' , " Syntax error " , $connection -> error ));
}
2010-04-22 23:02:28 +00:00
/** Create database
* @ param string
2012-09-16 13:43:55 +00:00
* @ param string
2010-04-22 23:02:28 +00:00
* @ return string
*/
function create_database ( $db , $collation ) {
2010-10-13 16:04:40 +00:00
return queries ( " CREATE DATABASE " . idf_escape ( $db ) . ( $collation ? " COLLATE " . q ( $collation ) : " " ));
2010-04-22 23:02:28 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-22 23:02:28 +00:00
/** Drop databases
* @ param array
* @ return bool
*/
function drop_databases ( $databases ) {
2014-06-24 13:26:51 +00:00
$return = apply_queries ( " DROP DATABASE " , $databases , 'idf_escape' );
2013-03-27 16:24:51 +00:00
restart_session ();
2010-10-15 08:58:08 +00:00
set_session ( " dbs " , null );
2014-06-24 13:26:51 +00:00
return $return ;
2010-04-22 23:02:28 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Rename database from DB
* @ param string new name
2012-09-16 13:43:55 +00:00
* @ param string
2010-04-21 12:01:32 +00:00
* @ return bool
*/
function rename_database ( $name , $collation ) {
2014-06-24 13:26:51 +00:00
$return = false ;
2010-04-22 23:02:28 +00:00
if ( create_database ( $name , $collation )) {
2010-04-21 12:01:32 +00:00
//! move triggers
2010-06-18 14:38:06 +00:00
$rename = array ();
foreach ( tables_list () as $table => $type ) {
$rename [] = table ( $table ) . " TO " . idf_escape ( $name ) . " . " . table ( $table );
2010-04-21 12:01:32 +00:00
}
2014-06-24 13:26:51 +00:00
$return = ( ! $rename || queries ( " RENAME TABLE " . implode ( " , " , $rename )));
if ( $return ) {
2010-04-21 12:01:32 +00:00
queries ( " DROP DATABASE " . idf_escape ( DB ));
}
2014-06-24 13:26:51 +00:00
restart_session ();
set_session ( " dbs " , null );
2010-04-21 12:01:32 +00:00
}
2014-06-24 13:26:51 +00:00
return $return ;
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Generate modifier for auto increment column
* @ return string
*/
function auto_increment () {
$auto_increment_index = " PRIMARY KEY " ;
// don't overwrite primary key by auto_increment
if ( $_GET [ " create " ] != " " && $_POST [ " auto_increment_col " ]) {
foreach ( indexes ( $_GET [ " create " ]) as $index ) {
if ( in_array ( $_POST [ " fields " ][ $_POST [ " auto_increment_col " ]][ " orig " ], $index [ " columns " ], true )) {
$auto_increment_index = " " ;
break ;
}
if ( $index [ " type " ] == " PRIMARY " ) {
$auto_increment_index = " UNIQUE " ;
}
}
}
return " AUTO_INCREMENT $auto_increment_index " ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Run commands to create or alter table
* @ param string " " to create
* @ param string new name
* @ param array of array ( $orig , $process_field , $after )
* @ param array of strings
* @ param string
* @ param string
* @ param string
2014-11-25 02:17:43 +00:00
* @ param string number
2010-04-21 12:01:32 +00:00
* @ param string
* @ return bool
*/
function alter_table ( $table , $name , $fields , $foreign , $comment , $engine , $collation , $auto_increment , $partitioning ) {
$alter = array ();
foreach ( $fields as $field ) {
$alter [] = ( $field [ 1 ]
2012-07-15 21:38:45 +00:00
? ( $table != " " ? ( $field [ 0 ] != " " ? " CHANGE " . idf_escape ( $field [ 0 ]) : " ADD " ) : " " ) . " " . implode ( $field [ 1 ]) . ( $table != " " ? $field [ 2 ] : " " )
2010-04-21 12:01:32 +00:00
: " DROP " . idf_escape ( $field [ 0 ])
);
}
$alter = array_merge ( $alter , $foreign );
2014-11-18 17:50:02 +00:00
$status = ( $comment !== null ? " COMMENT= " . q ( $comment ) : " " )
2010-10-13 16:04:40 +00:00
. ( $engine ? " ENGINE= " . q ( $engine ) : " " )
. ( $collation ? " COLLATE " . q ( $collation ) : " " )
2010-04-21 12:01:32 +00:00
. ( $auto_increment != " " ? " AUTO_INCREMENT= $auto_increment " : " " )
;
if ( $table == " " ) {
2014-11-20 17:53:52 +00:00
return queries ( " CREATE TABLE " . table ( $name ) . " ( \n " . implode ( " , \n " , $alter ) . " \n ) $status $partitioning " );
2010-04-21 12:01:32 +00:00
}
if ( $table != $name ) {
2010-05-11 14:45:04 +00:00
$alter [] = " RENAME TO " . table ( $name );
2010-04-21 12:01:32 +00:00
}
2014-11-18 17:50:02 +00:00
if ( $status ) {
$alter [] = ltrim ( $status );
}
2014-11-20 17:53:52 +00:00
return ( $alter || $partitioning ? queries ( " ALTER TABLE " . table ( $table ) . " \n " . implode ( " , \n " , $alter ) . $partitioning ) : true );
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Run commands to alter indexes
* @ param string escaped table name
2014-01-12 03:22:44 +00:00
* @ param array of array ( " index type " , " name " , array ( " column definition " , ... )) or array ( " index type " , " name " , " DROP " )
2010-04-21 12:01:32 +00:00
* @ return bool
*/
function alter_indexes ( $table , $alter ) {
foreach ( $alter as $key => $val ) {
2011-07-13 13:13:00 +00:00
$alter [ $key ] = ( $val [ 2 ] == " DROP "
? " \n DROP INDEX " . idf_escape ( $val [ 1 ])
2014-01-12 03:22:44 +00:00
: " \n ADD $val[0] " . ( $val [ 0 ] == " PRIMARY " ? " KEY " : " " ) . ( $val [ 1 ] != " " ? idf_escape ( $val [ 1 ]) . " " : " " ) . " ( " . implode ( " , " , $val [ 2 ]) . " ) "
2011-07-13 13:13:00 +00:00
);
2010-04-21 12:01:32 +00:00
}
2010-05-11 14:45:04 +00:00
return queries ( " ALTER TABLE " . table ( $table ) . implode ( " , " , $alter ));
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Run commands to truncate tables
* @ param array
* @ return bool
*/
function truncate_tables ( $tables ) {
2010-05-17 16:18:32 +00:00
return apply_queries ( " TRUNCATE TABLE " , $tables );
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Drop views
* @ param array
* @ return bool
*/
function drop_views ( $views ) {
2010-05-11 14:45:04 +00:00
return queries ( " DROP VIEW " . implode ( " , " , array_map ( 'table' , $views )));
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Drop tables
* @ param array
* @ return bool
*/
function drop_tables ( $tables ) {
2010-05-11 14:45:04 +00:00
return queries ( " DROP TABLE " . implode ( " , " , array_map ( 'table' , $tables )));
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2010-05-05 20:11:24 +00:00
/** Move tables to other schema
* @ param array
2011-02-01 13:12:22 +00:00
* @ param array
2010-05-05 20:11:24 +00:00
* @ param string
* @ return bool
*/
function move_tables ( $tables , $views , $target ) {
$rename = array ();
foreach ( array_merge ( $tables , $views ) as $table ) { // views will report SQL error
2010-05-11 14:45:04 +00:00
$rename [] = table ( $table ) . " TO " . idf_escape ( $target ) . " . " . table ( $table );
2010-05-05 20:11:24 +00:00
}
return queries ( " RENAME TABLE " . implode ( " , " , $rename ));
//! move triggers
}
2013-07-24 23:26:41 +00:00
2011-02-01 13:12:22 +00:00
/** Copy tables to other schema
* @ param array
* @ param array
* @ param string
* @ return bool
*/
function copy_tables ( $tables , $views , $target ) {
2011-07-12 13:14:15 +00:00
queries ( " SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' " );
2011-02-01 13:12:22 +00:00
foreach ( $tables as $table ) {
$name = ( $target == DB ? table ( " copy_ $table " ) : idf_escape ( $target ) . " . " . table ( $table ));
2014-03-15 21:46:56 +00:00
if ( ! queries ( " \n DROP TABLE IF EXISTS $name " )
2011-02-01 13:12:22 +00:00
|| ! queries ( " CREATE TABLE $name LIKE " . table ( $table ))
|| ! queries ( " INSERT INTO $name SELECT * FROM " . table ( $table ))
) {
return false ;
}
}
foreach ( $views as $table ) {
$name = ( $target == DB ? table ( " copy_ $table " ) : idf_escape ( $target ) . " . " . table ( $table ));
$view = view ( $table );
if ( ! queries ( " DROP VIEW IF EXISTS $name " )
|| ! queries ( " CREATE VIEW $name AS $view[select] " ) //! USE to avoid db.table
) {
return false ;
}
}
return true ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Get information about trigger
* @ param string trigger name
2014-03-15 17:58:24 +00:00
* @ return array array ( " Trigger " => , " Timing " => , " Event " => , " Of " => , " Type " => , " Statement " => )
2010-04-21 12:01:32 +00:00
*/
function trigger ( $name ) {
2011-08-08 16:18:16 +00:00
if ( $name == " " ) {
return array ();
}
2010-10-13 16:04:40 +00:00
$rows = get_rows ( " SHOW TRIGGERS WHERE `Trigger` = " . q ( $name ));
2010-10-13 15:53:59 +00:00
return reset ( $rows );
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Get defined triggers
* @ param string
* @ return array array ( $name => array ( $timing , $event ))
*/
function triggers ( $table ) {
$return = array ();
2013-04-27 02:24:07 +00:00
foreach ( get_rows ( " SHOW TRIGGERS LIKE " . q ( addcslashes ( $table , " %_ \\ " ))) as $row ) {
2010-04-21 12:01:32 +00:00
$return [ $row [ " Trigger " ]] = array ( $row [ " Timing " ], $row [ " Event " ]);
}
return $return ;
}
2013-07-24 23:26:41 +00:00
2010-04-22 23:02:28 +00:00
/** Get trigger options
2014-03-15 17:58:24 +00:00
* @ return array ( " Timing " => array (), " Event " => array (), " Type " => array ())
2010-04-22 23:02:28 +00:00
*/
2010-04-22 15:53:42 +00:00
function trigger_options () {
return array (
" Timing " => array ( " BEFORE " , " AFTER " ),
2014-03-15 17:58:24 +00:00
" Event " => array ( " INSERT " , " UPDATE " , " DELETE " ),
2010-04-22 15:53:42 +00:00
" Type " => array ( " FOR EACH ROW " ),
);
}
2013-07-24 23:26:41 +00:00
2010-04-28 00:11:39 +00:00
/** Get information about stored routine
* @ param string
2011-06-03 13:45:33 +00:00
* @ param string " FUNCTION " or " PROCEDURE "
* @ return array ( " fields " => array ( " field " => , " type " => , " length " => , " unsigned " => , " inout " => , " collation " => ), " returns " => , " definition " => , " language " => )
2010-04-28 00:11:39 +00:00
*/
function routine ( $name , $type ) {
global $connection , $enum_length , $inout , $types ;
2010-05-25 11:29:53 +00:00
$aliases = array ( " bool " , " boolean " , " integer " , " double precision " , " real " , " dec " , " numeric " , " fixed " , " national char " , " national varchar " );
2018-01-24 15:37:38 +00:00
$space = " (?: \\ s|/ \\ *[ \ s \ S]*? \\ */|(?:#|-- )[^ \n ]* \n ?|-- \r ? \n ) " ;
2014-06-15 16:33:28 +00:00
$type_pattern = " (( " . implode ( " | " , array_merge ( array_keys ( $types ), $aliases )) . " ) \\ b(?: \\ s* \\ (((?:[^' \" )]| $enum_length )++) \\ ))? \\ s*(zerofill \\ s*)?(unsigned(?: \\ s+zerofill)?)?)(?: \\ s*(?:CHARSET|CHARACTER \\ s+SET) \\ s*[' \" ]?([^' \" \\ s,]+)[' \" ]?)? " ;
2018-01-24 15:37:38 +00:00
$pattern = " $space *( " . ( $type == " FUNCTION " ? " " : $inout ) . " )? \\ s*(?:`((?:[^`]|``)*)` \\ s*| \\ b( \\ S+) \\ s+) $type_pattern " ;
2010-04-28 00:11:39 +00:00
$create = $connection -> result ( " SHOW CREATE $type " . idf_escape ( $name ), 2 );
2012-05-14 00:19:53 +00:00
preg_match ( " ~ \\ (((?: $pattern\\s *,?)*) \\ ) \\ s* " . ( $type == " FUNCTION " ? " RETURNS \\ s+ $type_pattern\\s + " : " " ) . " (.*)~is " , $create , $match );
2010-04-28 00:11:39 +00:00
$fields = array ();
preg_match_all ( " ~ $pattern\\s *,?~is " , $match [ 1 ], $matches , PREG_SET_ORDER );
foreach ( $matches as $param ) {
$name = str_replace ( " `` " , " ` " , $param [ 2 ]) . $param [ 3 ];
$fields [] = array (
" field " => $name ,
2010-05-25 11:29:53 +00:00
" type " => strtolower ( $param [ 5 ]),
2010-04-28 00:11:39 +00:00
" length " => preg_replace_callback ( " ~ $enum_length ~s " , 'normalize_enum' , $param [ 6 ]),
2018-02-20 15:27:40 +00:00
" unsigned " => strtolower ( preg_replace ( '~\s+~' , ' ' , trim ( " $param[8] $param[7] " ))),
2012-12-12 18:58:13 +00:00
" null " => 1 ,
2010-04-28 00:11:39 +00:00
" full_type " => $param [ 4 ],
" inout " => strtoupper ( $param [ 1 ]),
" collation " => strtolower ( $param [ 9 ]),
);
}
if ( $type != " FUNCTION " ) {
return array ( " fields " => $fields , " definition " => $match [ 11 ]);
}
return array (
" fields " => $fields ,
" returns " => array ( " type " => $match [ 12 ], " length " => $match [ 13 ], " unsigned " => $match [ 15 ], " collation " => $match [ 16 ]),
" definition " => $match [ 17 ],
2011-06-03 13:45:33 +00:00
" language " => " SQL " , // available in information_schema.ROUTINES.PARAMETER_STYLE
2010-04-28 00:11:39 +00:00
);
}
2013-07-24 23:26:41 +00:00
2011-05-31 05:43:08 +00:00
/** Get list of routines
2018-01-30 14:18:26 +00:00
* @ return array ( " SPECIFIC_NAME " => , " ROUTINE_NAME " => , " ROUTINE_TYPE " => , " DTD_IDENTIFIER " => )
2011-05-31 05:43:08 +00:00
*/
2010-04-28 00:11:39 +00:00
function routines () {
2018-01-30 14:18:26 +00:00
return get_rows ( " SELECT ROUTINE_NAME AS SPECIFIC_NAME, ROUTINE_NAME, ROUTINE_TYPE, DTD_IDENTIFIER FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q ( DB ));
2010-04-28 00:11:39 +00:00
}
2013-07-24 23:26:41 +00:00
2011-06-03 13:45:33 +00:00
/** Get list of available routine languages
* @ return array
*/
function routine_languages () {
2011-06-04 01:37:43 +00:00
return array (); // "SQL" not required
2011-06-03 13:45:33 +00:00
}
2013-07-24 23:26:41 +00:00
2018-01-30 14:18:26 +00:00
/** Get routine signature
* @ param string
* @ param array result of routine ()
* @ return string
*/
function routine_id ( $name , $row ) {
return idf_escape ( $name );
}
2010-05-12 16:07:46 +00:00
/** Get last auto increment ID
* @ return string
*/
function last_id () {
global $connection ;
return $connection -> result ( " SELECT LAST_INSERT_ID() " ); // mysql_insert_id() truncates bigint
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Explain select
* @ param Min_DB
* @ param string
* @ return Min_Result
*/
function explain ( $connection , $query ) {
2018-01-29 18:49:52 +00:00
return $connection -> query ( " EXPLAIN " . ( min_version ( 5.1 ) ? " PARTITIONS " : " " ) . $query );
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2011-07-29 15:08:06 +00:00
/** Get approximate number of rows
* @ param array
* @ param array
* @ return int or null if approximate number can ' t be retrieved
*/
function found_rows ( $table_status , $where ) {
return ( $where || $table_status [ " Engine " ] != " InnoDB " ? null : $table_status [ " Rows " ]);
}
2013-07-24 23:26:41 +00:00
2010-05-21 14:07:22 +00:00
/** Get user defined types
* @ return array
*/
function types () {
return array ();
}
2013-07-24 23:26:41 +00:00
2010-05-05 16:30:55 +00:00
/** Get existing schemas
* @ return array
*/
function schemas () {
return array ();
}
2013-07-24 23:26:41 +00:00
2010-05-05 16:30:55 +00:00
/** Get current schema
* @ return string
*/
function get_schema () {
return " " ;
}
2013-07-24 23:26:41 +00:00
2010-05-05 16:30:55 +00:00
/** Set current schema
* @ param string
* @ return bool
*/
function set_schema ( $schema ) {
return true ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Get SQL command to create table
* @ param string
2010-06-03 12:15:23 +00:00
* @ param bool
2018-01-22 13:33:21 +00:00
* @ param string
2010-04-21 12:01:32 +00:00
* @ return string
*/
2018-01-22 13:33:21 +00:00
function create_sql ( $table , $auto_increment , $style ) {
2010-04-21 12:01:32 +00:00
global $connection ;
2010-06-03 12:15:23 +00:00
$return = $connection -> result ( " SHOW CREATE TABLE " . table ( $table ), 1 );
if ( ! $auto_increment ) {
2018-02-20 15:27:40 +00:00
$return = preg_replace ( '~ AUTO_INCREMENT=\d+~' , '' , $return ); //! skip comments
2010-06-03 12:15:23 +00:00
}
return $return ;
2010-04-21 12:01:32 +00:00
}
2013-07-24 23:26:41 +00:00
2010-05-27 14:10:17 +00:00
/** Get SQL command to truncate table
* @ param string
* @ return string
*/
function truncate_sql ( $table ) {
return " TRUNCATE " . table ( $table );
}
2013-07-24 23:26:41 +00:00
2010-04-21 22:37:16 +00:00
/** Get SQL command to change database
* @ param string
* @ return string
*/
function use_sql ( $database ) {
return " USE " . idf_escape ( $database );
}
2013-07-24 23:26:41 +00:00
2010-05-05 16:28:37 +00:00
/** Get SQL commands to create triggers
* @ param string
* @ return string
*/
2018-01-22 13:14:42 +00:00
function trigger_sql ( $table ) {
2010-05-05 16:28:37 +00:00
$return = " " ;
2013-04-27 02:24:07 +00:00
foreach ( get_rows ( " SHOW TRIGGERS LIKE " . q ( addcslashes ( $table , " %_ \\ " )), null , " -- " ) as $row ) {
2018-01-22 13:14:42 +00:00
$return .= " \n CREATE TRIGGER " . idf_escape ( $row [ " Trigger " ]) . " $row[Timing] $row[Event] ON " . table ( $row [ " Table " ]) . " FOR EACH ROW \n $row[Statement] ;; \n " ;
2010-05-05 16:28:37 +00:00
}
return $return ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 22:37:16 +00:00
/** Get server variables
* @ return array ( $name => $value )
*/
2010-04-21 15:09:52 +00:00
function show_variables () {
return get_key_vals ( " SHOW VARIABLES " );
}
2013-07-24 23:26:41 +00:00
2011-05-11 09:48:51 +00:00
/** Get process list
* @ return array ( $row )
*/
2012-08-20 04:55:00 +00:00
function process_list () {
return get_rows ( " SHOW FULL PROCESSLIST " );
2011-05-11 09:48:51 +00:00
}
2013-07-24 23:26:41 +00:00
2010-04-21 22:37:16 +00:00
/** Get status variables
* @ return array ( $name => $value )
*/
2010-04-21 15:09:52 +00:00
function show_status () {
return get_key_vals ( " SHOW STATUS " );
2015-12-04 23:43:28 +00:00
}
2012-09-09 05:56:34 +00:00
/** Convert field in select and edit
* @ param array one element from fields ()
* @ return string
*/
function convert_field ( $field ) {
2013-07-24 23:26:41 +00:00
if ( preg_match ( " ~binary~ " , $field [ " type " ])) {
2012-09-09 05:56:34 +00:00
return " HEX( " . idf_escape ( $field [ " field " ]) . " ) " ;
}
2013-04-27 03:04:57 +00:00
if ( $field [ " type " ] == " bit " ) {
return " BIN( " . idf_escape ( $field [ " field " ]) . " + 0) " ; // + 0 is required outside MySQLnd
}
2013-07-24 23:26:41 +00:00
if ( preg_match ( " ~geometry|point|linestring|polygon~ " , $field [ " type " ])) {
2018-01-29 18:49:52 +00:00
return ( min_version ( 8 ) ? " ST_ " : " " ) . " AsWKT( " . idf_escape ( $field [ " field " ]) . " ) " ;
2012-09-09 05:56:34 +00:00
}
}
2013-07-24 23:26:41 +00:00
2012-09-09 05:56:34 +00:00
/** Convert value in edit after applying functions back
* @ param array one element from fields ()
* @ param string
* @ return string
*/
function unconvert_field ( $field , $return ) {
2013-07-24 23:26:41 +00:00
if ( preg_match ( " ~binary~ " , $field [ " type " ])) {
2012-12-12 05:25:56 +00:00
$return = " UNHEX( $return ) " ;
2012-09-09 05:56:34 +00:00
}
2013-04-27 03:04:57 +00:00
if ( $field [ " type " ] == " bit " ) {
2013-06-05 02:40:17 +00:00
$return = " CONV( $return , 2, 10) + 0 " ;
2013-04-27 03:04:57 +00:00
}
2013-07-24 23:26:41 +00:00
if ( preg_match ( " ~geometry|point|linestring|polygon~ " , $field [ " type " ])) {
2018-02-06 12:07:37 +00:00
$return = ( min_version ( 8 ) ? " ST_ " : " " ) . " GeomFromText( $return ) " ;
2012-09-09 05:56:34 +00:00
}
return $return ;
}
2013-07-24 23:26:41 +00:00
2010-04-21 12:01:32 +00:00
/** Check whether a feature is supported
2014-05-11 10:20:08 +00:00
* @ param string " comment " , " copy " , " database " , " drop_col " , " dump " , " event " , " kill " , " materializedview " , " partitioning " , " privileges " , " procedure " , " processlist " , " routine " , " scheme " , " sequence " , " status " , " table " , " trigger " , " type " , " variables " , " view " , " view_trigger "
2010-04-21 12:01:32 +00:00
* @ return bool
*/
function support ( $feature ) {
2018-01-29 18:49:52 +00:00
return ! preg_match ( " ~scheme|sequence|type|view_trigger|materializedview " . ( min_version ( 5.1 ) ? " " : " |event|partitioning " . ( min_version ( 5 ) ? " " : " |routine|trigger|view " )) . " ~ " , $feature );
2010-04-21 12:01:32 +00:00
}
2015-03-18 09:34:35 +00:00
function kill_process ( $val ) {
return queries ( " KILL " . number ( $val ));
}
2017-01-16 16:03:02 +00:00
function connection_id (){
return " SELECT CONNECTION_ID() " ;
}
2015-03-18 09:34:35 +00:00
function max_connections () {
global $connection ;
return $connection -> result ( " SELECT @@max_connections " );
}
2010-05-07 13:44:22 +00:00
$jush = " sql " ; ///< @var string JUSH identifier
2010-04-21 12:01:32 +00:00
$types = array (); ///< @var array ($type => $maximum_unsigned_length, ...)
$structured_types = array (); ///< @var array ($description => array($type, ...), ...)
foreach ( array (
lang ( 'Numbers' ) => array ( " tinyint " => 3 , " smallint " => 5 , " mediumint " => 8 , " int " => 10 , " bigint " => 20 , " decimal " => 66 , " float " => 12 , " double " => 21 ),
lang ( 'Date and time' ) => array ( " date " => 10 , " datetime " => 19 , " timestamp " => 19 , " time " => 10 , " year " => 4 ),
lang ( 'Strings' ) => array ( " char " => 255 , " varchar " => 65535 , " tinytext " => 255 , " text " => 65535 , " mediumtext " => 16777215 , " longtext " => 4294967295 ),
lang ( 'Lists' ) => array ( " enum " => 65535 , " set " => 64 ),
2012-09-09 05:56:34 +00:00
lang ( 'Binary' ) => array ( " bit " => 20 , " binary " => 255 , " varbinary " => 65535 , " tinyblob " => 255 , " blob " => 65535 , " mediumblob " => 16777215 , " longblob " => 4294967295 ),
lang ( 'Geometry' ) => array ( " geometry " => 0 , " point " => 0 , " linestring " => 0 , " polygon " => 0 , " multipoint " => 0 , " multilinestring " => 0 , " multipolygon " => 0 , " geometrycollection " => 0 ),
2010-04-21 12:01:32 +00:00
) as $key => $val ) {
$types += $val ;
$structured_types [ $key ] = array_keys ( $val );
}
$unsigned = array ( " unsigned " , " zerofill " , " unsigned zerofill " ); ///< @var array number variants
2018-02-01 14:25:38 +00:00
$operators = array ( " = " , " < " , " > " , " <= " , " >= " , " != " , " LIKE " , " LIKE %% " , " REGEXP " , " IN " , " FIND_IN_SET " , " IS NULL " , " NOT LIKE " , " NOT REGEXP " , " NOT IN " , " IS NOT NULL " , " SQL " ); ///< @var array operators used in select
2018-02-01 13:32:01 +00:00
$functions = array ( " char_length " , " date " , " from_unixtime " , " lower " , " round " , " floor " , " ceil " , " sec_to_time " , " time_to_sec " , " upper " ); ///< @var array functions used in select
2010-04-21 12:01:32 +00:00
$grouping = array ( " avg " , " count " , " count distinct " , " group_concat " , " max " , " min " , " sum " ); ///< @var array grouping functions used in select
$edit_functions = array ( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only
array (
2018-02-20 23:28:59 +00:00
" char " => " md5/sha1/password/encrypt/uuid " ,
2012-09-09 05:39:15 +00:00
" binary " => " md5/sha1 " ,
2010-04-21 12:01:32 +00:00
" date|time " => " now " ,
), array (
2018-02-06 11:17:01 +00:00
number_type () => " +/- " ,
2010-04-21 12:01:32 +00:00
" date " => " + interval/- interval " ,
" time " => " addtime/subtime " ,
" char|text " => " concat " ,
)
);
}