From c6b27468526d31753d6138a2f1e18fdee3452c3a Mon Sep 17 00:00:00 2001 From: "Committo,Ergo:sum" <esj@rezo.net> Date: Mon, 29 Oct 2007 22:14:46 +0000 Subject: [PATCH] =?UTF-8?q?La=20fonction=20{{{calcul=5Fmysql=5Fin}}}=20doi?= =?UTF-8?q?t=20finalement=20elle=20aussi=20=C3=AAtre=20abstraite=20=C3=A0?= =?UTF-8?q?=20cause=20des=20valeurs=20hexad=C3=A9cimales=20qui=20peuvent?= =?UTF-8?q?=20s'y=20trouver.=20Pour=20=C3=A9viter=20des=20probl=C3=A8mes?= =?UTF-8?q?=20de=20compatibilit=C3=A9,=20cette=20fonction=20reste=20sous?= =?UTF-8?q?=20ce=20nom=20dans=20le=20coeur=20de=20SPIP,=20mais=20il=20faut?= =?UTF-8?q?=20la=20consid=C3=A9rer=20comme=20obsol=C3=A8te=20et=20lui=20pr?= =?UTF-8?q?=C3=A9f=C3=A9rer:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit {{{ in => fonction d'abstraction du test de la présence d'une valeur dans une liste. }}} Cette fonction s'ajoute à celles définies dans [10667], [10433], [10131], [10146], [10154] et [10113]. Par ailleurs, les fonctions récemment introduites {{{test_sql_int}}} et {{{test_sql_date}}} se nomment finalement {{{sql_test_int}}} et {{{sql_test_date}}}: bien qu'elles n'abstraient actuellement rien, il est vraisemblable que ce soit le cas lors d'autre portages, on unifie donc tout de suite les nommages. Ce dépot a remplacé les occurrences de {{{calcul_mysql_in}}} dans {{{ecrire/}} avec: {{{ for i in $(grep -l calcul_mysql_in [pige]*/*.php) do sed s/calcul_mysql_in/sql_in/g $i > x mv x $i done }}} --- ecrire/base/abstract_sql.php | 35 +++++------------------ ecrire/exec/auteurs.php | 2 +- ecrire/exec/recherche.php | 2 +- ecrire/genie/optimiser.php | 2 +- ecrire/genie/visites.php | 10 +++---- ecrire/inc/documents.php | 2 +- ecrire/inc/forum.php | 2 +- ecrire/inc/modifier.php | 2 +- ecrire/inc/prepare_recherche.php | 6 ++-- ecrire/inc/rechercher.php | 2 +- ecrire/inc/rubriques.php | 2 +- ecrire/public/criteres.php | 9 +++--- ecrire/public/vertebrer.php | 6 ++-- ecrire/req/mysql.php | 36 +++++++++++++++++++++-- ecrire/req/pg.php | 49 +++++++++++++++++++------------- 15 files changed, 94 insertions(+), 73 deletions(-) diff --git a/ecrire/base/abstract_sql.php b/ecrire/base/abstract_sql.php index 583036c01d..990afc7645 100644 --- a/ecrire/base/abstract_sql.php +++ b/ecrire/base/abstract_sql.php @@ -319,32 +319,6 @@ function sql_version($serveur='') { return ($row['n']); } -// -// IN (...) est limite a 255 elements, d'ou cette fonction assistante -// -// http://doc.spip.org/@calcul_mysql_in -function calcul_mysql_in($val, $valeurs, $not='') { - if (is_array($valeurs)) - $valeurs = join(',', array_map('_q', $valeurs)); - if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); - - $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)"; -} - // prend une chaine sur l'aphabet hexa // et retourne sa representation numerique: // FF ==> 0xFF en MySQL mais x'FF' en PG @@ -355,8 +329,13 @@ function sql_hex($val, $serveur='') return $f($val); } +function sql_in($val, $valeurs, $not='', $serveur='') { + $f = sql_serveur('in', $serveur); + return $f($val, $valeurs, $not, $serveur); +} + // http://doc.spip.org/@test_sql_int -function test_sql_int($type) +function sql_test_int($type) { return (preg_match('/^bigint/i',$type) OR preg_match('/^int/i',$type) @@ -364,7 +343,7 @@ function test_sql_int($type) } // http://doc.spip.org/@test_sql_date -function test_sql_date($type) +function sql_test_date($type) { return (preg_match('/^datetime/i',$type) OR preg_match('/^timestamp/i',$type)); diff --git a/ecrire/exec/auteurs.php b/ecrire/exec/auteurs.php index ce16a498e7..8df4fe2665 100644 --- a/ecrire/exec/auteurs.php +++ b/ecrire/exec/auteurs.php @@ -267,7 +267,7 @@ function requete_auteurs($tri, $statut, $recherche=NULL) $tables = array('auteur'=>$tables['auteur']); $results = recherche_en_base($recherche, $tables); $in_auteurs = $results['auteur'] - ? calcul_mysql_in('aut.id_auteur',array_keys($results['auteur'])) + ? sql_in('aut.id_auteur',array_keys($results['auteur'])) : '0=1'; } diff --git a/ecrire/exec/recherche.php b/ecrire/exec/recherche.php index 2a1fca4ec0..031a0951b2 100644 --- a/ecrire/exec/recherche.php +++ b/ecrire/exec/recherche.php @@ -111,7 +111,7 @@ function exec_recherche_dist() { array( // gasp: la requete spip_articles exige AS articles... 'FROM' => table_objet_sql($table).' AS '.$table.'s', - 'WHERE' => calcul_mysql_in( + 'WHERE' => sql_in( $table.'s.'.id_table_objet($table), array_keys($r) ), diff --git a/ecrire/genie/optimiser.php b/ecrire/genie/optimiser.php index f554ef9675..f6d5f2c1a2 100644 --- a/ecrire/genie/optimiser.php +++ b/ecrire/genie/optimiser.php @@ -73,7 +73,7 @@ function optimiser_sansref($table, $id, $sel) if ($in) { $in = join(',', array_keys($in)); - sql_delete($table, calcul_mysql_in($id,$in)); + sql_delete($table, sql_in($id,$in)); spip_log("Numeros des entrees $id supprimees dans la table $table: $in"); } return count($in); diff --git a/ecrire/genie/visites.php b/ecrire/genie/visites.php index 585fd71e86..e686213673 100644 --- a/ecrire/genie/visites.php +++ b/ecrire/genie/visites.php @@ -111,7 +111,7 @@ function calculer_visites($t) { } else $ar[$n][] = $id_article; } foreach ($ar as $n => $liste) { - $tous = calcul_mysql_in('id_article', $liste); + $tous = sql_in('id_article', $liste); sql_update('spip_visites_articles', array('visites' => "visites+$n"), "date='$date' AND $tous"); @@ -127,14 +127,14 @@ function calculer_visites($t) { array('visites' => "visites+$n", 'popularite' => "popularite+$n", 'maj' => 'maj'), - calcul_mysql_in('id_article',$noref)); + sql_in('id_article',$noref)); if ($ref) sql_update('spip_articles', array('visites' => "visites+".($n+1), 'popularite' => "popularite+$n", 'maj' => 'maj'), - calcul_mysql_in('id_article',$ref)); + sql_in('id_article',$ref)); ## Ajouter un JOIN sur le statut de l'article ? } @@ -162,10 +162,10 @@ function calculer_visites($t) { } // appliquer les increments sur les anciens - // attention on appelle calcul_mysql_in en mode texte et pas array + // attention on appelle sql_in en mode texte et pas array // pour ne pas passer _q() sur les '0x1234' de referer_md5, cf #849 foreach ($ar as $num => $liste) { - sql_update('spip_referers', array('visites' => "visites+$num", 'visites_jour' => "visites_jour+$num"), calcul_mysql_in('referer_md5',join(', ', $liste))); + sql_update('spip_referers', array('visites' => "visites+$num", 'visites_jour' => "visites_jour+$num"), sql_in('referer_md5',join(', ', $liste))); } } diff --git a/ecrire/inc/documents.php b/ecrire/inc/documents.php index 1ce3943e8a..15479322b0 100644 --- a/ecrire/inc/documents.php +++ b/ecrire/inc/documents.php @@ -498,7 +498,7 @@ function supprimer_documents($liste = array()) { if (!count($liste)) return; - $in = calcul_mysql_in('id_document', $liste); + $in = sql_in('id_document', $liste); // Supprimer les fichiers locaux et les copies locales // des docs distants diff --git a/ecrire/inc/forum.php b/ecrire/inc/forum.php index 5b6e96aea1..0bf35a3aa7 100644 --- a/ecrire/inc/forum.php +++ b/ecrire/inc/forum.php @@ -212,7 +212,7 @@ function critere_statut_controle_forum($type, $id_rubrique=0, $recherche='') { if ($recherche) { include_spip('inc/rechercher'); if ($a = recherche_en_base($recherche, 'forum')) - $and .= " AND ".calcul_mysql_in('id_forum', + $and .= " AND ".sql_in('id_forum', array_keys(array_pop($a))); else $and .= " 0=1"; diff --git a/ecrire/inc/modifier.php b/ecrire/inc/modifier.php index 6d157ffbf0..085b02a0fa 100644 --- a/ecrire/inc/modifier.php +++ b/ecrire/inc/modifier.php @@ -119,7 +119,7 @@ function marquer_doublons_documents($champs,$id,$id_table_objet,$table_objet){ sql_updateq("spip_documents_$table_objet", array("vu" => 'non'), "$id_table_objet=$id"); if (count($GLOBALS['doublons_documents_inclus'])){ // on repasse par une requete sur spip_documents pour verifier que les documents existent bien ! - $in_liste = calcul_mysql_in('id_document', + $in_liste = sql_in('id_document', $GLOBALS['doublons_documents_inclus']); $res = sql_select("id_document", "spip_documents", $in_liste); while ($row = sql_fetch($res)) { diff --git a/ecrire/inc/prepare_recherche.php b/ecrire/inc/prepare_recherche.php index 26914a0cc2..6fe019afa8 100644 --- a/ecrire/inc/prepare_recherche.php +++ b/ecrire/inc/prepare_recherche.php @@ -59,7 +59,7 @@ function inc_prepare_recherche_dist($recherche, $table='articles', $cond=false) # Pour les forums, unifier par id_thread et forcer statut='publie' if ($x == 'forum' AND $points) { $p2 = array(); - $s = sql_select("id_thread, id_forum", "spip_forum", "statut='publie' AND ".calcul_mysql_in('id_forum', array_keys($points))); + $s = sql_select("id_thread, id_forum", "spip_forum", "statut='publie' AND ".sql_in('id_forum', array_keys($points))); while ($t = sql_fetch($s)) $p2[intval($t['id_thread'])]['score'] += $points[intval($t['id_forum'])]['score']; @@ -77,11 +77,11 @@ function inc_prepare_recherche_dist($recherche, $table='articles', $cond=false) $listes_ids[$p['score']] .= ','.$id; foreach ($listes_ids as $p => $liste_ids) $select .= "+$p*(". - calcul_mysql_in("$table.$primary", substr($liste_ids, 1)) + sql_in("$table.$primary", substr($liste_ids, 1)) .") "; $cache[$recherche][$table] = array($select, - '('.calcul_mysql_in("$table.$primary", + '('.sql_in("$table.$primary", array_keys($points)).')' ); } diff --git a/ecrire/inc/rechercher.php b/ecrire/inc/rechercher.php index ede8ef5048..dd93ef67ba 100644 --- a/ecrire/inc/rechercher.php +++ b/ecrire/inc/rechercher.php @@ -246,7 +246,7 @@ function recherche_en_base($recherche='', $tables=NULL, $options=array()) { foreach ($joints as $jtable => $jj) { $it = id_table_objet($table); $ij = id_table_objet($jtable); - $s = sql_select("$it,$ij", "spip_${jtable}s_${table}s", calcul_mysql_in('id_'.${jtable}, array_keys($jj))); + $s = sql_select("$it,$ij", "spip_${jtable}s_${table}s", sql_in('id_'.${jtable}, array_keys($jj))); while ($t = sql_fetch($s)) { $id = $t[$it]; $joint = $jj[$t[$ij]]; diff --git a/ecrire/inc/rubriques.php b/ecrire/inc/rubriques.php index d408eb2baa..9b50f65f32 100644 --- a/ecrire/inc/rubriques.php +++ b/ecrire/inc/rubriques.php @@ -290,7 +290,7 @@ function calcul_generation ($generation) { $lesfils = array(); $result = sql_select(array('id_rubrique'), array('spip_rubriques AS rubriques'), - array(calcul_mysql_in('id_parent', $generation))); + array(sql_in('id_parent', $generation))); while ($row = sql_fetch($result)) $lesfils[] = $row['id_rubrique']; return join(",",$lesfils); diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php index 2fb7c2aba1..b888073c2a 100644 --- a/ecrire/public/criteres.php +++ b/ecrire/public/criteres.php @@ -59,7 +59,7 @@ function critere_doublons_dist($idb, &$boucles, $crit) { erreur_squelette(_T('zbug_doublon_table_sans_index'), "BOUCLE$idb"); $nom = !isset($crit->param[0]) ? "''" : calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent); // mettre un tableau pour que ce ne soit pas vu comme une constante - $boucle->where[]= array("calcul_mysql_in('".$boucle->id_table . '.' . $boucle->primary . + $boucle->where[]= array("sql_in('".$boucle->id_table . '.' . $boucle->primary . "', " . '"0".$doublons[' . ($crit->not ? '' : ($boucle->doublons . "[]= ")) . @@ -248,7 +248,7 @@ function critere_branche_dist($idb, &$boucles, $crit) { $cle = calculer_jointure($boucle, array($boucle->id_table, $desc), $cle, false); } - $c = "calcul_mysql_in('" . + $c = "sql_in('" . ($cle ? "L$cle" : $boucle->id_table) . ".id_rubrique', calcul_branche($arg), '')"; if ($crit->cond) $c = "($arg ? $c : 1)"; @@ -266,7 +266,7 @@ function critere_logo_dist($idb, &$boucles, $crit) { $not = $crit->not; $boucle = &$boucles[$idb]; - $c = "calcul_mysql_in('" . + $c = "sql_in('" . $boucle->id_table . '.' . $boucle->primary . "', lister_objets_avec_logos('". $boucle->primary ."'), '')"; if ($crit->cond) $c = "($arg ? $c : 1)"; @@ -739,7 +739,7 @@ function calculer_critere_infixe($idb, &$boucles, $crit) { // la valeur comparee doit etre munie ou non d'apostrophes if ($op == '=' OR in_array($op, $table_criteres_infixes)) { if (strpos($val[0], '_q(') === 0 - AND $desc AND test_sql_int($desc['field'][$col])) + AND $desc AND sql_test_int($desc['field'][$col])) $val[0] = 'intval' . substr($val[0],2); } // tag du critere pour permettre aux boucles de modifier leurs requetes par defaut en fonction de ca @@ -1023,7 +1023,6 @@ function calculer_critere_infixe_ops($idb, &$boucles, $crit) $val = 'id_parent'; // un critere conditionnel sur date est traite a part // car la date est mise d'office par SPIP, - // il faut if ($crit->cond AND tester_param_date('articles', $col)) $val ='@$Pile["env"][\'' . $col ."']"; else $val = calculer_argument_precedent($idb, $val, $boucles); diff --git a/ecrire/public/vertebrer.php b/ecrire/public/vertebrer.php index f8456b3dde..43af1a063f 100755 --- a/ecrire/public/vertebrer.php +++ b/ecrire/public/vertebrer.php @@ -32,7 +32,7 @@ function vertebrer_sort($fields, $direction) $res = ''; foreach($fields as $n => $t) { $tri = $direction - . ((test_sql_int($t) OR test_sql_date($r)) ? 'tri_n' : 'tri'); + . ((sql_test_int($t) OR sql_test_date($r)) ? 'tri_n' : 'tri'); $url = vertebrer_sanstri($tri) . "|parametre_url{" . $tri . ",'" . $n . "'}"; @@ -59,7 +59,7 @@ function vertebrer_form($fields) $url = join('|', array_keys($fields)); $url = "#SELF|\n\t\t\tparametre_url{'$url',''}"; foreach($fields as $n => $t) { - $s = test_sql_int($t) ? 11 + $s = sql_test_int($t) ? 11 : (preg_match('/char\s*\((\d)\)/i', $t, $r) ? $r[1] : ''); $res .= "\n\t\t<td><form action='./' method='get'>" @@ -98,7 +98,7 @@ function vertebrer_cell($fields) $url = "[(#SELF|parametre_url{page,'" . $r[1] . "'})]"; $texte = "<a href='$url'>" . $texte . "</a>"; } - $s = test_sql_int($t) ? " style='text-align: right;'" : ''; + $s = sql_test_int($t) ? " style='text-align: right;'" : ''; $res .= "\n\t\t<td$s>$texte</td>"; } } diff --git a/ecrire/req/mysql.php b/ecrire/req/mysql.php index 727f148d5d..d643f9f718 100644 --- a/ecrire/req/mysql.php +++ b/ecrire/req/mysql.php @@ -47,6 +47,7 @@ function req_mysql_dist($host, $port, $login, $pass, $db='', $prefixe='', $ldap= 'fetch' => 'spip_mysql_fetch', 'free' => 'spip_mysql_free', 'hex' => 'spip_mysql_hex', + 'in' => 'spip_mysql_in', 'insert' => 'spip_mysql_insert', 'insertq' => 'spip_mysql_insertq', 'listdbs' => 'spip_mysql_listdbs', @@ -524,10 +525,41 @@ function spip_mysql_hex($v) return "0x" . $v; } +// pour compatibilite +function spip_mysql_in($val, $valeurs, $not='', $serveur='') { + return calcul_mysql_in($val, $valeurs, $not); +} + +// +// IN (...) est limite a 255 elements, d'ou cette fonction assistante +// +// http://doc.spip.org/@calcul_mysql_in +function calcul_mysql_in($val, $valeurs, $not='') { + if (is_array($valeurs)) + $valeurs = join(',', array_map('_q', $valeurs)); + if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); + + $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)"; +} + // http://doc.spip.org/@spip_mysql_cite function spip_mysql_cite($v, $type) { - if (test_sql_date($type) AND preg_match('/^\w+\(/', $v) - OR (test_sql_int($type) + if (sql_test_date($type) AND preg_match('/^\w+\(/', $v) + OR (sql_test_int($type) AND (is_numeric($v) OR (ctype_xdigit(substr($v,2)) AND $v[0]=='0' AND $v[1]=='x')))) diff --git a/ecrire/req/pg.php b/ecrire/req/pg.php index a367ca85a7..656ac8a7a9 100644 --- a/ecrire/req/pg.php +++ b/ecrire/req/pg.php @@ -57,6 +57,7 @@ function req_pg_dist($addr, $port, $login, $pass, $db='', $prefixe='', $ldap='') 'fetch' => 'spip_pg_fetch', 'free' => 'spip_pg_free', 'hex' => 'spip_pg_hex', + 'in' => 'spip_pg_in', 'insert' => 'spip_pg_insert', 'insertq' => 'spip_pg_insertq', 'listdbs' => 'spip_pg_listdbs', @@ -642,7 +643,7 @@ function spip_pg_sequence($table) // http://doc.spip.org/@spip_pg_cite function spip_pg_cite($v, $t) { - if (test_sql_date($t)) { + if (sql_test_date($t)) { if (strpos("0123456789", $v[0]) === false) return spip_pg_frommysql($v); else { @@ -651,7 +652,7 @@ function spip_pg_cite($v, $t) return "date '$v'"; } } - elseif (test_sql_int($t) + elseif (sql_test_int($t) AND (is_numeric($v) OR (strpos($v, 'CAST(') === 0) OR ($v[0]== 'x' ? @@ -667,6 +668,33 @@ function spip_pg_hex($v) return "CAST(x'" . $v . "' as bigint)"; } +// http://doc.spip.org/@calcul_pg_in +function spip_pg_in($val, $valeurs, $not='', $serveur) { +// +// IN (...) souvent limite a 255 elements, d'ou cette fonction assistante +// + if (is_array($valeurs)) + $valeurs = join(',', array_map('_q', $valeurs)); + if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); + if (strpos($valeurs, "CAST(x'") !== false) + return "($val=" . join("OR $val=", explode(',',$valeurs)).')'; + $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)"; +} + // http://doc.spip.org/@spip_pg_error function spip_pg_error($query) { $s = str_replace('ERROR', 'errcode: 1000 ', pg_last_error()); @@ -725,23 +753,6 @@ function spip_pg_showtable($nom_table, $serveur='') return array('field' => $fields, 'key' => $keys); } -// http://doc.spip.org/@calcul_pg_in -function calcul_pg_in($val, $valeurs, $not='') { -// -// IN (...) souvent limite a 255 elements, d'ou cette fonction assistante -// - if (!$valeurs) return '0=0'; - $s = split(',', $valeurs, 255); - if (count($s) < 255) { - return ("($val $not IN ($valeurs))"); - } else { - $valeurs = array_pop($s); - return ("($val $not IN (" . join(',',$s) . "))\n" . - ($not ? "AND\t" : "OR\t") . - calcul_pgsql_in($val, $valeurs, $not)); - } -} - // Fonction de creation d'une table SQL nommee $nom // a partir de 2 tableaux PHP : // champs: champ => type -- GitLab