= 0.1) return 'spip_query_db'; // La version 0.0 (non numerotee) doit etre refaite par un admin if (!_DIR_RESTREINT) return false; include_spip('inc/headers'); redirige_par_entete(generer_url_ecrire('upgrade', 'reinstall=oui', true)); } // http://doc.spip.org/@spip_query_db function spip_query_db($query) { $query = traite_query($query); $start = (isset($_GET['var_profile']) AND isset($GLOBALS['auteur_session']['statut']) AND ($GLOBALS['auteur_session']['statut'] == '0minirezo') ) ? microtime() : 0; return spip_mysql_trace($query, $start, (($GLOBALS['mysql_rappel_connexion'] AND $GLOBALS['spip_mysql_link']) ? mysql_query($query, $GLOBALS['spip_mysql_link']) : mysql_query($query))); } // http://doc.spip.org/@spip_mysql_trace function spip_mysql_trace($query, $start, $result) { $s = mysql_errno(); if ($start) spip_mysql_timing($start, microtime(), $query, $result); if ($s) { $s .= ' '.mysql_error(); if ($GLOBALS['mysql_debug'] AND (isset($GLOBALS['auteur_session']['statut'])) AND ($GLOBALS['auteur_session']['statut'] == '0minirezo')) { include_spip('public/debug'); echo _T('info_erreur_requete'), " ", htmlentities($query), "
« ", htmlentities($result = $s), " »

"; } spip_log($GLOBALS['REQUEST_METHOD'].' '.$GLOBALS['REQUEST_URI'], 'mysql'); spip_log("$result - $query", 'mysql'); spip_log($s, 'mysql'); } return $result; } // http://doc.spip.org/@spip_mysql_timing function spip_mysql_timing($m1, $m2, $query, $result) { static $tt = 0; list($usec, $sec) = explode(" ", $m1); list($usec2, $sec2) = explode(" ", $m2); $dt = $sec2 + $usec2 - $sec - $usec; $tt += $dt; echo "", htmlentities($query), " -> ", sprintf("%3f", $dt)," (", $tt, ") $result

