From fc2537b7ea6160b341dd1cbab1258ebaa46cf8a6 Mon Sep 17 00:00:00 2001 From: "Committo,Ergo:sum" <esj@rezo.net> Date: Wed, 31 Oct 2007 13:22:00 +0000 Subject: [PATCH] Introduction d'un gestionnaire de version d'interface SQL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Afin de prévenir les désagréments d'éventuels changements de spécification, l'interface de SPIP aux serveurs SQL inrègre d'emblée un gestionnaire de versions, permettant à une même connexcion SQL d'être exploitée {simultanément} par plusieurs versions des fonctions d'abstraction. Et également fourni un script rendant automatiquement compatibles des extensions fondées sur d'anciennes versions de l'interface. Principe. Toutes les fonctions de l'interface sont définies dans le fichier (((ecrire/base/abstract_sql))), se nomment {{{sql_}}}{X} et sont les seules à se nommées ainsi. Elles se connectent toutes en appelant une fonction dont le premier argument est le numéro de version de l'interface. Le jour où une nouvelle version de (((ecrire/base/abstract_sql))) apparaitra nécessaire, la version courante sera renommée {{{abstract_sql_}}}{{N}}, et le Sed suivant lui sera appliqué ({{{N}}} désigne le numéro de version): {{{ s/\(sql_[A-Za-z_0-9 ]*\)/\1_N/ }}} En appliquant également ce script aux extensions de SPIP fondées sur cette version, on leur permettra d'en appeler ses fonctions, qui seront chargées sans collision de noms, le Sed ayant préfixé le noms des anciennes avec leur numéro de version. Il faudra juste rajouter une instruction {{{include}}} portant sur le fichier {{{abstract_sql_}}}{{N}}. Ce service repose sur la réservation des noms commençant par {{{sql_}}} aux seules fonctions d'interface, grâce aux renommages effectués en [9916] [9918] et [9919]. Les extensions de SPIP doivent respecter cette contrainte s'ils veulent en bénéficier. Le présent dépot consiste en une reconception de la sructure de données décrivant une connexion, afin d'associer plusieurs jeux de fonction à une même connexion. --- ecrire/base/abstract_sql.php | 29 +++++------ ecrire/inc/utils.php | 91 ++++++++++++++++++++++++----------- ecrire/inc_version.php | 3 ++ ecrire/install/etape_2.php | 3 ++ ecrire/install/etape_3.php | 8 +-- ecrire/install/etape_sup1.php | 3 ++ ecrire/install/etape_sup2.php | 3 ++ ecrire/req/mysql.php | 5 +- ecrire/req/pg.php | 7 ++- 9 files changed, 102 insertions(+), 50 deletions(-) diff --git a/ecrire/base/abstract_sql.php b/ecrire/base/abstract_sql.php index c64d415655..5ec184d921 100644 --- a/ecrire/base/abstract_sql.php +++ b/ecrire/base/abstract_sql.php @@ -12,35 +12,32 @@ if (!defined("_ECRIRE_INC_VERSION")) return; +define('sql_ABSTRACT_VERSION', 1); + // Ce fichier definit la couche d'abstraction entre SPIP et ses serveurs SQL. -// Cette couche n'est pour le moment qu'un ensemble de fonctions ecrites -// rapidement pour generaliser le code strictement MySQL de SPIP < 1.9.3. +// Cette version 1 est un ensemble de fonctions ecrites rapidement +// pour generaliser le code strictement MySQL de SPIP < 1.9.3. // Des retouches sont a prevoir apres l'experience des premiers portages. +// Les symboles sql_* (constantes et nom de fonctions) sont reserves +// a cette interface, sans quoi le gestionnaire de version dysfonctionnera. -// Cette fonction charge la description d'un serveur de base de donnees -// (via la fonction spip_connect qui etablira la connexion si ce n'est fait) -// et retourne la fonction produisant la requête SQL demandee +// Fonction principale. Elle charge l'interface au serveur de base de donnees +// via la fonction spip_connect_version qui etablira la connexion au besoin. +// Elle retourne la fonction produisant la requête SQL demandee // Erreur fatale si la fonctionnalite est absente sauf si le 3e arg <> false // http://doc.spip.org/@sql_serveur function sql_serveur($ins_sql='', $serveur='', $continue=false) { - - $desc = spip_connect($serveur); - if (function_exists($f = @$desc[$ins_sql])) return $f; - if ($ins_sql) - spip_log("Le serveur '$serveur' n'a pas '$ins_sql'"); - if ($continue) return $desc; - include_spip('inc/minipres'); - echo minipres(_T('info_travaux_titre'), _T('titre_probleme_technique')); - exit; + return spip_connect_sql(sql_ABSTRACT_VERSION, $ins_sql, $serveur, $continue); } // Demande si un charset est disponible. // http://doc.spip.org/@sql_get_charset function sql_get_charset($charset, $serveur=''){ // le nom http du charset differe parfois du nom SQL utf-8 ==> utf8 etc. - $desc = spip_connect($serveur); - $c = @$desc['charsets'][$charset]; + $desc = sql_serveur('', $serveur, true); + $desc = $desc[sql_ABSTRACT_VERSION]; + $c = $desc['charsets'][$charset]; if ($c) { if (function_exists($f=@$desc['get_charset'])) if ($f($c, $serveur)) return $c; diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php index 43d821784f..1e27395a0e 100644 --- a/ecrire/inc/utils.php +++ b/ecrire/inc/utils.php @@ -229,40 +229,58 @@ function spip_connect_db($host, $port, $login, $pass, $db='', $type='mysql', $pr } // API d'appel aux bases de donnees: -// on charge le fichier config/connect$serveur ($serveur='' pour le principal) +// on charge le fichier config/$serveur ($serveur='connect' pour le principal) // qui est cense initaliser la connexion en appelant spip_connect_db // laquelle met dans la globale db_ok la description de la connexion // On la memorise dans un tableau pour permettre plusieurs serveurs. // A l'installation, il faut simuler l'existence de ce fichier // http://doc.spip.org/@spip_connect -function spip_connect($serveur='') { - global $connexions; +function spip_connect($serveur='', $version='') { + global $connexions, $spip_sql_version; $index = $serveur ? $serveur : 0; - if (isset($connexions[$index])) return $connexions[$index]; + if (!$version) $version = $spip_sql_version; + if (isset($connexions[$index][$version])) return $connexions[$index]; include_spip('base/abstract_sql'); if (isset($_GET['var_profile'])) include_spip('public/debug'); $install = (_request('exec') == 'install'); - $f = (!preg_match('/^\w*$/', $serveur)) ? '' - : (($serveur AND !$install) ? - ( _DIR_CONNECT. $serveur . '.php') - : (_FILE_CONNECT ? _FILE_CONNECT - : ($install ? _FILE_CONNECT_TMP : ''))); - - unset($GLOBALS['db_ok']); - unset($GLOBALS['spip_connect_version']); - if ($f AND is_readable($f)) include($f); - if (!isset($GLOBALS['db_ok'])) { - if ($install) return false; // fera mieux la prochaine fois - spip_log("spip_connect: serveur $index mal defini dans '$f'."); - // ne plus reessayer si ce n'est pas l'install - return $connexions[$index]=false; + // Premiere connexion ? + if (!($old = isset($connexions[$index]))) { + $f = (!preg_match('/^\w*$/', $serveur)) ? '' + : (($serveur AND !$install) ? + ( _DIR_CONNECT. $serveur . '.php') + : (_FILE_CONNECT ? _FILE_CONNECT + : ($install ? _FILE_CONNECT_TMP : ''))); + + unset($GLOBALS['db_ok']); + unset($GLOBALS['spip_connect_version']); + if ($f AND is_readable($f)) include($f); + if (!isset($GLOBALS['db_ok'])) { + // fera mieux la prochaine fois + if ($install) return false; + spip_log("spip_connect: serveur $index mal defini dans '$f'."); + // ne plus reessayer si ce n'est pas l'install + return $connexions[$index]=false; + } + $connexions[$index] = $GLOBALS['db_ok']; + } + // la connexion a reussi ou etait deja faite. + // chargement de la version du jeu de fonctions + // si pas dans le fichier par defaut + $type = $GLOBALS['db_ok']['type']; + $jeu = 'spip_' . $type .'_functions_' . $version; + if (!isset($GLOBALS[$jeu])) { + if (!include_spip($type . '_' . $version, 'req')) + spip_log("spip_connect: serveur $index version '$version' non defini par $jeu."); + // ne plus reessayer + return $connexions[$index][$version] = array(); } + $connexions[$index][$version] = $GLOBALS[$jeu]; + if ($old) return $connexions[$index]; - $connexions[$index] = $GLOBALS['db_ok']; $connexions[$index]['spip_connect_version'] = isset($GLOBALS['spip_connect_version']) ? $GLOBALS['spip_connect_version'] : 0; // initialisation de l'alphabet utilise dans les connexions SQL @@ -271,7 +289,7 @@ function spip_connect($serveur='') { // s'ils le connaissent if (!$serveur) { - $charset = spip_connect_main($GLOBALS['db_ok']); + $charset = spip_connect_main($GLOBALS[$jeu]); if (!$charset) { unset($connexions[$index]); spip_log("spip_connect: absence de charset"); @@ -282,13 +300,37 @@ function spip_connect($serveur='') { $GLOBALS['meta']['charset_sql_connexion'] : 'utf8'; } if ($charset != -1) { - $f = $GLOBALS['db_ok']['set_charset']; + $f = $GLOBALS[$jeu]['set_charset']; if (function_exists($f)) $f($charset, $serveur); } return $connexions[$index]; } +// Cette fonction ne doit etre appelee qu'a travers la fonction sql_serveur +// definie dans base/abstract_sql +// Elle existe en tant que gestionnaire de versions, +// connue seulement des convertisseurs automatiques + +function spip_connect_sql($version, $ins='', $serveur='', $cont=false) { + $desc = spip_connect($serveur, $version); + if (function_exists($f = @$desc[$version][$ins])) return $f; + if ($ins) + spip_log("Le serveur '$serveur' version $version n'a pas '$ins'"); + if ($cont) return $desc; + include_spip('inc/minipres'); + echo minipres(_T('info_travaux_titre'), _T('titre_probleme_technique')); + exit; +} + +// Ici pour compatibilite. Ne plus utiliser. +// http://doc.spip.org/@spip_query +function spip_query($query, $serveur='') { + global $spip_sql_version; + $f = spip_connect_sql($spip_sql_version, 'query', $serveur, true); + return function_exists($f) ? $f($query, $serveur) : false; +} + // Premiere connexion au serveur principal: // retourner le charset donnee par la table principale // mais verifier que le fichier de connexion n'est pas trop vieux @@ -317,13 +359,6 @@ function spip_connect_main($connexion) return ($r['valeur'] ? $r['valeur'] : -1); } -// http://doc.spip.org/@spip_query -function spip_query($query, $serveur='') { - if (!($desc = spip_connect($serveur))) return false; - $f = $desc['query']; - return $f($query, $serveur); -} - // http://doc.spip.org/@spip_connect_ldap function spip_connect_ldap($serveur='') { $connexion = spip_connect($serveur); diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php index 7268b5e090..70c13e5257 100644 --- a/ecrire/inc_version.php +++ b/ecrire/inc_version.php @@ -288,6 +288,9 @@ $liste_des_statuts = array( // version de la base $spip_version = 1.958; +// version de l'interface a la base +$spip_sql_version = 1; + // version de spip en chaine // et en numerique a incrementer sur les evolutions qui cassent la compatibilite descendante // 1.xxyy : xx00 versions stables publiees, xxyy versions de dev diff --git a/ecrire/install/etape_2.php b/ecrire/install/etape_2.php index 46eb1d7fae..2fb296df42 100644 --- a/ecrire/install/etape_2.php +++ b/ecrire/install/etape_2.php @@ -38,6 +38,9 @@ function install_etape_2_dist() $GLOBALS['connexions'][$server_db] = $link; + $GLOBALS['connexions'][$server_db][$GLOBALS['spip_sql_version']] + = $GLOBALS['spip_' . $server_db .'_functions_' . $GLOBALS['spip_sql_version']]; + echo install_debut_html(); // prenons toutes les dispositions possibles pour que rien ne s'affiche ! diff --git a/ecrire/install/etape_3.php b/ecrire/install/etape_3.php index a32b46402b..57a36ffc60 100644 --- a/ecrire/install/etape_3.php +++ b/ecrire/install/etape_3.php @@ -34,10 +34,13 @@ function install_bases($adresse_db, $login_db, $pass_db, $server_db, $choix_db, $table_prefix = _INSTALL_TABLE_PREFIX; } - $GLOBALS['connexions'][$server_db] = spip_connect_db($adresse_db, 0, $login_db, $pass_db, '', $server_db); + $GLOBALS['connexions'][$server_db] + = spip_connect_db($adresse_db, 0, $login_db, $pass_db, '', $server_db); - $fquery = sql_serveur('query', $server_db); + $GLOBALS['connexions'][$server_db][$GLOBALS['spip_sql_version']] + = $GLOBALS['spip_' . $server_db .'_functions_' . $GLOBALS['spip_sql_version']]; + $fquery = sql_serveur('query', $server_db); if ($choix_db == "new_spip") { if (preg_match(',^[a-z_0-9]+$,i', $sel_db)) $fquery("CREATE DATABASE $sel_db", $server_db); @@ -55,7 +58,6 @@ function install_bases($adresse_db, $login_db, $pass_db, $server_db, $choix_db, // Si possible, demander au serveur d'envoyer les textes // dans le codage std de SPIP, - $charset = sql_get_charset(_DEFAULT_CHARSET, $server_db); if ($charset) { diff --git a/ecrire/install/etape_sup1.php b/ecrire/install/etape_sup1.php index da4292dc53..31991316ce 100644 --- a/ecrire/install/etape_sup1.php +++ b/ecrire/install/etape_sup1.php @@ -48,6 +48,9 @@ function install_etape_sup1_dist() echo install_debut_html(_L("Déclaration d'une base supplémentaire")); $link = spip_connect_db($adresse_db, 0, $login_db, $pass_db, '', $server_db); + $GLOBALS['connexions'][$server_db][$GLOBALS['spip_sql_version']] + = $GLOBALS['spip_' . $server_db .'_functions_' . $GLOBALS['spip_sql_version']]; + if ($link) { $GLOBALS['connexions'][$server_db] = $link; diff --git a/ecrire/install/etape_sup2.php b/ecrire/install/etape_sup2.php index e1b32f1f6a..fed776c051 100644 --- a/ecrire/install/etape_sup2.php +++ b/ecrire/install/etape_sup2.php @@ -21,6 +21,9 @@ function install_bases_sup($adresse_db, $login_db, $pass_db, $server_db, $sup_d return "<!-- connection perdue -->"; + $GLOBALS['connexions'][$server_db][$GLOBALS['spip_sql_version']] + = $GLOBALS['spip_' . $server_db .'_functions_' . $GLOBALS['spip_sql_version']]; + if (!sql_selectdb($sup_db, $server_db)) return "<!-- base inaccessible -->"; diff --git a/ecrire/req/mysql.php b/ecrire/req/mysql.php index d643f9f718..bfbd91b653 100644 --- a/ecrire/req/mysql.php +++ b/ecrire/req/mysql.php @@ -35,6 +35,10 @@ function req_mysql_dist($host, $port, $login, $pass, $db='', $prefixe='', $ldap= 'prefixe' => $prefixe ? $prefixe : $db, 'link' => $GLOBALS['mysql_rappel_connexion'] ? $link : false, 'ldap' => $ldap, + ); +} + +$GLOBALS['spip_mysql_functions_1'] = array( 'alter' => 'spip_mysql_alter', 'count' => 'spip_mysql_count', 'countsel' => 'spip_mysql_countsel', @@ -76,7 +80,6 @@ function req_mysql_dist($host, $port, $login, $pass, $db='', $prefixe='', $ldap= //'iso-8859-15'=>array('charset'=>'latin1','collation'=>'latin1_swedish_ci'), 'utf-8'=>array('charset'=>'utf8','collation'=>'utf8_general_ci')) ); -} // http://doc.spip.org/@spip_mysql_set_charset function spip_mysql_set_charset($charset, $serveur=''){ diff --git a/ecrire/req/pg.php b/ecrire/req/pg.php index 656ac8a7a9..757cd1d957 100644 --- a/ecrire/req/pg.php +++ b/ecrire/req/pg.php @@ -44,7 +44,11 @@ function req_pg_dist($addr, $port, $login, $pass, $db='', $prefixe='', $ldap='') 'db' => $db, 'prefixe' => $prefixe ? $prefixe : $db, 'link' => $link, - 'ldap' => $ldap, + 'ldap' => $ldap + ); +} + +$GLOBALS['spip_pg_functions_1'] = array( 'alter' => 'spip_pg_alter', 'count' => 'spip_pg_count', 'countsel' => 'spip_pg_countsel', @@ -72,7 +76,6 @@ function req_pg_dist($addr, $port, $login, $pass, $db='', $prefixe='', $ldap='') 'update' => 'spip_pg_update', 'updateq' => 'spip_pg_updateq', ); -} // Par ou ca passe une fois les traductions faites // http://doc.spip.org/@spip_pg_trace_query -- GitLab