function maj_vieille_base_13000_create($serveur='') { global $tables_principales, $tables_auxiliaires; // Note: les mises a jour reexecutent ce code pour s'assurer // de la conformite de la base // pas de panique sur "already exists" et "duplicate entry" donc. foreach($tables_principales as $k => $v) creer_ou_upgrader_table($k,$v,true,false,$serveur); foreach($tables_auxiliaires as $k => $v) creer_ou_upgrader_table($k,$v,false,false,$serveur); }
function alterer_base($tables_inc, $tables_noinc, $up=false, $serveur='') { if ($up === false) { $old = false; $up = array(); } else { $old = true; if (!is_array($up)) $up = array($up); } foreach($tables_inc as $k => $v) if (!$old OR in_array($k, $up)) creer_ou_upgrader_table($k,$v,true,$old,$serveur); foreach($tables_noinc as $k => $v) if (!$old OR in_array($k, $up)) creer_ou_upgrader_table($k,$v,false,$old,$serveur); }
/** * Preparer la table dans la base de destination : * la droper si elle existe (sauf si auteurs ou meta sur le serveur principal) * la creer si necessaire, ou ajouter simplement les champs manquants * * @param string $table * @param array $desc * @param string $serveur_dest * @param bool $init * @return array */ function base_preparer_table_dest($table, $desc, $serveur_dest, $init = false) { $upgrade = false; // si la table existe et qu'on est a l'init, la dropper if ($desc_dest = sql_showtable($table, true, $serveur_dest) and $init) { if ($serveur_dest == '' and in_array($table, array('spip_meta', 'spip_auteurs'))) { // ne pas dropper auteurs et meta sur le serveur principal // faire un simple upgrade a la place // pour ajouter les champs manquants $upgrade = true; // coherence avec le drop sur les autres tables base_vider_tables_destination_copie(array($table), array(), $serveur_dest); if ($table == 'spip_meta') { // virer les version base qui vont venir avec l'import sql_delete($table, "nom like '%_base_version'", $serveur_dest); // hum casse la base si pas version_installee a l'import ... sql_delete($table, "nom='version_installee'", $serveur_dest); } } else { sql_drop_table($table, '', $serveur_dest); spip_log("drop table '{$table}' sur serveur '{$serveur_dest}'", 'dump.' . _LOG_INFO_IMPORTANTE); } $desc_dest = false; } // si la table n'existe pas dans la destination, la creer a l'identique ! if (!$desc_dest) { spip_log("creation '{$table}' sur serveur '{$serveur_dest}'", 'dump.' . _LOG_INFO_IMPORTANTE); include_spip('base/create'); creer_ou_upgrader_table($table, $desc, 'auto', $upgrade, $serveur_dest); $desc_dest = sql_showtable($table, true, $serveur_dest); } if (!$desc_dest) { spip_log("Erreur creation '{$table}' sur serveur '{$serveur_dest}'" . var_export($desc, 1), 'dump.' . _LOG_ERREUR); } return $desc_dest; }
/** * Créer les champs extras (colonnes en base de données) * definies par le lot de saisies donné * * @param string $table * Nom de la table SQL * @param array $saisies * Description des saisies * @return bool|void * False si pas de table ou aucune saisie de type SQL **/ function champs_extras_creer($table, $saisies) { if (!$table) { return false; } if (!is_array($saisies) or !count($saisies)) { return false; } // uniquement les saisies décrivant SQL $saisies = champs_extras_saisies_lister_avec_sql($saisies); if (!$saisies) { return false; } $desc = lister_tables_objets_sql($table); // parcours des saisies et ajout des champs extras nouveaux dans // la description de la table foreach ($saisies as $saisie) { $nom = $saisie['options']['nom']; // le champ ne doit pas deja exister ! if (!isset($desc['field'][$nom])) { $desc['field'][$nom] = $saisie['options']['sql']; } } // executer la mise a jour include_spip('base/create'); creer_ou_upgrader_table($table, $desc, true, true); }
/** * Une fonction pour installer une table de configuration supplementaire * @param string $table */ function installer_table_meta($table) { $trouver_table = charger_fonction('trouver_table', 'base'); if (!$trouver_table("spip_{$table}")) { include_spip('base/auxiliaires'); include_spip('base/create'); creer_ou_upgrader_table("spip_{$table}", $GLOBALS['tables_auxiliaires']['spip_meta'], false, false); $trouver_table(''); } lire_metas($table); }
/** * Mise à jour des tables de liens * * Crée la table de lien au nouveau format (spip_xx_liens) ou insère * les données d'ancien format dans la nouveau format. * * Par exemple pour réunir en une seule table les liens de documents, * spip_documents_articles et spip_documents_forum * * Supprime la table au vieux format une fois les données transférées. * * @uses creer_ou_upgrader_table() * @uses maj_liens_insertq_multi_check() * * @param string $pivot * Nom de la table pivot, tel que `auteur` * @param string $l * Vide : crée la table de lien pivot. * Sinon, nom de la table à lier, tel que `article`, et dans ce cas là, * remplit spip_auteurs_liens à partir de spip_auteurs_articles. */ function maj_liens($pivot, $l = '') { @define('_LOG_FILTRE_GRAVITE', 8); $exceptions_pluriel = array('forum' => 'forum', 'syndic' => 'syndic'); $pivot = preg_replace(',[^\\w],', '', $pivot); // securite $pivots = isset($exceptions_pluriel[$pivot]) ? $exceptions_pluriel[$pivot] : $pivot . "s"; $liens = "spip_" . $pivots . "_liens"; $id_pivot = "id_" . $pivot; // Creer spip_auteurs_liens global $tables_auxiliaires; if (!$l) { include_spip('base/auxiliaires'); include_spip('base/create'); creer_ou_upgrader_table($liens, $tables_auxiliaires[$liens], false); } else { // Preparer $l = preg_replace(',[^\\w],', '', $l); // securite $primary = "id_{$l}"; $objet = $l == 'syndic' ? 'site' : $l; $ls = isset($exceptions_pluriel[$l]) ? $exceptions_pluriel[$l] : $l . "s"; $ancienne_table = 'spip_' . $pivots . '_' . $ls; $pool = 400; $trouver_table = charger_fonction('trouver_table', 'base'); if (!($desc = $trouver_table($ancienne_table))) { return; } // securite pour ne pas perdre de donnees if (!$trouver_table($liens)) { return; } $champs = $desc['field']; if (isset($champs['maj'])) { unset($champs['maj']); } if (isset($champs[$primary])) { unset($champs[$primary]); } $champs = array_keys($champs); // ne garder que les champs qui existent sur la table destination if ($desc_cible = $trouver_table($liens)) { $champs = array_intersect($champs, array_keys($desc_cible['field'])); } $champs[] = "{$primary} as id_objet"; $champs[] = "'{$objet}' as objet"; $champs = implode(', ', $champs); // Recopier les donnees $sub_pool = 100; while ($ids = array_map('reset', sql_allfetsel("{$primary}", $ancienne_table, '', '', '', "0,{$sub_pool}"))) { $insert = array(); foreach ($ids as $id) { $n = sql_countsel($liens, "objet='{$objet}' AND id_objet=" . intval($id)); while ($t = sql_allfetsel($champs, $ancienne_table, "{$primary}=" . intval($id), '', $id_pivot, "{$n},{$pool}")) { $n += count($t); // empiler en s'assurant a minima de l'unicite while ($r = array_shift($t)) { $insert[$r[$id_pivot] . ':' . $r['id_objet']] = $r; } if (count($insert) >= $sub_pool) { maj_liens_insertq_multi_check($liens, $insert, $tables_auxiliaires[$liens]); $insert = array(); } // si timeout, sortir, la relance nous ramenera dans cette fonction // et on verifiera/repartira de la if (time() >= _TIME_OUT) { return; } } if (time() >= _TIME_OUT) { return; } } if (count($insert)) { maj_liens_insertq_multi_check($liens, $insert, $tables_auxiliaires[$liens]); } sql_delete($ancienne_table, sql_in($primary, $ids)); } } }
/** * Preparer la table dans la base de destination : * la droper si elle existe (sauf si auteurs ou meta sur le serveur principal) * la creer si necessaire, ou ajouter simplement les champs manquants * * @param string $table * @param array $desc * @param string $serveur_dest * @param bool $init * @return array */ function base_preparer_table_dest($table, $desc, $serveur_dest, $init=false) { $upgrade = false; // si la table existe et qu'on est a l'init, la dropper if ($desc_dest=sql_showtable($table,true,$serveur_dest) AND $init) { if ($serveur_dest=='' AND in_array($table,array('spip_meta','spip_auteurs'))) { // ne pas dropper auteurs et meta sur le serveur principal // faire un simple upgrade a la place // pour ajouter les champs manquants $upgrade = true; // coherence avec le drop sur les autres tables base_vider_tables_destination_copie(array($table),array(),$serveur_dest); if ($table=='spip_meta'){ // virer les version base qui vont venir avec l'import sql_delete($table, "nom like '%_base_version'",$serveur_dest); // hum casse la base si pas version_installee a l'import ... sql_delete($table, "nom='version_installee'",$serveur_dest); } } else { sql_drop_table($table, '', $serveur_dest); spip_log( "drop table '$table' sur serveur '$serveur_dest'",'dump.'._LOG_INFO_IMPORTANTE); } $desc_dest = false; } // si la table n'existe pas dans la destination, la creer a l'identique ! if (!$desc_dest) { spip_log( "creation '$table' sur serveur '$serveur_dest'",'dump.'._LOG_INFO_IMPORTANTE); include_spip('base/create'); // on fait la detection d'autoinc ici car creer_ou_upgrader_table ne sait pas forcement le faire // (depend de la version de SPIP) if (isset($GLOBALS['tables_principales'][$table])) $autoinc = true; elseif (isset($GLOBALS['tables_auxiliaires'][$table])) $autoinc = false; else { // essayer de faire au mieux ! $autoinc = (isset($desc['key']['PRIMARY KEY']) AND strpos($desc['key']['PRIMARY KEY'],',')===false AND strpos($desc['field'][$desc['key']['PRIMARY KEY']],'default')===false); } creer_ou_upgrader_table($table, $desc, $autoinc, $upgrade,$serveur_dest); $desc_dest = sql_showtable($table,false,$serveur_dest); // si c'est une table de liens ancienne mode il faut aussi vider xx_liens si elle existe // (migration d'un SPIP 2 vers un SPIP 3 peuple) if (preg_match(",^spip_(auteurs|documents|mots)_(\w+)$,",$table,$m) AND $m[2]!="liens"){ base_vider_tables_destination_copie(array("spip_".$m[1]."_liens"),array(),$serveur_dest); } } if (!$desc_dest){ spip_log( "Erreur creation '$table' sur serveur '$serveur_dest'".var_export($desc,1),'dump.'._LOG_ERREUR); } return $desc_dest; }