0) $host = "$host:$port"; $link = @mysql_connect($host, $login, $pass, true); if (!$link) { spip_log('Echec mysql_connect. Erreur : ' . mysql_error(),'mysql.'._LOG_HS); return false; } $last = ''; if (!$db) { $ok = $link; $db = 'spip'; } else { $ok = spip_mysql_selectdb($db); if (defined('_MYSQL_SET_SQL_MODE') OR defined('_MYSQL_SQL_MODE_TEXT_NOT_NULL') // compatibilite ) mysql_query($last = "set sql_mode=''"); } spip_log("Connexion vers $host, base $db, prefixe $prefixe " . ($ok ? "operationnelle sur $link" : 'impossible'), _LOG_DEBUG); return !$ok ? false : array( 'db' => $db, 'last' => $last, 'prefixe' => $prefixe ? $prefixe : $db, 'link' => $GLOBALS['mysql_rappel_connexion'] ? $link : false, ); } $GLOBALS['spip_mysql_functions_1'] = array( 'alter' => 'spip_mysql_alter', 'count' => 'spip_mysql_count', 'countsel' => 'spip_mysql_countsel', 'create' => 'spip_mysql_create', 'create_base' => 'spip_mysql_create_base', 'create_view' => 'spip_mysql_create_view', 'date_proche' => 'spip_mysql_date_proche', 'delete' => 'spip_mysql_delete', 'drop_table' => 'spip_mysql_drop_table', 'drop_view' => 'spip_mysql_drop_view', 'errno' => 'spip_mysql_errno', 'error' => 'spip_mysql_error', 'explain' => 'spip_mysql_explain', 'fetch' => 'spip_mysql_fetch', 'seek' => 'spip_mysql_seek', 'free' => 'spip_mysql_free', 'hex' => 'spip_mysql_hex', 'in' => 'spip_mysql_in', 'insert' => 'spip_mysql_insert', 'insertq' => 'spip_mysql_insertq', 'insertq_multi' => 'spip_mysql_insertq_multi', 'listdbs' => 'spip_mysql_listdbs', 'multi' => 'spip_mysql_multi', 'optimize' => 'spip_mysql_optimize', 'query' => 'spip_mysql_query', 'quote' => 'spip_mysql_quote', 'replace' => 'spip_mysql_replace', 'replace_multi' => 'spip_mysql_replace_multi', 'repair' => 'spip_mysql_repair', 'select' => 'spip_mysql_select', 'selectdb' => 'spip_mysql_selectdb', 'set_charset' => 'spip_mysql_set_charset', 'get_charset' => 'spip_mysql_get_charset', 'showbase' => 'spip_mysql_showbase', 'showtable' => 'spip_mysql_showtable', 'update' => 'spip_mysql_update', 'updateq' => 'spip_mysql_updateq', // association de chaque nom http d'un charset aux couples MySQL 'charsets' => array( 'cp1250'=>array('charset'=>'cp1250','collation'=>'cp1250_general_ci'), 'cp1251'=>array('charset'=>'cp1251','collation'=>'cp1251_general_ci'), 'cp1256'=>array('charset'=>'cp1256','collation'=>'cp1256_general_ci'), 'iso-8859-1'=>array('charset'=>'latin1','collation'=>'latin1_swedish_ci'), //'iso-8859-6'=>array('charset'=>'latin1','collation'=>'latin1_swedish_ci'), 'iso-8859-9'=>array('charset'=>'latin5','collation'=>'latin5_turkish_ci'), //'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 /** * @param $charset * @param string $serveur * @param bool $requeter * @param bool $requeter * @return resource */ function spip_mysql_set_charset($charset, $serveur='',$requeter=true,$requeter=true){ $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; spip_log("changement de charset sql : "."SET NAMES "._q($charset), _LOG_DEBUG); return mysql_query($connexion['last'] = "SET NAMES "._q($charset)); } // http://doc.spip.org/@spip_mysql_get_charset /** * @param array $charset * @param string $serveur * @param bool $requeter * @return array * */ function spip_mysql_get_charset($charset=array(), $serveur='',$requeter=true){ $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $connexion['last'] = $c = "SHOW CHARACTER SET" . (!$charset ? '' : (" LIKE "._q($charset['charset']))); return spip_mysql_fetch(mysql_query($c), NULL, $serveur); } // obsolete, ne plus utiliser // http://doc.spip.org/@spip_query_db function spip_query_db($query, $serveur='',$requeter=true) { return spip_mysql_query($query, $serveur, $requeter); } // Fonction de requete generale, munie d'une trace a la demande // http://doc.spip.org/@spip_mysql_query /** * @param $query * @param string $serveur * @param bool $requeter * @return array|null|resource|string * */ function spip_mysql_query($query, $serveur='',$requeter=true) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $prefixe = $connexion['prefixe']; $link = $connexion['link']; $db = $connexion['db']; $query = traite_query($query, $db, $prefixe); // renvoyer la requete inerte si demandee if (!$requeter) return $query; if (isset($_GET['var_profile'])) { include_spip('public/tracer'); $t = trace_query_start(); } else $t = 0 ; $connexion['last'] = $query; // ajouter un debug utile dans log/mysql-slow.log ? $debug = ''; if (defined('_DEBUG_SLOW_QUERIES') AND _DEBUG_SLOW_QUERIES){ if(isset($GLOBALS['debug']['aucasou'])){ list(,$id,, $infos) = $GLOBALS['debug']['aucasou']; $debug .= " BOUCLE$id @ ".$infos[0] ." | "; } $debug .= " " . $_SERVER['REQUEST_URI'].' + '.$GLOBALS['ip']; $debug = ' /*'.str_replace('*/','@/',$debug).' */'; } $r = $link ? mysql_query($query.$debug, $link) : mysql_query($query.$debug); if ($e = spip_mysql_errno($serveur)) // Log de l'erreur eventuelle $e .= spip_mysql_error($query, $serveur); // et du fautif return $t ? trace_query_end($query, $t, $r, $e, $serveur) : $r; } // http://doc.spip.org/@spip_mysql_alter /** * @param $query * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_alter($query, $serveur='',$requeter=true){ // ici on supprime les ` entourant le nom de table pour permettre // la transposition du prefixe, compte tenu que les plugins ont la mauvaise habitude // d'utiliser ceux-ci, copie-colle de phpmyadmin $query = preg_replace(",^TABLE\s*`([^`]*)`,i","TABLE \\1",$query); return spip_mysql_query("ALTER ".$query, $serveur, $requeter); # i.e. que PG se debrouille } // http://doc.spip.org/@spip_mysql_optimize /** * @param $table * @param string $serveur * @param bool $requeter * @return bool */ function spip_mysql_optimize($table, $serveur='',$requeter=true){ spip_mysql_query("OPTIMIZE TABLE ". $table); return true; } // http://doc.spip.org/@spip_mysql_explain /** * @param $query * @param string $serveur * @param bool $requeter * @return array */ function spip_mysql_explain($query, $serveur='',$requeter=true){ if (strpos(ltrim($query), 'SELECT') !== 0) return array(); $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $prefixe = $connexion['prefixe']; $link = $connexion['link']; $db = $connexion['db']; $query = 'EXPLAIN ' . traite_query($query, $db, $prefixe); $r = $link ? mysql_query($query, $link) : mysql_query($query); return spip_mysql_fetch($r, NULL, $serveur); } // fonction instance de sql_select, voir ses specs dans abstract.php // traite_query pourrait y etre fait d'avance ce serait moins cher // Les \n et \t sont utiles au debusqueur. // http://doc.spip.org/@spip_mysql_select /** * @param $select * @param $from * @param string $where * @param string $groupby * @param string $orderby * @param string $limit * @param string $having * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_select($select, $from, $where='', $groupby='', $orderby='', $limit='', $having='', $serveur='',$requeter=true) { $from = (!is_array($from) ? $from : spip_mysql_select_as($from)); $query = calculer_mysql_expression('SELECT', $select, ', ') . calculer_mysql_expression('FROM', $from, ', ') . calculer_mysql_expression('WHERE', $where) . calculer_mysql_expression('GROUP BY', $groupby, ',') . calculer_mysql_expression('HAVING', $having) . ($orderby ? ("\nORDER BY " . spip_mysql_order($orderby)) :'') . ($limit ? "\nLIMIT $limit" : ''); // renvoyer la requete inerte si demandee if ($requeter === false) return $query; $r = spip_mysql_query($query, $serveur, $requeter); return $r ? $r : $query; } // 0+x avec un champ x commencant par des chiffres est converti par MySQL // en le nombre qui commence x. // Pas portable malheureusement, on laisse pour le moment. // http://doc.spip.org/@spip_mysql_order /** * @param $orderby * @return string */ function spip_mysql_order($orderby) { return (is_array($orderby)) ? join(", ", $orderby) : $orderby; } // http://doc.spip.org/@calculer_mysql_where /** * @param $v * @return array|mixed|string */ function calculer_mysql_where($v) { if (!is_array($v)) return $v ; $op = array_shift($v); if (!($n=count($v))) return $op; else { $arg = calculer_mysql_where(array_shift($v)); if ($n==1) { return "$op($arg)"; } else { $arg2 = calculer_mysql_where(array_shift($v)); if ($n==2) { return "($arg $op $arg2)"; } else return "($arg $op ($arg2) : $v[0])"; } } } // http://doc.spip.org/@calculer_mysql_expression /** * @param $expression * @param $v * @param string $join * @return string */ function calculer_mysql_expression($expression, $v, $join = 'AND'){ if (empty($v)) return ''; $exp = "\n$expression "; if (!is_array($v)) { return $exp . $v; } else { if (strtoupper($join) === 'AND') return $exp . join("\n\t$join ", array_map('calculer_mysql_where', $v)); else return $exp . join($join, $v); } } // http://doc.spip.org/@spip_mysql_select_as /** * @param $args * @return string */ function spip_mysql_select_as($args) { $res = ''; foreach($args as $k => $v) { if (substr($k,-1)=='@') { // c'est une jointure qui se refere au from precedent // pas de virgule $res .= ' ' . $v ; } else { if (!is_numeric($k)) { $p = strpos($v, " "); if ($p) $v = substr($v,0,$p) . " AS `$k`" . substr($v,$p); else $v .= " AS `$k`"; } $res .= ', ' . $v ; } } return substr($res,2); } // // Changer les noms des tables ($table_prefix) // Quand tous les appels SQL seront abstraits on pourra l'ameliorer define('_SQL_PREFIXE_TABLE', '/([,\s])spip_/S'); // http://doc.spip.org/@traite_query /** * @param $query * @param string $db * @param string $prefixe * @return array|null|string */ function traite_query($query, $db='', $prefixe='') { if ($GLOBALS['mysql_rappel_nom_base'] AND $db) $pref = '`'. $db.'`.'; else $pref = ''; if ($prefixe) $pref .= $prefixe . "_"; if (!preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/i', $query, $regs)) { $suite =''; } else { $suite = strstr($query, $regs[0]); $query = substr($query, 0, -strlen($suite)); // propager le prefixe en cas de requete imbriquee // il faut alors echapper les chaine avant de le faire, pour ne pas risquer de // modifier une requete qui est en fait juste du texte dans un champ if (stripos($suite,"SELECT")!==false) { list($suite,$textes) = query_echappe_textes($suite); if (preg_match('/^(.*?)([(]\s*SELECT\b.*)$/si', $suite, $r)) $suite = $r[1] . traite_query($r[2], $db, $prefixe); $suite = query_reinjecte_textes($suite, $textes); } } $r = preg_replace(_SQL_PREFIXE_TABLE, '\1'.$pref, $query) . $suite; #spip_log("traite_query: " . substr($r,0, 50) . ".... $db, $prefixe", _LOG_DEBUG); return $r; } /** * Selectionne une base de donnees * * @param string $nom * Nom de la base a utiliser * * @return bool * True cas de success. * False en cas d'erreur. **/ function spip_mysql_selectdb($db) { $ok = mysql_select_db($db); if (!$ok) spip_log('Echec mysql_selectdb. Erreur : ' . mysql_error(),'mysql.'._LOG_CRITIQUE); return $ok; } /** * Retourne les bases de donnees accessibles * * Retourne un tableau du nom de toutes les bases de donnees * accessibles avec les permissions de l'utilisateur SQL * de cette connexion. * Attention on n'a pas toujours les droits ! * * @param string $serveur * Nom du connecteur * @param bool $requeter * Inutilise * @return array * Liste de noms de bases de donnees **/ function spip_mysql_listdbs($serveur='',$requeter=true) { $dbs = array(); if ($res = spip_mysql_query("SHOW DATABASES")){ while($row = mysql_fetch_assoc($res)) $dbs[] = $row['Database']; } return $dbs; } // 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 /** * @param $nom * @param $champs * @param $cles * @param bool $autoinc * @param bool $temporary * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_create($nom, $champs, $cles, $autoinc=false, $temporary=false, $serveur='',$requeter=true) { $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; $res = spip_mysql_query("SELECT version() as v"); if (($row = mysql_fetch_array($res)) && (version_compare($row['v'],'5.0','>='))) { spip_mysql_query("SET sql_mode=''", $serveur); } foreach($cles as $k => $v) { $keys .= "$s\n\t\t$k ($v)"; if ($k == "PRIMARY KEY") $p = $v; $s = ","; } $s = ''; $character_set = ""; if (@$GLOBALS['meta']['charset_sql_base']) $character_set .= " CHARACTER SET ".$GLOBALS['meta']['charset_sql_base']; if (@$GLOBALS['meta']['charset_collation_sql_base']) $character_set .= " COLLATE ".$GLOBALS['meta']['charset_collation_sql_base']; foreach($champs as $k => $v) { $v = _mysql_remplacements_definitions_table($v); if (preg_match(',([a-z]*\s*(\(\s*[0-9]*\s*\))?(\s*binary)?),i',$v,$defs)){ if (preg_match(',(char|text),i',$defs[1]) AND !preg_match(',(binary|CHARACTER|COLLATE),i',$v) ){ $v = $defs[1] . $character_set . ' ' . substr($v,strlen($defs[1])); } } $query .= "$s\n\t\t$k $v" . (($autoinc && ($p == $k) && preg_match(',\b(big|small|medium)?int\b,i', $v)) ? " auto_increment" : '' ); $s = ","; } $temporary = $temporary ? 'TEMPORARY':''; $q = "CREATE $temporary TABLE IF NOT EXISTS $nom ($query" . ($keys ? ",$keys" : '') . ")". ($character_set?" DEFAULT $character_set":"") ."\n"; return spip_mysql_query($q, $serveur); } /** * Adapte pour Mysql la declaration SQL d'une colonne d'une table * * @param string $query * Definition SQL d'un champ de table * @return string * Definition SQL adaptee pour MySQL d'un champ de table */ function _mysql_remplacements_definitions_table($query){ // quelques remplacements $num = "(\s*\([0-9]*\))?"; $enum = "(\s*\([^\)]*\))?"; $remplace = array( '/VARCHAR(\s*[^\s\(])/is' => 'VARCHAR(255)\\1', ); $query = preg_replace(array_keys($remplace), $remplace, $query); return $query; } /** * @param $nom * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_create_base($nom, $serveur='',$requeter=true) { return spip_mysql_query("CREATE DATABASE `$nom`", $serveur, $requeter); } // Fonction de creation d'une vue SQL nommee $nom // http://doc.spip.org/@spip_mysql_create_view /** * @param $nom * @param $query_select * @param string $serveur * @param bool $requeter * @return array|bool|null|resource|string */ function spip_mysql_create_view($nom, $query_select, $serveur='',$requeter=true) { if (!$query_select) return false; // vue deja presente if (sql_showtable($nom, false, $serveur)) { spip_log("Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)", _LOG_ERREUR); return false; } $query = "CREATE VIEW $nom AS ". $query_select; return spip_mysql_query($query, $serveur, $requeter); } // http://doc.spip.org/@spip_mysql_drop_table /** * @param $table * @param string $exist * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_drop_table($table, $exist='', $serveur='',$requeter=true) { if ($exist) $exist =" IF EXISTS"; return spip_mysql_query("DROP TABLE$exist $table", $serveur, $requeter); } // supprime une vue // http://doc.spip.org/@spip_mysql_drop_view /** * @param $view * @param string $exist * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_drop_view($view, $exist='', $serveur='',$requeter=true) { if ($exist) $exist =" IF EXISTS"; return spip_mysql_query("DROP VIEW$exist $view", $serveur, $requeter); } /** * Retourne une ressource de la liste des tables de la base de données * * @param string $match * Filtre sur tables à récupérer * @param string $serveur * Connecteur de la base * @param bool $requeter * true pour éxecuter la requête * false pour retourner le texte de la requête. * @return ressource * Ressource à utiliser avec sql_fetch() **/ function spip_mysql_showbase($match, $serveur='',$requeter=true) { return spip_mysql_query("SHOW TABLES LIKE " . _q($match), $serveur, $requeter); } // http://doc.spip.org/@spip_mysql_repair /** * @param $table * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_repair($table, $serveur='',$requeter=true) { return spip_mysql_query("REPAIR TABLE `$table`", $serveur, $requeter); } define('_MYSQL_RE_SHOW_TABLE', '/^[^(),]*\(((?:[^()]*\((?:[^()]*\([^()]*\))?[^()]*\)[^()]*)*[^()]*)\)[^()]*$/'); // Recupere la definition d'une table ou d'une vue MySQL // colonnes, indexes, etc. // au meme format que la definition des tables de SPIP // http://doc.spip.org/@spip_mysql_showtable /** * @param $nom_table * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_showtable($nom_table, $serveur='',$requeter=true) { $s = spip_mysql_query("SHOW CREATE TABLE `$nom_table`", $serveur, $requeter); if (!$s) return ''; if (!$requeter) return $s; list(,$a) = mysql_fetch_array($s ,MYSQL_NUM); if (preg_match(_MYSQL_RE_SHOW_TABLE, $a, $r)){ $desc = $r[1]; // extraction d'une KEY éventuelle en prenant garde de ne pas // relever un champ dont le nom contient KEY (ex. ID_WHISKEY) if (preg_match("/^(.*?),([^,]*\sKEY[ (].*)$/s", $desc, $r)) { $namedkeys = $r[2]; $desc = $r[1]; } else $namedkeys = ""; $fields = array(); foreach(preg_split("/,\s*`/",$desc) 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*([^(]*)\(([^(]*(\(\d+\))?)$/",$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; } } spip_mysql_free($s); return array('field' => $fields, 'key' => $keys); } $res = spip_mysql_query("SHOW COLUMNS FROM `$nom_table`", $serveur); if($res) { $nfields = array(); $nkeys = array(); while($val = spip_mysql_fetch($res)) { $nfields[$val["Field"]] = $val['Type']; if($val['Null']=='NO') { $nfields[$val["Field"]] .= ' NOT NULL'; } if($val['Default'] === '0' || $val['Default']) { if(preg_match('/[A-Z_]/',$val['Default'])) { $nfields[$val["Field"]] .= ' DEFAULT '.$val['Default']; } else { $nfields[$val["Field"]] .= " DEFAULT '".$val['Default']."'"; } } if($val['Extra']) $nfields[$val["Field"]] .= ' '.$val['Extra']; if($val['Key'] == 'PRI') { $nkeys['PRIMARY KEY'] = $val["Field"]; } else if($val['Key'] == 'MUL') { $nkeys['KEY '.$val["Field"]] = $val["Field"]; } else if($val['Key'] == 'UNI') { $nkeys['UNIQUE KEY '.$val["Field"]] = $val["Field"]; } } spip_mysql_free($res); return array('field' => $nfields, 'key' => $nkeys); } return ""; } // // Recuperation des resultats // // http://doc.spip.org/@spip_mysql_fetch /** * @param $r * @param string $t * @param string $serveur * @param bool $requeter * @return array */ function spip_mysql_fetch($r, $t='', $serveur='',$requeter=true) { if (!$t) $t = MYSQL_ASSOC; if ($r) return mysql_fetch_array($r, $t); } function spip_mysql_seek($r, $row_number, $serveur='',$requeter=true) { if ($r and mysql_num_rows($r)) return mysql_data_seek($r,$row_number); } // http://doc.spip.org/@spip_mysql_countsel /** * @param array $from * @param array $where * @param string $groupby * @param array $having * @param string $serveur * @param bool $requeter * @return array|int|null|resource|string * */ function spip_mysql_countsel($from = array(), $where = array(), $groupby = '', $having = array(), $serveur='',$requeter=true) { $c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby))); $r = spip_mysql_select("COUNT($c)", $from, $where,'', '', '', $having, $serveur, $requeter); if (!$requeter) return $r; if (!is_resource($r)) return 0; list($c) = mysql_fetch_array($r, MYSQL_NUM); mysql_free_result($r); return $c; } // Bien specifier le serveur auquel on s'adresse, // mais a l'install la globale n'est pas encore completement definie // http://doc.spip.org/@spip_mysql_error /** * @param string $query * @param string $serveur * @param bool $requeter * @return string */ function spip_mysql_error($query='', $serveur='',$requeter=true) { $link = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]['link']; $s = $link ? mysql_error($link) : mysql_error(); if ($s) spip_log("$s - $query", 'mysql.'._LOG_ERREUR); return $s; } // A transposer dans les portages // http://doc.spip.org/@spip_mysql_errno /** * @param string $serveur * @param bool $requeter * @return int */ function spip_mysql_errno($serveur='',$requeter=true) { $link = $GLOBALS['connexions'][$serveur ? $serveur : 0]['link']; $s = $link ? mysql_errno($link) : mysql_errno(); // 2006 MySQL server has gone away // 2013 Lost connection to MySQL server during query if (in_array($s, array(2006,2013))) define('spip_interdire_cache', true); if ($s) spip_log("Erreur mysql $s", _LOG_ERREUR); return $s; } // Interface de abstract_sql // http://doc.spip.org/@spip_mysql_count /** * @param $r * @param string $serveur * @param bool $requeter * @return int */ function spip_mysql_count($r, $serveur='',$requeter=true) { if ($r) return mysql_num_rows($r); } // http://doc.spip.org/@spip_mysql_free /** * @param $r * @param string $serveur * @param bool $requeter * @return bool */ function spip_mysql_free($r, $serveur='',$requeter=true) { return (is_resource($r)?mysql_free_result($r):false); } // http://doc.spip.org/@spip_mysql_insert /** * @param $table * @param $champs * @param $valeurs * @param string $desc * @param string $serveur * @param bool $requeter * @return int|string */ function spip_mysql_insert($table, $champs, $valeurs, $desc='', $serveur='',$requeter=true) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $prefixe = $connexion['prefixe']; $link = $connexion['link']; $db = $connexion['db']; if ($prefixe) $table = preg_replace('/^spip/', $prefixe, $table); $query ="INSERT INTO $table $champs VALUES $valeurs"; if (!$requeter) return $query; if (isset($_GET['var_profile'])) { include_spip('public/tracer'); $t = trace_query_start(); } else $t = 0 ; $connexion['last'] = $query; #spip_log($query, 'mysql.'._LOG_DEBUG); if (mysql_query($query, $link)) $r = mysql_insert_id($link); else { if ($e = spip_mysql_errno($serveur)) // Log de l'erreur eventuelle $e .= spip_mysql_error($query, $serveur); // et du fautif } return $t ? trace_query_end($query, $t, $r, $e, $serveur) : $r; // return $r ? $r : (($r===0) ? -1 : 0); pb avec le multi-base. } // http://doc.spip.org/@spip_mysql_insertq /** * @param $table * @param array $couples * @param array $desc * @param string $serveur * @param bool $requeter * @return int|string */ function spip_mysql_insertq($table, $couples=array(), $desc=array(), $serveur='',$requeter=true) { if (!$desc) $desc = description_table($table, $serveur); if (!$desc) $couples = array(); $fields = isset($desc['field'])?$desc['field']:array(); foreach ($couples as $champ => $val) { $couples[$champ]= spip_mysql_cite($val, $fields[$champ]); } return spip_mysql_insert($table, "(".join(',',array_keys($couples)).")", "(".join(',', $couples).")", $desc, $serveur, $requeter); } // http://doc.spip.org/@spip_mysql_insertq_multi /** * @param $table * @param array $tab_couples * @param array $desc * @param string $serveur * @param bool $requeter * @return bool|int|string */ function spip_mysql_insertq_multi($table, $tab_couples=array(), $desc=array(), $serveur='',$requeter=true) { if (!$desc) $desc = description_table($table, $serveur); if (!$desc) $tab_couples = array(); $fields = isset($desc['field'])?$desc['field']:array(); $cles = "(" . join(',',array_keys(reset($tab_couples))) . ')'; $valeurs = array(); $r = false; // Quoter et Inserer par groupes de 100 max pour eviter un debordement de pile foreach ($tab_couples as $couples) { foreach ($couples as $champ => $val){ $couples[$champ]= spip_mysql_cite($val, $fields[$champ]); } $valeurs[] = '(' .join(',', $couples) . ')'; if (count($valeurs)>=100){ $r = spip_mysql_insert($table, $cles, join(', ', $valeurs), $desc, $serveur, $requeter); $valeurs = array(); } } if (count($valeurs)) $r = spip_mysql_insert($table, $cles, join(', ', $valeurs), $desc, $serveur, $requeter); return $r; // dans le cas d'une table auto_increment, le dernier insert_id } // http://doc.spip.org/@spip_mysql_update /** * @param $table * @param $champs * @param string $where * @param string $desc * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_update($table, $champs, $where='', $desc='', $serveur='',$requeter=true) { $set = array(); foreach ($champs as $champ => $val) $set[] = $champ . "=$val"; if (!empty($set)) return spip_mysql_query( calculer_mysql_expression('UPDATE', $table, ',') . calculer_mysql_expression('SET', $set, ',') . calculer_mysql_expression('WHERE', $where), $serveur, $requeter); } // idem, mais les valeurs sont des constantes a mettre entre apostrophes // sauf les expressions de date lorsqu'il s'agit de fonctions SQL (NOW etc) // http://doc.spip.org/@spip_mysql_updateq /** * @param $table * @param $champs * @param string $where * @param array $desc * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_updateq($table, $champs, $where='', $desc=array(), $serveur='',$requeter=true) { if (!$champs) return; if (!$desc) $desc = description_table($table, $serveur); if (!$desc) $champs = array(); else $fields = $desc['field']; $set = array(); foreach ($champs as $champ => $val) { $set[] = $champ . '=' . spip_mysql_cite($val, $fields[$champ]); } return spip_mysql_query( calculer_mysql_expression('UPDATE', $table, ',') . calculer_mysql_expression('SET', $set, ',') . calculer_mysql_expression('WHERE', $where), $serveur, $requeter); } // http://doc.spip.org/@spip_mysql_delete /** * @param $table * @param string $where * @param string $serveur * @param bool $requeter * @return array|bool|int|null|resource|string */ function spip_mysql_delete($table, $where='', $serveur='',$requeter=true) { $res = spip_mysql_query( calculer_mysql_expression('DELETE FROM', $table, ',') . calculer_mysql_expression('WHERE', $where), $serveur, $requeter); if (!$requeter) return $res; if ($res){ $connexion = &$GLOBALS['connexions'][$serveur ? $serveur : 0]; $link = $connexion['link']; return $link ? mysql_affected_rows($link) : mysql_affected_rows(); } else return false; } // http://doc.spip.org/@spip_mysql_replace /** * @param $table * @param $couples * @param array $desc * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_replace($table, $couples, $desc=array(), $serveur='',$requeter=true) { return spip_mysql_query("REPLACE $table (" . join(',',array_keys($couples)) . ') VALUES (' .join(',',array_map('_q', $couples)) . ')', $serveur, $requeter); } // http://doc.spip.org/@spip_mysql_replace_multi /** * @param $table * @param $tab_couples * @param array $desc * @param string $serveur * @param bool $requeter * @return array|null|resource|string */ function spip_mysql_replace_multi($table, $tab_couples, $desc=array(), $serveur='',$requeter=true) { $cles = "(" . join(',',array_keys($tab_couples[0])). ')'; $valeurs = array(); foreach ($tab_couples as $couples) { $valeurs[] = '(' .join(',',array_map('_q', $couples)) . ')'; } $valeurs = implode(', ',$valeurs); return spip_mysql_query("REPLACE $table $cles VALUES $valeurs", $serveur, $requeter); } // http://doc.spip.org/@spip_mysql_multi /** * @param $objet * @param $lang * @return string * */ function spip_mysql_multi ($objet, $lang) { $lengthlang = strlen("[$lang]"); $posmulti = "INSTR(".$objet.", '')"; $posfinmulti = "INSTR(".$objet.", '')"; $debutchaine = "LEFT(".$objet.", $posmulti-1)"; $finchaine = "RIGHT(".$objet.", CHAR_LENGTH(".$objet.") -(7+$posfinmulti))"; $chainemulti = "TRIM(SUBSTRING(".$objet.", $posmulti+7, $posfinmulti -(7+$posmulti)))"; $poslang = "INSTR($chainemulti,'[".$lang."]')"; $poslang = "IF($poslang=0,INSTR($chainemulti,']')+1,$poslang+$lengthlang)"; $chainelang = "TRIM(SUBSTRING(".$objet.", $posmulti+7+$poslang-1,$posfinmulti -($posmulti+7+$poslang-1) ))"; $posfinlang = "INSTR(".$chainelang.", '[')"; $chainelang = "IF($posfinlang>0,LEFT($chainelang,$posfinlang-1),$chainelang)"; //$chainelang = "LEFT($chainelang,$posfinlang-1)"; $retour = "(TRIM(IF($posmulti = 0 , ". " TRIM(".$objet."), ". " CONCAT( ". " $debutchaine, ". " IF( ". " $poslang = 0, ". " $chainemulti, ". " $chainelang". " ), ". " $finchaine". " ) ". "))) AS multi"; return $retour; } // http://doc.spip.org/@spip_mysql_hex /** * @param $v * @return string */ function spip_mysql_hex($v) { return "0x" . $v; } /** * @param $v * @param string $type * @return array|int|string */ function spip_mysql_quote($v, $type='') { if ($type) { if (!is_array($v)) return spip_mysql_cite($v,$type); // si c'est un tableau, le parcourir en propageant le type foreach($v as $k=>$r) $v[$k] = spip_mysql_quote($r, $type); return $v; } // si on ne connait pas le type, s'en remettre a _q : // on ne fera pas mieux else return _q($v); } /** * @param $champ * @param $interval * @param $unite * @return string */ function spip_mysql_date_proche($champ, $interval, $unite) { return '(' . $champ . (($interval <= 0) ? '>' : '<') . (($interval <= 0) ? 'DATE_SUB' : 'DATE_ADD') . '(' . sql_quote(date('Y-m-d H:i:s')) . ', INTERVAL ' . (($interval > 0) ? $interval : (0-$interval)) . ' ' . $unite . '))'; } // // IN (...) est limite a 255 elements, d'ou cette fonction assistante // // http://doc.spip.org/@spip_mysql_in /** * @param $val * @param $valeurs * @param string $not * @param string $serveur * @param bool $requeter * @return string */ function spip_mysql_in($val, $valeurs, $not='', $serveur='',$requeter=true) { $n = $i = 0; $in_sql =""; while ($n = strpos($valeurs, ',', $n+1)) { if ((++$i) >= 255) { $in_sql .= "($val $not IN (" . substr($valeurs, 0, $n) . "))\n" . ($not ? "AND\t" : "OR\t"); $valeurs = substr($valeurs, $n+1); $i = $n = 0; } } $in_sql .= "($val $not IN ($valeurs))"; return "($in_sql)"; } // pour compatibilite. Ne plus utiliser. // http://doc.spip.org/@calcul_mysql_in /** * @param $val * @param $valeurs * @param string $not * @return string */ function calcul_mysql_in($val, $valeurs, $not='') { if (is_array($valeurs)) $valeurs = join(',', array_map('_q', $valeurs)); elseif ($valeurs[0]===',') $valeurs = substr($valeurs,1); if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); return spip_mysql_in($val, $valeurs, $not); } // http://doc.spip.org/@spip_mysql_cite /** * @param $v * @param $type * @return int|string */ function spip_mysql_cite($v, $type) { if(is_null($v) AND stripos($type,"NOT NULL")===false) return 'NULL'; // null php se traduit en NULL SQL if (sql_test_date($type) AND preg_match('/^\w+\(/', $v)) return $v; if (sql_test_int($type)) { if (is_numeric($v) OR (ctype_xdigit(substr($v,2)) AND $v[0]=='0' AND $v[1]=='x')) return $v; // si pas numerique, forcer le intval else return intval($v); } return ("'" . addslashes($v) . "'"); } // Ces deux fonctions n'ont pas d'equivalent exact PostGres // et ne sont la que pour compatibilite avec les extensions de SPIP < 1.9.3 // // Poser un verrou local a un SPIP donne // Changer de nom toutes les heures en cas de blocage MySQL (ca arrive) // // http://doc.spip.org/@spip_get_lock /** * @param $nom * @param int $timeout * @return mixed */ function spip_get_lock($nom, $timeout = 0) { define('_LOCK_TIME', intval(time()/3600-316982)); $connexion = &$GLOBALS['connexions'][0]; $bd = $connexion['db']; $prefixe = $connexion['prefixe']; $nom = "$bd:$prefixe:$nom" . _LOCK_TIME; $connexion['last'] = $q = "SELECT GET_LOCK(" . _q($nom) . ", $timeout) AS n"; $q = @sql_fetch(mysql_query($q)); if (!$q) spip_log("pas de lock sql pour $nom", _LOG_ERREUR); return $q['n']; } // http://doc.spip.org/@spip_release_lock /** * @param $nom */ function spip_release_lock($nom) { $connexion = &$GLOBALS['connexions'][0]; $bd = $connexion['db']; $prefixe = $connexion['prefixe']; $nom = "$bd:$prefixe:$nom" . _LOCK_TIME; $connexion['last'] = $q = "SELECT RELEASE_LOCK(" . _q($nom) . ")"; @mysql_query($q); } // Renvoie false si on n'a pas les fonctions mysql (pour l'install) // http://doc.spip.org/@spip_versions_mysql /** * @return bool */ function spip_versions_mysql() { charger_php_extension('mysql'); return function_exists('mysql_query'); } // Tester si mysql ne veut pas du nom de la base dans les requetes // http://doc.spip.org/@test_rappel_nom_base_mysql /** * @param $server_db * @return string */ function test_rappel_nom_base_mysql($server_db) { $GLOBALS['mysql_rappel_nom_base'] = true; sql_delete('spip_meta', "nom='mysql_rappel_nom_base'", $server_db); $ok = spip_query("INSERT INTO spip_meta (nom,valeur) VALUES ('mysql_rappel_nom_base', 'test')", $server_db); if ($ok) { sql_delete('spip_meta', "nom='mysql_rappel_nom_base'", $server_db); return ''; } else { $GLOBALS['mysql_rappel_nom_base'] = false; return "\$GLOBALS['mysql_rappel_nom_base'] = false; ". "/* echec de test_rappel_nom_base_mysql a l'installation. */\n"; } } // http://doc.spip.org/@test_sql_mode_mysql /** * @param $server_db * @return string */ function test_sql_mode_mysql($server_db){ $res = sql_select("version() as v",'','','','','','',$server_db); $row = sql_fetch($res,$server_db); if (version_compare($row['v'],'5.0.0','>=')){ define('_MYSQL_SET_SQL_MODE',true); return "define('_MYSQL_SET_SQL_MODE',true);\n"; } return ''; } ?>