[ Index ]
 

Code source de SPIP 1.9.2c

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/ecrire/base/ -> db_mysql.php (source)

   1  <?php
   2  
   3  /***************************************************************************\
   4   *  SPIP, Systeme de publication pour l'internet                           *
   5   *                                                                         *
   6   *  Copyright (c) 2001-2007                                                *
   7   *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
   8   *                                                                         *
   9   *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
  10   *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
  11  \***************************************************************************/
  12  
  13  if (!defined("_ECRIRE_INC_VERSION")) return;
  14  
  15  //constantes spip pour spip_fetch_array()
  16  define('SPIP_BOTH', MYSQL_BOTH);
  17  define('SPIP_ASSOC', MYSQL_ASSOC);
  18  define('SPIP_NUM', MYSQL_NUM);
  19  
  20  //
  21  // Appel de requetes SQL
  22  //
  23  
  24  // fonction pour la premiere connexion
  25  
  26  // http://doc.spip.org/@base_db_mysql_dist
  27  function base_db_mysql_dist()
  28  {
  29      // fichier d'init present ?
  30      if (!_FILE_CONNECT) {
  31          if ($GLOBALS['exec'] != 'install') // est-ce l'installation ?
  32              return false; // non, faut faire sans
  33          else  return 'spip_query_db'; // oui; valeur d'office
  34      }
  35  
  36      include_once(_FILE_CONNECT); 
  37      if (!$GLOBALS['db_ok']) return false;
  38  
  39      // Version courante = 0.3
  40      //
  41      // les versions 0.1 et 0.2 fonctionnent toujours, meme si :
  42      // - la version 0.1 est moins performante que la 0.2
  43      // - la 0.2 fait un include_ecrire('inc_db_mysql.php3')
  44      // En tout cas on ne force pas la mise a niveau
  45      if ($GLOBALS['spip_connect_version'] >= 0.1)
  46          return 'spip_query_db';
  47  
  48      // La version 0.0 (non numerotee) doit etre refaite par un admin
  49  
  50      if (!_DIR_RESTREINT) return false;
  51  
  52      include_spip('inc/headers');
  53      redirige_par_entete(generer_url_ecrire('upgrade', 'reinstall=oui', true));
  54  }
  55  
  56  // http://doc.spip.org/@spip_query_db
  57  function spip_query_db($query) {
  58  
  59      $query = traite_query($query);
  60  
  61      $start = (isset($_GET['var_profile'])
  62          AND isset($GLOBALS['auteur_session']['statut'])
  63          AND ($GLOBALS['auteur_session']['statut'] == '0minirezo')
  64          ) ? microtime() : 0;
  65  
  66      return spip_mysql_trace($query, 
  67                  $start,
  68           (($GLOBALS['mysql_rappel_connexion'] AND $GLOBALS['spip_mysql_link']) ?
  69              mysql_query($query, $GLOBALS['spip_mysql_link']) :
  70              mysql_query($query)));
  71  }
  72  
  73  // http://doc.spip.org/@spip_mysql_trace
  74  function spip_mysql_trace($query, $start, $result)
  75  {
  76      $s = mysql_errno();
  77  
  78      if ($start) spip_mysql_timing($start, microtime(), $query, $result);
  79  
  80      if ($s) {
  81          $s .= ' '.mysql_error();
  82          if ($GLOBALS['mysql_debug']
  83          AND (isset($GLOBALS['auteur_session']['statut']))
  84          AND ($GLOBALS['auteur_session']['statut'] == '0minirezo')) {
  85              include_spip('public/debug');
  86              echo _T('info_erreur_requete'),
  87                " ",
  88                htmlentities($query),
  89                "<br />&laquo; ",
  90                htmlentities($result = $s),
  91                " &raquo;<p>";
  92          }
  93          spip_log($GLOBALS['REQUEST_METHOD'].' '.$GLOBALS['REQUEST_URI'], 'mysql');
  94          spip_log("$result - $query", 'mysql');
  95          spip_log($s, 'mysql');
  96      }
  97      return $result;
  98  }
  99  
 100  // http://doc.spip.org/@spip_mysql_timing
 101  function spip_mysql_timing($m1, $m2, $query, $result)
 102  {
 103      static $tt = 0;
 104      list($usec, $sec) = explode(" ", $m1);
 105      list($usec2, $sec2) = explode(" ", $m2);
 106       $dt = $sec2 + $usec2 - $sec - $usec;
 107      $tt += $dt;
 108      echo "<small>", htmlentities($query), " -> <span style='color: blue'>", sprintf("%3f", $dt),"</span> (", $tt, ")</small> $result<p>\n";
 109  }
 110  
 111  // fonction appelant la precedente  specifiquement pour l'espace public
 112  // c'est une instance de spip_abstract_select, voir ses specs dans abstract.php
 113  // traite_query pourrait y est fait d'avance, à moindre cout.
 114  // Les \n et \t sont utiles au debusqueur.
 115  
 116  // La parametre sous_requete n'est plus utilise
 117  
 118  // http://doc.spip.org/@spip_mysql_select
 119  function spip_mysql_select($select, $from, $where,
 120                 $groupby, $orderby, $limit,
 121                 $sousrequete, $having,
 122                 $table, $id, $server) {
 123  
 124      $query = (!is_array($select) ? $select : join(", ", $select)) .
 125          (!$from ? '' :
 126              ("\nFROM " .
 127              (!is_array($from) ? $from : spip_select_as($from))))
 128          . (!$where ? '' : ("\nWHERE " . (!is_array($where) ? $where : (join("\n\tAND ", array_map('calculer_where', $where))))))
 129          . ($groupby ? "\nGROUP BY $groupby" : '')
 130          . (!$having ? '' : "\nHAVING " . (!is_array($having) ? $having : (join("\n\tAND ", array_map('calculer_where', $having)))))
 131          . ($orderby ? ("\nORDER BY " . join(", ", $orderby)) : '')
 132          . ($limit ? "\nLIMIT $limit" : '');
 133  
 134      // Erreur ? C'est du debug de squelette, ou une erreur du serveur
 135  
 136      if (isset($GLOBALS['var_mode']) AND $GLOBALS['var_mode'] == 'debug') {
 137          include_spip('public/debug');
 138          boucle_debug_resultat($id, 'requete', "SELECT " . $query);
 139      }
 140  
 141      if (!($res = @spip_query("SELECT ". $query, $server))) {
 142          include_spip('public/debug');
 143          erreur_requete_boucle($query, $id, $table,
 144                        spip_sql_errno(),
 145                        spip_sql_error());
 146      }
 147      return $res;
 148  }
 149  
 150  // http://doc.spip.org/@calculer_where
 151  function calculer_where($v)
 152  {
 153      if (!is_array($v))
 154        return $v ;
 155  
 156      $op = array_shift($v);
 157      if (!($n=count($v)))
 158          return $op;
 159      else {
 160          $arg = calculer_where(array_shift($v));
 161          if ($n==1) {
 162                return "$op($arg)";
 163          } else {
 164              $arg2 = calculer_where(array_shift($v));
 165              if ($n==2) {
 166                  return "($arg $op $arg2)";
 167              } else return "($arg $op ($arg2) : $v[0])";
 168          }
 169      }
 170  }
 171  
 172  // http://doc.spip.org/@spip_select_as
 173  function spip_select_as($args)
 174  {
 175      $argsas = "";
 176      foreach($args as $k => $v) {
 177          $argsas .= ', ' . $v . (is_numeric($k) ? '' : " AS `$k`");
 178      }
 179      return substr($argsas,2);
 180  }
 181  
 182  //
 183  // Passage d'une requete standardisee
 184  // Quand tous les appels SQL seront abstraits on pourra l'ameliorer
 185  
 186  // http://doc.spip.org/@traite_query
 187  function traite_query($query) {
 188      if ($GLOBALS['table_prefix']) $table_pref = $GLOBALS['table_prefix']."_";
 189      else $table_pref = "";
 190  
 191      if ($GLOBALS['mysql_rappel_nom_base'] AND $db = $GLOBALS['spip_mysql_db'])
 192          $db = '`'.$db.'`.';
 193  
 194      // changer les noms des tables ($table_prefix)
 195      if (preg_match('/\s(SET|VALUES|WHERE)\s/i', $query, $regs)) {
 196          $suite = strstr($query, $regs[0]);
 197          $query = substr($query, 0, -strlen($suite));
 198      } else $suite ='';
 199      return preg_replace('/([,\s])spip_/', '\1'.$db.$table_pref, $query) . $suite;
 200  }
 201  
 202  //
 203  // Fonction appelee uniquement par le fichier FILE_CONNECT cree a l'installation, 
 204  // et comportant les identifants de connexion SQL
 205  // db_ok est globale, pour test par base_db_mysql_dist ci-dessus
 206  // Ce serait plus propre de reduire FILE_CONNECT a un fichier de donnees
 207  // et d'appeler cette fonction a partir de base_db_mysql_dist.
 208  
 209  // http://doc.spip.org/@spip_connect_db
 210  function spip_connect_db($host, $port, $login, $pass, $db) {
 211      global $spip_mysql_link, $spip_mysql_db;    // pour connexions multiples
 212  
 213      // gerer le fichier tmp/mysql_out
 214      ## TODO : ajouter md5(parametres de connexion)
 215      if (@file_exists(_DIR_TMP.'mysql_out')
 216      AND (time() - @filemtime(_DIR_TMP.'mysql_out') < 30)
 217      AND !defined('_ECRIRE_INSTALL'))
 218          return $GLOBALS['db_ok'] = false;
 219  
 220      if ($port > 0) $host = "$host:$port";
 221      $spip_mysql_link = @mysql_connect($host, $login, $pass);
 222      $spip_mysql_db = $db;
 223      $ok = @mysql_select_db($db);
 224  
 225      if (defined('_MYSQL_SQL_MODE_TEXT_NOT_NULL'))
 226          mysql_query("set sql_mode=''");
 227  
 228      $GLOBALS['db_ok'] = $ok
 229      AND !!@spip_num_rows(@spip_query_db('SELECT COUNT(*) FROM spip_meta'));
 230  
 231      // En cas d'erreur marquer le fichier mysql_out
 232      if (!$GLOBALS['db_ok']
 233      AND !defined('_ECRIRE_INSTALL')) {
 234          @touch(_DIR_TMP.'mysql_out');
 235          $err = 'Echec connexion MySQL '.spip_sql_errno().' '.spip_sql_error();
 236          spip_log($err);
 237          spip_log($err, 'mysql');
 238      } else $GLOBALS['db_ok'] = 'spip_query_db';
 239      return $GLOBALS['db_ok'];
 240  }
 241  
 242  // Fonction de creation d'une table SQL nommee $nom
 243  // a partir de 2 tableaux PHP :
 244  // champs: champ => type
 245  // cles: type-de-cle => champ(s)
 246  // si $autoinc, c'est une auto-increment (i.e. serial) sur la Primary Key
 247  // Le nom des caches doit etre inferieur a 64 caracteres
 248  
 249  // http://doc.spip.org/@spip_mysql_create
 250  function spip_mysql_create($nom, $champs, $cles, $autoinc=false, $temporary=false) {
 251      $query = ''; $keys = ''; $s = ''; $p='';
 252  
 253      // certains plugins declarent les tables  (permet leur inclusion dans le dump)
 254      // sans les renseigner (laisse le compilo recuperer la description)
 255      if (!is_array($champs) || !is_array($cles)) 
 256          return;
 257  
 258      foreach($cles as $k => $v) {
 259          $keys .= "$s\n\t\t$k ($v)";
 260          if ($k == "PRIMARY KEY")
 261              $p = $v;
 262          $s = ",";
 263      }
 264      $s = '';
 265  
 266      foreach($champs as $k => $v) {
 267          $query .= "$s\n\t\t$k $v" .
 268          (($autoinc && ($p == $k)) ? " auto_increment" : '');
 269          $s = ",";
 270      }
 271      $temporary = $temporary ? 'TEMPORARY':'';
 272      spip_query_db("CREATE $temporary TABLE IF NOT EXISTS $nom ($query" . ($keys ? ",$keys" : '') . ")\n");
 273  }
 274  
 275  // http://doc.spip.org/@spip_mysql_showtable
 276  function spip_mysql_showtable($nom_table)
 277  {
 278      $a = spip_query("SHOW TABLES LIKE '$nom_table'");
 279      if (!$a) return "";
 280      if (!spip_fetch_array($a)) return "";
 281      list(,$a) = spip_fetch_array(spip_query("SHOW CREATE TABLE $nom_table"),SPIP_NUM);
 282      if (!preg_match("/^[^(),]*\((([^()]*\([^()]*\)[^()]*)*)\)[^()]*$/", $a, $r))
 283          return "";
 284      else {
 285          $dec = $r[1];
 286          if (preg_match("/^(.*?),([^,]*KEY.*)$/s", $dec, $r)) {
 287              $namedkeys = $r[2];
 288              $dec = $r[1];
 289          }
 290          else 
 291              $namedkeys = "";
 292  
 293          $fields = array();
 294          foreach(preg_split("/,\s*`/",$dec) as $v) {
 295              preg_match("/^\s*`?([^`]*)`\s*(.*)/",$v,$r);
 296              $fields[strtolower($r[1])] = $r[2];
 297          }
 298          $keys = array();
 299  
 300          foreach(preg_split('/\)\s*,?/',$namedkeys) as $v) {
 301              if (preg_match("/^\s*([^(]*)\((.*)$/",$v,$r)) {
 302                  $k = str_replace("`", '', trim($r[1]));
 303                  $t = strtolower(str_replace("`", '', $r[2]));
 304                  if ($k && !isset($keys[$k])) $keys[$k] = $t; else $keys[] = $t;
 305              }
 306          }
 307          return array('field' => $fields,    'key' => $keys);
 308      }
 309  } 
 310  
 311  //
 312  // Recuperation des resultats
 313  //
 314  
 315  // interface de abstract_sql.
 316  
 317  // http://doc.spip.org/@spip_mysql_fetch
 318  function spip_mysql_fetch($r, $t=SPIP_ASSOC) {
 319      if ($r) return mysql_fetch_array($r, $t);
 320  }
 321  
 322  // http://doc.spip.org/@spip_fetch_array
 323  function spip_fetch_array($r, $t=SPIP_ASSOC) {
 324      if ($r) return mysql_fetch_array($r, $t);
 325  }
 326  
 327  // http://doc.spip.org/@spip_sql_error
 328  function spip_sql_error() {
 329      return mysql_error();
 330  }
 331  
 332  // http://doc.spip.org/@spip_sql_errno
 333  function spip_sql_errno() {
 334      return mysql_errno();
 335  }
 336  
 337  // Interface de abstract_sql
 338  // http://doc.spip.org/@spip_mysql_count
 339  function spip_mysql_count($r) {
 340      if ($r)    return mysql_num_rows($r);
 341  }
 342  
 343  // http://doc.spip.org/@spip_num_rows
 344  function spip_num_rows($r) {
 345      if ($r)    return mysql_num_rows($r);
 346  }
 347  
 348  // Interface de abstract_sql (on est sur de l'argument, c'est le compilateur)
 349  
 350  // http://doc.spip.org/@spip_mysql_free
 351  function spip_mysql_free($r) {
 352      return mysql_free_result($r);
 353  }
 354  
 355  // Vieux nom a laisser tomber
 356  // http://doc.spip.org/@spip_free_result
 357  function spip_free_result($r) {
 358      if ($r)    return mysql_free_result($r);
 359  }
 360  
 361  // http://doc.spip.org/@spip_mysql_insert
 362  function spip_mysql_insert($table, $champs, $valeurs) {
 363      spip_query("INSERT INTO $table $champs VALUES $valeurs");
 364      return  mysql_insert_id();
 365  }
 366  
 367  // http://doc.spip.org/@spip_insert_id
 368  function spip_insert_id() {
 369      return mysql_insert_id();
 370  }
 371  
 372  //
 373  // Poser un verrou local a un SPIP donne
 374  //
 375  // http://doc.spip.org/@spip_get_lock
 376  function spip_get_lock($nom, $timeout = 0) {
 377      global $spip_mysql_db, $table_prefix;
 378      if ($table_prefix) $nom = "$table_prefix:$nom";
 379      if ($spip_mysql_db) $nom = "$spip_mysql_db:$nom";
 380  
 381      // Changer de nom toutes les heures en cas de blocage MySQL (ca arrive)
 382      define('_LOCK_TIME', intval(time()/3600-316982));
 383      $nom .= _LOCK_TIME;
 384  
 385      $q = spip_query("SELECT GET_LOCK(" . _q($nom) . ", $timeout)");
 386      list($lock_ok) = spip_fetch_array($q,SPIP_NUM);
 387  
 388      if (!$lock_ok) spip_log("pas de lock sql pour $nom");
 389      return $lock_ok;
 390  }
 391  
 392  // http://doc.spip.org/@spip_release_lock
 393  function spip_release_lock($nom) {
 394      global $spip_mysql_db, $table_prefix;
 395      if ($table_prefix) $nom = "$table_prefix:$nom";
 396      if ($spip_mysql_db) $nom = "$spip_mysql_db:$nom";
 397  
 398      $nom .= _LOCK_TIME;
 399  
 400      spip_query("SELECT RELEASE_LOCK(" . _q($nom) . ")");
 401  }
 402  
 403  // http://doc.spip.org/@spip_mysql_version
 404  function spip_mysql_version() {
 405      $row = spip_fetch_array(spip_query("SELECT version() AS n"));
 406      return ($row['n']);
 407  }
 408  
 409  // http://doc.spip.org/@creer_objet_multi
 410  function creer_objet_multi ($objet, $lang) {
 411      $retour = "(TRIM(IF(INSTR(".$objet.", '<multi>') = 0 , ".
 412          "     TRIM(".$objet."), ".
 413          "     CONCAT( ".
 414          "          LEFT(".$objet.", INSTR(".$objet.", '<multi>')-1), ".
 415          "          IF( ".
 416          "               INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))),'[".$lang."]') = 0, ".
 417          "               IF( ".
 418          "                     TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))) REGEXP '^\\[[a-z\_]{2,}\\]', ".
 419          "                     INSERT( ".
 420          "                          TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))), ".
 421          "                          1, ".
 422          "                          INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))), ']'), ".
 423          "                          '' ".
 424          "                     ), ".
 425          "                     TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '<multi>')))) ".
 426          "                ), ".
 427          "               TRIM(RIGHT(".$objet.", ( LENGTH(".$objet.") - (INSTR(".$objet.", '[".$lang."]')+ LENGTH('[".$lang."]')-1) ) )) ".
 428          "          ) ".
 429          "     ) ".
 430          "))) AS multi ";
 431  
 432      return $retour;
 433  }
 434  
 435  
 436  ?>


Généré le : Wed Nov 21 10:20:27 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics