3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2019 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
14 * Gestion de l'itérateur SQL
16 * @package SPIP\Core\Iterateur\SQL
19 if (!defined('_ECRIRE_INC_VERSION')) {
27 * Permet d'itérer sur des données en base de données
29 class IterateurSQL
implements Iterator
{
36 protected $sqlresult = false;
43 protected $row = null;
45 protected $firstseek = false;
55 * Calcul du total des elements
62 * selectionner les donnees, ie faire la requete SQL
66 protected function select() {
69 $this->sqlresult
= calculer_select($v['select'], $v['from'], $v['type'], $v['where'], $v['join'], $v['groupby'],
70 $v['orderby'], $v['limit'], $v['having'], $v['table'], $v['id'], $v['connect'], $this->info
);
71 $this->err
= !$this->sqlresult
;
72 $this->firstseek
= false;
75 // pas d'init a priori, le calcul ne sera fait qu'en cas de besoin (provoque une double requete souvent inutile en sqlite)
76 //$this->total = $this->count();
80 * array command: les commandes d'initialisation
81 * array info: les infos sur le squelette
83 public function __construct($command, $info = array()) {
85 $this->command
= $command;
95 public function rewind() {
96 return ($this->pos
> 0)
102 * Verifier l'etat de l'iterateur
106 public function valid() {
110 if (!$this->firstseek
) {
114 return is_array($this->row
);
118 * Valeurs sur la position courante
122 public function current() {
126 public function key() {
131 * Sauter a une position absolue
134 * @param null|string $continue
137 public function seek($n = 0, $continue = null) {
138 if (!sql_seek($this->sqlresult
, $n, $this->command
['connect'], $continue)) {
139 // SQLite ne sait pas seek(), il faut relancer la query
140 // si la position courante est apres la position visee
141 // il faut relancer la requete
142 if ($this->pos
> $n) {
147 // et utiliser la methode par defaut pour se deplacer au bon endroit
148 // (sera fait en cas d'echec de cette fonction)
151 $this->row
= sql_fetch($this->sqlresult
, $this->command
['connect']);
152 $this->pos
= min($n, $this->count());
162 public function next() {
163 $this->row
= sql_fetch($this->sqlresult
, $this->command
['connect']);
165 $this->firstseek |
= true;
169 * Avancer et retourner les donnees pour le nouvel element
171 * @return array|bool|null
173 public function fetch() {
174 if ($this->valid()) {
175 $r = $this->current();
185 * liberer les ressources
189 public function free() {
190 if (!$this->sqlresult
) {
193 $a = sql_free($this->sqlresult
, $this->command
['connect']);
194 $this->sqlresult
= null;
200 * Compter le nombre de resultats
204 public function count() {
205 if (is_null($this->total
)) {
206 if (!$this->sqlresult
) {
210 if (in_array('count(*)', $this->command
['select'])) {
212 $s = $this->current();
213 $this->total
= $s['count(*)'];
215 $this->total
= sql_count($this->sqlresult
, $this->command
['connect']);