diff --git a/ChangeLog b/ChangeLog index 8f039fa5444140ed214db07806c6434a13a9e1c7..fb719bc77986672184c9e1251861316335efd3f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -42,6 +42,7 @@ For developers: - Updated wiki documentation. - Better W3C standard. - Can add data provided with a module. +- Can fix some corruptions in database by calling the update page with action=repair ***** Changelog for 2.6 compared to 2.5 ***** diff --git a/htdocs/install/upgrade.php b/htdocs/install/upgrade.php index 4399b24cbafffbc01b8547695c17872c9e5493de..b893364223a66531d7acf3274f1d8f338ff982da 100644 --- a/htdocs/install/upgrade.php +++ b/htdocs/install/upgrade.php @@ -1,6 +1,6 @@ <?php /* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> - * Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2004-2009 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2005-2009 Regis Houssin <regis@dolibarr.fr> * * This program is free software; you can redistribute it and/or modify @@ -19,10 +19,11 @@ */ /** - \file htdocs/install/upgrade.php - \brief Run migration script - \version $Id$ -*/ + * \file htdocs/install/upgrade.php + * \brief Run migration script + * \version $Id$ + * \remarks Can be also called directly with http://mydolibarr/install/upgrade.php?action=repair + */ include_once("./inc.php"); if (file_exists($conffile)) include_once($conffile); @@ -60,14 +61,22 @@ dolibarr_install_syslog("upgrade: Entering upgrade.php page"); if (! is_object($conf)) dolibarr_install_syslog("upgrade2: conf file not initialized",LOG_ERR); +/* + * View + */ + pHeader($langs->trans("DatabaseMigration"),"upgrade2","upgrade"); +$actiondone=0; -if (! isset($_GET["action"]) || $_GET["action"] == "upgrade") +// Action to launch the repair or migrate script +if (! isset($_GET["action"]) || $_GET["action"] == "upgrade" || $_GET["action"] == "repair") { + $actiondone=1; + print '<h3>'.$langs->trans("DatabaseMigration").'<h3>'; - if (! $versionfrom && ! $versionto) + if ($_GET["action"] != "repair" && ! $versionfrom && ! $versionto) { print '<div class="error">Parameter versionfrom or version to missing.</div>'; exit; @@ -138,131 +147,137 @@ if (! isset($_GET["action"]) || $_GET["action"] == "upgrade") print '<tr><td colspan="2">'.$langs->trans("PleaseBePatient").'</td></tr>'; flush(); - // Delete duplicates in table categorie_association - $couples=array(); - $filles=array(); - $sql = "SELECT fk_categorie_mere, fk_categorie_fille"; - $sql.= " FROM ".MAIN_DB_PREFIX."categorie_association"; - dolibarr_install_syslog("upgrade: search duplicate sql=".$sql); - $resql = $db->query($sql); - if ($resql) + + if ($_GET["action"] != "repair") { - $num=$db->num_rows($resql); - while ($obj=$db->fetch_object($resql)) + /* + * Delete duplicates in table categorie_association + */ + $couples=array(); + $filles=array(); + $sql = "SELECT fk_categorie_mere, fk_categorie_fille"; + $sql.= " FROM ".MAIN_DB_PREFIX."categorie_association"; + dolibarr_install_syslog("upgrade: search duplicate sql=".$sql); + $resql = $db->query($sql); + if ($resql) { - if (! isset($filles[$obj->fk_categorie_fille])) // Only one record as child (a child has only on parent). + $num=$db->num_rows($resql); + while ($obj=$db->fetch_object($resql)) { - if ($obj->fk_categorie_mere != $obj->fk_categorie_fille) + if (! isset($filles[$obj->fk_categorie_fille])) // Only one record as child (a child has only on parent). { - $filles[$obj->fk_categorie_fille]=1; // Set record for this child - $couples[$obj->fk_categorie_mere.'_'.$obj->fk_categorie_fille]=array('mere'=>$obj->fk_categorie_mere, 'fille'=>$obj->fk_categorie_fille); + if ($obj->fk_categorie_mere != $obj->fk_categorie_fille) + { + $filles[$obj->fk_categorie_fille]=1; // Set record for this child + $couples[$obj->fk_categorie_mere.'_'.$obj->fk_categorie_fille]=array('mere'=>$obj->fk_categorie_mere, 'fille'=>$obj->fk_categorie_fille); + } } } - } - dolibarr_install_syslog("upgrade: result is num=".$num." sizeof(couples)=".sizeof($couples)); + dolibarr_install_syslog("upgrade: result is num=".$num." sizeof(couples)=".sizeof($couples)); - // If there is duplicates couples or child with two parents - if (sizeof($couples) > 0 && $num > sizeof($couples)) - { - $error=0; + // If there is duplicates couples or child with two parents + if (sizeof($couples) > 0 && $num > sizeof($couples)) + { + $error=0; - $db->begin(); + $db->begin(); - $sql="DELETE FROM ".MAIN_DB_PREFIX."categorie_association"; - dolibarr_install_syslog("upgrade: delete association sql=".$sql); - $resqld=$db->query($sql); - if ($resqld) - { - foreach($couples as $key => $val) + $sql="DELETE FROM ".MAIN_DB_PREFIX."categorie_association"; + dolibarr_install_syslog("upgrade: delete association sql=".$sql); + $resqld=$db->query($sql); + if ($resqld) { - $sql ="INSERT INTO ".MAIN_DB_PREFIX."categorie_association(fk_categorie_mere,fk_categorie_fille)"; - $sql.=" VALUES(".$val['mere'].", ".$val['fille'].")"; - dolibarr_install_syslog("upgrade: insert association sql=".$sql); - $resqli=$db->query($sql); - if (! $resqli) $error++; + foreach($couples as $key => $val) + { + $sql ="INSERT INTO ".MAIN_DB_PREFIX."categorie_association(fk_categorie_mere,fk_categorie_fille)"; + $sql.=" VALUES(".$val['mere'].", ".$val['fille'].")"; + dolibarr_install_syslog("upgrade: insert association sql=".$sql); + $resqli=$db->query($sql); + if (! $resqli) $error++; + } } - } - if (! $error) - { - print '<tr><td>'.$langs->trans("RemoveDuplicates").'</td>'; - print '<td align="right">'.$langs->trans("Success").' ('.$num.'=>'.sizeof($couples).')</td></tr>'; - $db->commit(); - } - else - { - print '<tr><td>'.$langs->trans("RemoveDuplicates").'</td>'; - print '<td align="right">'.$langs->trans("Failed").'</td></tr>'; - $db->rollback(); + if (! $error) + { + print '<tr><td>'.$langs->trans("RemoveDuplicates").'</td>'; + print '<td align="right">'.$langs->trans("Success").' ('.$num.'=>'.sizeof($couples).')</td></tr>'; + $db->commit(); + } + else + { + print '<tr><td>'.$langs->trans("RemoveDuplicates").'</td>'; + print '<td align="right">'.$langs->trans("Failed").'</td></tr>'; + $db->rollback(); + } } } - } - else - { - print '<div class="error">'.$langs->trans("Error").'</div>'; - } - + else + { + print '<div class="error">'.$langs->trans("Error").'</div>'; + } - if ($ok) - { - $versioncommande=split('\.','4.0'); - if (sizeof($versioncommande) && sizeof($versionarray) - && versioncompare($versioncommande,$versionarray) <= 0) // Si mysql >= 4.0 + /* + * Remove deprecated indexes and constraints + */ + if ($ok) { - // Suppression vieilles contraintes sans noms et en doubles - // Les contraintes indesirables ont un nom qui commence par 0_ ou se termine par ibfk_999 -/* $listtables=array( 'llx_product_fournisseur_price', - 'llx_fichinter', - 'llx_facture_fourn', - 'llx_propal', - 'llx_socpeople', - 'llx_telephonie_adsl_fournisseur', - 'llx_telephonie_client_stats', - 'llx_telephonie_contact_facture', - 'llx_telephonie_societe_ligne', - 'llx_telephonie_tarif_client'); -*/ - $listtables = $db->DDLListTables($conf->db->name,''); - foreach ($listtables as $val) + $versioncommande=split('\.','4.0'); + if (sizeof($versioncommande) && sizeof($versionarray) + && versioncompare($versioncommande,$versionarray) <= 0) // Si mysql >= 4.0 { - //print "x".$val."<br>"; - $sql = "SHOW CREATE TABLE ".$val; - $resql = $db->query($sql); - if ($resql) + // Suppression vieilles contraintes sans noms et en doubles + // Les contraintes indesirables ont un nom qui commence par 0_ ou se termine par ibfk_999 + /* $listtables=array( 'llx_product_fournisseur_price', + 'llx_fichinter', + 'llx_facture_fourn', + 'llx_propal', + 'llx_socpeople', + 'llx_telephonie_adsl_fournisseur', + 'llx_telephonie_client_stats', + 'llx_telephonie_contact_facture', + 'llx_telephonie_societe_ligne', + 'llx_telephonie_tarif_client'); + */ + $listtables = $db->DDLListTables($conf->db->name,''); + foreach ($listtables as $val) { - $values=$db->fetch_array($resql); - $i=0; - $createsql=$values[1]; - while (eregi('CONSTRAINT `(0_[0-9a-zA-Z]+|[_0-9a-zA-Z]+_ibfk_[0-9]+)`',$createsql,$reg) && $i < 100) + //print "x".$val."<br>"; + $sql = "SHOW CREATE TABLE ".$val; + $resql = $db->query($sql); + if ($resql) { - $sqldrop="ALTER TABLE ".$val." DROP FOREIGN KEY ".$reg[1]; - $resqldrop = $db->query($sqldrop); - if ($resqldrop) + $values=$db->fetch_array($resql); + $i=0; + $createsql=$values[1]; + while (eregi('CONSTRAINT `(0_[0-9a-zA-Z]+|[_0-9a-zA-Z]+_ibfk_[0-9]+)`',$createsql,$reg) && $i < 100) { - print '<tr><td colspan="2">'.$sqldrop.";</td></tr>\n"; + $sqldrop="ALTER TABLE ".$val." DROP FOREIGN KEY ".$reg[1]; + $resqldrop = $db->query($sqldrop); + if ($resqldrop) + { + print '<tr><td colspan="2">'.$sqldrop.";</td></tr>\n"; + } + $createsql=eregi_replace('CONSTRAINT `'.$reg[1].'`','XXX',$createsql); + $i++; } - $createsql=eregi_replace('CONSTRAINT `'.$reg[1].'`','XXX',$createsql); - $i++; + $db->free($resql); } - $db->free($resql); - } - else - { - if ($db->lasterrno() != 'DB_ERROR_NOSUCHTABLE') + else { - print '<tr><td colspan="2"><font class="error">'.$sql.' : '.$db->lasterror()."</font></td></tr>\n"; + if ($db->lasterrno() != 'DB_ERROR_NOSUCHTABLE') + { + print '<tr><td colspan="2"><font class="error">'.$sql.' : '.$db->lasterror()."</font></td></tr>\n"; + } } } } } } - /*************************************************************************************** - * - * Chargement fichiers dans migration - * - ***************************************************************************************/ + /* + * Load sql files + */ if ($ok) { if ($choix==1) $dir = "../../mysql/migration/"; @@ -284,16 +299,29 @@ if (! isset($_GET["action"]) || $_GET["action"] == "upgrade") } sort($filesindir); - # Determine les fichiers sql a passer - foreach($filesindir as $file) + # Define which file to run + if ($_GET["action"] != "repair") { - if (eregi($from,$file)) + foreach($filesindir as $file) { - $filelist[]=$file; + if (eregi($from,$file)) + { + $filelist[]=$file; + } + else if (eregi($to,$file)) // First test may be false if we migrate from x.y.* to x.y.* + { + $filelist[]=$file; + } } - else if (eregi($to,$file)) // First test may be false if we migrate from x.y.* to x.y.* + } + else + { + foreach($filesindir as $file) { - $filelist[]=$file; + if (eregi('repair',$file)) + { + $filelist[]=$file; + } } } @@ -314,7 +342,9 @@ if (! isset($_GET["action"]) || $_GET["action"] == "upgrade") if ($db->connected) $db->close(); } -else + + +if (empty($actiondone)) { print '<div class="error">'.$langs->trans("ErrorWrongParameters").'</div>'; } diff --git a/mysql/migration/2.6.0-2.7.0.sql b/mysql/migration/2.6.0-2.7.0.sql index 6f8b34db8005e0f9ce630eaba21d2bb521190bca..be52ec38a375b228282a9f20aaf77db8a07488d9 100644 --- a/mysql/migration/2.6.0-2.7.0.sql +++ b/mysql/migration/2.6.0-2.7.0.sql @@ -172,8 +172,3 @@ alter table llx_commande_fournisseur add column ref_supplier varchar(30 alter table llx_mailing add column bgcolor varchar(8) after body; alter table llx_mailing add column bgimage varchar(255) after bgcolor; - --- Request to clean corrupted database -delete from llx_facture where facnumber = '(PROV)'; -delete from llx_commande where ref = '(PROV)'; -delete from llx_propal where ref = '(PROV)'; diff --git a/mysql/migration/repair.sql b/mysql/migration/repair.sql new file mode 100644 index 0000000000000000000000000000000000000000..e8ed4eba1f62371648fedb8d0d568caca2e2f86c --- /dev/null +++ b/mysql/migration/repair.sql @@ -0,0 +1,13 @@ +-- +-- $Id$ +-- +-- Script to repair some fatal errors due to database corruption +-- +-- when current version is 2.6.0 or higher. +-- + + +-- Request to clean corrupted database +delete from llx_facture where facnumber = '(PROV)'; +delete from llx_commande where ref = '(PROV)'; +delete from llx_propal where ref = '(PROV)';