123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- <?php
- backup_migrate_include('destinations.db');
- class backup_migrate_destination_db_mysql extends backup_migrate_destination_db {
- function type_name() {
- return t("MySQL Database");
- }
-
- function file_types() {
- return array(
- "sql" => array(
- "extension" => "sql",
- "filemime" => "text/x-sql",
- "backup" => TRUE,
- "restore" => TRUE,
- ),
- "mysql" => array(
- "extension" => "mysql",
- "filemime" => "text/x-sql",
- "backup" => TRUE,
- "restore" => TRUE,
- ),
- );
- }
-
- function destinations() {
- $out = array();
- global $databases;
- foreach ((array)$databases as $db_key => $target) {
- foreach ((array)$target as $tgt_key => $info) {
-
- $key = $db_key . ':' . $tgt_key;
- if ($info['driver'] === 'mysql') {
- $url = $info['driver'] . '://' . $info['username'] . ':' . $info['password'] . '@' . $info['host'] . (isset($info['port']) ? ':' . $info['port'] : '') . '/' . $info['database'];
- if ($destination = backup_migrate_create_destination('mysql', array('url' => $url))) {
-
- if ($key == 'default:default') {
- $destination->set_id('db');
- $destination->set_name(t('Default Database'));
-
- $destination->remove_op('scheduled backup');
- $destination->remove_op('manual backup');
- }
- else {
- $destination->set_id('db:'. $key);
- $destination->set_name($key .": ". $destination->get_display_location());
- }
- $out[$destination->get_id()] = $destination;
- }
- }
- }
- }
- return $out;
- }
-
- function get_file_type_id() {
- return 'mysql';
- }
-
- function backup_settings_form($settings) {
- $form = parent::backup_settings_form($settings);
- $form['use_mysqldump'] = array(
- "#type" => "checkbox",
- "#title" => t("Use mysqldump command"),
- "#default_value" => !empty($settings['use_mysqldump']),
- "#description" => t("Use the mysqldump command line tool if available. This can be faster for large databases but will not work on all servers. Also exporting SQL views is not really solid with this option. EXPERIMENTAL"),
- );
- return $form;
- }
-
- function _backup_db_to_file($file, $settings) {
- if (!empty($settings->filters['use_mysqldump']) && $this->_backup_db_to_file_mysqldump($file, $settings)) {
- return TRUE;
- }
- $lines = 0;
- $exclude = !empty($settings->filters['exclude_tables']) ? $settings->filters['exclude_tables'] : array();
- $nodata = !empty($settings->filters['nodata_tables']) ? $settings->filters['nodata_tables'] : array();
- if ($file->open(TRUE)) {
- $file->write($this->_get_sql_file_header());
- $alltables = $this->_get_tables();
- $allviews = $this->_get_views();
- foreach ($alltables as $table) {
- if (_backup_migrate_check_timeout()) {
- return FALSE;
- }
- if ($table['name'] && !isset($exclude[$table['name']])) {
- $file->write($this->_get_table_structure_sql($table));
- $lines++;
- if (!in_array($table['name'], $nodata)) {
- $lines += $this->_dump_table_data_sql_to_file($file, $table);
- }
- }
- }
- foreach ($allviews as $view) {
- if (_backup_migrate_check_timeout()) {
- return FALSE;
- }
- if ($view['name'] && !isset($exclude[$view['name']])) {
- $file->write($this->_get_view_create_sql($view));
- }
- }
- $file->write($this->_get_sql_file_footer());
- $file->close();
- return $lines;
- }
- else {
- return FALSE;
- }
- }
-
- function _backup_db_to_file_mysqldump($file, $settings) {
- $success = FALSE;
- $nodata_tables = array();
- $alltables = $this->_get_tables();
- $command = 'mysqldump --result-file=%file --opt -Q --host=%host --port=%port --user=%user --password=%pass %db';
- $args = array(
- '%file' => $file->filepath(),
- '%host' => $this->dest_url['host'],
- '%port' => !empty($this->dest_url['port']) ? $this->dest_url['port'] : '3306',
- '%user' => $this->dest_url['user'],
- '%pass' => $this->dest_url['pass'],
- '%db' => $this->dest_url['path'],
- );
-
- $db = $this->dest_url['path'];
- if (!empty($settings->filters['exclude_tables'])) {
- foreach ((array)$settings->filters['exclude_tables'] as $table) {
- if (isset($alltables[$table])) {
- $command .= ' --ignore-table='. $db .'.'. $table;
- }
- }
- }
- if (!empty($settings->filters['nodata_tables'])) {
- foreach ((array)$settings->filters['nodata_tables'] as $table) {
- if (isset($alltables[$table])) {
- $nodata_tables[] = $table;
- $command .= ' --ignore-table='. $db .'.'. $table;
- }
- }
- }
- $success = backup_migrate_exec($command, $args);
-
- if ($success && !empty($nodata_tables)) {
- $tables = implode(' ', array_unique($nodata_tables));
- $command = "mysqldump --no-data --opt -Q --host=%host --port=%port --user=%user --password=%pass %db $tables >> %file";
- $success = backup_migrate_exec($command, $args);
- }
- return $success;
- }
-
- function _restore_db_from_file($file, $settings) {
- $num = 0;
- if ($file->open() && $conn = $this->_get_db_connection()) {
-
- while ($line = $this->_read_sql_command_from_file($file)) {
- if (_backup_migrate_check_timeout()) {
- return FALSE;
- }
- if ($line) {
-
- $stmt = $conn->prepare($line);
- $stmt->execute();
- $num++;
- }
- }
-
- $file->close();
- }
- else {
- drupal_set_message(t("Unable to open file %file to restore database", array("%file" => $file->filepath())), 'error');
- $num = FALSE;
- }
- return $num;
- }
-
- function _read_sql_command_from_file($file) {
- $out = '';
- while ($line = $file->read()) {
- $line = trim($line);
-
- if (!empty($line) && substr($line, 0, 2) != '--') {
- $out .= ' ' . $line;
-
- if (substr($out, strlen($out) - 1, 1) == ';' || substr($out, strlen($out) - 2, 2) == '*/') {
- return trim($out);
- }
- }
- }
- return trim($out);
- }
-
- function _get_table_names() {
- $out = array();
- foreach ($this->_get_tables() as $table) {
- $out[$table['name']] = $table['name'];
- }
- return $out;
- }
-
- function _get_view_names() {
- $out = array();
- foreach ($this->_get_views() as $view) {
- $out[$view['name']] = $view['name'];
- }
- return $out;
- }
-
- function _lock_tables($tables) {
- if ($tables) {
- $tables_escaped = array();
- foreach ($tables as $table) {
- $tables_escaped[] = '`'. db_escape_table($table) .'` WRITE';
- }
- $this->query('LOCK TABLES '. implode(', ', $tables_escaped));
- }
- }
-
- function _unlock_tables($settings) {
- $this->query('UNLOCK TABLES');
- }
-
- function _get_tables() {
- $out = array();
-
- $tables = $this->query("show table status", array(), array('fetch' => PDO::FETCH_ASSOC));
- foreach ($tables as $table) {
-
-
- $table = array_change_key_case($table);
- if (!empty($table['engine'])) {
- $out[$table['name']] = $table;
- }
- }
- return $out;
- }
-
- function _get_views() {
- $out = array();
-
- $tables = $this->query("show table status", array(), array('fetch' => PDO::FETCH_ASSOC));
- foreach ($tables as $table) {
-
-
- $table = array_change_key_case($table);
- if (empty($table['engine'])) {
- $out[$table['name']] = $table;
- }
- }
- return $out;
- }
-
- function _get_table_structure_sql($table) {
- $out = "";
- $result = $this->query("SHOW CREATE TABLE `". $table['name'] ."`", array(), array('fetch' => PDO::FETCH_ASSOC));
- foreach ($result as $create) {
-
-
- $create = array_change_key_case($create);
- $out .= "DROP TABLE IF EXISTS `". $table['name'] ."`;\n";
-
- $out .= strtr($create['create table'], array("\n" => ' ', '"' => '`'));
- if ($table['auto_increment']) {
- $out .= " AUTO_INCREMENT=". $table['auto_increment'];
- }
- $out .= ";\n";
- }
- return $out;
- }
-
-
- function _get_view_create_sql($view) {
- $out = "";
-
- $sql_mode = $this->query("SELECT @@SESSION.sql_mode")->fetchField();
- $this->query("SET sql_mode = 'ANSI'");
- $result = $this->query("SHOW CREATE VIEW `" . $view['name'] . "`", array(), array('fetch' => PDO::FETCH_ASSOC));
- $this->query("SET SQL_mode = :mode", array(':mode' => $sql_mode));
- foreach ($result as $create) {
- $out .= "DROP VIEW IF EXISTS `". $view['name'] ."`;\n";
- $out .= "SET sql_mode = 'ANSI';\n";
- $out .= strtr($create['Create View'], "\n", " ") . ";\n";
- $out .= "SET sql_mode = '$sql_mode';\n";
- }
- return $out;
- }
-
- function _dump_table_data_sql_to_file($file, $table) {
- $rows_per_line = variable_get('backup_migrate_data_rows_per_line', 30);
- $bytes_per_line = variable_get('backup_migrate_data_bytes_per_line', 2000);
-
- $lines = 0;
- $data = $this->query("SELECT * FROM `". $table['name'] ."`", array(), array('fetch' => PDO::FETCH_ASSOC));
- $rows = $bytes = 0;
-
- $search = array('\\', "'", "\x00", "\x0a", "\x0d", "\x1a");
- $replace = array('\\\\', "''", '\0', '\n', '\r', '\Z');
-
- $line = array();
- foreach ($data as $row) {
-
- $items = array();
- foreach ($row as $key => $value) {
- $items[] = is_null($value) ? "null" : "'". str_replace($search, $replace, $value) ."'";
- }
-
-
- if ($items) {
-
- if ($rows == 0) {
- $file->write("INSERT INTO `". $table['name'] ."` VALUES ");
- $bytes = $rows = 0;
- }
-
- else {
- $file->write(",");
- }
-
-
- $sql = implode(',', $items);
- $file->write('('. $sql .')');
- $bytes += strlen($sql);
- $rows++;
-
-
- if ($rows >= $rows_per_line || $bytes >= $bytes_per_line) {
- $file->write(";\n");
- $lines++;
- $bytes = $rows = 0;
- }
- }
- }
-
- if ($rows > 0) {
- $file->write(";\n");
- $lines++;
- }
-
- return $lines;
- }
-
- function _get_db_connection() {
- if (!$this->connection) {
- $this->connection = parent::_get_db_connection();
-
- $this->connection->exec("SET sql_mode=''");
- }
- return $this->connection;
- }
-
- function query($query, $args = array(), $options = array()) {
- if ($conn = $this->_get_db_connection()) {
- return $conn->query($query, $args, $options);
- }
- }
-
- function _get_sql_file_header() {
- return "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
- /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
- /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
- /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
- /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
- /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */;
- SET NAMES utf8;
- ";
- }
-
-
- function _get_sql_file_footer() {
- return "
-
- /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
- /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
- /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
- /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
- /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
- /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
- ";
- }
- }
|