Skip to content
Extraits de code Groupes Projets
Valider 446799bc rédigé par Fil's avatar Fil
Parcourir les fichiers

introduction d'un iterateur generique a la place de la logique SQL des boucles

parent 9c09dfe9
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -300,6 +300,7 @@ ecrire/public/aiguiller.php -text ...@@ -300,6 +300,7 @@ ecrire/public/aiguiller.php -text
ecrire/public/decompiler.php -text ecrire/public/decompiler.php -text
ecrire/public/format_html.php -text ecrire/public/format_html.php -text
ecrire/public/index.php -text ecrire/public/index.php -text
ecrire/public/iterateur.php -text
ecrire/public/jointures.php -text ecrire/public/jointures.php -text
ecrire/public/normaliser.php -text ecrire/public/normaliser.php -text
ecrire/public/quete.php -text ecrire/public/quete.php -text
......
...@@ -242,13 +242,28 @@ function calculer_boucle_rec($id_boucle, &$boucles, $trace) { ...@@ -242,13 +242,28 @@ function calculer_boucle_rec($id_boucle, &$boucles, $trace) {
define('CODE_CORPS_BOUCLE', '%s define('CODE_CORPS_BOUCLE', '%s
$t0 = ""; $t0 = "";
// REQUETE // REQUETE
$result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect, $iter = new Iter("SQL");
array(%s)); $iter->init( array(
if ($result) { "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++; %s%s$SP++;
// RESULTATS // RESULTATS
%s %s
%s@sql_free($result%s); %s$iter->free();
}%s }%s
return $t0;' return $t0;'
); );
...@@ -342,9 +357,6 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { ...@@ -342,9 +357,6 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) {
. $boucle->partie . $boucle->partie
. $corps; . $corps;
$serveur = !$boucle->sql_serveur ? ''
: (', ' . _q($boucle->sql_serveur));
// si le corps est une constante, ne pas appeler le serveur N fois! // si le corps est une constante, ne pas appeler le serveur N fois!
if (preg_match(CODE_MONOTONE,str_replace("\\'",'',$corps), $r)) { if (preg_match(CODE_MONOTONE,str_replace("\\'",'',$corps), $r)) {
...@@ -357,7 +369,7 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { ...@@ -357,7 +369,7 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) {
$boucle->numrows = true; $boucle->numrows = true;
$corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);"; $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 = ''; $count = '';
if (!$boucle->select) { if (!$boucle->select) {
...@@ -374,8 +386,8 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { ...@@ -374,8 +386,8 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) {
if ($boucle->numrows OR $boucle->mode_partie) { if ($boucle->numrows OR $boucle->mode_partie) {
if ($count == 'count(*)') if ($count == 'count(*)')
$count = "array_shift(sql_fetch(\$result$serveur))"; $count = "array_shift(\$iter->next())";
else $count = "sql_count(\$result$serveur)"; else $count = "\$iter->count()";
$nums .= "\$Numrows['$id_boucle']['total'] = @intval($count);" $nums .= "\$Numrows['$id_boucle']['total'] = @intval($count);"
. $boucle->mode_partie . $boucle->mode_partie
. "\n\t"; . "\n\t";
...@@ -389,8 +401,10 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { ...@@ -389,8 +401,10 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) {
. calculer_requete_sql($boucles[$id_boucle]); . calculer_requete_sql($boucles[$id_boucle]);
$contexte = memoriser_contexte_compil($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;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
if (!defined("_ECRIRE_INC_VERSION")) return; if (!defined("_ECRIRE_INC_VERSION")) return;
include_spip('public/iterateur');
include_spip('inc/texte'); include_spip('inc/texte');
include_spip('inc/documents'); include_spip('inc/documents');
include_spip('inc/distant'); include_spip('inc/distant');
......
...@@ -156,11 +156,8 @@ function critere_pagination_dist($idb, &$boucles, $crit) { ...@@ -156,11 +156,8 @@ function critere_pagination_dist($idb, &$boucles, $crit) {
// tester si le numero de page demande est de la forme '@yyy' // tester si le numero de page demande est de la forme '@yyy'
'isset($Pile[0]['.$debut.']) ? $Pile[0]['.$debut.'] : _request('.$debut.");\n" 'isset($Pile[0]['.$debut.']) ? $Pile[0]['.$debut.'] : _request('.$debut.");\n"
."\tif(substr(\$debut_boucle,0,1)=='@'){\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".'$debut_boucle = $Pile[0]['. $debut.'] = quete_debut_pagination(\''.$boucle->primary.'\',$Pile[0][\'@'.$boucle->primary.'\'] = substr($debut_boucle,1),'.$pas.',$iter);'."\n"
."\t\t".'if (!sql_seek($result,0,'._q($boucle->sql_serveur).")){\n" ."\t\t".'$iter->seek(0);'."\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}\n" ."\t}\n"
."\t".'$debut_boucle = intval($debut_boucle)'; ."\t".'$debut_boucle = intval($debut_boucle)';
...@@ -665,7 +662,7 @@ function calculer_parties(&$boucles, $id_boucle, $debut, $mode) { ...@@ -665,7 +662,7 @@ function calculer_parties(&$boucles, $id_boucle, $debut, $mode) {
. '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n " . '$fin_boucle = min(' . $fin . ", \$Numrows['$id_boucle']['total'] - 1);\n "
. '$Numrows[\''.$id_boucle. "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n " . '$Numrows[\''.$id_boucle. "']['grand_total'] = \$Numrows['$id_boucle']['total'];\n "
. '$Numrows[\''.$id_boucle.'\']["total"] = max(0,$fin_boucle - $debut_boucle + 1);' . '$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 = " $boucles[$id_boucle]->partie = "
if (\$Numrows['$id_boucle']['compteur_boucle'] <= \$debut_boucle) continue; if (\$Numrows['$id_boucle']['compteur_boucle'] <= \$debut_boucle) continue;
......
<?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']);
}
}
?>
...@@ -254,14 +254,14 @@ function calcul_exposer ($id, $prim, $reference, $parent, $type, $connect='') { ...@@ -254,14 +254,14 @@ function calcul_exposer ($id, $prim, $reference, $parent, $type, $connect='') {
return isset($exposer[$m][$prim]) ? isset($exposer[$m][$prim][$id]) : ''; 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 // on ne devrait pas arriver ici si la cle primaire est inexistante
// ou composee, mais verifions // ou composee, mais verifions
if (!$primary OR preg_match('/[,\s]/',$primary)) if (!$primary OR preg_match('/[,\s]/',$primary))
return 0; return 0;
$pos = 0; $pos = 0;
while ($row = sql_fetch($res,$serveur) AND $row[$primary]!=$valeur){ while ($row = $iter->next() AND $row[$primary]!=$valeur){
$pos++; $pos++;
} }
// si on a pas trouve // si on a pas trouve
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter