3081 lines
98 KiB
PHP
3081 lines
98 KiB
PHP
<?php
|
|
|
|
use PDO as PDO;
|
|
use PDOException as PDOException;
|
|
|
|
/**
|
|
* Enum with all available compression methods
|
|
*
|
|
*/
|
|
|
|
abstract class WPvividCompressMethod
|
|
{
|
|
public static $enums = array(
|
|
"None",
|
|
"Gzip",
|
|
"Bzip2"
|
|
);
|
|
|
|
/**
|
|
* @param string $c
|
|
* @return boolean
|
|
*/
|
|
public static function isValid($c)
|
|
{
|
|
return in_array($c, self::$enums);
|
|
}
|
|
}
|
|
|
|
abstract class WPvividCompressManagerFactory
|
|
{
|
|
/**
|
|
* @param string $c
|
|
* @return WPvividCompressBzip2|WPvividCompressGzip|WPvividCompressNone
|
|
*/
|
|
public static function create($c)
|
|
{
|
|
$c = ucfirst(strtolower($c));
|
|
if (! WPvividCompressMethod::isValid($c)) {
|
|
throw new Exception("Compression method (".esc_html($c).") is not defined yet");
|
|
}
|
|
|
|
$method = __NAMESPACE__ . "\\" . "WPvividCompress" . $c;
|
|
|
|
return new $method;
|
|
}
|
|
}
|
|
|
|
class WPvividCompressBzip2 extends WPvividCompressManagerFactory
|
|
{
|
|
private $fileHandler = null;
|
|
|
|
public function __construct()
|
|
{
|
|
if (! function_exists("bzopen")) {
|
|
throw new Exception("Compression is enabled, but bzip2 lib is not installed or configured properly");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $filename
|
|
*/
|
|
public function open($filename)
|
|
{
|
|
$this->fileHandler = bzopen($filename, "w");
|
|
if (false === $this->fileHandler) {
|
|
throw new Exception("Output file is not writable");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function write($str)
|
|
{
|
|
if (false === ($bytesWritten = bzwrite($this->fileHandler, $str))) {
|
|
throw new Exception("Writting to file failed! Probably, there is no more free space left?");
|
|
}
|
|
return $bytesWritten;
|
|
}
|
|
|
|
public function close()
|
|
{
|
|
return bzclose($this->fileHandler);
|
|
}
|
|
}
|
|
|
|
class WPvividCompressGzip extends WPvividCompressManagerFactory
|
|
{
|
|
private $fileHandler = null;
|
|
|
|
public function __construct()
|
|
{
|
|
if (! function_exists("gzopen")) {
|
|
throw new Exception("Compression is enabled, but gzip lib is not installed or configured properly");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $filename
|
|
*/
|
|
public function open($filename)
|
|
{
|
|
$this->fileHandler = gzopen($filename, "wb");
|
|
if (false === $this->fileHandler) {
|
|
throw new Exception("Output file is not writable");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function write($str)
|
|
{
|
|
if (false === ($bytesWritten = gzwrite($this->fileHandler, $str))) {
|
|
throw new Exception("Writting to file failed! Probably, there is no more free space left?");
|
|
}
|
|
return $bytesWritten;
|
|
}
|
|
|
|
public function close()
|
|
{
|
|
return gzclose($this->fileHandler);
|
|
}
|
|
}
|
|
|
|
class WPvividCompressNone extends WPvividCompressManagerFactory
|
|
{
|
|
private $fileHandler = null;
|
|
|
|
/**
|
|
* @param string $filename
|
|
*/
|
|
public function open($filename)
|
|
{
|
|
$this->fileHandler = fopen($filename, "wb");
|
|
if (false === $this->fileHandler) {
|
|
throw new Exception("Output file is not writable");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function write($str)
|
|
{
|
|
if (false === ($bytesWritten = fwrite($this->fileHandler, $str))) {
|
|
throw new Exception("Writting to file failed! Probably, there is no more free space left?");
|
|
}
|
|
return $bytesWritten;
|
|
}
|
|
|
|
public function close()
|
|
{
|
|
return fclose($this->fileHandler);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enum with all available TypeAdapter implementations
|
|
*
|
|
*/
|
|
abstract class WPvividTypeAdapter
|
|
{
|
|
public static $enums = array(
|
|
"Sqlite",
|
|
"Mysql",
|
|
"Wpdb"
|
|
);
|
|
|
|
/**
|
|
* @param string $c
|
|
* @return boolean
|
|
*/
|
|
public static function isValid($c)
|
|
{
|
|
return in_array($c, self::$enums);
|
|
}
|
|
}
|
|
|
|
|
|
if(!class_exists('TypeAdapterFactory'))
|
|
{
|
|
abstract class TypeAdapterFactory
|
|
{
|
|
/**
|
|
* @param string $c Type of database factory to create (Mysql, Sqlite,...)
|
|
* @param PDO $dbHandler
|
|
*/
|
|
public static function create($c, $dbHandler = null)
|
|
{
|
|
$c = ucfirst(strtolower($c));
|
|
if (! WPvividTypeAdapter::isValid($c)) {
|
|
if($c === 'Mysql'){
|
|
$c = 'PDO_MySQL';
|
|
}
|
|
throw new Exception("Database type support for (".esc_html($c).") not yet available");
|
|
}
|
|
$method = __NAMESPACE__ . "\\" . "WPvividTypeAdapter" . $c;
|
|
return new $method($dbHandler);
|
|
}
|
|
|
|
/**
|
|
* function databases Add sql to create and use database
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function databases()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function show_create_table($tableName)
|
|
{
|
|
return "SELECT tbl_name as 'Table', sql as 'Create Table' " .
|
|
"FROM sqlite_master " .
|
|
"WHERE type='table' AND tbl_name='$tableName'";
|
|
}
|
|
|
|
/**
|
|
* function create_table Get table creation code from database
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function create_table($row, $dumpSettings)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function show_create_view($viewName)
|
|
{
|
|
return "SELECT tbl_name as 'View', sql as 'Create View' " .
|
|
"FROM sqlite_master " .
|
|
"WHERE type='view' AND tbl_name='$viewName'";
|
|
}
|
|
|
|
/**
|
|
* function create_view Get view creation code from database
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function create_view($row)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* function show_create_trigger Get trigger creation code from database
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function show_create_trigger($triggerName)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* function create_trigger Modify trigger code, add delimiters, etc
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function create_trigger($triggerName)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* function create_procedure Modify procedure code, add delimiters, etc
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function create_procedure($procedureName, $dumpSettings)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function show_tables()
|
|
{
|
|
return "SELECT tbl_name FROM sqlite_master WHERE type='table'";
|
|
}
|
|
|
|
public function show_views()
|
|
{
|
|
return "SELECT tbl_name FROM sqlite_master WHERE type='view'";
|
|
}
|
|
|
|
public function show_triggers()
|
|
{
|
|
return "SELECT name FROM sqlite_master WHERE type='trigger'";
|
|
}
|
|
|
|
public function show_columns()
|
|
{
|
|
if (func_num_args() != 1) {
|
|
return "";
|
|
}
|
|
|
|
$args = func_get_args();
|
|
|
|
return "pragma table_info({$args[0]})";
|
|
}
|
|
|
|
public function show_procedures()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function show_events()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function setup_transaction()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function start_transaction()
|
|
{
|
|
return "BEGIN EXCLUSIVE";
|
|
}
|
|
|
|
public function commit_transaction()
|
|
{
|
|
return "COMMIT";
|
|
}
|
|
|
|
public function lock_table()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function unlock_table()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function start_add_lock_table()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function end_add_lock_table()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function start_add_disable_keys()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function end_add_disable_keys()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function start_disable_foreign_keys_check()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function end_disable_foreign_keys_check()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_database()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_trigger()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function drop_table()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function drop_view()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
/**
|
|
* Decode column metadata and fill info structure.
|
|
* type, is_numeric and is_blob will always be available.
|
|
*
|
|
* @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
|
|
* @return array
|
|
*/
|
|
public function parseColumnType($colType)
|
|
{
|
|
return array();
|
|
}
|
|
|
|
public function backup_parameters()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function restore_parameters()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
}
|
|
|
|
class TypeAdapterPgsql extends TypeAdapterFactory
|
|
{
|
|
}
|
|
|
|
class TypeAdapterDblib extends TypeAdapterFactory
|
|
{
|
|
}
|
|
|
|
class TypeAdapterSqlite extends TypeAdapterFactory
|
|
{
|
|
}
|
|
|
|
|
|
|
|
class TypeAdapterMysql extends TypeAdapterFactory
|
|
{
|
|
|
|
private $dbHandler = null;
|
|
|
|
private $dsn;
|
|
private $user;
|
|
private $pass;
|
|
private $pdoSettings;
|
|
private $reconnect_count;
|
|
|
|
// Numerical Mysql types
|
|
public $mysqlTypes = array(
|
|
'numerical' => array(
|
|
'bit',
|
|
'tinyint',
|
|
'smallint',
|
|
'mediumint',
|
|
'int',
|
|
'integer',
|
|
'bigint',
|
|
'real',
|
|
'double',
|
|
'float',
|
|
'decimal',
|
|
'numeric'
|
|
),
|
|
'blob' => array(
|
|
'tinyblob',
|
|
'blob',
|
|
'mediumblob',
|
|
'longblob',
|
|
'binary',
|
|
'varbinary',
|
|
'bit',
|
|
'geometry', /* http://bugs.mysql.com/bug.php?id=43544 */
|
|
'point',
|
|
'linestring',
|
|
'polygon',
|
|
'multipoint',
|
|
'multilinestring',
|
|
'multipolygon',
|
|
'geometrycollection',
|
|
)
|
|
);
|
|
|
|
public function __construct ($dbHandler)
|
|
{
|
|
$pdoSettingsDefault = array(
|
|
PDO::ATTR_PERSISTENT => true,
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
|
|
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false
|
|
);
|
|
|
|
$this->dbHandler = $dbHandler;
|
|
$this->dsn='';
|
|
$this->user='';
|
|
$this->pass='';
|
|
$this->pdoSettings=$pdoSettingsDefault;
|
|
$this->reconnect_count=0;
|
|
}
|
|
|
|
public function set_connect_info($dsn,$user,$pass,$pdoSetting)
|
|
{
|
|
$this->dsn=$dsn;
|
|
$this->user=$user;
|
|
$this->pass=$pass;
|
|
$this->pdoSettings=$pdoSetting;
|
|
}
|
|
|
|
public function connect($host,$dbname,$user,$pass,$init_commands=array())
|
|
{
|
|
if(empty($host))
|
|
{
|
|
$host=DB_HOST;
|
|
}
|
|
$res = explode(':',$host);
|
|
$db_host = $res[0];
|
|
$db_port = empty($res[1])?'':$res[1];
|
|
if(!empty($db_port)) {
|
|
$this->dsn='mysql:host=' . $db_host . ';port=' . $db_port . ';dbname=' . $dbname;
|
|
}
|
|
else{
|
|
$this->dsn='mysql:host=' . $db_host . ';dbname=' . $dbname;
|
|
}
|
|
$this->user=$user;
|
|
$this->pass=$pass;
|
|
$this->dbHandler = @new PDO(
|
|
$this->dsn,
|
|
$this->user,
|
|
$this->pass,
|
|
$this->pdoSettings
|
|
);
|
|
// Execute init commands once connected
|
|
foreach($init_commands as $stmt)
|
|
{
|
|
$this->dbHandler->exec($stmt);
|
|
}
|
|
$this->dbHandler->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);
|
|
}
|
|
|
|
public function errorInfo()
|
|
{
|
|
$error=$this->dbHandler->errorInfo();
|
|
return $error;
|
|
}
|
|
|
|
public function quote($colValue)
|
|
{
|
|
return $this->dbHandler->quote($colValue);
|
|
}
|
|
|
|
|
|
public function databases()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$databaseName = $args[0];
|
|
|
|
$resultSet = $this->query("SHOW VARIABLES LIKE 'character_set_database';");
|
|
$characterSet = $resultSet->fetchColumn(1);
|
|
$resultSet->closeCursor();
|
|
|
|
$resultSet = $this->query("SHOW VARIABLES LIKE 'collation_database';");
|
|
$collationDb = $resultSet->fetchColumn(1);
|
|
$resultSet->closeCursor();
|
|
$ret = "";
|
|
|
|
$ret .= "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$databaseName}`".
|
|
" /*!40100 DEFAULT CHARACTER SET {$characterSet} " .
|
|
" COLLATE {$collationDb} */;" . PHP_EOL . PHP_EOL .
|
|
"USE `{$databaseName}`;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function show_create_table($tableName)
|
|
{
|
|
return "SHOW CREATE TABLE `$tableName`";
|
|
}
|
|
|
|
public function show_create_view($viewName)
|
|
{
|
|
return "SHOW CREATE VIEW `$viewName`";
|
|
}
|
|
|
|
public function show_create_trigger($triggerName)
|
|
{
|
|
return "SHOW CREATE TRIGGER `$triggerName`";
|
|
}
|
|
|
|
public function show_create_procedure($procedureName)
|
|
{
|
|
return "SHOW CREATE PROCEDURE `$procedureName`";
|
|
}
|
|
|
|
public function show_create_event($eventName)
|
|
{
|
|
return "SHOW CREATE EVENT `$eventName`";
|
|
}
|
|
|
|
public function create_table( $row, $dumpSettings )
|
|
{
|
|
|
|
if ( !isset($row['Create Table']) ) {
|
|
throw new Exception("Error getting table code, unknown output");
|
|
}
|
|
|
|
//$createTable = str_replace('\'0000-00-00 00:00:00\'','\'1999-01-01 00:00:00\'',$row['Create Table']);
|
|
$createTable = $row['Create Table'];
|
|
|
|
if ( $dumpSettings['reset-auto-increment'] ) {
|
|
$match = "/AUTO_INCREMENT=[0-9]+/s";
|
|
$replace = "";
|
|
$createTable = preg_replace($match, $replace, $createTable);
|
|
}
|
|
|
|
$ret = "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
|
|
$createTable . ";" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL .
|
|
PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_view($row)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['Create View'])) {
|
|
throw new Exception("Error getting view structure, unknown output");
|
|
}
|
|
|
|
$triggerStmt = $row['Create View'];
|
|
|
|
$triggerStmtReplaced1 = str_replace(
|
|
"CREATE ALGORITHM",
|
|
"/*!50001 CREATE ALGORITHM",
|
|
$triggerStmt
|
|
);
|
|
$triggerStmtReplaced2 = str_replace(
|
|
" DEFINER=",
|
|
" */" . PHP_EOL . "/*!50013 DEFINER=",
|
|
$triggerStmtReplaced1
|
|
);
|
|
$triggerStmtReplaced3 = str_replace(
|
|
" VIEW ",
|
|
" */" . PHP_EOL . "/*!50001 VIEW ",
|
|
$triggerStmtReplaced2
|
|
);
|
|
if (false === $triggerStmtReplaced1 ||
|
|
false === $triggerStmtReplaced2 ||
|
|
false === $triggerStmtReplaced3) {
|
|
$triggerStmtReplaced = $triggerStmt;
|
|
} else {
|
|
$triggerStmtReplaced = $triggerStmtReplaced3 . " */;";
|
|
}
|
|
|
|
$ret .= $triggerStmtReplaced . PHP_EOL . PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_trigger($row)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['SQL Original Statement'])) {
|
|
throw new Exception("Error getting trigger code, unknown output");
|
|
}
|
|
|
|
$triggerStmt = $row['SQL Original Statement'];
|
|
$triggerStmtReplaced = str_replace(
|
|
"CREATE DEFINER",
|
|
"/*!50003 CREATE*/ /*!50017 DEFINER",
|
|
$triggerStmt
|
|
);
|
|
$triggerStmtReplaced = str_replace(
|
|
" TRIGGER",
|
|
"*/ /*!50003 TRIGGER",
|
|
$triggerStmtReplaced
|
|
);
|
|
if ( false === $triggerStmtReplaced ) {
|
|
$triggerStmtReplaced = $triggerStmt . " /* ";
|
|
}
|
|
|
|
$ret .= "DELIMITER ;;" . PHP_EOL .
|
|
$triggerStmtReplaced . " */ ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL . PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_procedure($row, $dumpSettings)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['Create Procedure'])) {
|
|
throw new Exception("Error getting procedure code, unknown output. " .
|
|
"Please check 'https://bugs.mysql.com/bug.php?id=14564'");
|
|
}
|
|
$procedureStmt = $row['Create Procedure'];
|
|
|
|
$ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
|
|
$row['Procedure'] . "` */;" . PHP_EOL .
|
|
"/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
|
|
"DELIMITER ;;" . PHP_EOL .
|
|
$procedureStmt . " ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function create_event($row)
|
|
{
|
|
$ret = "";
|
|
if ( !isset($row['Create Event']) ) {
|
|
throw new Exception("Error getting event code, unknown output. " .
|
|
"Please check 'http://stackoverflow.com/questions/10853826/mysql-5-5-create-event-gives-syntax-error'");
|
|
}
|
|
$eventName = $row['Event'];
|
|
$eventStmt = $row['Create Event'];
|
|
$sqlMode = $row['sql_mode'];
|
|
|
|
$eventStmtReplaced = str_replace(
|
|
"CREATE DEFINER",
|
|
"/*!50106 CREATE*/ /*!50117 DEFINER",
|
|
$eventStmt
|
|
);
|
|
$eventStmtReplaced = str_replace(
|
|
" EVENT ",
|
|
"*/ /*!50106 EVENT ",
|
|
$eventStmtReplaced
|
|
);
|
|
|
|
if ( false === $eventStmtReplaced ) {
|
|
$eventStmtReplaced = $eventStmt . " /* ";
|
|
}
|
|
|
|
$ret .= "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;" . PHP_EOL .
|
|
"/*!50106 DROP EVENT IF EXISTS `" . $eventName . "` */;" . PHP_EOL .
|
|
"DELIMITER ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_cs_client = @@character_set_client */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_cs_results = @@character_set_results */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_col_connection = @@collation_connection */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_client = utf8 */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_results = utf8 */ ;;" . PHP_EOL .
|
|
"/*!50003 SET collation_connection = utf8_general_ci */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;" . PHP_EOL .
|
|
"/*!50003 SET sql_mode = '" . $sqlMode . "' */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_time_zone = @@time_zone */ ;;" . PHP_EOL .
|
|
"/*!50003 SET time_zone = 'SYSTEM' */ ;;" . PHP_EOL .
|
|
$eventStmtReplaced . " */ ;;" . PHP_EOL .
|
|
"/*!50003 SET time_zone = @saved_time_zone */ ;;" . PHP_EOL .
|
|
"/*!50003 SET sql_mode = @saved_sql_mode */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_client = @saved_cs_client */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_results = @saved_cs_results */ ;;" . PHP_EOL .
|
|
"/*!50003 SET collation_connection = @saved_col_connection */ ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL .
|
|
"/*!50106 SET TIME_ZONE= @save_time_zone */ ;" . PHP_EOL . PHP_EOL;
|
|
// Commented because we are doing this in restore_parameters()
|
|
// "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function show_tables()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT TABLE_NAME AS tbl_name " .
|
|
"FROM INFORMATION_SCHEMA.TABLES " .
|
|
"WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function show_views()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT TABLE_NAME AS tbl_name " .
|
|
"FROM INFORMATION_SCHEMA.TABLES " .
|
|
"WHERE TABLE_TYPE='VIEW' AND TABLE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function show_triggers()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SHOW TRIGGERS FROM `{$args[0]}`;";
|
|
}
|
|
|
|
public function show_columns()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SHOW COLUMNS FROM `{$args[0]}`;";
|
|
}
|
|
|
|
public function show_procedures()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT SPECIFIC_NAME AS procedure_name " .
|
|
"FROM INFORMATION_SCHEMA.ROUTINES " .
|
|
"WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
/**
|
|
* Get query string to ask for names of events from current database.
|
|
*
|
|
* @param string Name of database
|
|
* @return string
|
|
*/
|
|
public function show_events()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT EVENT_NAME AS event_name " .
|
|
"FROM INFORMATION_SCHEMA.EVENTS " .
|
|
"WHERE EVENT_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function setup_transaction()
|
|
{
|
|
return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
|
|
}
|
|
|
|
public function start_transaction()
|
|
{
|
|
return "START TRANSACTION";
|
|
}
|
|
|
|
public function commit_transaction()
|
|
{
|
|
return "COMMIT";
|
|
}
|
|
|
|
public function lock_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return $this->dbHandler->exec("LOCK TABLES `{$args[0]}` READ LOCAL");
|
|
|
|
}
|
|
|
|
public function unlock_table()
|
|
{
|
|
return $this->dbHandler->exec("UNLOCK TABLES");
|
|
}
|
|
|
|
public function start_add_lock_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "LOCK TABLES `{$args[0]}` WRITE;" . PHP_EOL;
|
|
}
|
|
|
|
public function end_add_lock_table()
|
|
{
|
|
return "UNLOCK TABLES;" . PHP_EOL;
|
|
}
|
|
|
|
public function start_add_disable_keys()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 ALTER TABLE `{$args[0]}` DISABLE KEYS */;" .
|
|
PHP_EOL;
|
|
}
|
|
|
|
public function end_add_disable_keys()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 ALTER TABLE `{$args[0]}` ENABLE KEYS */;" .
|
|
PHP_EOL;
|
|
}
|
|
|
|
public function start_disable_autocommit()
|
|
{
|
|
return "SET autocommit=0;" . PHP_EOL;
|
|
}
|
|
|
|
public function end_disable_autocommit()
|
|
{
|
|
return "COMMIT;" . PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_database()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 DROP DATABASE IF EXISTS `{$args[0]}`*/;" .
|
|
PHP_EOL . PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_trigger()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TRIGGER IF EXISTS `{$args[0]}`;" . PHP_EOL;
|
|
}
|
|
|
|
public function drop_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TABLE IF EXISTS `{$args[0]}`;" . PHP_EOL;
|
|
}
|
|
|
|
public function drop_view()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TABLE IF EXISTS `{$args[0]}`;" . PHP_EOL .
|
|
"/*!50001 DROP VIEW IF EXISTS `{$args[0]}`*/;" . PHP_EOL;
|
|
}
|
|
|
|
public function getDatabaseHeader()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "--" . PHP_EOL .
|
|
"-- Current Database: `{$args[0]}`" . PHP_EOL .
|
|
"--" . PHP_EOL . PHP_EOL;
|
|
}
|
|
|
|
/**
|
|
* Decode column metadata and fill info structure.
|
|
* type, is_numeric and is_blob will always be available.
|
|
*
|
|
* @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
|
|
* @return array
|
|
*/
|
|
public function parseColumnType($colType)
|
|
{
|
|
$colInfo = array();
|
|
$colParts = explode(" ", $colType['Type']);
|
|
|
|
if($fparen = strpos($colParts[0], "("))
|
|
{
|
|
$colInfo['type'] = substr($colParts[0], 0, $fparen);
|
|
$colInfo['length'] = str_replace(")", "", substr($colParts[0], $fparen+1));
|
|
$colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
|
|
}
|
|
else
|
|
{
|
|
$colInfo['type'] = $colParts[0];
|
|
}
|
|
$colInfo['is_numeric'] = in_array($colInfo['type'], $this->mysqlTypes['numerical']);
|
|
$colInfo['is_blob'] = in_array($colInfo['type'], $this->mysqlTypes['blob']);
|
|
// for virtual 'Extra' -> "STORED GENERATED"
|
|
$colInfo['is_virtual'] = strpos($colType['Extra'], "STORED GENERATED") === false ? false : true;
|
|
|
|
return $colInfo;
|
|
}
|
|
|
|
public function get_connection_charset($wpdb = null) {
|
|
if (null === $wpdb) {
|
|
global $wpdb;
|
|
}
|
|
|
|
$charset = (defined('DB_CHARSET') && DB_CHARSET) ? DB_CHARSET : 'utf8mb4';
|
|
|
|
if (method_exists($wpdb, 'determine_charset')) {
|
|
$charset_collate = $wpdb->determine_charset($charset, '');
|
|
if (!empty($charset_collate['charset'])) $charset = $charset_collate['charset'];
|
|
}
|
|
|
|
return $charset;
|
|
}
|
|
|
|
public function backup_parameters()
|
|
{
|
|
global $wpdb;
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$dumpSettings = $args[0];
|
|
$ret = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" . PHP_EOL .
|
|
"/*!40101 SET NAMES " . $this->get_connection_charset($wpdb) . " */;" . PHP_EOL;
|
|
|
|
if (false === $dumpSettings['skip-tz-utc']) {
|
|
$ret .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" . PHP_EOL .
|
|
"/*!40103 SET TIME_ZONE='+00:00' */;" . PHP_EOL;
|
|
}
|
|
|
|
$ret .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;" . PHP_EOL .
|
|
"/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;" . PHP_EOL .
|
|
"/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;" . PHP_EOL .PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function restore_parameters()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$dumpSettings = $args[0];
|
|
$ret = "";
|
|
|
|
if (false === $dumpSettings['skip-tz-utc']) {
|
|
$ret .= "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL;
|
|
}
|
|
|
|
$ret .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;" . PHP_EOL .
|
|
"/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;" . PHP_EOL .
|
|
"/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;" . PHP_EOL .
|
|
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;" . PHP_EOL .
|
|
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;" . PHP_EOL .
|
|
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;" . PHP_EOL .
|
|
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* Check number of parameters passed to function, useful when inheriting.
|
|
* Raise exception if unexpected.
|
|
*
|
|
* @param integer $num_args
|
|
* @param integer $expected_num_args
|
|
* @param string $method_name
|
|
*/
|
|
private function check_parameters($num_args, $expected_num_args, $method_name)
|
|
{
|
|
if ( $num_args != $expected_num_args ) {
|
|
throw new Exception("Unexpected parameter passed to ".esc_html($method_name));
|
|
}
|
|
return;
|
|
}
|
|
|
|
public function query($string)
|
|
{
|
|
$ret= $this->dbHandler->query($string);
|
|
|
|
if($ret===false)
|
|
{
|
|
$info=$this->dbHandler->errorInfo();
|
|
if($info[1] == 2006)
|
|
{
|
|
if($this->reconnect_count>3)
|
|
{
|
|
throw new Exception("MySQL server has gone away. Too many reconnect.");
|
|
}
|
|
$this->reconnect();
|
|
$this->reconnect_count++;
|
|
$ret= $this->dbHandler->query($string);
|
|
if($ret!==false)
|
|
{
|
|
$ret->setFetchMode(PDO::FETCH_ASSOC);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$ret->setFetchMode(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function exec($string)
|
|
{
|
|
$ret=$this->dbHandler->exec($string);
|
|
|
|
if($ret===false)
|
|
{
|
|
$info=$this->dbHandler->errorInfo();
|
|
if($info[1] == 2006)
|
|
{
|
|
if($this->reconnect_count>3)
|
|
{
|
|
throw new Exception("MySQL server has gone away. Too many reconnect.");
|
|
}
|
|
$this->reconnect();
|
|
$this->reconnect_count++;
|
|
$ret= $this->dbHandler->exec($string);
|
|
}
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
public function reconnect()
|
|
{
|
|
$this->dbHandler = @new PDO(
|
|
$this->dsn,
|
|
$this->user,
|
|
$this->pass,
|
|
$this->pdoSettings
|
|
);
|
|
}
|
|
|
|
public function closeCursor($resultSet)
|
|
{
|
|
$resultSet->closeCursor();
|
|
}
|
|
}
|
|
|
|
class TypeAdapterWpdb extends TypeAdapterFactory
|
|
{
|
|
|
|
private $dbHandler = null;
|
|
|
|
// Numerical Mysql types
|
|
public $mysqlTypes = array(
|
|
'numerical' => array(
|
|
'bit',
|
|
'tinyint',
|
|
'smallint',
|
|
'mediumint',
|
|
'int',
|
|
'integer',
|
|
'bigint',
|
|
'real',
|
|
'double',
|
|
'float',
|
|
'decimal',
|
|
'numeric'
|
|
),
|
|
'blob' => array(
|
|
'tinyblob',
|
|
'blob',
|
|
'mediumblob',
|
|
'longblob',
|
|
'binary',
|
|
'varbinary',
|
|
'bit',
|
|
'geometry', /* http://bugs.mysql.com/bug.php?id=43544 */
|
|
'point',
|
|
'linestring',
|
|
'polygon',
|
|
'multipoint',
|
|
'multilinestring',
|
|
'multipolygon',
|
|
'geometrycollection',
|
|
)
|
|
);
|
|
|
|
public function __construct ($dbHandler)
|
|
{
|
|
$this->dbHandler = $dbHandler;
|
|
}
|
|
|
|
public function connect($host,$dbname,$user,$pass,$init_commands=array())
|
|
{
|
|
global $wpdb;
|
|
|
|
$this->dbHandler=$wpdb;
|
|
}
|
|
|
|
public function databases()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$databaseName = $args[0];
|
|
|
|
$resultSet = $this->query("SHOW VARIABLES LIKE 'character_set_database';");
|
|
$characterSet = $resultSet->fetchColumn(1);
|
|
$resultSet->closeCursor();
|
|
|
|
$resultSet = $this->query("SHOW VARIABLES LIKE 'collation_database';");
|
|
$collationDb = $resultSet->fetchColumn(1);
|
|
$resultSet->closeCursor();
|
|
$ret = "";
|
|
|
|
$ret .= "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$databaseName}`".
|
|
" /*!40100 DEFAULT CHARACTER SET {$characterSet} " .
|
|
" COLLATE {$collationDb} */;" . PHP_EOL . PHP_EOL .
|
|
"USE `{$databaseName}`;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function show_create_table($tableName)
|
|
{
|
|
return "SHOW CREATE TABLE `$tableName`";
|
|
}
|
|
|
|
public function show_create_view($viewName)
|
|
{
|
|
return "SHOW CREATE VIEW `$viewName`";
|
|
}
|
|
|
|
public function show_create_trigger($triggerName)
|
|
{
|
|
return "SHOW CREATE TRIGGER `$triggerName`";
|
|
}
|
|
|
|
public function show_create_procedure($procedureName)
|
|
{
|
|
return "SHOW CREATE PROCEDURE `$procedureName`";
|
|
}
|
|
|
|
public function show_create_event($eventName)
|
|
{
|
|
return "SHOW CREATE EVENT `$eventName`";
|
|
}
|
|
|
|
public function create_table( $row, $dumpSettings )
|
|
{
|
|
|
|
if ( !isset($row['Create Table']) ) {
|
|
throw new Exception("Error getting table code, unknown output");
|
|
}
|
|
|
|
//$createTable = str_replace('\'0000-00-00 00:00:00\'','\'1999-01-01 00:00:00\'',$row['Create Table']);
|
|
$createTable = $row['Create Table'];
|
|
|
|
if ( $dumpSettings['reset-auto-increment'] ) {
|
|
$match = "/AUTO_INCREMENT=[0-9]+/s";
|
|
$replace = "";
|
|
$createTable = preg_replace($match, $replace, $createTable);
|
|
}
|
|
|
|
$ret = "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
|
|
$createTable . ";" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL .
|
|
PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_view($row)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['Create View'])) {
|
|
throw new Exception("Error getting view structure, unknown output");
|
|
}
|
|
|
|
$triggerStmt = $row['Create View'];
|
|
|
|
$triggerStmtReplaced1 = str_replace(
|
|
"CREATE ALGORITHM",
|
|
"/*!50001 CREATE ALGORITHM",
|
|
$triggerStmt
|
|
);
|
|
$triggerStmtReplaced2 = str_replace(
|
|
" DEFINER=",
|
|
" */" . PHP_EOL . "/*!50013 DEFINER=",
|
|
$triggerStmtReplaced1
|
|
);
|
|
$triggerStmtReplaced3 = str_replace(
|
|
" VIEW ",
|
|
" */" . PHP_EOL . "/*!50001 VIEW ",
|
|
$triggerStmtReplaced2
|
|
);
|
|
if (false === $triggerStmtReplaced1 ||
|
|
false === $triggerStmtReplaced2 ||
|
|
false === $triggerStmtReplaced3) {
|
|
$triggerStmtReplaced = $triggerStmt;
|
|
} else {
|
|
$triggerStmtReplaced = $triggerStmtReplaced3 . " */;";
|
|
}
|
|
|
|
$ret .= $triggerStmtReplaced . PHP_EOL . PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_trigger($row)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['SQL Original Statement'])) {
|
|
throw new Exception("Error getting trigger code, unknown output");
|
|
}
|
|
|
|
$triggerStmt = $row['SQL Original Statement'];
|
|
$triggerStmtReplaced = str_replace(
|
|
"CREATE DEFINER",
|
|
"/*!50003 CREATE*/ /*!50017 DEFINER",
|
|
$triggerStmt
|
|
);
|
|
$triggerStmtReplaced = str_replace(
|
|
" TRIGGER",
|
|
"*/ /*!50003 TRIGGER",
|
|
$triggerStmtReplaced
|
|
);
|
|
if ( false === $triggerStmtReplaced ) {
|
|
$triggerStmtReplaced = $triggerStmt . " /* ";
|
|
}
|
|
|
|
$ret .= "DELIMITER ;;" . PHP_EOL .
|
|
$triggerStmtReplaced . " */ ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL . PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_procedure($row, $dumpSettings)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['Create Procedure'])) {
|
|
throw new Exception("Error getting procedure code, unknown output. " .
|
|
"Please check 'https://bugs.mysql.com/bug.php?id=14564'");
|
|
}
|
|
$procedureStmt = $row['Create Procedure'];
|
|
|
|
$ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
|
|
$row['Procedure'] . "` */;" . PHP_EOL .
|
|
"/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
|
|
"DELIMITER ;;" . PHP_EOL .
|
|
$procedureStmt . " ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function create_event($row)
|
|
{
|
|
$ret = "";
|
|
if ( !isset($row['Create Event']) ) {
|
|
throw new Exception("Error getting event code, unknown output. " .
|
|
"Please check 'http://stackoverflow.com/questions/10853826/mysql-5-5-create-event-gives-syntax-error'");
|
|
}
|
|
$eventName = $row['Event'];
|
|
$eventStmt = $row['Create Event'];
|
|
$sqlMode = $row['sql_mode'];
|
|
|
|
$eventStmtReplaced = str_replace(
|
|
"CREATE DEFINER",
|
|
"/*!50106 CREATE*/ /*!50117 DEFINER",
|
|
$eventStmt
|
|
);
|
|
$eventStmtReplaced = str_replace(
|
|
" EVENT ",
|
|
"*/ /*!50106 EVENT ",
|
|
$eventStmtReplaced
|
|
);
|
|
|
|
if ( false === $eventStmtReplaced ) {
|
|
$eventStmtReplaced = $eventStmt . " /* ";
|
|
}
|
|
|
|
$ret .= "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;" . PHP_EOL .
|
|
"/*!50106 DROP EVENT IF EXISTS `" . $eventName . "` */;" . PHP_EOL .
|
|
"DELIMITER ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_cs_client = @@character_set_client */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_cs_results = @@character_set_results */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_col_connection = @@collation_connection */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_client = utf8 */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_results = utf8 */ ;;" . PHP_EOL .
|
|
"/*!50003 SET collation_connection = utf8_general_ci */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;" . PHP_EOL .
|
|
"/*!50003 SET sql_mode = '" . $sqlMode . "' */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_time_zone = @@time_zone */ ;;" . PHP_EOL .
|
|
"/*!50003 SET time_zone = 'SYSTEM' */ ;;" . PHP_EOL .
|
|
$eventStmtReplaced . " */ ;;" . PHP_EOL .
|
|
"/*!50003 SET time_zone = @saved_time_zone */ ;;" . PHP_EOL .
|
|
"/*!50003 SET sql_mode = @saved_sql_mode */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_client = @saved_cs_client */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_results = @saved_cs_results */ ;;" . PHP_EOL .
|
|
"/*!50003 SET collation_connection = @saved_col_connection */ ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL .
|
|
"/*!50106 SET TIME_ZONE= @save_time_zone */ ;" . PHP_EOL . PHP_EOL;
|
|
// Commented because we are doing this in restore_parameters()
|
|
// "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function show_tables()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT TABLE_NAME AS tbl_name " .
|
|
"FROM INFORMATION_SCHEMA.TABLES " .
|
|
"WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function show_views()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT TABLE_NAME AS tbl_name " .
|
|
"FROM INFORMATION_SCHEMA.TABLES " .
|
|
"WHERE TABLE_TYPE='VIEW' AND TABLE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function show_triggers()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SHOW TRIGGERS FROM `{$args[0]}`;";
|
|
}
|
|
|
|
public function show_columns()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SHOW COLUMNS FROM `{$args[0]}`;";
|
|
}
|
|
|
|
public function show_procedures()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT SPECIFIC_NAME AS procedure_name " .
|
|
"FROM INFORMATION_SCHEMA.ROUTINES " .
|
|
"WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
/**
|
|
* Get query string to ask for names of events from current database.
|
|
*
|
|
* @param string Name of database
|
|
* @return string
|
|
*/
|
|
public function show_events()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT EVENT_NAME AS event_name " .
|
|
"FROM INFORMATION_SCHEMA.EVENTS " .
|
|
"WHERE EVENT_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function setup_transaction()
|
|
{
|
|
return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
|
|
}
|
|
|
|
public function start_transaction()
|
|
{
|
|
return "START TRANSACTION";
|
|
}
|
|
|
|
public function commit_transaction()
|
|
{
|
|
return "COMMIT";
|
|
}
|
|
|
|
public function lock_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return $this->dbHandler->get_results("LOCK TABLES `{$args[0]}` READ LOCAL",ARRAY_A);
|
|
|
|
}
|
|
|
|
public function unlock_table()
|
|
{
|
|
return $this->dbHandler->get_results("UNLOCK TABLES",ARRAY_A);
|
|
}
|
|
|
|
public function start_add_lock_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "LOCK TABLES `{$args[0]}` WRITE;" . PHP_EOL;
|
|
}
|
|
|
|
public function end_add_lock_table()
|
|
{
|
|
return "UNLOCK TABLES;" . PHP_EOL;
|
|
}
|
|
|
|
public function start_add_disable_keys()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 ALTER TABLE `{$args[0]}` DISABLE KEYS */;" .
|
|
PHP_EOL;
|
|
}
|
|
|
|
public function end_add_disable_keys()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 ALTER TABLE `{$args[0]}` ENABLE KEYS */;" .
|
|
PHP_EOL;
|
|
}
|
|
|
|
public function start_disable_autocommit()
|
|
{
|
|
return "SET autocommit=0;" . PHP_EOL;
|
|
}
|
|
|
|
public function end_disable_autocommit()
|
|
{
|
|
return "COMMIT;" . PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_database()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 DROP DATABASE IF EXISTS `{$args[0]}`*/;" .
|
|
PHP_EOL . PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_trigger()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TRIGGER IF EXISTS `{$args[0]}`;" . PHP_EOL;
|
|
}
|
|
|
|
public function drop_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TABLE IF EXISTS `{$args[0]}`;" . PHP_EOL;
|
|
}
|
|
|
|
public function drop_view()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TABLE IF EXISTS `{$args[0]}`;" . PHP_EOL .
|
|
"/*!50001 DROP VIEW IF EXISTS `{$args[0]}`*/;" . PHP_EOL;
|
|
}
|
|
|
|
public function getDatabaseHeader()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "--" . PHP_EOL .
|
|
"-- Current Database: `{$args[0]}`" . PHP_EOL .
|
|
"--" . PHP_EOL . PHP_EOL;
|
|
}
|
|
|
|
/**
|
|
* Decode column metadata and fill info structure.
|
|
* type, is_numeric and is_blob will always be available.
|
|
*
|
|
* @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
|
|
* @return array
|
|
*/
|
|
public function parseColumnType($colType)
|
|
{
|
|
$colInfo = array();
|
|
$colParts = explode(" ", $colType['Type']);
|
|
|
|
if($fparen = strpos($colParts[0], "("))
|
|
{
|
|
$colInfo['type'] = substr($colParts[0], 0, $fparen);
|
|
$colInfo['length'] = str_replace(")", "", substr($colParts[0], $fparen+1));
|
|
$colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
|
|
}
|
|
else
|
|
{
|
|
$colInfo['type'] = $colParts[0];
|
|
}
|
|
$colInfo['is_numeric'] = in_array($colInfo['type'], $this->mysqlTypes['numerical']);
|
|
$colInfo['is_blob'] = in_array($colInfo['type'], $this->mysqlTypes['blob']);
|
|
// for virtual 'Extra' -> "STORED GENERATED"
|
|
$colInfo['is_virtual'] = strpos($colType['Extra'], "STORED GENERATED") === false ? false : true;
|
|
|
|
return $colInfo;
|
|
}
|
|
|
|
public function get_connection_charset($wpdb = null) {
|
|
if (null === $wpdb) {
|
|
global $wpdb;
|
|
}
|
|
|
|
$charset = (defined('DB_CHARSET') && DB_CHARSET) ? DB_CHARSET : 'utf8mb4';
|
|
|
|
if (method_exists($wpdb, 'determine_charset')) {
|
|
$charset_collate = $wpdb->determine_charset($charset, '');
|
|
if (!empty($charset_collate['charset'])) $charset = $charset_collate['charset'];
|
|
}
|
|
|
|
return $charset;
|
|
}
|
|
|
|
public function backup_parameters()
|
|
{
|
|
global $wpdb;
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$dumpSettings = $args[0];
|
|
$ret = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" . PHP_EOL .
|
|
"/*!40101 SET NAMES " . $this->get_connection_charset($wpdb) . " */;" . PHP_EOL;
|
|
|
|
if (false === $dumpSettings['skip-tz-utc']) {
|
|
$ret .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" . PHP_EOL .
|
|
"/*!40103 SET TIME_ZONE='+00:00' */;" . PHP_EOL;
|
|
}
|
|
|
|
$ret .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;" . PHP_EOL .
|
|
"/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;" . PHP_EOL .
|
|
"/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;" . PHP_EOL .PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function restore_parameters()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$dumpSettings = $args[0];
|
|
$ret = "";
|
|
|
|
if (false === $dumpSettings['skip-tz-utc']) {
|
|
$ret .= "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL;
|
|
}
|
|
|
|
$ret .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;" . PHP_EOL .
|
|
"/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;" . PHP_EOL .
|
|
"/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;" . PHP_EOL .
|
|
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;" . PHP_EOL .
|
|
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;" . PHP_EOL .
|
|
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;" . PHP_EOL .
|
|
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* Check number of parameters passed to function, useful when inheriting.
|
|
* Raise exception if unexpected.
|
|
*
|
|
* @param integer $num_args
|
|
* @param integer $expected_num_args
|
|
* @param string $method_name
|
|
*/
|
|
private function check_parameters($num_args, $expected_num_args, $method_name)
|
|
{
|
|
if ( $num_args != $expected_num_args ) {
|
|
throw new Exception("Unexpected parameter passed to ".esc_html($method_name));
|
|
}
|
|
return;
|
|
}
|
|
|
|
public function query($string)
|
|
{
|
|
return $this->dbHandler->get_results($string, ARRAY_A);
|
|
}
|
|
|
|
public function exec($string)
|
|
{
|
|
return $this->dbHandler->get_results($string, ARRAY_A);
|
|
}
|
|
|
|
public function quote($value)
|
|
{
|
|
$search = array("\x00", "\x0a", "\x0d", "\x1a");
|
|
$replace = array('\0', '\n', '\r', '\Z');
|
|
$value=str_replace('\\', '\\\\', $value);
|
|
$value=str_replace('\'', '\\\'', $value);
|
|
$value= "'" . str_replace($search, $replace, $value) . "'";
|
|
return $value;
|
|
}
|
|
|
|
public function closeCursor($resultSet)
|
|
{
|
|
$this->dbHandler->flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* TypeAdapter Factory
|
|
*
|
|
*/
|
|
abstract class WPvividTypeAdapterFactory
|
|
{
|
|
/**
|
|
* @param string $c Type of database factory to create (Mysql, Sqlite,...)
|
|
* @param PDO $dbHandler
|
|
*/
|
|
public static function create($c, $dbHandler = null)
|
|
{
|
|
$c = ucfirst(strtolower($c));
|
|
if (! WPvividTypeAdapter::isValid($c)) {
|
|
if($c === 'Mysql'){
|
|
$c = 'PDO_MySQL';
|
|
}
|
|
throw new Exception("Database type support for (".esc_html($c).") not yet available");
|
|
}
|
|
$method = __NAMESPACE__ . "\\" . "WPvividTypeAdapter" . $c;
|
|
return new $method($dbHandler);
|
|
}
|
|
|
|
/**
|
|
* function databases Add sql to create and use database
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function databases()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function show_create_table($tableName)
|
|
{
|
|
return "SELECT tbl_name as 'Table', sql as 'Create Table' " .
|
|
"FROM sqlite_master " .
|
|
"WHERE type='table' AND tbl_name='$tableName'";
|
|
}
|
|
|
|
/**
|
|
* function create_table Get table creation code from database
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function create_table($row, $dumpSettings)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function show_create_view($viewName)
|
|
{
|
|
return "SELECT tbl_name as 'View', sql as 'Create View' " .
|
|
"FROM sqlite_master " .
|
|
"WHERE type='view' AND tbl_name='$viewName'";
|
|
}
|
|
|
|
/**
|
|
* function create_view Get view creation code from database
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function create_view($row)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* function show_create_trigger Get trigger creation code from database
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function show_create_trigger($triggerName)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* function create_trigger Modify trigger code, add delimiters, etc
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function create_trigger($triggerName)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* function create_procedure Modify procedure code, add delimiters, etc
|
|
* @todo make it do something with sqlite
|
|
*/
|
|
public function create_procedure($procedureName, $dumpSettings)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function show_tables()
|
|
{
|
|
return "SELECT tbl_name FROM sqlite_master WHERE type='table'";
|
|
}
|
|
|
|
public function show_views()
|
|
{
|
|
return "SELECT tbl_name FROM sqlite_master WHERE type='view'";
|
|
}
|
|
|
|
public function show_triggers()
|
|
{
|
|
return "SELECT name FROM sqlite_master WHERE type='trigger'";
|
|
}
|
|
|
|
public function show_columns()
|
|
{
|
|
if (func_num_args() != 1) {
|
|
return "";
|
|
}
|
|
|
|
$args = func_get_args();
|
|
|
|
return "pragma table_info({$args[0]})";
|
|
}
|
|
|
|
public function show_procedures()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function show_events()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function setup_transaction()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function start_transaction()
|
|
{
|
|
return "BEGIN EXCLUSIVE";
|
|
}
|
|
|
|
public function commit_transaction()
|
|
{
|
|
return "COMMIT";
|
|
}
|
|
|
|
public function lock_table()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function unlock_table()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public function start_add_lock_table()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function end_add_lock_table()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function start_add_disable_keys()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function end_add_disable_keys()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function start_disable_foreign_keys_check()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function end_disable_foreign_keys_check()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_database()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_trigger()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function drop_table()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function drop_view()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
/**
|
|
* Decode column metadata and fill info structure.
|
|
* type, is_numeric and is_blob will always be available.
|
|
*
|
|
* @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
|
|
* @return array
|
|
*/
|
|
public function parseColumnType($colType)
|
|
{
|
|
return array();
|
|
}
|
|
|
|
public function backup_parameters()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
|
|
public function restore_parameters()
|
|
{
|
|
return PHP_EOL;
|
|
}
|
|
}
|
|
|
|
class WPvividTypeAdapterPgsql extends WPvividTypeAdapterFactory
|
|
{
|
|
}
|
|
|
|
class WPvividTypeAdapterDblib extends WPvividTypeAdapterFactory
|
|
{
|
|
}
|
|
|
|
class WPvividTypeAdapterSqlite extends WPvividTypeAdapterFactory
|
|
{
|
|
}
|
|
|
|
|
|
|
|
class WPvividTypeAdapterMysql extends WPvividTypeAdapterFactory
|
|
{
|
|
|
|
private $dbHandler = null;
|
|
|
|
private $dsn;
|
|
private $user;
|
|
private $pass;
|
|
private $pdoSettings;
|
|
private $reconnect_count;
|
|
|
|
// Numerical Mysql types
|
|
public $mysqlTypes = array(
|
|
'numerical' => array(
|
|
'bit',
|
|
'tinyint',
|
|
'smallint',
|
|
'mediumint',
|
|
'int',
|
|
'integer',
|
|
'bigint',
|
|
'real',
|
|
'double',
|
|
'float',
|
|
'decimal',
|
|
'numeric'
|
|
),
|
|
'blob' => array(
|
|
'tinyblob',
|
|
'blob',
|
|
'mediumblob',
|
|
'longblob',
|
|
'binary',
|
|
'varbinary',
|
|
'bit',
|
|
'geometry', /* http://bugs.mysql.com/bug.php?id=43544 */
|
|
'point',
|
|
'linestring',
|
|
'polygon',
|
|
'multipoint',
|
|
'multilinestring',
|
|
'multipolygon',
|
|
'geometrycollection',
|
|
)
|
|
);
|
|
|
|
public function __construct ($dbHandler)
|
|
{
|
|
$pdoSettingsDefault = array(
|
|
PDO::ATTR_PERSISTENT => true,
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
|
|
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false
|
|
);
|
|
|
|
$this->dbHandler = $dbHandler;
|
|
$this->dsn='';
|
|
$this->user='';
|
|
$this->pass='';
|
|
$this->pdoSettings=$pdoSettingsDefault;
|
|
$this->reconnect_count=0;
|
|
}
|
|
|
|
public function set_connect_info($dsn,$user,$pass,$pdoSetting)
|
|
{
|
|
$this->dsn=$dsn;
|
|
$this->user=$user;
|
|
$this->pass=$pass;
|
|
$this->pdoSettings=$pdoSetting;
|
|
}
|
|
|
|
public function connect($host,$dbname,$user,$pass,$init_commands=array())
|
|
{
|
|
if(empty($host))
|
|
{
|
|
$host=DB_HOST;
|
|
}
|
|
$res = explode(':',$host);
|
|
$db_host = $res[0];
|
|
$db_port = empty($res[1])?'':$res[1];
|
|
if(!empty($db_port)) {
|
|
$this->dsn='mysql:host=' . $db_host . ';port=' . $db_port . ';dbname=' . $dbname;
|
|
}
|
|
else{
|
|
$this->dsn='mysql:host=' . $db_host . ';dbname=' . $dbname;
|
|
}
|
|
$this->user=$user;
|
|
$this->pass=$pass;
|
|
$this->dbHandler = @new PDO(
|
|
$this->dsn,
|
|
$this->user,
|
|
$this->pass,
|
|
$this->pdoSettings
|
|
);
|
|
// Execute init commands once connected
|
|
foreach($init_commands as $stmt)
|
|
{
|
|
$this->dbHandler->exec($stmt);
|
|
}
|
|
$this->dbHandler->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);
|
|
}
|
|
|
|
public function errorInfo()
|
|
{
|
|
$error=$this->dbHandler->errorInfo();
|
|
return $error;
|
|
}
|
|
|
|
public function quote($colValue)
|
|
{
|
|
return $this->dbHandler->quote($colValue);
|
|
}
|
|
|
|
|
|
public function databases()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$databaseName = $args[0];
|
|
|
|
$resultSet = $this->query("SHOW VARIABLES LIKE 'character_set_database';");
|
|
$characterSet = $resultSet->fetchColumn(1);
|
|
$resultSet->closeCursor();
|
|
|
|
$resultSet = $this->query("SHOW VARIABLES LIKE 'collation_database';");
|
|
$collationDb = $resultSet->fetchColumn(1);
|
|
$resultSet->closeCursor();
|
|
$ret = "";
|
|
|
|
$ret .= "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$databaseName}`".
|
|
" /*!40100 DEFAULT CHARACTER SET {$characterSet} " .
|
|
" COLLATE {$collationDb} */;" . PHP_EOL . PHP_EOL .
|
|
"USE `{$databaseName}`;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function show_create_table($tableName)
|
|
{
|
|
return "SHOW CREATE TABLE `$tableName`";
|
|
}
|
|
|
|
public function show_create_view($viewName)
|
|
{
|
|
return "SHOW CREATE VIEW `$viewName`";
|
|
}
|
|
|
|
public function show_create_trigger($triggerName)
|
|
{
|
|
return "SHOW CREATE TRIGGER `$triggerName`";
|
|
}
|
|
|
|
public function show_create_procedure($procedureName)
|
|
{
|
|
return "SHOW CREATE PROCEDURE `$procedureName`";
|
|
}
|
|
|
|
public function show_create_event($eventName)
|
|
{
|
|
return "SHOW CREATE EVENT `$eventName`";
|
|
}
|
|
|
|
public function create_table( $row, $dumpSettings )
|
|
{
|
|
|
|
if ( !isset($row['Create Table']) ) {
|
|
throw new Exception("Error getting table code, unknown output");
|
|
}
|
|
|
|
//$createTable = str_replace('\'0000-00-00 00:00:00\'','\'1999-01-01 00:00:00\'',$row['Create Table']);
|
|
$createTable = $row['Create Table'];
|
|
|
|
if ( $dumpSettings['reset-auto-increment'] ) {
|
|
$match = "/AUTO_INCREMENT=[0-9]+/s";
|
|
$replace = "";
|
|
$createTable = preg_replace($match, $replace, $createTable);
|
|
}
|
|
|
|
$ret = "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
|
|
$createTable . ";" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL .
|
|
PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_view($row)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['Create View'])) {
|
|
throw new Exception("Error getting view structure, unknown output");
|
|
}
|
|
|
|
$triggerStmt = $row['Create View'];
|
|
|
|
$triggerStmtReplaced1 = str_replace(
|
|
"CREATE ALGORITHM",
|
|
"/*!50001 CREATE ALGORITHM",
|
|
$triggerStmt
|
|
);
|
|
$triggerStmtReplaced2 = str_replace(
|
|
" DEFINER=",
|
|
" */" . PHP_EOL . "/*!50013 DEFINER=",
|
|
$triggerStmtReplaced1
|
|
);
|
|
$triggerStmtReplaced3 = str_replace(
|
|
" VIEW ",
|
|
" */" . PHP_EOL . "/*!50001 VIEW ",
|
|
$triggerStmtReplaced2
|
|
);
|
|
if (false === $triggerStmtReplaced1 ||
|
|
false === $triggerStmtReplaced2 ||
|
|
false === $triggerStmtReplaced3) {
|
|
$triggerStmtReplaced = $triggerStmt;
|
|
} else {
|
|
$triggerStmtReplaced = $triggerStmtReplaced3 . " */;";
|
|
}
|
|
|
|
$ret .= $triggerStmtReplaced . PHP_EOL . PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_trigger($row)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['SQL Original Statement'])) {
|
|
throw new Exception("Error getting trigger code, unknown output");
|
|
}
|
|
|
|
$triggerStmt = $row['SQL Original Statement'];
|
|
$triggerStmtReplaced = str_replace(
|
|
"CREATE DEFINER",
|
|
"/*!50003 CREATE*/ /*!50017 DEFINER",
|
|
$triggerStmt
|
|
);
|
|
$triggerStmtReplaced = str_replace(
|
|
" TRIGGER",
|
|
"*/ /*!50003 TRIGGER",
|
|
$triggerStmtReplaced
|
|
);
|
|
if ( false === $triggerStmtReplaced ) {
|
|
$triggerStmtReplaced = $triggerStmt . " /* ";
|
|
}
|
|
|
|
$ret .= "DELIMITER ;;" . PHP_EOL .
|
|
$triggerStmtReplaced . " */ ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL . PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_procedure($row, $dumpSettings)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['Create Procedure'])) {
|
|
throw new Exception("Error getting procedure code, unknown output. " .
|
|
"Please check 'https://bugs.mysql.com/bug.php?id=14564'");
|
|
}
|
|
$procedureStmt = $row['Create Procedure'];
|
|
|
|
$ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
|
|
$row['Procedure'] . "` */;" . PHP_EOL .
|
|
"/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
|
|
"DELIMITER ;;" . PHP_EOL .
|
|
$procedureStmt . " ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function create_event($row)
|
|
{
|
|
$ret = "";
|
|
if ( !isset($row['Create Event']) ) {
|
|
throw new Exception("Error getting event code, unknown output. " .
|
|
"Please check 'http://stackoverflow.com/questions/10853826/mysql-5-5-create-event-gives-syntax-error'");
|
|
}
|
|
$eventName = $row['Event'];
|
|
$eventStmt = $row['Create Event'];
|
|
$sqlMode = $row['sql_mode'];
|
|
|
|
$eventStmtReplaced = str_replace(
|
|
"CREATE DEFINER",
|
|
"/*!50106 CREATE*/ /*!50117 DEFINER",
|
|
$eventStmt
|
|
);
|
|
$eventStmtReplaced = str_replace(
|
|
" EVENT ",
|
|
"*/ /*!50106 EVENT ",
|
|
$eventStmtReplaced
|
|
);
|
|
|
|
if ( false === $eventStmtReplaced ) {
|
|
$eventStmtReplaced = $eventStmt . " /* ";
|
|
}
|
|
|
|
$ret .= "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;" . PHP_EOL .
|
|
"/*!50106 DROP EVENT IF EXISTS `" . $eventName . "` */;" . PHP_EOL .
|
|
"DELIMITER ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_cs_client = @@character_set_client */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_cs_results = @@character_set_results */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_col_connection = @@collation_connection */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_client = utf8 */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_results = utf8 */ ;;" . PHP_EOL .
|
|
"/*!50003 SET collation_connection = utf8_general_ci */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;" . PHP_EOL .
|
|
"/*!50003 SET sql_mode = '" . $sqlMode . "' */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_time_zone = @@time_zone */ ;;" . PHP_EOL .
|
|
"/*!50003 SET time_zone = 'SYSTEM' */ ;;" . PHP_EOL .
|
|
$eventStmtReplaced . " */ ;;" . PHP_EOL .
|
|
"/*!50003 SET time_zone = @saved_time_zone */ ;;" . PHP_EOL .
|
|
"/*!50003 SET sql_mode = @saved_sql_mode */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_client = @saved_cs_client */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_results = @saved_cs_results */ ;;" . PHP_EOL .
|
|
"/*!50003 SET collation_connection = @saved_col_connection */ ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL .
|
|
"/*!50106 SET TIME_ZONE= @save_time_zone */ ;" . PHP_EOL . PHP_EOL;
|
|
// Commented because we are doing this in restore_parameters()
|
|
// "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function show_tables()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT TABLE_NAME AS tbl_name " .
|
|
"FROM INFORMATION_SCHEMA.TABLES " .
|
|
"WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function show_views()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT TABLE_NAME AS tbl_name " .
|
|
"FROM INFORMATION_SCHEMA.TABLES " .
|
|
"WHERE TABLE_TYPE='VIEW' AND TABLE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function show_triggers()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SHOW TRIGGERS FROM `{$args[0]}`;";
|
|
}
|
|
|
|
public function show_columns()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SHOW COLUMNS FROM `{$args[0]}`;";
|
|
}
|
|
|
|
public function show_procedures()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT SPECIFIC_NAME AS procedure_name " .
|
|
"FROM INFORMATION_SCHEMA.ROUTINES " .
|
|
"WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
/**
|
|
* Get query string to ask for names of events from current database.
|
|
*
|
|
* @param string Name of database
|
|
* @return string
|
|
*/
|
|
public function show_events()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT EVENT_NAME AS event_name " .
|
|
"FROM INFORMATION_SCHEMA.EVENTS " .
|
|
"WHERE EVENT_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function setup_transaction()
|
|
{
|
|
return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
|
|
}
|
|
|
|
public function start_transaction()
|
|
{
|
|
return "START TRANSACTION";
|
|
}
|
|
|
|
public function commit_transaction()
|
|
{
|
|
return "COMMIT";
|
|
}
|
|
|
|
public function lock_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return $this->dbHandler->exec("LOCK TABLES `{$args[0]}` READ LOCAL");
|
|
|
|
}
|
|
|
|
public function unlock_table()
|
|
{
|
|
return $this->dbHandler->exec("UNLOCK TABLES");
|
|
}
|
|
|
|
public function start_add_lock_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "LOCK TABLES `{$args[0]}` WRITE;" . PHP_EOL;
|
|
}
|
|
|
|
public function end_add_lock_table()
|
|
{
|
|
return "UNLOCK TABLES;" . PHP_EOL;
|
|
}
|
|
|
|
public function start_add_disable_keys()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 ALTER TABLE `{$args[0]}` DISABLE KEYS */;" .
|
|
PHP_EOL;
|
|
}
|
|
|
|
public function end_add_disable_keys()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 ALTER TABLE `{$args[0]}` ENABLE KEYS */;" .
|
|
PHP_EOL;
|
|
}
|
|
|
|
public function start_disable_autocommit()
|
|
{
|
|
return "SET autocommit=0;" . PHP_EOL;
|
|
}
|
|
|
|
public function end_disable_autocommit()
|
|
{
|
|
return "COMMIT;" . PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_database()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 DROP DATABASE IF EXISTS `{$args[0]}`*/;" .
|
|
PHP_EOL . PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_trigger()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TRIGGER IF EXISTS `{$args[0]}`;" . PHP_EOL;
|
|
}
|
|
|
|
public function drop_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TABLE IF EXISTS `{$args[0]}`;" . PHP_EOL;
|
|
}
|
|
|
|
public function drop_view()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TABLE IF EXISTS `{$args[0]}`;" . PHP_EOL .
|
|
"/*!50001 DROP VIEW IF EXISTS `{$args[0]}`*/;" . PHP_EOL;
|
|
}
|
|
|
|
public function getDatabaseHeader()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "--" . PHP_EOL .
|
|
"-- Current Database: `{$args[0]}`" . PHP_EOL .
|
|
"--" . PHP_EOL . PHP_EOL;
|
|
}
|
|
|
|
/**
|
|
* Decode column metadata and fill info structure.
|
|
* type, is_numeric and is_blob will always be available.
|
|
*
|
|
* @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
|
|
* @return array
|
|
*/
|
|
public function parseColumnType($colType)
|
|
{
|
|
$colInfo = array();
|
|
$colParts = explode(" ", $colType['Type']);
|
|
|
|
if($fparen = strpos($colParts[0], "("))
|
|
{
|
|
$colInfo['type'] = substr($colParts[0], 0, $fparen);
|
|
$colInfo['length'] = str_replace(")", "", substr($colParts[0], $fparen+1));
|
|
$colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
|
|
}
|
|
else
|
|
{
|
|
$colInfo['type'] = $colParts[0];
|
|
}
|
|
$colInfo['is_numeric'] = in_array($colInfo['type'], $this->mysqlTypes['numerical']);
|
|
$colInfo['is_blob'] = in_array($colInfo['type'], $this->mysqlTypes['blob']);
|
|
// for virtual 'Extra' -> "STORED GENERATED"
|
|
$colInfo['is_virtual'] = strpos($colType['Extra'], "STORED GENERATED") === false ? false : true;
|
|
|
|
return $colInfo;
|
|
}
|
|
|
|
public function get_connection_charset($wpdb = null) {
|
|
if (null === $wpdb) {
|
|
global $wpdb;
|
|
}
|
|
|
|
$charset = (defined('DB_CHARSET') && DB_CHARSET) ? DB_CHARSET : 'utf8mb4';
|
|
|
|
if (method_exists($wpdb, 'determine_charset')) {
|
|
$charset_collate = $wpdb->determine_charset($charset, '');
|
|
if (!empty($charset_collate['charset'])) $charset = $charset_collate['charset'];
|
|
}
|
|
|
|
return $charset;
|
|
}
|
|
|
|
public function backup_parameters()
|
|
{
|
|
global $wpdb;
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$dumpSettings = $args[0];
|
|
$ret = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" . PHP_EOL .
|
|
"/*!40101 SET NAMES " . $this->get_connection_charset($wpdb) . " */;" . PHP_EOL;
|
|
|
|
if (false === $dumpSettings['skip-tz-utc']) {
|
|
$ret .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" . PHP_EOL .
|
|
"/*!40103 SET TIME_ZONE='+00:00' */;" . PHP_EOL;
|
|
}
|
|
|
|
$ret .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;" . PHP_EOL .
|
|
"/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;" . PHP_EOL .
|
|
"/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;" . PHP_EOL .PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function restore_parameters()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$dumpSettings = $args[0];
|
|
$ret = "";
|
|
|
|
if (false === $dumpSettings['skip-tz-utc']) {
|
|
$ret .= "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL;
|
|
}
|
|
|
|
$ret .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;" . PHP_EOL .
|
|
"/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;" . PHP_EOL .
|
|
"/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;" . PHP_EOL .
|
|
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;" . PHP_EOL .
|
|
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;" . PHP_EOL .
|
|
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;" . PHP_EOL .
|
|
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* Check number of parameters passed to function, useful when inheriting.
|
|
* Raise exception if unexpected.
|
|
*
|
|
* @param integer $num_args
|
|
* @param integer $expected_num_args
|
|
* @param string $method_name
|
|
*/
|
|
private function check_parameters($num_args, $expected_num_args, $method_name)
|
|
{
|
|
if ( $num_args != $expected_num_args ) {
|
|
throw new Exception("Unexpected parameter passed to ".esc_html($method_name));
|
|
}
|
|
return;
|
|
}
|
|
|
|
public function query($string)
|
|
{
|
|
$ret= $this->dbHandler->query($string);
|
|
|
|
if($ret===false)
|
|
{
|
|
$info=$this->dbHandler->errorInfo();
|
|
if($info[1] == 2006)
|
|
{
|
|
if($this->reconnect_count>3)
|
|
{
|
|
throw new Exception("MySQL server has gone away. Too many reconnect.");
|
|
}
|
|
$this->reconnect();
|
|
$this->reconnect_count++;
|
|
$ret= $this->dbHandler->query($string);
|
|
if($ret!==false)
|
|
{
|
|
$ret->setFetchMode(PDO::FETCH_ASSOC);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$ret->setFetchMode(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function exec($string)
|
|
{
|
|
$ret=$this->dbHandler->exec($string);
|
|
|
|
if($ret===false)
|
|
{
|
|
$info=$this->dbHandler->errorInfo();
|
|
if($info[1] == 2006)
|
|
{
|
|
if($this->reconnect_count>3)
|
|
{
|
|
throw new Exception("MySQL server has gone away. Too many reconnect.");
|
|
}
|
|
$this->reconnect();
|
|
$this->reconnect_count++;
|
|
$ret= $this->dbHandler->exec($string);
|
|
}
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
public function reconnect()
|
|
{
|
|
$this->dbHandler = @new PDO(
|
|
$this->dsn,
|
|
$this->user,
|
|
$this->pass,
|
|
$this->pdoSettings
|
|
);
|
|
}
|
|
|
|
public function closeCursor($resultSet)
|
|
{
|
|
$resultSet->closeCursor();
|
|
}
|
|
}
|
|
|
|
class WPvividTypeAdapterWpdb extends WPvividTypeAdapterFactory
|
|
{
|
|
|
|
private $dbHandler = null;
|
|
|
|
// Numerical Mysql types
|
|
public $mysqlTypes = array(
|
|
'numerical' => array(
|
|
'bit',
|
|
'tinyint',
|
|
'smallint',
|
|
'mediumint',
|
|
'int',
|
|
'integer',
|
|
'bigint',
|
|
'real',
|
|
'double',
|
|
'float',
|
|
'decimal',
|
|
'numeric'
|
|
),
|
|
'blob' => array(
|
|
'tinyblob',
|
|
'blob',
|
|
'mediumblob',
|
|
'longblob',
|
|
'binary',
|
|
'varbinary',
|
|
'bit',
|
|
'geometry', /* http://bugs.mysql.com/bug.php?id=43544 */
|
|
'point',
|
|
'linestring',
|
|
'polygon',
|
|
'multipoint',
|
|
'multilinestring',
|
|
'multipolygon',
|
|
'geometrycollection',
|
|
)
|
|
);
|
|
|
|
public function __construct ($dbHandler)
|
|
{
|
|
$this->dbHandler = $dbHandler;
|
|
}
|
|
|
|
public function connect($host,$dbname,$user,$pass,$init_commands=array())
|
|
{
|
|
global $wpdb;
|
|
|
|
$this->dbHandler=$wpdb;
|
|
}
|
|
|
|
public function databases()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$databaseName = $args[0];
|
|
|
|
$resultSet = $this->query("SHOW VARIABLES LIKE 'character_set_database';");
|
|
$characterSet = $resultSet->fetchColumn(1);
|
|
$resultSet->closeCursor();
|
|
|
|
$resultSet = $this->query("SHOW VARIABLES LIKE 'collation_database';");
|
|
$collationDb = $resultSet->fetchColumn(1);
|
|
$resultSet->closeCursor();
|
|
$ret = "";
|
|
|
|
$ret .= "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$databaseName}`".
|
|
" /*!40100 DEFAULT CHARACTER SET {$characterSet} " .
|
|
" COLLATE {$collationDb} */;" . PHP_EOL . PHP_EOL .
|
|
"USE `{$databaseName}`;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function show_create_table($tableName)
|
|
{
|
|
return "SHOW CREATE TABLE `$tableName`";
|
|
}
|
|
|
|
public function show_create_view($viewName)
|
|
{
|
|
return "SHOW CREATE VIEW `$viewName`";
|
|
}
|
|
|
|
public function show_create_trigger($triggerName)
|
|
{
|
|
return "SHOW CREATE TRIGGER `$triggerName`";
|
|
}
|
|
|
|
public function show_create_procedure($procedureName)
|
|
{
|
|
return "SHOW CREATE PROCEDURE `$procedureName`";
|
|
}
|
|
|
|
public function show_create_event($eventName)
|
|
{
|
|
return "SHOW CREATE EVENT `$eventName`";
|
|
}
|
|
|
|
public function create_table( $row, $dumpSettings )
|
|
{
|
|
|
|
if ( !isset($row['Create Table']) ) {
|
|
throw new Exception("Error getting table code, unknown output");
|
|
}
|
|
|
|
//$createTable = str_replace('\'0000-00-00 00:00:00\'','\'1999-01-01 00:00:00\'',$row['Create Table']);
|
|
$createTable = $row['Create Table'];
|
|
|
|
if ( $dumpSettings['reset-auto-increment'] ) {
|
|
$match = "/AUTO_INCREMENT=[0-9]+/s";
|
|
$replace = "";
|
|
$createTable = preg_replace($match, $replace, $createTable);
|
|
}
|
|
|
|
$ret = "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
|
|
$createTable . ";" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL .
|
|
PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_view($row)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['Create View'])) {
|
|
throw new Exception("Error getting view structure, unknown output");
|
|
}
|
|
|
|
$triggerStmt = $row['Create View'];
|
|
|
|
$triggerStmtReplaced1 = str_replace(
|
|
"CREATE ALGORITHM",
|
|
"/*!50001 CREATE ALGORITHM",
|
|
$triggerStmt
|
|
);
|
|
$triggerStmtReplaced2 = str_replace(
|
|
" DEFINER=",
|
|
" */" . PHP_EOL . "/*!50013 DEFINER=",
|
|
$triggerStmtReplaced1
|
|
);
|
|
$triggerStmtReplaced3 = str_replace(
|
|
" VIEW ",
|
|
" */" . PHP_EOL . "/*!50001 VIEW ",
|
|
$triggerStmtReplaced2
|
|
);
|
|
if (false === $triggerStmtReplaced1 ||
|
|
false === $triggerStmtReplaced2 ||
|
|
false === $triggerStmtReplaced3) {
|
|
$triggerStmtReplaced = $triggerStmt;
|
|
} else {
|
|
$triggerStmtReplaced = $triggerStmtReplaced3 . " */;";
|
|
}
|
|
|
|
$ret .= $triggerStmtReplaced . PHP_EOL . PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_trigger($row)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['SQL Original Statement'])) {
|
|
throw new Exception("Error getting trigger code, unknown output");
|
|
}
|
|
|
|
$triggerStmt = $row['SQL Original Statement'];
|
|
$triggerStmtReplaced = str_replace(
|
|
"CREATE DEFINER",
|
|
"/*!50003 CREATE*/ /*!50017 DEFINER",
|
|
$triggerStmt
|
|
);
|
|
$triggerStmtReplaced = str_replace(
|
|
" TRIGGER",
|
|
"*/ /*!50003 TRIGGER",
|
|
$triggerStmtReplaced
|
|
);
|
|
if ( false === $triggerStmtReplaced ) {
|
|
$triggerStmtReplaced = $triggerStmt . " /* ";
|
|
}
|
|
|
|
$ret .= "DELIMITER ;;" . PHP_EOL .
|
|
$triggerStmtReplaced . " */ ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL . PHP_EOL;
|
|
return $ret;
|
|
}
|
|
|
|
public function create_procedure($row, $dumpSettings)
|
|
{
|
|
$ret = "";
|
|
if (!isset($row['Create Procedure'])) {
|
|
throw new Exception("Error getting procedure code, unknown output. " .
|
|
"Please check 'https://bugs.mysql.com/bug.php?id=14564'");
|
|
}
|
|
$procedureStmt = $row['Create Procedure'];
|
|
|
|
$ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
|
|
$row['Procedure'] . "` */;" . PHP_EOL .
|
|
"/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
|
|
"DELIMITER ;;" . PHP_EOL .
|
|
$procedureStmt . " ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL .
|
|
"/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function create_event($row)
|
|
{
|
|
$ret = "";
|
|
if ( !isset($row['Create Event']) ) {
|
|
throw new Exception("Error getting event code, unknown output. " .
|
|
"Please check 'http://stackoverflow.com/questions/10853826/mysql-5-5-create-event-gives-syntax-error'");
|
|
}
|
|
$eventName = $row['Event'];
|
|
$eventStmt = $row['Create Event'];
|
|
$sqlMode = $row['sql_mode'];
|
|
|
|
$eventStmtReplaced = str_replace(
|
|
"CREATE DEFINER",
|
|
"/*!50106 CREATE*/ /*!50117 DEFINER",
|
|
$eventStmt
|
|
);
|
|
$eventStmtReplaced = str_replace(
|
|
" EVENT ",
|
|
"*/ /*!50106 EVENT ",
|
|
$eventStmtReplaced
|
|
);
|
|
|
|
if ( false === $eventStmtReplaced ) {
|
|
$eventStmtReplaced = $eventStmt . " /* ";
|
|
}
|
|
|
|
$ret .= "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;" . PHP_EOL .
|
|
"/*!50106 DROP EVENT IF EXISTS `" . $eventName . "` */;" . PHP_EOL .
|
|
"DELIMITER ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_cs_client = @@character_set_client */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_cs_results = @@character_set_results */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_col_connection = @@collation_connection */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_client = utf8 */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_results = utf8 */ ;;" . PHP_EOL .
|
|
"/*!50003 SET collation_connection = utf8_general_ci */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;" . PHP_EOL .
|
|
"/*!50003 SET sql_mode = '" . $sqlMode . "' */ ;;" . PHP_EOL .
|
|
"/*!50003 SET @saved_time_zone = @@time_zone */ ;;" . PHP_EOL .
|
|
"/*!50003 SET time_zone = 'SYSTEM' */ ;;" . PHP_EOL .
|
|
$eventStmtReplaced . " */ ;;" . PHP_EOL .
|
|
"/*!50003 SET time_zone = @saved_time_zone */ ;;" . PHP_EOL .
|
|
"/*!50003 SET sql_mode = @saved_sql_mode */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_client = @saved_cs_client */ ;;" . PHP_EOL .
|
|
"/*!50003 SET character_set_results = @saved_cs_results */ ;;" . PHP_EOL .
|
|
"/*!50003 SET collation_connection = @saved_col_connection */ ;;" . PHP_EOL .
|
|
"DELIMITER ;" . PHP_EOL .
|
|
"/*!50106 SET TIME_ZONE= @save_time_zone */ ;" . PHP_EOL . PHP_EOL;
|
|
// Commented because we are doing this in restore_parameters()
|
|
// "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function show_tables()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT TABLE_NAME AS tbl_name " .
|
|
"FROM INFORMATION_SCHEMA.TABLES " .
|
|
"WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function show_views()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT TABLE_NAME AS tbl_name " .
|
|
"FROM INFORMATION_SCHEMA.TABLES " .
|
|
"WHERE TABLE_TYPE='VIEW' AND TABLE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function show_triggers()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SHOW TRIGGERS FROM `{$args[0]}`;";
|
|
}
|
|
|
|
public function show_columns()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SHOW COLUMNS FROM `{$args[0]}`;";
|
|
}
|
|
|
|
public function show_procedures()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT SPECIFIC_NAME AS procedure_name " .
|
|
"FROM INFORMATION_SCHEMA.ROUTINES " .
|
|
"WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
/**
|
|
* Get query string to ask for names of events from current database.
|
|
*
|
|
* @param string Name of database
|
|
* @return string
|
|
*/
|
|
public function show_events()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "SELECT EVENT_NAME AS event_name " .
|
|
"FROM INFORMATION_SCHEMA.EVENTS " .
|
|
"WHERE EVENT_SCHEMA='{$args[0]}'";
|
|
}
|
|
|
|
public function setup_transaction()
|
|
{
|
|
return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
|
|
}
|
|
|
|
public function start_transaction()
|
|
{
|
|
return "START TRANSACTION";
|
|
}
|
|
|
|
public function commit_transaction()
|
|
{
|
|
return "COMMIT";
|
|
}
|
|
|
|
public function lock_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return $this->dbHandler->get_results("LOCK TABLES `{$args[0]}` READ LOCAL",ARRAY_A);
|
|
|
|
}
|
|
|
|
public function unlock_table()
|
|
{
|
|
return $this->dbHandler->get_results("UNLOCK TABLES",ARRAY_A);
|
|
}
|
|
|
|
public function start_add_lock_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "LOCK TABLES `{$args[0]}` WRITE;" . PHP_EOL;
|
|
}
|
|
|
|
public function end_add_lock_table()
|
|
{
|
|
return "UNLOCK TABLES;" . PHP_EOL;
|
|
}
|
|
|
|
public function start_add_disable_keys()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 ALTER TABLE `{$args[0]}` DISABLE KEYS */;" .
|
|
PHP_EOL;
|
|
}
|
|
|
|
public function end_add_disable_keys()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 ALTER TABLE `{$args[0]}` ENABLE KEYS */;" .
|
|
PHP_EOL;
|
|
}
|
|
|
|
public function start_disable_autocommit()
|
|
{
|
|
return "SET autocommit=0;" . PHP_EOL;
|
|
}
|
|
|
|
public function end_disable_autocommit()
|
|
{
|
|
return "COMMIT;" . PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_database()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "/*!40000 DROP DATABASE IF EXISTS `{$args[0]}`*/;" .
|
|
PHP_EOL . PHP_EOL;
|
|
}
|
|
|
|
public function add_drop_trigger()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TRIGGER IF EXISTS `{$args[0]}`;" . PHP_EOL;
|
|
}
|
|
|
|
public function drop_table()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TABLE IF EXISTS `{$args[0]}`;" . PHP_EOL;
|
|
}
|
|
|
|
public function drop_view()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "DROP TABLE IF EXISTS `{$args[0]}`;" . PHP_EOL .
|
|
"/*!50001 DROP VIEW IF EXISTS `{$args[0]}`*/;" . PHP_EOL;
|
|
}
|
|
|
|
public function getDatabaseHeader()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
return "--" . PHP_EOL .
|
|
"-- Current Database: `{$args[0]}`" . PHP_EOL .
|
|
"--" . PHP_EOL . PHP_EOL;
|
|
}
|
|
|
|
/**
|
|
* Decode column metadata and fill info structure.
|
|
* type, is_numeric and is_blob will always be available.
|
|
*
|
|
* @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
|
|
* @return array
|
|
*/
|
|
public function parseColumnType($colType)
|
|
{
|
|
$colInfo = array();
|
|
$colParts = explode(" ", $colType['Type']);
|
|
|
|
if($fparen = strpos($colParts[0], "("))
|
|
{
|
|
$colInfo['type'] = substr($colParts[0], 0, $fparen);
|
|
$colInfo['length'] = str_replace(")", "", substr($colParts[0], $fparen+1));
|
|
$colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
|
|
}
|
|
else
|
|
{
|
|
$colInfo['type'] = $colParts[0];
|
|
}
|
|
$colInfo['is_numeric'] = in_array($colInfo['type'], $this->mysqlTypes['numerical']);
|
|
$colInfo['is_blob'] = in_array($colInfo['type'], $this->mysqlTypes['blob']);
|
|
// for virtual 'Extra' -> "STORED GENERATED"
|
|
$colInfo['is_virtual'] = strpos($colType['Extra'], "STORED GENERATED") === false ? false : true;
|
|
|
|
return $colInfo;
|
|
}
|
|
|
|
public function get_connection_charset($wpdb = null) {
|
|
if (null === $wpdb) {
|
|
global $wpdb;
|
|
}
|
|
|
|
$charset = (defined('DB_CHARSET') && DB_CHARSET) ? DB_CHARSET : 'utf8mb4';
|
|
|
|
if (method_exists($wpdb, 'determine_charset')) {
|
|
$charset_collate = $wpdb->determine_charset($charset, '');
|
|
if (!empty($charset_collate['charset'])) $charset = $charset_collate['charset'];
|
|
}
|
|
|
|
return $charset;
|
|
}
|
|
|
|
public function backup_parameters()
|
|
{
|
|
global $wpdb;
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$dumpSettings = $args[0];
|
|
$ret = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" . PHP_EOL .
|
|
"/*!40101 SET NAMES " . $this->get_connection_charset($wpdb) . " */;" . PHP_EOL;
|
|
|
|
if (false === $dumpSettings['skip-tz-utc']) {
|
|
$ret .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" . PHP_EOL .
|
|
"/*!40103 SET TIME_ZONE='+00:00' */;" . PHP_EOL;
|
|
}
|
|
|
|
$ret .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;" . PHP_EOL .
|
|
"/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;" . PHP_EOL .
|
|
"/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;" . PHP_EOL .
|
|
"/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;" . PHP_EOL .PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function restore_parameters()
|
|
{
|
|
$this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
|
|
$args = func_get_args();
|
|
$dumpSettings = $args[0];
|
|
$ret = "";
|
|
|
|
if (false === $dumpSettings['skip-tz-utc']) {
|
|
$ret .= "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL;
|
|
}
|
|
|
|
$ret .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;" . PHP_EOL .
|
|
"/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;" . PHP_EOL .
|
|
"/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;" . PHP_EOL .
|
|
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;" . PHP_EOL .
|
|
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;" . PHP_EOL .
|
|
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;" . PHP_EOL .
|
|
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;" . PHP_EOL . PHP_EOL;
|
|
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* Check number of parameters passed to function, useful when inheriting.
|
|
* Raise exception if unexpected.
|
|
*
|
|
* @param integer $num_args
|
|
* @param integer $expected_num_args
|
|
* @param string $method_name
|
|
*/
|
|
private function check_parameters($num_args, $expected_num_args, $method_name)
|
|
{
|
|
if ( $num_args != $expected_num_args ) {
|
|
throw new Exception("Unexpected parameter passed to ".esc_html($method_name));
|
|
}
|
|
return;
|
|
}
|
|
|
|
public function query($string)
|
|
{
|
|
return $this->dbHandler->get_results($string, ARRAY_A);
|
|
}
|
|
|
|
public function exec($string)
|
|
{
|
|
return $this->dbHandler->get_results($string, ARRAY_A);
|
|
}
|
|
|
|
public function quote($value)
|
|
{
|
|
$search = array("\x00", "\x0a", "\x0d", "\x1a");
|
|
$replace = array('\0', '\n', '\r', '\Z');
|
|
$value=str_replace('\\', '\\\\', $value);
|
|
$value=str_replace('\'', '\\\'', $value);
|
|
$value= "'" . str_replace($search, $replace, $value) . "'";
|
|
return $value;
|
|
}
|
|
|
|
public function closeCursor($resultSet)
|
|
{
|
|
$this->dbHandler->flush();
|
|
}
|
|
} |