\n"; } // fonction appelant la precedente specifiquement pour l'espace public // c'est une instance de spip_abstract_select, voir ses specs dans abstract.php // traite_query pourrait y est fait d'avance, à moindre cout. // Les \n et \t sont utiles au debusqueur. // La parametre sous_requete n'est plus utilise // http://doc.spip.org/@spip_mysql_select function spip_mysql_select($select, $from, $where, $groupby, $orderby, $limit, $sousrequete, $having, $table, $id, $server) { $query = (!is_array($select) ? $select : join(", ", $select)) . (!$from ? '' : ("\nFROM " . (!is_array($from) ? $from : spip_select_as($from)))) . (!$where ? '' : ("\nWHERE " . (!is_array($where) ? $where : (join("\n\tAND ", array_map('calculer_where', $where)))))) . ($groupby ? "\nGROUP BY $groupby" : '') . (!$having ? '' : "\nHAVING " . (!is_array($having) ? $having : (join("\n\tAND ", array_map('calculer_where', $having))))) . ($orderby ? ("\nORDER BY " . join(", ", $orderby)) : '') . ($limit ? "\nLIMIT $limit" : ''); // Erreur ? C'est du debug de squelette, ou une erreur du serveur if (isset($GLOBALS['var_mode']) AND $GLOBALS['var_mode'] == 'debug') { include_spip('public/debug'); boucle_debug_resultat($id, 'requete', "SELECT " . $query); } if (!($res = @spip_query("SELECT ". $query, $server))) { include_spip('public/debug'); erreur_requete_boucle($query, $id, $table, spip_sql_errno(), spip_sql_error()); } return $res; } // http://doc.spip.org/@calculer_where function calculer_where($v) { if (!is_array($v)) return $v ; $op = array_shift($v); if (!($n=count($v))) return $op; else { $arg = calculer_where(array_shift($v)); if ($n==1) { return "$op($arg)"; } else { $arg2 = calculer_where(array_shift($v)); if ($n==2) { return "($arg $op $arg2)"; } else return "($arg $op ($arg2) : $v[0])"; } } } // http://doc.spip.org/@spip_select_as function spip_select_as($args) { $argsas = ""; foreach($args as $k => $v) { $argsas .= ', ' . $v . (is_numeric($k) ? '' : " AS `$k`"); } return substr($argsas,2); } // // Passage d'une requete standardisee // Quand tous les appels SQL seront abstraits on pourra l'ameliorer // http://doc.spip.org/@traite_query function traite_query($query) { if ($GLOBALS['table_prefix']) $table_pref = $GLOBALS['table_prefix']."_"; else $table_pref = ""; if ($GLOBALS['mysql_rappel_nom_base'] AND $db = $GLOBALS['spip_mysql_db']) $db = '`'.$db.'`.'; // changer les noms des tables ($table_prefix) if (preg_match('/\s(SET|VALUES|WHERE)\s/i', $query, $regs)) { $suite = strstr($query, $regs[0]); $query = substr($query, 0, -strlen($suite)); } else $suite =''; return preg_replace('/([,\s])spip_/', '\1'.$db.$table_pref, $query) . $suite; } // // Fonction appelee uniquement par le fichier FILE_CONNECT cree a l'installation, // et comportant les identifants de connexion SQL // db_ok est globale, pour test par base_db_mysql_dist ci-dessus // Ce serait plus propre de reduire FILE_CONNECT a un fichier de donnees // et d'appeler cette fonction a partir de base_db_mysql_dist. // http://doc.spip.org/@spip_connect_db function spip_connect_db($host, $port, $login, $pass, $db) { global $spip_mysql_link, $spip_mysql_db; // pour connexions multiples // gerer le fichier tmp/mysql_out ## TODO : ajouter md5(parametres de connexion) if (@file_exists(_DIR_TMP.'mysql_out') AND (time() - @filemtime(_DIR_TMP.'mysql_out') < 30) AND !defined('_ECRIRE_INSTALL')) return $GLOBALS['db_ok'] = false; if ($port > 0) $host = "$host:$port"; $spip_mysql_link = @mysql_connect($host, $login, $pass); $spip_mysql_db = $db; $ok = @mysql_select_db($db); if (defined('_MYSQL_SQL_MODE_TEXT_NOT_NULL')) mysql_query("set sql_mode=''"); $GLOBALS['db_ok'] = $ok AND !!@spip_num_rows(@spip_query_db('SELECT COUNT(*) FROM spip_meta')); // En cas d'erreur marquer le fichier mysql_out if (!$GLOBALS['db_ok'] AND !defined('_ECRIRE_INSTALL')) { @touch(_DIR_TMP.'mysql_out'); $err = 'Echec connexion MySQL '.spip_sql_errno().' '.spip_sql_error(); spip_log($err); spip_log($err, 'mysql'); } else $GLOBALS['db_ok'] = 'spip_query_db'; return $GLOBALS['db_ok']; } // Fonction de creation d'une table SQL nommee $nom // a partir de 2 tableaux PHP : // champs: champ => type // cles: type-de-cle => champ(s) // si $autoinc, c'est une auto-increment (i.e. serial) sur la Primary Key // Le nom des caches doit etre inferieur a 64 caracteres // http://doc.spip.org/@spip_mysql_create function spip_mysql_create($nom, $champs, $cles, $autoinc=false, $temporary=false) { $query = ''; $keys = ''; $s = ''; $p=''; // certains plugins declarent les tables (permet leur inclusion dans le dump) // sans les renseigner (laisse le compilo recuperer la description) if (!is_array($champs) || !is_array($cles)) return; foreach($cles as $k => $v) { $keys .= "$s\n\t\t$k ($v)"; if ($k == "PRIMARY KEY") $p = $v; $s = ","; } $s = ''; foreach($champs as $k => $v) { $query .= "$s\n\t\t$k $v" . (($autoinc && ($p == $k)) ? " auto_increment" : ''); $s = ","; } $temporary = $temporary ? 'TEMPORARY':''; spip_query_db("CREATE $temporary TABLE IF NOT EXISTS $nom ($query" . ($keys ? ",$keys" : '') . ")\n"); } // http://doc.spip.org/@spip_mysql_showtable function spip_mysql_showtable($nom_table) { $a = spip_query("SHOW TABLES LIKE '$nom_table'"); if (!$a) return ""; if (!spip_fetch_array($a)) return ""; list(,$a) = spip_fetch_array(spip_query("SHOW CREATE TABLE $nom_table"),SPIP_NUM); if (!preg_match("/^[^(),]*\((([^()]*\([^()]*\)[^()]*)*)\)[^()]*$/", $a, $r)) return ""; else { $dec = $r[1]; if (preg_match("/^(.*?),([^,]*KEY.*)$/s", $dec, $r)) { $namedkeys = $r[2]; $dec = $r[1]; } else $namedkeys = ""; $fields = array(); foreach(preg_split("/,\s*`/",$dec) as $v) { preg_match("/^\s*`?([^`]*)`\s*(.*)/",$v,$r); $fields[strtolower($r[1])] = $r[2]; } $keys = array(); foreach(preg_split('/\)\s*,?/',$namedkeys) as $v) { if (preg_match("/^\s*([^(]*)\((.*)$/",$v,$r)) { $k = str_replace("`", '', trim($r[1])); $t = strtolower(str_replace("`", '', $r[2])); if ($k && !isset($keys[$k])) $keys[$k] = $t; else $keys[] = $t; } } return array('field' => $fields, 'key' => $keys); } } // // Recuperation des resultats // // interface de abstract_sql. // http://doc.spip.org/@spip_mysql_fetch function spip_mysql_fetch($r, $t=SPIP_ASSOC) { if ($r) return mysql_fetch_array($r, $t); } // http://doc.spip.org/@spip_fetch_array function spip_fetch_array($r, $t=SPIP_ASSOC) { if ($r) return mysql_fetch_array($r, $t); } // http://doc.spip.org/@spip_sql_error function spip_sql_error() { return mysql_error(); } // http://doc.spip.org/@spip_sql_errno function spip_sql_errno() { return mysql_errno(); } // Interface de abstract_sql // http://doc.spip.org/@spip_mysql_count function spip_mysql_count($r) { if ($r) return mysql_num_rows($r); } // http://doc.spip.org/@spip_num_rows function spip_num_rows($r) { if ($r) return mysql_num_rows($r); } // Interface de abstract_sql (on est sur de l'argument, c'est le compilateur) // http://doc.spip.org/@spip_mysql_free function spip_mysql_free($r) { return mysql_free_result($r); } // Vieux nom a laisser tomber // http://doc.spip.org/@spip_free_result function spip_free_result($r) { if ($r) return mysql_free_result($r); } // http://doc.spip.org/@spip_mysql_insert function spip_mysql_insert($table, $champs, $valeurs) { spip_query("INSERT INTO $table $champs VALUES $valeurs"); return mysql_insert_id(); } // http://doc.spip.org/@spip_insert_id function spip_insert_id() { return mysql_insert_id(); } // // Poser un verrou local a un SPIP donne // // http://doc.spip.org/@spip_get_lock function spip_get_lock($nom, $timeout = 0) { global $spip_mysql_db, $table_prefix; if ($table_prefix) $nom = "$table_prefix:$nom"; if ($spip_mysql_db) $nom = "$spip_mysql_db:$nom"; // Changer de nom toutes les heures en cas de blocage MySQL (ca arrive) define('_LOCK_TIME', intval(time()/3600-316982)); $nom .= _LOCK_TIME; $q = spip_query("SELECT GET_LOCK(" . _q($nom) . ", $timeout)"); list($lock_ok) = spip_fetch_array($q,SPIP_NUM); if (!$lock_ok) spip_log("pas de lock sql pour $nom"); return $lock_ok; } // http://doc.spip.org/@spip_release_lock function spip_release_lock($nom) { global $spip_mysql_db, $table_prefix; if ($table_prefix) $nom = "$table_prefix:$nom"; if ($spip_mysql_db) $nom = "$spip_mysql_db:$nom"; $nom .= _LOCK_TIME; spip_query("SELECT RELEASE_LOCK(" . _q($nom) . ")"); } // http://doc.spip.org/@spip_mysql_version function spip_mysql_version() { $row = spip_fetch_array(spip_query("SELECT version() AS n")); return ($row['n']); } // http://doc.spip.org/@creer_objet_multi function creer_objet_multi ($objet, $lang) { $retour = "(TRIM(IF(INSTR(".$objet.", '') = 0 , ". " TRIM(".$objet."), ". " CONCAT( ". " LEFT(".$objet.", INSTR(".$objet.", '')-1), ". " IF( ". " INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))),'[".$lang."]') = 0, ". " IF( ". " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))) REGEXP '^\\[[a-z\_]{2,}\\]', ". " INSERT( ". " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))), ". " 1, ". " INSTR(TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))), ']'), ". " '' ". " ), ". " TRIM(RIGHT(".$objet.", LENGTH(".$objet.") -(6+INSTR(".$objet.", '')))) ". " ), ". " TRIM(RIGHT(".$objet.", ( LENGTH(".$objet.") - (INSTR(".$objet.", '[".$lang."]')+ LENGTH('[".$lang."]')-1) ) )) ". " ) ". " ) ". "))) AS multi "; return $retour; } ?>