0337d704 |
1 | <?php |
2 | /*************************************************************************** |
50a40a33 |
3 | * Copyright (C) 2003-2006 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 | { |
f1ca33de |
24 | var $_trace_data = array(); |
25 | |
0337d704 |
26 | // {{{ function _prepare |
27 | |
28 | function _prepare($args) { |
08cce2ff |
29 | $query = array_map(Array('XDB', '_db_escape'), $args); |
0337d704 |
30 | $query[0] = str_replace('{?}', '%s', str_replace('%', '%%', $args[0])); |
31 | return call_user_func_array('sprintf', $query); |
32 | } |
13a25546 |
33 | |
0337d704 |
34 | // }}} |
7c571120 |
35 | // {{{ function _reformatQuery |
36 | |
37 | function _reformatQuery($query) |
38 | { |
39 | $query = preg_split("/\n\\s*/", $query); |
40 | $length = 0; |
d3c52d30 |
41 | foreach ($query as $key=>$line) { |
42 | $local = -2; |
eadff9f9 |
43 | if (preg_match('/^([A-Z]+(?:\s+(?:JOIN|BY|FROM|INTO))?)\s+(.*)/', $line, $matches) |
74581a1b |
44 | && $matches[1] != 'AND' && $matches[1] != 'OR') { |
d3c52d30 |
45 | $local = strlen($matches[1]); |
46 | $line = $matches[1] . ' ' . $matches[2]; |
47 | $length = max($length, $local); |
7c571120 |
48 | } |
d3c52d30 |
49 | $query[$key] = array($line, $local); |
7c571120 |
50 | } |
51 | $res = ''; |
d3c52d30 |
52 | foreach ($query as $array) { |
53 | list($line, $local) = $array; |
7c571120 |
54 | $local = $length - $local; |
55 | $res .= str_repeat(' ', $local) . $line . "\n"; |
56 | $length += 2 * (substr_count($line, '(') - substr_count($line, ')')); |
57 | } |
58 | return $res; |
59 | } |
60 | |
61 | // }}} |
62 | // {{{ function _query |
f1ca33de |
63 | |
64 | function _query($query) { |
65 | global $globals; |
66 | |
67 | if ($globals->debug & 1) { |
68 | $_res = mysql_query("EXPLAIN $query"); |
69 | $explain = array(); |
70 | while ($row = @mysql_fetch_assoc($_res)) { |
71 | $explain[] = $row; |
72 | } |
7c571120 |
73 | $trace_data = array('query' => XDB::_reformatQuery($query), 'explain' => $explain); |
f1ca33de |
74 | @mysql_free_result($_res); |
75 | } |
76 | |
77 | $res = mysql_query($query); |
78 | |
79 | if ($globals->debug & 1) { |
80 | $trace_data['error'] = mysql_error(); |
81 | $GLOBALS['XDB::trace_data'][] = $trace_data; |
eadff9f9 |
82 | if (mysql_errno()) { |
83 | $GLOBALS['XDB::error'] = true; |
84 | } |
f1ca33de |
85 | } |
86 | |
87 | return $res; |
88 | } |
89 | |
7c571120 |
90 | // }}} |
0337d704 |
91 | // {{{ function query |
92 | |
93 | function &query() |
94 | { |
08cce2ff |
95 | return new XOrgDBResult(XDB::_prepare(func_get_args())); |
0337d704 |
96 | } |
97 | |
98 | // }}} |
99 | // {{{ function execute() |
100 | |
f1ca33de |
101 | function execute() |
102 | { |
103 | return XDB::_query(XDB::_prepare(func_get_args())); |
0337d704 |
104 | } |
13a25546 |
105 | |
0337d704 |
106 | // }}} |
107 | // {{{ function iterator() |
108 | |
109 | function &iterator() |
110 | { |
08cce2ff |
111 | return new XOrgDBIterator(XDB::_prepare(func_get_args())); |
0337d704 |
112 | } |
13a25546 |
113 | |
0337d704 |
114 | // }}} |
115 | // {{{ function iterRow() |
116 | |
117 | function &iterRow() |
118 | { |
08cce2ff |
119 | return new XOrgDBIterator(XDB::_prepare(func_get_args()), MYSQL_NUM); |
0337d704 |
120 | } |
13a25546 |
121 | |
122 | // }}} |
123 | // {{{ function insertId() |
124 | |
125 | function insertId() |
126 | { |
127 | return mysql_insert_id(); |
128 | } |
129 | |
0337d704 |
130 | // }}} |
131 | // {{{ function _db_escape |
132 | |
133 | function _db_escape($var) |
134 | { |
135 | switch (gettype($var)) { |
13a25546 |
136 | case 'boolean': |
137 | return $var ? 1 : 0; |
138 | |
139 | case 'integer': |
140 | case 'double': |
141 | case 'float': |
142 | return $var; |
143 | |
144 | case 'string': |
145 | return "'".addslashes($var)."'"; |
146 | |
147 | case 'NULL': |
148 | return 'NULL'; |
149 | |
150 | case 'object': |
151 | case 'array': |
152 | return "'".addslashes(serialize($var))."'"; |
153 | |
154 | default: |
155 | die(var_export($var, true).' is not a valid for a database entry'); |
0337d704 |
156 | } |
157 | } |
158 | |
159 | // }}} |
f1ca33de |
160 | |
161 | function trace_format(&$page, $template = 'database-debug.tpl') { |
162 | $page->assign('trace_data', $GLOBALS['XDB::trace_data']); |
eadff9f9 |
163 | $page->assign('db_error', $GLOBALS['XDB::error']); |
f1ca33de |
164 | return $page->fetch($template); |
165 | } |
0337d704 |
166 | } |
167 | |
0337d704 |
168 | class XOrgDBResult |
169 | { |
170 | // {{{ properties |
171 | |
172 | var $_res; |
173 | |
174 | // }}} |
175 | // {{{ constructor |
176 | |
177 | function XOrgDBResult($query) |
178 | { |
755abda6 |
179 | $this->_res = XDB::_query($query); |
0337d704 |
180 | } |
181 | |
182 | // }}} |
183 | // {{{ destructor |
184 | |
185 | function free() |
186 | { |
187 | mysql_free_result($this->_res); |
188 | unset($this); |
189 | } |
190 | |
191 | // }}} |
192 | // {{{ function fetchRow |
193 | |
194 | function _fetchRow() |
195 | { |
196 | return mysql_fetch_row($this->_res); |
197 | } |
198 | |
199 | // }}} |
200 | // {{{ function fetchAssoc |
201 | |
202 | function _fetchAssoc() |
203 | { |
204 | return mysql_fetch_assoc($this->_res); |
205 | } |
206 | |
207 | // }}} |
208 | // {{{ function fetchAllRow |
209 | |
210 | function fetchAllRow() |
211 | { |
212 | $result = Array(); |
213 | while ($result[] = mysql_fetch_row($this->_res)) { } |
214 | array_pop($result); |
215 | $this->free(); |
216 | return $result; |
217 | } |
218 | |
219 | // }}} |
220 | // {{{ function fetchAllAssoc |
221 | |
222 | function fetchAllAssoc() |
223 | { |
224 | $result = Array(); |
225 | while ($result[] = mysql_fetch_assoc($this->_res)) { } |
226 | array_pop($result); |
227 | $this->free(); |
228 | return $result; |
229 | } |
230 | |
231 | // }}} |
232 | // {{{ function fetchOneAssoc() |
233 | |
234 | function fetchOneAssoc() |
235 | { |
236 | $tmp = $this->_fetchAssoc(); |
237 | $this->free(); |
238 | return $tmp; |
239 | } |
240 | |
241 | // }}} |
242 | // {{{ function fetchOneRow() |
243 | |
244 | function fetchOneRow() |
245 | { |
246 | $tmp = $this->_fetchRow(); |
247 | $this->free(); |
248 | return $tmp; |
249 | } |
250 | |
251 | // }}} |
252 | // {{{ function fetchOneCell() |
253 | |
254 | function fetchOneCell() |
255 | { |
256 | $tmp = $this->_fetchRow(); |
257 | $this->free(); |
258 | return $tmp[0]; |
259 | } |
260 | |
261 | // }}} |
262 | // {{{ function fetchColumn() |
263 | |
264 | function fetchColumn($key = 0) |
265 | { |
266 | $res = Array(); |
267 | if (is_numeric($key)) { |
268 | while($tmp = $this->_fetchRow()) { |
269 | $res[] = $tmp[$key]; |
270 | } |
271 | } else { |
272 | while($tmp = $this->_fetchAssoc()) { |
273 | $res[] = $tmp[$key]; |
274 | } |
275 | } |
276 | $this->free(); |
277 | return $res; |
278 | } |
279 | |
280 | // }}} |
281 | // {{{ function numRows |
13a25546 |
282 | |
0337d704 |
283 | function numRows() |
284 | { |
285 | return mysql_num_rows($this->_res); |
286 | } |
287 | |
288 | // }}} |
289 | } |
290 | |
da88cfee |
291 | class XOrgDBIterator |
0337d704 |
292 | { |
293 | // {{{ properties |
294 | |
295 | var $_result; |
296 | var $_pos; |
297 | var $_total; |
298 | var $_mode = MYSQL_ASSOC; |
299 | |
300 | // }}} |
301 | // {{{ constructor |
13a25546 |
302 | |
0337d704 |
303 | function XOrgDBIterator($query, $mode = MYSQL_ASSOC) |
304 | { |
305 | $this->_result =& new XOrgDBResult($query); |
306 | $this->_pos = 0; |
307 | $this->_total = $this->_result->numRows(); |
308 | $this->_mode = $mode; |
309 | } |
310 | |
311 | // }}} |
312 | // {{{ function next () |
13a25546 |
313 | |
0337d704 |
314 | function next() |
315 | { |
316 | $this->_pos ++; |
317 | if ($this->_pos > $this->_total) { |
318 | $this->_result->free(); |
319 | unset($this); |
320 | return null; |
321 | } |
322 | return $this->_mode != MYSQL_ASSOC ? $this->_result->_fetchRow() : $this->_result->_fetchAssoc(); |
323 | } |
324 | |
325 | // }}} |
326 | // {{{ function first |
327 | |
328 | function first() |
329 | { |
330 | return $this->_pos == 1; |
331 | } |
332 | |
333 | // }}} |
334 | // {{{ function last |
335 | |
336 | function last() |
337 | { |
338 | return $this->_last == $this->_total; |
339 | } |
340 | |
341 | // }}} |
342 | // {{{ function total() |
343 | |
344 | function total() |
345 | { |
346 | return $this->_total; |
347 | } |
348 | |
349 | // }}} |
350 | } |
351 | |
0337d704 |
352 | // vim:set et sw=4 sts=4 sws=4 foldmethod=marker: |
353 | ?> |