[SPIP] ~v3.0.20-->v3.0.25
[lhc/web/clavette_www.git] / www / ecrire / iterateur / sql.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2016 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
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 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15
16 /**
17 * Iterateur SQL
18 */
19 class IterateurSQL implements Iterator {
20
21 /**
22 * ressource sql
23 * @var resource|bool
24 */
25 protected $sqlresult = false;
26
27 /**
28 * row sql courante
29 * @var array|null
30 */
31 protected $row = null;
32
33 protected $firstseek = false;
34
35 /**
36 * Erreur presente ?
37 *
38 * @var bool
39 **/
40 public $err = false;
41
42 /**
43 * Calcul du total des elements
44 *
45 * @var int|null
46 **/
47 public $total = null;
48
49 /**
50 * selectionner les donnees, ie faire la requete SQL
51 * @return void
52 */
53 protected function select() {
54 $this->row = null;
55 $v = &$this->command;
56 $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);
57 $this->err = !$this->sqlresult;
58 $this->firstseek = false;
59 $this->pos = -1;
60
61 // pas d'init a priori, le calcul ne sera fait qu'en cas de besoin (provoque une double requete souvent inutile en sqlite)
62 //$this->total = $this->count();
63 }
64
65 /*
66 * array command: les commandes d'initialisation
67 * array info: les infos sur le squelette
68 */
69 public function __construct($command, $info=array()) {
70 $this->type='SQL';
71 $this->command = $command;
72 $this->info = $info;
73 $this->select();
74 }
75
76 /**
77 * Rembobiner
78 * @return bool
79 */
80 public function rewind() {
81 return ($this->pos > 0)
82 ? $this->seek(0)
83 : true;
84 }
85
86 /**
87 * Verifier l'etat de l'iterateur
88 * @return bool
89 */
90 public function valid() {
91 if ($this->err)
92 return false;
93 if (!$this->firstseek)
94 $this->next();
95 return is_array($this->row);
96 }
97
98 /**
99 * Valeurs sur la position courante
100 * @return array
101 */
102 public function current() {
103 return $this->row;
104 }
105
106 public function key() {
107 return $this->pos;
108 }
109
110 /**
111 * Sauter a une position absolue
112 * @param int $n
113 * @param null|string $continue
114 * @return bool
115 */
116 public function seek($n=0, $continue=null) {
117 if (!sql_seek($this->sqlresult, $n, $this->command['connect'], $continue)) {
118 // SQLite ne sait pas seek(), il faut relancer la query
119 // si la position courante est apres la position visee
120 // il faut relancer la requete
121 if ($this->pos>$n){
122 $this->free();
123 $this->select();
124 $this->valid();
125 }
126 // et utiliser la methode par defaut pour se deplacer au bon endroit
127 // (sera fait en cas d'echec de cette fonction)
128 return false;
129 }
130 $this->row = sql_fetch($this->sqlresult, $this->command['connect']);
131 $this->pos = min($n,$this->count());
132 return true;
133 }
134
135 /**
136 * Avancer d'un cran
137 * @return void
138 */
139 public function next(){
140 $this->row = sql_fetch($this->sqlresult, $this->command['connect']);
141 $this->pos ++;
142 $this->firstseek |= true;
143 }
144
145 /**
146 * Avancer et retourner les donnees pour le nouvel element
147 * @return array|bool|null
148 */
149 public function fetch(){
150 if ($this->valid()) {
151 $r = $this->current();
152 $this->next();
153 } else
154 $r = false;
155 return $r;
156 }
157
158 /**
159 * liberer les ressources
160 * @return bool
161 */
162 public function free(){
163 if (!$this->sqlresult) return true;
164 $a = sql_free($this->sqlresult, $this->command['connect']);
165 $this->sqlresult = null;
166 return $a;
167 }
168
169 /**
170 * Compter le nombre de resultats
171 * @return int
172 */
173 public function count() {
174 if (is_null($this->total)) {
175 if (!$this->sqlresult) {
176 $this->total = 0;
177 } else {
178 # cas count(*)
179 if (in_array('count(*)', $this->command['select'])) {
180 $this->valid();
181 $s = $this->current();
182 $this->total = $s['count(*)'];
183 } else
184 $this->total = sql_count($this->sqlresult, $this->command['connect']);
185 }
186 }
187 return $this->total;
188 }
189 }
190
191 ?>