From 5105a66b4029866270b64bc6395233c85b3fa65e Mon Sep 17 00:00:00 2001 From: "Committo,Ergo:sum" <esj@rezo.net> Date: Mon, 27 Jun 2005 22:18:35 +0000 Subject: [PATCH] =?UTF-8?q?mauvais=20retour=20de=20boucles=20r=C3=A9cursiv?= =?UTF-8?q?es=20(nic;o=20&=20paolo);=20code=20gourmand,=20mort=20ou=20mal?= =?UTF-8?q?=20structur=C3=A9=20dans=20le=20calcul=20des=20champs=20SQL=20p?= =?UTF-8?q?ar=20le=20compilateur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecrire/inc_index.php3 | 20 +++------ inc-boucles.php3 | 2 - inc-compilo-api.php3 | 2 +- inc-compilo-index.php3 | 6 ++- inc-compilo.php3 | 100 ++++++++++++++++++----------------------- inc-criteres.php3 | 29 ++++++------ 6 files changed, 69 insertions(+), 90 deletions(-) diff --git a/ecrire/inc_index.php3 b/ecrire/inc_index.php3 index 59e969b397..1b57a94f5b 100644 --- a/ecrire/inc_index.php3 +++ b/ecrire/inc_index.php3 @@ -617,25 +617,19 @@ function prepare_recherche($recherche, $type = 'id_article', $table='articles') arsort($points, SORT_NUMERIC); # calculer le {id_article IN()} et le {... as points} - if (count($points)) { + if (!count($points)) { + $cache[$type][$recherche] = array('', ''); + } else { $ids = array(); - $expr = ''; + $select = '0'; foreach ($points as $id => $p) $listes_ids[$p] .= ','.$id; foreach ($listes_ids as $p => $liste_ids) - $expr .= "+$p*(".calcul_mysql_in("$table.$type", substr($liste_ids, 1)).") "; - if ($expr = substr($expr,1)) - $select = "$expr as points"; - else - $select = "0 as points"; + $select .= "+$p*(".calcul_mysql_in("$table.$type", substr($liste_ids, 1)).") "; - $where = '('.calcul_mysql_in("$table.$type", join(',',array_keys($points))).')'; - } else { - $select = ''; - $where = ''; + $cache[$type][$recherche] = array($select, + '('.calcul_mysql_in("$table.$type", join(',',array_keys($points))).')'); } - - $cache[$type][$recherche] = array($select, $where); } return $cache[$type][$recherche]; diff --git a/inc-boucles.php3 b/inc-boucles.php3 index 1da2f5d2ef..045343e5a1 100644 --- a/inc-boucles.php3 +++ b/inc-boucles.php3 @@ -280,8 +280,6 @@ function boucle_SYNDIC_ARTICLES_dist($id_boucle, &$boucles) { $boucle->where['statut'] = "$id_table.statut IN ('publie','prop')"; } - $boucle->select[]='syndic.nom_site AS nom_site'; # derogation zarbi - $boucle->select[]='syndic.url_site AS url_site'; # idem return calculer_boucle($id_boucle, $boucles); } diff --git a/inc-compilo-api.php3 b/inc-compilo-api.php3 index 0775a7e019..2b90e401ca 100644 --- a/inc-compilo-api.php3 +++ b/inc-compilo-api.php3 @@ -62,7 +62,7 @@ class Boucle { var $order = ''; var $default_order = ''; var $date = 'date' ; - var $hash = false ; + var $hash = "" ; var $lien = false; var $sous_requete = false; var $hierarchie = ''; diff --git a/inc-compilo-index.php3 b/inc-compilo-index.php3 index 7b78726525..c68e23697a 100644 --- a/inc-compilo-index.php3 +++ b/inc-compilo-index.php3 @@ -90,8 +90,10 @@ function index_pile($idb, $nom_champ, &$boucles, $explicite='') { // On l'a trouve if ($e) { - $boucles[$idb]->select[] = $t . "." . $e; - return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']'; + $t .= ".$e"; + if (!in_array($t, $boucles[$idb]->select)) + $boucles[$idb]->select[] = $t; + return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']'; } # spip_log("On remonte vers $i"); // Sinon on remonte d'un cran diff --git a/inc-compilo.php3 b/inc-compilo.php3 index b7c1943f24..198d9fad18 100644 --- a/inc-compilo.php3 +++ b/inc-compilo.php3 @@ -19,6 +19,8 @@ if (defined("_INC_COMPILO")) return; define("_INC_COMPILO", "1"); +// reperer un code ne calculant rien, meme avec commentaire +define('CODE_MONOTONE', "^(\n//[^\n]*\n)?\(?'([^'])*'\)?$"); // Definition de la structure $p, et fonctions de recherche et de reservation // dans l'arborescence des boucles @@ -83,20 +85,16 @@ function calculer_inclure($struct, $descr, &$boucles, $id_boucle) { // function calculer_boucle($id_boucle, &$boucles) { - $boucle = &$boucles[$id_boucle]; - $return = $boucle->return; - $type_boucle = $boucle->type_requete; - - if ($type_boucle == 'boucle') - return "\n \$t0 = " . $return . ";"; + $boucle = &$boucles[$id_boucle]; + $return = $boucle->return; + $type_boucle = $boucle->type_requete; + if ($type_boucle == 'boucle') { + $corps = "\n \$t0 = " . $return . ";"; + $init = ""; + } else { $id_table = $boucle->id_table; $primary = $boucle->primary; - if($p = strpos($primary, ',')) { - $id_field = $id_table . "." . substr($primary, 0, $p); - } else { - $id_field = $id_table . "." . $primary; - } // La boucle doit-elle selectionner la langue ? // 1. par defaut, les boucles suivantes le font @@ -114,33 +112,26 @@ function calculer_boucle($id_boucle, &$boucles) { if ($boucle->lang_select == 'oui') $lang_select = 'oui'; if ($boucle->lang_select == 'non') $lang_select = false; - // Penser a demander le champ lang + // Penser a demander le champ lang au serveur SQL if ($lang_select) - $boucle->select[] = - // cas des tables SPIP - ($id_table ? $id_table.'.' : '') - // cas general ({lang_select} sur une table externe) - . 'lang'; + index_pile($id_boucle, 'lang', $boucles); // Calculer les invalideurs si c'est une boucle non constante - $constant = ereg("^\(?'[^']*'\)?$",$return); - + $constant = ereg(CODE_MONOTONE,$return); if ((!$primary) || $constant) $invalide = ''; else { - $boucle->select[] = $id_field; - - $invalide = "\n \$Cache['$primary']"; - if ($primary != 'id_forum') - $invalide .= "[\$Pile[\$SP]['$primary']] = 1;"; - else - $invalide .= "[calcul_index_forum(" . - // Retournera 4 [$SP] mais force la demande du champ a MySQL - index_pile($id_boucle, 'id_article', $boucles) . ',' . - index_pile($id_boucle, 'id_breve', $boucles) . ',' . - index_pile($id_boucle, 'id_rubrique', $boucles) .',' . - index_pile($id_boucle, 'id_syndic', $boucles) . ")] = 1;"; - $invalide .= ' // invalideurs'; + $invalide = "\n \$Cache['$primary'][" . + (($primary != 'id_forum') ? + index_pile($id_boucle, $primary, $boucles) : + ("calcul_index_forum(" . + // Retournera 4 [$SP] mais force la demande du champ a MySQL + index_pile($id_boucle, 'id_article', $boucles) . ',' . + index_pile($id_boucle, 'id_breve', $boucles) . ',' . + index_pile($id_boucle, 'id_rubrique', $boucles) .',' . + index_pile($id_boucle, 'id_syndic', $boucles) . + ")")) . + '] = 1; // invalideurs'; } // Cas {1/3} {1,4} {n-2,1}... @@ -181,7 +172,6 @@ function calculer_boucle($id_boucle, &$boucles) { $code_sep = ("'" . ereg_replace("'","\'",join('',$boucle->separateur)) . "'"); // gestion optimale des separateurs et des boucles constantes - $corps = $debut . ((!$boucle->separateur) ? (($constant && !$debut) ? $return : @@ -197,29 +187,27 @@ function calculer_boucle($id_boucle, &$boucles) { if ($boucle->mode_partie) $corps .= "\n }\n"; - $texte = ''; + $init = ''; // Gestion de la hierarchie (voir inc-boucles.php3) if ($boucle->hierarchie) - $texte .= "\n ".$boucle->hierarchie; - + $init .= "\n ".$boucle->hierarchie; // si le corps est une constante, ne pas appeler le serveur N fois! - if (ereg("^\(?'[^']*'\)?$",$corps)) { - // vide ? - if (($corps == "''") || ($corps == "('')")) { + if (ereg(CODE_MONOTONE,$corps, $r)) { + if (!$r[2]) { if (!$boucle->numrows) return 'return "";'; else $corps = ""; } else { $boucle->numrows = true; - $corps = "\n ".'for($x=$Numrows["'.$id_boucle.'"]["total"];$x>0;$x--) + $corps = "\n ".'for($x=$Numrows["'.$id_boucle.'"]["total"];$x>0;$x--) $t0 .= ' . $corps .';'; } } else { - $corps = ' + $corps = ' // RESULTATS while ($Pile[$SP] = @spip_abstract_fetch($result,"' . @@ -229,7 +217,7 @@ function calculer_boucle($id_boucle, &$boucles) { // Memoriser la langue avant la boucle pour la restituer apres if ($lang_select) { - $texte .= "\n \$old_lang = \$GLOBALS['spip_lang'];"; + $init .= "\n \$old_lang = \$GLOBALS['spip_lang'];"; $corps .= "\n \$GLOBALS['spip_lang'] = \$old_lang;"; } } @@ -238,26 +226,21 @@ function calculer_boucle($id_boucle, &$boucles) { // Requete // - // hack critere recherche : ignorer la requete en cas de hash vide - // Recherche : recuperer les hash a partir de la chaine de recherche - if ($boucle->hash) - $init = ' - // RECHERCHE - list($rech_select, $rech_where) = prepare_recherche($GLOBALS["recherche"], "'.$boucle->primary.'", "'.$boucle->id_table.'"); - if ($rech_select) '; - if (!$order = $boucle->order AND !$order = $boucle->default_order) $order = "''"; - $init .= "\n\n // REQUETE + $init .= $boucle->hash . + "\n\n // REQUETE \$result = spip_abstract_select(\n\t\tarray(\"". # En absence de champ c'est un decompte : # prendre la primary pour avoir qqch # (COUNT incompatible avec le cas general - (($boucle->select) ? - join("\",\n\t\t\"", array_unique($boucle->select)) : - $id_field) . + ($boucle->select ? + join("\",\n\t\t\"", $boucle->select) : + ($id_table . "." . + (($p = strpos($primary, ',')) ? + substr($primary, 0, $p) : $primary))) . '"), # SELECT array("' . join('","', array_unique($boucle->from)) . @@ -297,15 +280,18 @@ function calculer_boucle($id_boucle, &$boucles) { // // Conclusion et retour // - $conclusion = "\n @spip_abstract_free(\$result,'" . - $boucle->sql_serveur . "');" . + $corps .= "\n @spip_abstract_free(\$result,'" . + $boucle->sql_serveur . "');"; + } + + return $init . $corps . ## inserer le code d'envoi au debusqueur du resultat de la fonction (($GLOBALS['var_mode_affiche'] != 'resultat') ? "" : " boucle_debug_resultat('$id_boucle', 'resultat', \$t0);") . "\n return \$t0;"; - return $texte . $init . $corps . $conclusion; + } diff --git a/inc-criteres.php3 b/inc-criteres.php3 index fa11e7cce8..fa4a0df15a 100644 --- a/inc-criteres.php3 +++ b/inc-criteres.php3 @@ -94,18 +94,18 @@ function critere_recherche_dist($idb, &$boucles, $crit) { $boucle = &$boucles[$idb]; - $table = $boucle->id_table; #articles - $id_table = 'id_'.preg_replace('/s$/', '', $table); #id_article + // Ne pas executer la requete en cas de hash vide + $boucle->hash = ' + // RECHERCHE + list($rech_select, $rech_where) = prepare_recherche($GLOBALS["recherche"], "'.$boucle->primary.'", "'.$boucle->id_table.'"); + if ($rech_where) '; - // horrible hack du aux id_forum = spip_forum et id_article=spip_articleS - // en fait il faudrait la fonction inverse de table_objet() - $id = 'id_'.preg_replace('/s$/', '', $boucle->id_table); - - $boucle->select[] = $boucle->id_table . '.' . $boucle->primary; # pour postgres, neuneu ici - $boucle->select[] = '$rech_select'; # pour les ... as points + $boucle->select[]= $boucle->id_table . '.' . $boucle->primary; # pour postgres, neuneu ici + $boucle->select[]= '$rech_select as points'; // et la recherche trouve $boucle->where[] = '$rech_where'; + } // {inverse} @@ -216,12 +216,12 @@ function critere_par_dist($idb, &$boucles, $crit) { // tester si cette version de MySQL accepte la commande RAND() // sinon faire un gloubi-boulga maison avec de la mayonnaise. if (spip_query("SELECT RAND()")) - $boucle->select[] = "RAND() AS alea"; + $tri = "RAND()"; else - $boucle->select[] = "MOD(".$boucle->id_table.'.'.$boucle->primary - ." * UNIX_TIMESTAMP(),32767) & UNIX_TIMESTAMP() AS alea"; - - $order = "'alea'"; + $tri = "MOD(".$boucle->id_table.'.'.$boucle->primary + ." * UNIX_TIMESTAMP(),32767) & UNIX_TIMESTAMP()"; + $boucle->select[]= $tri . " AS alea"; + $order = "'alea'"; } // par titre_mot @@ -559,8 +559,7 @@ function calculer_critere_DEFAUT($idb, &$boucles, $crit) { $where = "NOT ($where)"; } else { $boucle->default_order = 'rang'; - $boucle->select[] = - "FIND_IN_SET($ct, \\\"'\" . " . $val . ' . "\'\\") AS rang'; + $boucle->select[]= "FIND_IN_SET($ct, \\\"'\" . " . $val . ' . "\'\\") AS rang'; } } else { if ($op == '==') $op = 'REGEXP'; -- GitLab