0337d704 |
1 | <?php |
2 | /*************************************************************************** |
5ddeb07c |
3 | * Copyright (C) 2003-2007 Polytechnique.org * |
0337d704 |
4 | * http://opensource.polytechnique.org/ * |
5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU General Public License as published by * |
8 | * the Free Software Foundation; either version 2 of the License, or * |
9 | * (at your option) any later version. * |
10 | * * |
11 | * This program is distributed in the hope that it will be useful, * |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
14 | * GNU General Public License for more details. * |
15 | * * |
16 | * You should have received a copy of the GNU General Public License * |
17 | * along with this program; if not, write to the Free Software * |
18 | * Foundation, Inc., * |
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * |
20 | **************************************************************************/ |
21 | |
08cce2ff |
22 | class XDB |
0337d704 |
23 | { |
32d9ae72 |
24 | private static $mysqli = null; |
25 | |
821744e0 |
26 | public static function connect() |
32d9ae72 |
27 | { |
821744e0 |
28 | global $globals; |
29 | XDB::$mysqli = new mysqli($globals->dbhost, $globals->dbuser, $globals->dbpwd, $globals->dbdb); |
d3f26be9 |
30 | if ($globals->debug & 1) { |
31 | $bt = new PlBacktrace('MySQL'); |
32 | if (mysqli_connect_errno()) { |
33 | $bt->newEvent("MySQLI connection", 0, mysqli_connect_error()); |
34 | return false; |
35 | } |
32d9ae72 |
36 | } |
37 | XDB::$mysqli->autocommit(true); |
821744e0 |
38 | XDB::$mysqli->set_charset($globals->dbcharset); |
32d9ae72 |
39 | return true; |
40 | } |
f1ca33de |
41 | |
ed3f4d3e |
42 | public static function _prepare($args) |
43 | { |
08cce2ff |
44 | $query = array_map(Array('XDB', '_db_escape'), $args); |
0337d704 |
45 | $query[0] = str_replace('{?}', '%s', str_replace('%', '%%', $args[0])); |
46 | return call_user_func_array('sprintf', $query); |
47 | } |
13a25546 |
48 | |
6995a9b9 |
49 | public static function _reformatQuery($query) |
7c571120 |
50 | { |
a4f89886 |
51 | $query = preg_split("/\n\\s*/", trim($query)); |
7c571120 |
52 | $length = 0; |
d3c52d30 |
53 | foreach ($query as $key=>$line) { |
54 | $local = -2; |
a14159bf |
55 | if (preg_match('/^([A-Z]+(?:\s+(?:JOIN|BY|FROM|INTO))?)\s+(.*)/u', $line, $matches) |
85d3b330 |
56 | && $matches[1] != 'AND' && $matches[1] != 'OR') |
57 | { |
d3c52d30 |
58 | $local = strlen($matches[1]); |
59 | $line = $matches[1] . ' ' . $matches[2]; |
60 | $length = max($length, $local); |
7c571120 |
61 | } |
d3c52d30 |
62 | $query[$key] = array($line, $local); |
7c571120 |
63 | } |
64 | $res = ''; |
d3c52d30 |
65 | foreach ($query as $array) { |
66 | list($line, $local) = $array; |
9630c649 |
67 | $local = max(0, $length - $local); |
7c571120 |
68 | $res .= str_repeat(' ', $local) . $line . "\n"; |
69 | $length += 2 * (substr_count($line, '(') - substr_count($line, ')')); |
70 | } |
71 | return $res; |
72 | } |
73 | |
ed3f4d3e |
74 | public static function _query($query) |
75 | { |
f1ca33de |
76 | global $globals; |
77 | |
821744e0 |
78 | if (!XDB::$mysqli && !XDB::connect()) { |
79 | return false; |
80 | } |
81 | |
5fb22b39 |
82 | if ($globals->debug & 1) { |
f1ca33de |
83 | $explain = array(); |
5fb22b39 |
84 | if (strpos($query, 'FOUND_ROWS()') === false) { |
32d9ae72 |
85 | $res = XDB::$mysqli->query("EXPLAIN $query"); |
86 | if ($res) { |
87 | while ($row = $res->fetch_assoc()) { |
5fb22b39 |
88 | $explain[] = $row; |
89 | } |
32d9ae72 |
90 | $res->free(); |
5fb22b39 |
91 | } |
f1ca33de |
92 | } |
d3f26be9 |
93 | PlBacktrace::$bt['MySQL']->start(XDB::_reformatQuery($query)); |
f1ca33de |
94 | } |
95 | |
32d9ae72 |
96 | $res = XDB::$mysqli->query($query); |
a14159bf |
97 | |
f1ca33de |
98 | if ($globals->debug & 1) { |
d3f26be9 |
99 | PlBacktrace::$bt['MySQL']->stop(@$res->num_rows ? $res->num_rows : XDB::$mysqli->affected_rows, |
100 | XDB::$mysqli->error, |
101 | $explain); |
f1ca33de |
102 | } |
f1ca33de |
103 | return $res; |
104 | } |
105 | |
6995a9b9 |
106 | public static function query() |
0337d704 |
107 | { |
08cce2ff |
108 | return new XOrgDBResult(XDB::_prepare(func_get_args())); |
0337d704 |
109 | } |
110 | |
6995a9b9 |
111 | public static function execute() |
f1ca33de |
112 | { |
113 | return XDB::_query(XDB::_prepare(func_get_args())); |
0337d704 |
114 | } |
13a25546 |
115 | |
6995a9b9 |
116 | public static function iterator() |
0337d704 |
117 | { |
08cce2ff |
118 | return new XOrgDBIterator(XDB::_prepare(func_get_args())); |
0337d704 |
119 | } |
13a25546 |
120 | |
6995a9b9 |
121 | public static function iterRow() |
0337d704 |
122 | { |
08cce2ff |
123 | return new XOrgDBIterator(XDB::_prepare(func_get_args()), MYSQL_NUM); |
0337d704 |
124 | } |
13a25546 |
125 | |
6995a9b9 |
126 | public static function insertId() |
13a25546 |
127 | { |
32d9ae72 |
128 | return XDB::$mysqli->insert_id; |
13a25546 |
129 | } |
130 | |
0380bf85 |
131 | public static function errno() |
132 | { |
0380bf85 |
133 | return XDB::$mysqli->errno; |
134 | } |
135 | |
136 | public static function error() |
137 | { |
0380bf85 |
138 | return XDB::$mysqli->error; |
139 | } |
140 | |
141 | public static function affectedRows() |
142 | { |
143 | return XDB::$mysqli->affected_rows; |
144 | } |
145 | |
6995a9b9 |
146 | public static function _db_escape($var) |
0337d704 |
147 | { |
148 | switch (gettype($var)) { |
13a25546 |
149 | case 'boolean': |
150 | return $var ? 1 : 0; |
151 | |
152 | case 'integer': |
153 | case 'double': |
154 | case 'float': |
155 | return $var; |
156 | |
157 | case 'string': |
158 | return "'".addslashes($var)."'"; |
159 | |
160 | case 'NULL': |
161 | return 'NULL'; |
162 | |
163 | case 'object': |
164 | case 'array': |
165 | return "'".addslashes(serialize($var))."'"; |
166 | |
167 | default: |
168 | die(var_export($var, true).' is not a valid for a database entry'); |
0337d704 |
169 | } |
170 | } |
0337d704 |
171 | } |
172 | |
0337d704 |
173 | class XOrgDBResult |
174 | { |
0337d704 |
175 | |
32d9ae72 |
176 | private $_res; |
0337d704 |
177 | |
0337d704 |
178 | function XOrgDBResult($query) |
179 | { |
755abda6 |
180 | $this->_res = XDB::_query($query); |
0337d704 |
181 | } |
182 | |
0337d704 |
183 | function free() |
184 | { |
32d9ae72 |
185 | $this->_res->free(); |
0337d704 |
186 | unset($this); |
187 | } |
188 | |
0337d704 |
189 | function _fetchRow() |
190 | { |
32d9ae72 |
191 | return $this->_res->fetch_row(); |
0337d704 |
192 | } |
193 | |
0337d704 |
194 | function _fetchAssoc() |
195 | { |
32d9ae72 |
196 | return $this->_res->fetch_assoc(); |
0337d704 |
197 | } |
198 | |
0337d704 |
199 | function fetchAllRow() |
200 | { |
201 | $result = Array(); |
32d9ae72 |
202 | while ($result[] = $this->_res->fetch_row()); |
0337d704 |
203 | array_pop($result); |
204 | $this->free(); |
205 | return $result; |
206 | } |
207 | |
0337d704 |
208 | function fetchAllAssoc() |
209 | { |
210 | $result = Array(); |
32d9ae72 |
211 | while ($result[] = $this->_res->fetch_assoc()); |
0337d704 |
212 | array_pop($result); |
213 | $this->free(); |
214 | return $result; |
215 | } |
216 | |
0337d704 |
217 | function fetchOneAssoc() |
218 | { |
219 | $tmp = $this->_fetchAssoc(); |
220 | $this->free(); |
221 | return $tmp; |
222 | } |
223 | |
0337d704 |
224 | function fetchOneRow() |
225 | { |
226 | $tmp = $this->_fetchRow(); |
227 | $this->free(); |
228 | return $tmp; |
229 | } |
230 | |
0337d704 |
231 | function fetchOneCell() |
232 | { |
233 | $tmp = $this->_fetchRow(); |
234 | $this->free(); |
235 | return $tmp[0]; |
236 | } |
237 | |
0337d704 |
238 | function fetchColumn($key = 0) |
239 | { |
240 | $res = Array(); |
241 | if (is_numeric($key)) { |
242 | while($tmp = $this->_fetchRow()) { |
243 | $res[] = $tmp[$key]; |
244 | } |
245 | } else { |
246 | while($tmp = $this->_fetchAssoc()) { |
247 | $res[] = $tmp[$key]; |
248 | } |
249 | } |
250 | $this->free(); |
251 | return $res; |
252 | } |
253 | |
0380bf85 |
254 | function fetchOneField() |
255 | { |
256 | return $this->_res->fetch_field(); |
257 | } |
258 | |
259 | function fetchFields() |
260 | { |
261 | $res = array(); |
262 | while ($res[] = $this->fetchOneField()); |
263 | return $res; |
264 | } |
265 | |
0337d704 |
266 | function numRows() |
267 | { |
32d9ae72 |
268 | return $this->_res->num_rows; |
0337d704 |
269 | } |
0380bf85 |
270 | |
271 | function fieldCount() |
272 | { |
273 | return $this->_res->field_count; |
274 | } |
0337d704 |
275 | } |
276 | |
da88cfee |
277 | class XOrgDBIterator |
0337d704 |
278 | { |
85d3b330 |
279 | private $_result; |
280 | private $_pos; |
281 | private $_total; |
0380bf85 |
282 | private $_fpos; |
283 | private $_fields; |
85d3b330 |
284 | private $_mode = MYSQL_ASSOC; |
0337d704 |
285 | |
85d3b330 |
286 | function __construct($query, $mode = MYSQL_ASSOC) |
0337d704 |
287 | { |
a0f05027 |
288 | $this->_result = new XOrgDBResult($query); |
0337d704 |
289 | $this->_pos = 0; |
290 | $this->_total = $this->_result->numRows(); |
0380bf85 |
291 | $this->_fpost = 0; |
292 | $this->_fields = $this->_result->fieldCount(); |
0337d704 |
293 | $this->_mode = $mode; |
294 | } |
295 | |
0337d704 |
296 | function next() |
297 | { |
298 | $this->_pos ++; |
299 | if ($this->_pos > $this->_total) { |
300 | $this->_result->free(); |
301 | unset($this); |
302 | return null; |
303 | } |
304 | return $this->_mode != MYSQL_ASSOC ? $this->_result->_fetchRow() : $this->_result->_fetchAssoc(); |
305 | } |
306 | |
0337d704 |
307 | function first() |
308 | { |
309 | return $this->_pos == 1; |
310 | } |
311 | |
0337d704 |
312 | function last() |
313 | { |
0380bf85 |
314 | return $this->_pos == $this->_total; |
0337d704 |
315 | } |
316 | |
0337d704 |
317 | function total() |
318 | { |
319 | return $this->_total; |
320 | } |
0380bf85 |
321 | |
322 | function nextField() |
323 | { |
324 | $this->_fpos++; |
325 | if ($this->_fpos > $this->_fields) { |
326 | return null; |
327 | } |
328 | return $this->_result->fetchOneField(); |
329 | } |
330 | |
331 | function firstField() |
332 | { |
333 | return $this->_fpos == 1; |
334 | } |
335 | |
336 | function lastField() |
337 | { |
338 | return $this->_fpos == $this->_fields; |
339 | } |
340 | |
341 | function totalFields() |
342 | { |
343 | return $this->_fields; |
344 | } |
0337d704 |
345 | } |
346 | |
a7de4ef7 |
347 | // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: |
0337d704 |
348 | ?> |