123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- <?php
- # ***** BEGIN LICENSE BLOCK *****
- # This file is part of DotClear.
- # Copyright (c) 2004-2005 Olivier Meunier and contributors. All rights
- # reserved.
- #
- # DotClear is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # DotClear is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with DotClear; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- #
- # ***** END LICENSE BLOCK *****
- /**
- * @class dbdump
- *
- */
- class dbdump {
- /**
- @function _getDCTablesList
- Création d'un tableau contenant la listes des tables DC à sauvegarder.
- Les tables 'log' et 'session' sont ignorées et les éventuelles tables
- de plugins ajoutées, si elles sont correctement préfixées.
- @return array
- */
- function _getDCTablesList()
- {
- global $con;
- // D'emblée, on précise les tables "natives" dans l'ordre d'importance
- // pour sécuriser au mieux la remontée.
- // NB : on ignore les tables 'log' et 'session'
- $dc_dump_tables =
- array(
- DB_PREFIX.'user',
- DB_PREFIX.'categorie',
- DB_PREFIX.'post',
- DB_PREFIX.'comment',
- DB_PREFIX.'ping',
- DB_PREFIX.'link'
- );
- // Récupération auprès de MySQL de la liste des tables préfixées
- // pour le DC courant
- $dc_tables = $con->select("SHOW TABLES LIKE '".DB_PREFIX."%'");
- // Maintenant on consolide le tout...
- while ($dc_tables->fetch()) {
- $dc_table = $dc_tables->f(0);
- // S'il s'agit de la table 'log' ou 'session', on écarte...
- if ($dc_table == DB_PREFIX.'log' ||
- $dc_table == DB_PREFIX.'session') {
- continue;
- }
- // On n'ajoute que les tables supplémentaires susceptibles
- // d'alimenter des plugins.
- if (in_array($dc_table, $dc_dump_tables)) {
- continue;
- } else {
- $dc_dump_tables[] = $dc_table;
- }
- }
- return($dc_dump_tables);
- }
- /**
- @function getDump
- Effectue un dump des tables DotClear sous forme d'un fichier SQL standard.
- L'export se compose pour chacune des tables :
- - d'une instruction conditionnelle DROP TABLE
- - de la clause complète CREATE TABLE (clés comprises)
- - des clauses INSERT nécessaires à la restauration des données.
- NB : Les noms des colonnes sont "backquotés".
- @return string La chaine représentant le dump.
- */
- function getDump()
- {
- global $con;
- $dc_tables = dbdump::_getDCTablesList();
- // On précise à MySQL qu'il doit "quoter" les résultats des
- // requêtes SHOW CREATE TABLE qui vont suivre.
- $con->execute("SET SQL_QUOTE_SHOW_CREATE = 1");
- // Récupération de la version du serveur MySQL
- $rs = $con->select("SELECT REPLACE(VERSION(),'-log','')");
- $mysql_version = 'unknown';
- if ($rs) $mysql_version = $rs->f(0);
- // Une entête pour mettre quelques infos (in)utiles
- $dump_str =
- "#-------------------------------------------------------------------\n".
- "# Dump MySQL\n".
- "#\n".
- "# Blog : ". dc_blog_name ."\n".
- "# DotClear : ". DC_VERSION ."\n".
- "# Serveur : ". DB_HOST ." (MySQL v ". $mysql_version .")\n".
- "# Base : ". DB_DBASE ."\n".
- "# Date : ". date("d/m/Y H:i") ."\n".
- "#-------------------------------------------------------------------\n".
- "\n";
- // C'est parti !
- foreach ($dc_tables as $dc_table) {
- $rs = $con->select("SHOW CREATE TABLE $dc_table");
- while($rs->fetch()) {
- // Dump de la clause CREATE TABLE
- $dump_str .=
- "#-------------------------------------------------------------------\n".
- "# Structure de la table $dc_table\n".
- "#-------------------------------------------------------------------\n".
- "DROP TABLE IF EXISTS `$dc_table`;\n".
- str_replace("\n","",$rs->f(1)).";".
- "\n\n";
- // Dump des clauses INSERT
- $dump_str .=
- "#-------------------------------------------------------------------\n".
- "# Données de la table $dc_table\n".
- "#-------------------------------------------------------------------\n";
- $col_rs = $con->select("SELECT * FROM $dc_table");
- while($col_rs->fetch()) {
- $values = array();
- for ($i = 0; $i < $col_rs->int_col_count; $i++) {
- $values[] = $con->escapeStr($col_rs->f($i));
- }
- $dump_str .= "INSERT INTO `$dc_table` VALUES ( '". implode("', '",$values) ."' );\n";
- }
- $dump_str .= "\n";
- }
- }
- $dump_str .= "#-- EOF --\n";
- return($dump_str);
- }
- /**
- @function saveDump
- Enregistre un fichier de dump des tables DotClear.
- Avec les paramètres par défaut, un fichier gzippé dump-YYYYMMDD.sql.gz est
- créé dans le répertoire share/mysql/ de l'installation DotClear.
- @param boolean transmit indicateur d'envoi du fichier de dump (false)
- @param string path le chemin d'enregistrement ('')
- @param string name le nom du fichier cible ('')
- @param boolean compressed indicateur de compression ou non (true)
- @return mixed Retourne une chaine représentant le nom du fichier dans lequel
- le dump a été sauvegardé. Retourne un boolean à false en cas
- de problème sinon.
- @see dbdump::getDump
- */
- function saveDump($transmit = false, $path = '', $name = '', $compressed = true)
- {
- if ($compressed && !function_exists('gzencode')) {
- return(false);
- }
- if (!empty($path) && is_dir($path) && is_writable($path)) {
- $trg_path = $path;
- } else {
- $trg_path = DC_SHARE_DIR.'/mysql';
- }
- if (!empty($name)) {
- $trg_name = $name;
- } else {
- $trg_name = 'dbdump-'.date("Ymd").'.sql';
- }
- $dump = dbdump::getDump();
- if ($compressed) {
- $dump = gzencode($dump);
- $trg_name .= '.gz';
- }
- if ($transmit) {
- header('Content-Type: application/x-gzip');
- header('Content-Disposition: attachment; filename='.$trg_name);
- echo $dump;
- exit;
- } else {
- $trg_fullname = $trg_path.'/'.$trg_name;
- if ($fh = fopen($trg_fullname,"wb")) {
- fwrite($fh, $dump);
- fclose($fh);
- } else {
- return(false);
- }
- return($trg_name);
- }
- }
- /**
- @function restoreDump
- Restaure des tables DotClear depuis un fichier de dump précédemment créé
- par l'opération de sauvegarde.
- @param string src_file le chemin du fichier de dump à restaurer
- @param boolean compressed indicateur de compression ou non (true)
- @return mixed Retourne une chaine indiquant que l'opération s'est correctement
- déroulée. Retourne un boolean à false en cas de problème sinon.
- @see dbdump::saveDump
- */
- function restoreDump($src_file, $compressed = true)
- {
- global $con;
- // Pour un fichier compressé, on crée un version décompressée
- // temporaire dans le répertoire share/mysql/
- $chrono_start = dbdump::_getChrono();
- if ($compressed) {
- if (!$fh = fopen($src_file, "rb")) {
- return(false);
- }
- $tmp_dump = fread($fh, filesize($src_file));
- fclose($fh);
- if (!$dump = gzinflate(substr($tmp_dump, 10))) {
- return(false);
- }
- unset($tmp_dump);
- $tmp_file = DC_SHARE_DIR.'/mysql/_'.basename($src_file);
- if (!$fh = fopen($tmp_file, "wb")) {
- return(false);
- }
- fwrite($fh, $dump);
- fclose($fh);
- unlink($src_file);
- unset($dump);
- $src_file = $tmp_file;
- }
- // Parsing "simpliste" du fichier dump pour la remontée en base.
- // Seules les requêtes DROP TABLE, CREATE TABLE et INSERT seront
- // traitées.
- $scan = file($src_file);
- $token = $sql = '';
- foreach ($scan as $line) {
- $line = rtrim($line);
- if (empty($line) || strpos(ltrim($line), "#") === 0) continue;
- $token .= $line;
- if (preg_match("/^((DROP|CREATE) TABLE .*);$/", $token, $matches) ||
- preg_match("/^(INSERT INTO (.*)'\s\));$/", $token, $matches)) {
- $sql = $matches[1];
- if (!empty($sql)) {
- $res = $con->execute($sql);
- if ($res === false) {
- unlink($src_file);
- return(false);
- }
- }
- $token = $sql = '';
- }
- }
- unlink($src_file);
- $chrono_end = dbdump::_getChrono();
- buffer::str(sprintf("(%.2f sec.)",$chrono_end - $chrono_start));
- return(__('Dump has been restored'));
- }
- /**
- @function _getChrono
- @return float
- */
- function _getChrono()
- {
- list($usec, $sec) = explode(" ", microtime());
- return ((float)$usec + (float)$sec);
- }
- }
- ?>
|