From b231955973945b24778ef7af7b43fcb64d275e22 Mon Sep 17 00:00:00 2001 From: "Committo,Ergo:sum" <esj@rezo.net> Date: Mon, 22 Jan 2007 18:00:11 +0000 Subject: [PATCH] =?UTF-8?q?Correction=20de=20[8454]:=20vraiment=20sportif?= =?UTF-8?q?=20de=20concilier=20les=20extraits=20de=20table=20pour=20les=20?= =?UTF-8?q?admins=20restreints=20et=20l'=C3=A9criture=20par=20tranche=20de?= =?UTF-8?q?=20table=20pour=20reprendre=20sur=20time-out.=20Ca=20semble=20c?= =?UTF-8?q?orrect=20=C3=A0=20pr=C3=A9sent.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecrire/action/export_all.php | 26 ++++--- ecrire/exec/export_all.php | 60 ++++++++-------- ecrire/inc/export.php | 129 +++++++++++++++++------------------ 3 files changed, 103 insertions(+), 112 deletions(-) diff --git a/ecrire/action/export_all.php b/ecrire/action/export_all.php index 1c9e5c74f8..56f2094d71 100644 --- a/ecrire/action/export_all.php +++ b/ecrire/action/export_all.php @@ -18,7 +18,7 @@ include_spip('inc/minipres'); function action_export_all_dist() { - global $gz, $connect_toutes_rubriques ; + global $connect_toutes_rubriques ; $securiser_action = charger_fonction('securiser_action', 'inc'); $arg = $securiser_action(); @@ -28,18 +28,10 @@ function action_export_all_dist() if ($connect_toutes_rubriques AND file_exists(_DIR_DUMP)) $dir = _DIR_DUMP; - $file = $dir . $arg; - - if ($GLOBALS['flag_ob_flush']) ob_flush(); - flush(); - - $f = ($gz) ? gzopen($file, "ab") : fopen($file, "ab"); - $_fputs = ($gz) ? gzputs : fputs; - $_fputs($f, export_entete()); - $files = ramasse_parties($file, $gz, $file . ".part"); - $_fputs($f, export_enpied()); - if ($gz) gzclose($f); else fclose($f); - + list($file, $nb) = split('/', $arg); + $file = $dir . $file; + $files = ramasse_parties($file, $file, $nb, true); + effacer_meta("status_dump"); ecrire_metas(); @@ -49,9 +41,14 @@ function action_export_all_dist() array('archive' => ':<br /><b>'.joli_repertoire($file)."</b> ($n)")); echo install_debut_html(_T('info_sauvegarde')); + if (!$files) { + echo _T('avis_erreur_sauvegarde', array('type'=>'.', 'id_objet'=>'. .')); + + } else { // ne pas effrayer inutilement: il peut y avoir moins de fichiers // qu'annonce' si certains etaient vides -# echo "<ul><li>", join('</li><li>', $files), '</li></ul>'; + + echo "<!--", join("\n", $files), '-->'; echo "<p style='text-align: left'>". $n, " <a href='" . _DIR_RESTREINT . "'>". @@ -59,6 +56,7 @@ function action_export_all_dist() . "</a> " ._T('info_sauvegarde_reussi_04') . "</p>\n"; + } echo install_fin_html(); } ?> \ No newline at end of file diff --git a/ecrire/exec/export_all.php b/ecrire/exec/export_all.php index 13109f3c80..9a05e2bc3e 100644 --- a/ecrire/exec/export_all.php +++ b/ecrire/exec/export_all.php @@ -58,7 +58,7 @@ $GLOBALS['flag_ob_flush'] = function_exists('ob_flush'); // http://doc.spip.org/@exec_export_all_dist function exec_export_all_dist() { - global $archive, $etape, $gz, $connect_toutes_rubriques; + global $archive, $gz, $connect_toutes_rubriques; if ($connect_toutes_rubriques AND file_exists(_DIR_DUMP)) $dir = _DIR_DUMP; @@ -72,7 +72,6 @@ function exec_export_all_dist() if (!$archive) $archive = export_nom_fichier_dump($dir,$gz); $file = $dir . $archive; - $partfile = $file . ".part"; // utiliser une version fraiche des metas (ie pas le cache) include_spip('inc/meta'); @@ -89,7 +88,7 @@ function exec_export_all_dist() } if ($start){ - $status_dump = "$gz::$archive::0::0"; + $status_dump = "$gz::$archive::1::0"; ecrire_meta("status_dump", "$status_dump",'non'); $status_dump = explode("::",$status_dump); ecrire_metas(); @@ -105,19 +104,20 @@ function exec_export_all_dist() list($tables_for_dump, $tables_for_link) = export_all_list_tables(); $status_dump = explode("::",$GLOBALS['meta']["status_dump"]); - $etape = $status_dump[2]; + $etape_actuelle = $status_dump[2]; + $sous_etape = $status_dump[3]; + $all = count($tables_for_dump); // Pour avoir les valeurs de _DIR_IMG etc relatives a l'espace public // la phase finale de reunion des fichiers en un seul est faite la-bas - $href = generer_action_auteur("export_all",$archive,'',true); + $href = generer_action_auteur("export_all","$archive/$all",'',true); - if ($etape >= count($tables_for_dump)){ // au timeout + if ($etape_actuelle > $all){ // au timeout include_spip('inc/headers'); redirige_par_entete($href); } - echo install_debut_html(_T('info_sauvegarde')); - echo "<p>",_T("info_sauvegarde"), $reprise, "</p>\n"; + echo install_debut_html(_T('info_sauvegarde') . " ($all)"); $f = ($gz) ? gzopen($file, "ab") : fopen($file, "ab"); if (!$f) { echo "<p>", @@ -138,36 +138,34 @@ function exec_export_all_dist() if ($start) $timeout = round($timeout/2); // script de rechargement auto sur timeout echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".generer_url_ecrire("export_all","archive=$archive&gz=$gz",true)."\";',$timeout);</script>\n"); - $cpt = 0; - $paquets = 400; // nombre d'enregistrements dans chaque paquet - echo "<div style='text-align: left'>\n"; - foreach($tables_for_dump as $i=>$table){ - - while (1){ // on ne connait pas le nb de paquets d'avance - list($string,$status_dump)=export_objets($table, $tables_for_link[$table],0, false, $i, _T("info_sauvegarde").", $table",$paquets); - - if ($string) { -// on ecrit dans un fichier generique -// puis on le renomme pour avoir une operation atomique - ecrire_fichier ($partfile, $string); - rename($partfile,$partfile.".$cpt"); - $cpt ++; - } - // on se contente d'une ecriture en base pour aller plus vite - // a la relecture on en profitera pour mettre le cache a jour - ecrire_meta("status_dump", implode("::",$status_dump),'non'); - // attention $string vide ne suffit pas a sortir - // car les admins restreints peuvent parcourir - // une portion de table vide pour eux. - if (!$status_dump[3]) break; + echo "<div style='text-align: left'>\n"; + $etape = 1; + foreach($tables_for_dump as $table){ + + $liens = $tables_for_link[$table]; + if ($etape_actuelle <= $etape) { + $r = spip_query("SELECT COUNT(*) FROM $table"); + $r = spip_fetch_array($r, SPIP_NUM); + $r = $r[0]; + echo "\n<br /><strong>",$etape, '. ', $table,"</strong> "; + if (!$r) echo _T('texte_vide'); + else { + $cpt = export_objets($table, $liens, $etape, $sous_etape,$dir, $archive, $gz, $r); + $filetable = $dir . $archive . '_' . $etape; + ramasse_parties($dir . $archive . ".$etape", $filetable, $cpt); + } + $etape++; + $sous_etape = 0; + $status_dump = "$gz::$archive::" . $etape . "::0"; + ecrire_meta("status_dump", $status_dump,'non'); } } echo "</div>\n"; // si Javascript est dispo, anticiper le Time-out echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"$href\";',0);</script>\n"); echo install_fin_html(); -} + } // construction de la liste des tables pour le dump : // toutes les tables principales diff --git a/ecrire/inc/export.php b/ecrire/inc/export.php index 2c903e0a62..c07a7e243c 100644 --- a/ecrire/inc/export.php +++ b/ecrire/inc/export.php @@ -27,94 +27,88 @@ function export_nom_fichier_dump($dir,$gz=true){ // http://doc.spip.org/@ramasse_parties -function ramasse_parties($archive, $gz, $partfile){ +function ramasse_parties($archive, $partfile, $nb, $fin=''){ // a ameliorer par un preg_file // si le rammassage est interrompu par un timeout, on perd des morceaux - $cpt=0; $files = array(); - while(file_exists($f = $partfile.".$cpt")){ - $contenu = ""; - if (lire_fichier ($f, $contenu)) - if (!ecrire_fichier($archive,$contenu,false,false)) - { - echo "<p>"._T('avis_erreur_sauvegarde', array('type'=>'.', 'id_objet'=>'. .'))."</p>\n"; - exit; + $ok = true; + if (!ecrire_fichier($archive,$fin ? export_entete() : '',false,false)) + $ok = false; + else { + for($cpt =1; $cpt <= $nb; $cpt++) { + if (file_exists($f = $partfile.".$cpt")) { + $contenu = ""; + if (lire_fichier ($f, $contenu)) { + if (!ecrire_fichier($archive,$contenu,false,false)) + { $ok = false; break;} + } + unlink($f); + $files[]=$f; } - unlink($f); - $files[]=$f; - $cpt++; + } } - return $files; + + if ($fin AND $ok) + $ok = ecrire_fichier($archive, export_enpied(),false,false); + + return $ok ? $files : false; } +define('_EXPORT_TRANCHES_LIMITE', 400); + // -// Exportation generique d'objets (fichier ou retour de fonction) -// +// Exportation de table SQL au format xml +// La constante ci-dessus determine la taille des tranches, +// chaque tranche etant copiee immediatement dans un fichier +// et son numero memorisee dans le serveur SQL. +// En cas d'abandon sur Time-out, le travail pourra ainsi avancer +// charge a l'appelant de coller tous les morceaux de 1 a N + // http://doc.spip.org/@export_objets -function export_objets($table, $liens, $file = 0, $gz = false, $etape_actuelle="", $nom_etape="",$limit=0) { +function export_objets($table, $liens, $etape, $cpt, $dir, $archive, $gz, $total) { static $etape_affichee=array(); - $string=''; - $status_dump = explode("::",$GLOBALS['meta']["status_dump"]); - $etape_en_cours = $status_dump[2]; - $pos_in_table = $status_dump[3]; - - if ($etape_en_cours < 1 OR $etape_en_cours == $etape_actuelle){ - - // on calcule ca autant de fois qu'il y a de paquets! - // on devrait plutot le faire dans l'appelant - // et le memoriser dans status_dump - $result = spip_query("SELECT COUNT(*) FROM $table"); - $row = spip_fetch_array($result,SPIP_NUM); - $total = $row[0]; - if (!isset($etape_affichee[$etape_actuelle]) AND $total){ - echo "\n<br /><strong>$etape_actuelle-$nom_etape</strong>"; - $etape_affichee[$etape_actuelle] = 1; - } - if ($pos_in_table!=0 AND $total) - echo " ", $pos_in_table; + $debut = $cpt * _EXPORT_TRANCHES_LIMITE; + $filetable = $dir . $archive . '_' . $etape . '.'; + + while (1){ // on ne connait pas le nb de paquets d'avance + if ($GLOBALS['flag_ob_flush']) ob_flush(); flush(); - if ($limit == 0) $limit = $total; - - $string = build_while($pos_in_table, $limit, $table); - - if ($pos_in_table>=$total){ - if ($total) echo " ok"; - $status_dump[2] = $status_dump[2]+1; - $status_dump[3] = 0; - } else $status_dump[3] = $pos_in_table; - - if ($file) { - $_fputs = ($gz) ? gzputs : fputs; - $_fputs($file, $string); - fflush($file); - ecrire_meta("status_dump", implode("::",$status_dump),'non'); - $string=''; + + $string = build_while($debut, $table); + // attention $string vide ne suffit pas a sortir + // car les admins restreints peuvent parcourir + // une portion de table vide pour eux. + if ($string) { +// on ecrit dans un fichier generique +// puis on le renomme pour avoir une operation atomique + $cpt++; + ecrire_fichier ($filetable, $string); + rename($filetable,$filetable . $cpt); } - } else { // ca ne sert plus il me semble - if ($etape_actuelle < $etape_en_cours) { - if (!isset($etape_affichee[$etape_actuelle])) - echo "\n<li>", $etape_actuelle,'-',$nom_etape,"</li>"; - } else { - if (!isset($etape_affichee[$etape_actuelle])) - echo "\n<li> <span style='color: #999999'>",$etape_actuelle,'-',$nom_etape,'</span></li>'; - } - if ($GLOBALS['flag_ob_flush']) ob_flush(); - flush(); + + $debut += _EXPORT_TRANCHES_LIMITE; + if ($debut >= $total) {break;} + echo " $debut"; + // on se contente d'une ecriture en base pour aller plus vite + // a la relecture on en profitera pour mettre le cache a jour + $status_dump = "$gz::$archive::$etape::$cpt"; + ecrire_meta("status_dump", $status_dump,'non'); } - return array($string,$status_dump); + echo " $total."; + return $cpt; } -// Exporter les champs de la table +// Construit la version xml des champs d'une table // http://doc.spip.org/@build_while -function build_while(&$pos_in_table, $limit, $table) { +function build_while($debut, $table) { global $connect_toutes_rubriques ; global $tables_principales; static $table_fields=array(); - $result = spip_query("SELECT * FROM $table LIMIT " . intval($pos_in_table) .',' . intval($limit)); + $result = spip_query("SELECT * FROM $table LIMIT $debut," . _EXPORT_TRANCHES_LIMITE); // Recuperer les noms des champs // Ces infos sont donnees par le abstract_showtable // les instructions natives mysql ne devraient pas apparaitre ici @@ -125,20 +119,21 @@ function build_while(&$pos_in_table, $limit, $table) { } else $nfields = count($table_fields[$table]); $string = ''; + $all = $connect_toutes_rubriques ||(!in_array('id_rubrique',$table_fields[$table])); while ($row = spip_fetch_array($result,SPIP_ASSOC)) { if ((!isset($row['impt']) OR $row['impt']=='oui') AND ($all OR autoriser('publierdans','rubrique',$row['id_rubrique']))) { - $string .= "<$table>\n"; + $attributs = ""; + $string .= "<$table$attributs>\n"; for ($i = 0; $i < $nfields; ++$i) { $k = $table_fields[$table][$i]; $string .= "<$k>" . text_to_xml($row[$k]) . "</$k>\n"; } $string .= "</$table>\n\n"; } - $pos_in_table++; } spip_free_result($result); return $string; -- GitLab