[SPIP] +installation version 3.0.10
[lhc/web/www.git] / www / ecrire / iterateur / sql.php
diff --git a/www/ecrire/iterateur/sql.php b/www/ecrire/iterateur/sql.php
new file mode 100644 (file)
index 0000000..f5cea84
--- /dev/null
@@ -0,0 +1,191 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2012                                                *
+ *  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.   *
+\***************************************************************************/
+
+if (!defined('_ECRIRE_INC_VERSION')) return;
+
+
+/**
+ * Iterateur SQL
+ */
+class IterateurSQL implements Iterator {
+
+       /**
+        * ressource sql
+        * @var resource|bool
+        */
+       protected $sqlresult = false;
+
+       /**
+        * row sql courante
+        * @var array|null
+        */
+       protected $row = null;
+
+       protected $firstseek = false;
+
+       /**
+        * Erreur presente ? 
+        *
+        * @var bool
+       **/
+       public $err = false;
+
+       /**
+        * Calcul du total des elements 
+        *
+        * @var int|null
+       **/
+       public $total = null;
+
+       /**
+        * selectionner les donnees, ie faire la requete SQL
+        * @return void
+        */
+       protected function select() {
+               $this->row = null;
+               $v = &$this->command;
+               $this->sqlresult = 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->err = !$this->sqlresult;
+               $this->firstseek = false;
+               $this->pos = -1;
+
+               // pas d'init a priori, le calcul ne sera fait qu'en cas de besoin (provoque une double requete souvent inutile en sqlite)
+               //$this->total = $this->count();
+       }
+
+       /*
+        * array command: les commandes d'initialisation
+        * array info: les infos sur le squelette
+        */
+       public function __construct($command, $info=array()) {
+               $this->type='SQL';
+               $this->command = $command;
+               $this->info = $info;
+               $this->select();
+       }
+
+       /**
+        * Rembobiner
+        * @return bool
+        */
+       public function rewind() {
+               return ($this->pos > 0)
+                       ? $this->seek(0)
+                       : true;
+       }
+
+       /**
+        * Verifier l'etat de l'iterateur
+        * @return bool
+        */
+       public function valid() {
+               if ($this->err)
+                       return false;
+               if (!$this->firstseek)
+                       $this->next();
+               return is_array($this->row);
+       }
+
+       /**
+        * Valeurs sur la position courante
+        * @return array
+        */
+       public function current() {
+               return $this->row;
+       }
+
+       public function key() {
+               return $this->pos;
+       }
+       
+       /**
+        * Sauter a une position absolue
+        * @param int $n
+        * @param null|string $continue
+        * @return bool
+        */
+       public function seek($n=0, $continue=null) {
+               if (!sql_seek($this->sqlresult, $n, $this->command['connect'], $continue)) {
+                       // SQLite ne sait pas seek(), il faut relancer la query
+                       // si la position courante est apres la position visee
+                       // il faut relancer la requete
+                       if ($this->pos>$n){
+                               $this->free();
+                               $this->select();
+                               $this->valid();
+                       }
+                       // et utiliser la methode par defaut pour se deplacer au bon endroit
+                       // (sera fait en cas d'echec de cette fonction)
+                       return false;
+               }
+               $this->row = sql_fetch($this->sqlresult, $this->command['connect']);
+               $this->pos = min($n,$this->count());
+               return true;
+       }
+
+       /**
+        * Avancer d'un cran
+        * @return void
+        */
+       public function next(){
+               $this->row = sql_fetch($this->sqlresult, $this->command['connect']);
+               $this->pos ++;
+               $this->firstseek |= true;
+       }
+
+       /**
+        * Avancer et retourner les donnees pour le nouvel element
+        * @return array|bool|null
+        */
+       public function fetch(){
+               if ($this->valid()) {
+                       $r = $this->current();
+                       $this->next();
+               } else
+                       $r = false;
+               return $r;
+       }
+
+       /**
+        * liberer les ressources
+        * @return bool
+        */
+       public function free(){
+               if (!$this->sqlresult) return true;
+               $a = sql_free($this->sqlresult, $this->command['connect']);
+         $this->sqlresult = null;
+         return $a;
+       }
+       
+       /**
+        * Compter le nombre de resultats
+        * @return int
+        */
+       public function count() {
+               if (is_null($this->total)) {
+                       if (!$this->sqlresult) {
+                               $this->total = 0;
+                       } else {
+                               # cas count(*)
+                               if (in_array('count(*)', $this->command['select'])) {
+                                       $this->valid();
+                                       $s = $this->current();
+                                       $this->total = $s['count(*)'];
+                               } else
+                                       $this->total = sql_count($this->sqlresult, $this->command['connect']);
+                       }
+               }
+               return $this->total;
+       }
+}
+
+?>