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 | { |
f1ca33de |
24 | var $_trace_data = array(); |
25 | |
ed3f4d3e |
26 | public static function _prepare($args) |
27 | { |
08cce2ff |
28 | $query = array_map(Array('XDB', '_db_escape'), $args); |
0337d704 |
29 | $query[0] = str_replace('{?}', '%s', str_replace('%', '%%', $args[0])); |
30 | return call_user_func_array('sprintf', $query); |
31 | } |
13a25546 |
32 | |
6995a9b9 |
33 | public static function _reformatQuery($query) |
7c571120 |
34 | { |
a4f89886 |
35 | $query = preg_split("/\n\\s*/", trim($query)); |
7c571120 |
36 | $length = 0; |
d3c52d30 |
37 | foreach ($query as $key=>$line) { |
38 | $local = -2; |
eadff9f9 |
39 | if (preg_match('/^([A-Z]+(?:\s+(?:JOIN|BY|FROM|INTO))?)\s+(.*)/', $line, $matches) |
85d3b330 |
40 | && $matches[1] != 'AND' && $matches[1] != 'OR') |
41 | { |
d3c52d30 |
42 | $local = strlen($matches[1]); |
43 | $line = $matches[1] . ' ' . $matches[2]; |
44 | $length = max($length, $local); |
7c571120 |
45 | } |
d3c52d30 |
46 | $query[$key] = array($line, $local); |
7c571120 |
47 | } |
48 | $res = ''; |
d3c52d30 |
49 | foreach ($query as $array) { |
50 | list($line, $local) = $array; |
9630c649 |
51 | $local = max(0, $length - $local); |
7c571120 |
52 | $res .= str_repeat(' ', $local) . $line . "\n"; |
53 | $length += 2 * (substr_count($line, '(') - substr_count($line, ')')); |
54 | } |
55 | return $res; |
56 | } |
57 | |
ed3f4d3e |
58 | public static function _query($query) |
59 | { |
f1ca33de |
60 | global $globals; |
61 | |
62 | if ($globals->debug & 1) { |
63 | $_res = mysql_query("EXPLAIN $query"); |
64 | $explain = array(); |
65 | while ($row = @mysql_fetch_assoc($_res)) { |
66 | $explain[] = $row; |
67 | } |
7c571120 |
68 | $trace_data = array('query' => XDB::_reformatQuery($query), 'explain' => $explain); |
f1ca33de |
69 | @mysql_free_result($_res); |
ed3f4d3e |
70 | $time_start = microtime(); |
f1ca33de |
71 | } |
72 | |
73 | $res = mysql_query($query); |
74 | |
75 | if ($globals->debug & 1) { |
ed3f4d3e |
76 | list($ue, $se) = explode(" ", microtime()); |
77 | list($us, $ss) = explode(" ", $time_start); |
78 | $time = intval((($ue - $us) + ($se - $ss)) * 1000); |
f1ca33de |
79 | $trace_data['error'] = mysql_error(); |
ed3f4d3e |
80 | $trace_data['exectime'] = $time; |
81 | $trace_data['rows'] = @mysql_num_rows() ? mysql_num_rows() : mysql_affected_rows(); |
f1ca33de |
82 | $GLOBALS['XDB::trace_data'][] = $trace_data; |
eadff9f9 |
83 | if (mysql_errno()) { |
84 | $GLOBALS['XDB::error'] = true; |
85 | } |
f1ca33de |
86 | } |
87 | |
88 | return $res; |
89 | } |
90 | |
6995a9b9 |
91 | public static function query() |
0337d704 |
92 | { |
08cce2ff |
93 | return new XOrgDBResult(XDB::_prepare(func_get_args())); |
0337d704 |
94 | } |
95 | |
6995a9b9 |
96 | public static function execute() |
f1ca33de |
97 | { |
98 | return XDB::_query(XDB::_prepare(func_get_args())); |
0337d704 |
99 | } |
13a25546 |
100 | |
6995a9b9 |
101 | public static function iterator() |
0337d704 |
102 | { |
08cce2ff |
103 | return new XOrgDBIterator(XDB::_prepare(func_get_args())); |
0337d704 |
104 | } |
13a25546 |
105 | |
6995a9b9 |
106 | public static function iterRow() |
0337d704 |
107 | { |
08cce2ff |
108 | return new XOrgDBIterator(XDB::_prepare(func_get_args()), MYSQL_NUM); |
0337d704 |
109 | } |
13a25546 |
110 | |
6995a9b9 |
111 | public static function insertId() |
13a25546 |
112 | { |
113 | return mysql_insert_id(); |
114 | } |
115 | |
6995a9b9 |
116 | public static function _db_escape($var) |
0337d704 |
117 | { |
118 | switch (gettype($var)) { |
13a25546 |
119 | case 'boolean': |
120 | return $var ? 1 : 0; |
121 | |
122 | case 'integer': |
123 | case 'double': |
124 | case 'float': |
125 | return $var; |
126 | |
127 | case 'string': |
128 | return "'".addslashes($var)."'"; |
129 | |
130 | case 'NULL': |
131 | return 'NULL'; |
132 | |
133 | case 'object': |
134 | case 'array': |
135 | return "'".addslashes(serialize($var))."'"; |
136 | |
137 | default: |
138 | die(var_export($var, true).' is not a valid for a database entry'); |
0337d704 |
139 | } |
140 | } |
141 | |
8b1f8e12 |
142 | public static function trace_format(&$page, $template = 'skin/common.database-debug.tpl') { |
6995a9b9 |
143 | $page->assign('trace_data', @$GLOBALS['XDB::trace_data']); |
144 | $page->assign('db_error', @$GLOBALS['XDB::error']); |
f1ca33de |
145 | return $page->fetch($template); |
146 | } |
0337d704 |
147 | } |
148 | |
0337d704 |
149 | class XOrgDBResult |
150 | { |
0337d704 |
151 | |
152 | var $_res; |
153 | |
0337d704 |
154 | function XOrgDBResult($query) |
155 | { |
755abda6 |
156 | $this->_res = XDB::_query($query); |
0337d704 |
157 | } |
158 | |
0337d704 |
159 | function free() |
160 | { |
161 | mysql_free_result($this->_res); |
162 | unset($this); |
163 | } |
164 | |
0337d704 |
165 | function _fetchRow() |
166 | { |
167 | return mysql_fetch_row($this->_res); |
168 | } |
169 | |
0337d704 |
170 | function _fetchAssoc() |
171 | { |
172 | return mysql_fetch_assoc($this->_res); |
173 | } |
174 | |
0337d704 |
175 | function fetchAllRow() |
176 | { |
177 | $result = Array(); |
178 | while ($result[] = mysql_fetch_row($this->_res)) { } |
179 | array_pop($result); |
180 | $this->free(); |
181 | return $result; |
182 | } |
183 | |
0337d704 |
184 | function fetchAllAssoc() |
185 | { |
186 | $result = Array(); |
187 | while ($result[] = mysql_fetch_assoc($this->_res)) { } |
188 | array_pop($result); |
189 | $this->free(); |
190 | return $result; |
191 | } |
192 | |
0337d704 |
193 | function fetchOneAssoc() |
194 | { |
195 | $tmp = $this->_fetchAssoc(); |
196 | $this->free(); |
197 | return $tmp; |
198 | } |
199 | |
0337d704 |
200 | function fetchOneRow() |
201 | { |
202 | $tmp = $this->_fetchRow(); |
203 | $this->free(); |
204 | return $tmp; |
205 | } |
206 | |
0337d704 |
207 | function fetchOneCell() |
208 | { |
209 | $tmp = $this->_fetchRow(); |
210 | $this->free(); |
211 | return $tmp[0]; |
212 | } |
213 | |
0337d704 |
214 | function fetchColumn($key = 0) |
215 | { |
216 | $res = Array(); |
217 | if (is_numeric($key)) { |
218 | while($tmp = $this->_fetchRow()) { |
219 | $res[] = $tmp[$key]; |
220 | } |
221 | } else { |
222 | while($tmp = $this->_fetchAssoc()) { |
223 | $res[] = $tmp[$key]; |
224 | } |
225 | } |
226 | $this->free(); |
227 | return $res; |
228 | } |
229 | |
0337d704 |
230 | function numRows() |
231 | { |
232 | return mysql_num_rows($this->_res); |
233 | } |
0337d704 |
234 | } |
235 | |
da88cfee |
236 | class XOrgDBIterator |
0337d704 |
237 | { |
85d3b330 |
238 | private $_result; |
239 | private $_pos; |
240 | private $_total; |
241 | private $_mode = MYSQL_ASSOC; |
0337d704 |
242 | |
85d3b330 |
243 | function __construct($query, $mode = MYSQL_ASSOC) |
0337d704 |
244 | { |
a0f05027 |
245 | $this->_result = new XOrgDBResult($query); |
0337d704 |
246 | $this->_pos = 0; |
247 | $this->_total = $this->_result->numRows(); |
248 | $this->_mode = $mode; |
249 | } |
250 | |
0337d704 |
251 | function next() |
252 | { |
253 | $this->_pos ++; |
254 | if ($this->_pos > $this->_total) { |
255 | $this->_result->free(); |
256 | unset($this); |
257 | return null; |
258 | } |
259 | return $this->_mode != MYSQL_ASSOC ? $this->_result->_fetchRow() : $this->_result->_fetchAssoc(); |
260 | } |
261 | |
0337d704 |
262 | function first() |
263 | { |
264 | return $this->_pos == 1; |
265 | } |
266 | |
0337d704 |
267 | function last() |
268 | { |
269 | return $this->_last == $this->_total; |
270 | } |
271 | |
0337d704 |
272 | function total() |
273 | { |
274 | return $this->_total; |
275 | } |
0337d704 |
276 | } |
277 | |
0337d704 |
278 | // vim:set et sw=4 sts=4 sws=4 foldmethod=marker: |
279 | ?> |