= 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.", '