From 446799bc8aa3e37e3ac356a2469b041908a07022 Mon Sep 17 00:00:00 2001 From: Fil <fil@rezo.net> Date: Sat, 11 Dec 2010 13:35:49 +0000 Subject: [PATCH] introduction d'un iterateur generique a la place de la logique SQL des boucles --- .gitattributes | 1 + ecrire/public/compiler.php | 36 +++++++++++++------ ecrire/public/composer.php | 1 + ecrire/public/criteres.php | 9 ++--- ecrire/public/iterateur.php | 69 +++++++++++++++++++++++++++++++++++++ ecrire/public/quete.php | 4 +-- 6 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 ecrire/public/iterateur.php diff --git a/.gitattributes b/.gitattributes index 767bbe93f4..59c27ec16c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -300,6 +300,7 @@ ecrire/public/aiguiller.php -text ecrire/public/decompiler.php -text ecrire/public/format_html.php -text ecrire/public/index.php -text +ecrire/public/iterateur.php -text ecrire/public/jointures.php -text ecrire/public/normaliser.php -text ecrire/public/quete.php -text diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php index 5c77168c40..35b7a0c778 100644 --- a/ecrire/public/compiler.php +++ b/ecrire/public/compiler.php @@ -242,13 +242,28 @@ function calculer_boucle_rec($id_boucle, &$boucles, $trace) { define('CODE_CORPS_BOUCLE', '%s $t0 = ""; // REQUETE - $result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect, - array(%s)); - if ($result) { + $iter = new Iter("SQL"); + $iter->init( array( + "select"=>$select, + "from"=>$from, + "type"=>$type, + "where"=>$where, + "join"=>$join, + "groupby"=>$groupby, + "orderby"=>$orderby, + "limit"=>$limit, + "having"=>$having, + "table"=>$table, + "id"=>$id, + "connect"=>$connect + ), + array(%s) + ); + if ($iter->ok) { %s%s$SP++; // RESULTATS %s - %s@sql_free($result%s); + %s$iter->free(); }%s return $t0;' ); @@ -342,9 +357,6 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { . $boucle->partie . $corps; - $serveur = !$boucle->sql_serveur ? '' - : (', ' . _q($boucle->sql_serveur)); - // si le corps est une constante, ne pas appeler le serveur N fois! if (preg_match(CODE_MONOTONE,str_replace("\\'",'',$corps), $r)) { @@ -357,7 +369,7 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { $boucle->numrows = true; $corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);"; } - } else $corps = "while (\$Pile[\$SP] = @sql_fetch(\$result$serveur)) {\n$corps\n }"; + } else $corps = "while (\$Pile[\$SP] = \$iter->next()) {\n$corps\n }"; $count = ''; if (!$boucle->select) { @@ -374,8 +386,8 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { if ($boucle->numrows OR $boucle->mode_partie) { if ($count == 'count(*)') - $count = "array_shift(sql_fetch(\$result$serveur))"; - else $count = "sql_count(\$result$serveur)"; + $count = "array_shift(\$iter->next())"; + else $count = "\$iter->count()"; $nums .= "\$Numrows['$id_boucle']['total'] = @intval($count);" . $boucle->mode_partie . "\n\t"; @@ -389,8 +401,10 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { . calculer_requete_sql($boucles[$id_boucle]); $contexte = memoriser_contexte_compil($boucle); + $a = sprintf(CODE_CORPS_BOUCLE, $init, $contexte, $nums, $init_lang, $corps, $fin_lang, $trace); - return sprintf(CODE_CORPS_BOUCLE, $init, $contexte, $nums, $init_lang, $corps, $fin_lang, $serveur, $trace); +# var_dump($a);exit; + return $a; } diff --git a/ecrire/public/composer.php b/ecrire/public/composer.php index 1538b2bf7a..ecc139cdcc 100644 --- a/ecrire/public/composer.php +++ b/ecrire/public/composer.php @@ -12,6 +12,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return; +include_spip('public/iterateur'); include_spip('inc/texte'); include_spip('inc/documents'); include_spip('inc/distant'); diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php index fd8b097da0..c0265cf7a6 100644 --- a/ecrire/public/criteres.php +++ b/ecrire/public/criteres.php @@ -156,11 +156,8 @@ function critere_pagination_dist($idb, &$boucles, $crit) { // tester si le numero de page demande est de la forme '@yyy' 'isset($Pile[0]['.$debut.']) ? $Pile[0]['.$debut.'] : _request('.$debut.");\n" ."\tif(substr(\$debut_boucle,0,1)=='@'){\n" - ."\t\t".'$debut_boucle = $Pile[0]['. $debut.'] = quete_debut_pagination(\''.$boucle->primary.'\',$Pile[0][\'@'.$boucle->primary.'\'] = substr($debut_boucle,1),'.$pas.',$result,'._q($boucle->sql_serveur).');'."\n" - ."\t\t".'if (!sql_seek($result,0,'._q($boucle->sql_serveur).")){\n" - ."\t\t\t".'@sql_free($result,'._q($boucle->sql_serveur).");\n" - ."\t\t\t".'$result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect);'."\n" - ."\t\t}\n" + ."\t\t".'$debut_boucle = $Pile[0]['. $debut.'] = quete_debut_pagination(\''.$boucle->primary.'\',$Pile[0][\'@'.$boucle->primary.'\'] = substr($debut_boucle,1),'.$pas.',$iter);'."\n" + ."\t\t".'$iter->seek(0);'."\n" ."\t}\n" ."\t".'$debut_boucle = intval($debut_boucle)'; @@ -665,7 +662,7 @@ function calculer_parties(&$boucles, $id_boucle, $debut, $mode) { . '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n " . '$Numrows[\''.$id_boucle. "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n " . '$Numrows[\''.$id_boucle.'\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);' - . "\n\tif (\$debut_boucle>0 AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total'] AND sql_seek(\$result,\$debut_boucle,"._q($boucles[$id_boucle]->sql_serveur).",'continue'))\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t"; + . "\n\tif (\$debut_boucle>0 AND \$debut_boucle < \$Numrows['$id_boucle']['grand_total'] AND \$iter->seek(\$debut_boucle,'continue'))\n\t\t\$Numrows['$id_boucle']['compteur_boucle'] = \$debut_boucle;\n\t"; $boucles[$id_boucle]->partie = " if (\$Numrows['$id_boucle']['compteur_boucle'] <= \$debut_boucle) continue; diff --git a/ecrire/public/iterateur.php b/ecrire/public/iterateur.php new file mode 100644 index 0000000000..419b470d49 --- /dev/null +++ b/ecrire/public/iterateur.php @@ -0,0 +1,69 @@ +<?php + + +/***************************************************************************\ + * SPIP, Systeme de publication pour l'internet * + * * + * Copyright (c) 2001-2010 * + * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * + * * + * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * + * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * +\***************************************************************************/ + + +// +// Iterateur SQL +// + +class Iter { + var $ok = false; + var $type; + var $command; + var $info; + + private $result = false; + + + public function Iter($type) { + $this->type = $type; + } + + private function select() { + $v = &$this->command; + $this->result = calculer_select($v['select'], $v['from'], $v['type'], $v['where'], $v['join'], $v['groupby'], $v['orderby'], $v['limit'], $v['having'], $v['table'], $v['id'], $v['connect'], $this->info); + $this->ok = !!$this->result; + } + + /* + * array command: les commandes d'initialisation + * array info: les infos sur le squelette + */ + public function init($command, $info=array()) { + $this->command = $command; + $this->info = $info; + $this->select(); + } + public function seek($n=0, $continue=null) { + # SQLite ne sait pas seek(), il faut relancer la query + if (!$a = sql_seek($this->result, $this->command['connect'], $n, $continue)) { + $this->free(); + $this->select(); + return true; # ?? + } + return $a; + } + public function next(){ + return sql_fetch($this->result, $this->command['connect']); + } + public function free(){ + return sql_free($this->result, $this->command['connect']); + } + public function count() { + return sql_count($this->result, $this->command['connect']); + } +} + + + +?> diff --git a/ecrire/public/quete.php b/ecrire/public/quete.php index 7272421233..900f8b7d95 100644 --- a/ecrire/public/quete.php +++ b/ecrire/public/quete.php @@ -254,14 +254,14 @@ function calcul_exposer ($id, $prim, $reference, $parent, $type, $connect='') { return isset($exposer[$m][$prim]) ? isset($exposer[$m][$prim][$id]) : ''; } -function quete_debut_pagination($primary,$valeur,$pas,$res,$serveur=''){ +function quete_debut_pagination($primary,$valeur,$pas,$iter){ // on ne devrait pas arriver ici si la cle primaire est inexistante // ou composee, mais verifions if (!$primary OR preg_match('/[,\s]/',$primary)) return 0; $pos = 0; - while ($row = sql_fetch($res,$serveur) AND $row[$primary]!=$valeur){ + while ($row = $iter->next() AND $row[$primary]!=$valeur){ $pos++; } // si on a pas trouve -- GitLab