Verzeichnisstruktur phpBB-3.0.0
- Veröffentlicht
- 12.12.2007
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
firebird.php
001 <?php
002 /**
003 *
004 * @package dbal
005 * @version $Id$
006 * @copyright (c) 2005 phpBB Group
007 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
008 *
009 */
010
011 /**
012 * @ignore
013 */
014 if (!defined('IN_PHPBB'))
015 {
016 exit;
017 }
018
019 include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx);
020
021 /**
022 * Firebird/Interbase Database Abstraction Layer
023 * Minimum Requirement is Firebird 2.0
024 * @package dbal
025 */
026 class dbal_firebird extends dbal
027 {
028 var $last_query_text = '';
029 var $service_handle = false;
030 var $affected_rows = 0;
031
032 /**
033 * Connect to server
034 */
035 function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
036 {
037 $this->persistency = $persistency;
038 $this->user = $sqluser;
039 $this->server = $sqlserver . (($port) ? ':' . $port : '');
040 $this->dbname = $database;
041
042 $this->db_connect_id = ($this->persistency) ? @ibase_pconnect($this->server . ':' . $this->dbname, $this->user, $sqlpassword, false, false, 3) : @ibase_connect($this->server . ':' . $this->dbname, $this->user, $sqlpassword, false, false, 3);
043
044 $this->service_handle = (function_exists('ibase_service_attach')) ? @ibase_service_attach($this->server, $this->user, $sqlpassword) : false;
045
046 return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
047 }
048
049 /**
050 * Version information about used database
051 */
052 function sql_server_info()
053 {
054 if ($this->service_handle !== false && function_exists('ibase_server_info'))
055 {
056 return @ibase_server_info($this->service_handle, IBASE_SVC_SERVER_VERSION);
057 }
058
059 return 'Firebird/Interbase';
060 }
061
062 /**
063 * SQL Transaction
064 * @access private
065 */
066 function _sql_transaction($status = 'begin')
067 {
068 switch ($status)
069 {
070 case 'begin':
071 return true;
072 break;
073
074 case 'commit':
075 return @ibase_commit();
076 break;
077
078 case 'rollback':
079 return @ibase_rollback();
080 break;
081 }
082
083 return true;
084 }
085
086 /**
087 * Base query method
088 *
089 * @param string $query Contains the SQL query which shall be executed
090 * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
091 * @return mixed When casted to bool the returned value returns true on success and false on failure
092 *
093 * @access public
094 */
095 function sql_query($query = '', $cache_ttl = 0)
096 {
097 if ($query != '')
098 {
099 global $cache;
100
101 // EXPLAIN only in extra debug mode
102 if (defined('DEBUG_EXTRA'))
103 {
104 $this->sql_report('start', $query);
105 }
106
107 $this->last_query_text = $query;
108 $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
109 $this->sql_add_num_queries($this->query_result);
110
111 if ($this->query_result === false)
112 {
113 $array = array();
114 // We overcome Firebird's 32767 char limit by binding vars
115 if (strlen($query) > 32767)
116 {
117 if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/s', $query, $regs))
118 {
119 if (strlen($regs[3]) > 32767)
120 {
121 preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER);
122
123 $inserts = $vals[0];
124 unset($vals);
125
126 foreach ($inserts as $key => $value)
127 {
128 if (!empty($value) && $value[0] === "'" && strlen($value) > 32769) // check to see if this thing is greater than the max + 'x2
129 {
130 $inserts[$key] = '?';
131 $array[] = str_replace("''", "'", substr($value, 1, -1));
132 }
133 }
134
135 $query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')';
136 }
137 }
138 else if (preg_match('/^(UPDATE ([\\w_]++)\\s+SET )([\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|\\d+)(?:,\\s*[\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+)\\s+(WHERE.*)$/s', $query, $data))
139 {
140 if (strlen($data[3]) > 32767)
141 {
142 $update = $data[1];
143 $where = $data[4];
144 preg_match_all('/(\\w++)\\s*=\\s*(\'(?:[^\']++|\'\')*+\'|[\d-.]++)/', $data[3], $temp, PREG_SET_ORDER);
145 unset($data);
146
147 $cols = array();
148 foreach ($temp as $value)
149 {
150 if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 32769) // check to see if this thing is greater than the max + 'x2
151 {
152 $array[] = str_replace("''", "'", substr($value[2], 1, -1));
153 $cols[] = $value[1] . '=?';
154 }
155 else
156 {
157 $cols[] = $value[1] . '=' . $value[2];
158 }
159 }
160
161 $query = $update . implode(', ', $cols) . ' ' . $where;
162 unset($cols);
163 }
164 }
165 }
166
167 if (!function_exists('ibase_affected_rows') && (preg_match('/^UPDATE ([\w_]++)\s+SET [\w_]++\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+)(?:,\s*[\w_]++\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+\s+(WHERE.*)?$/s', $query, $regs) || preg_match('/^DELETE FROM ([\w_]++)\s*(WHERE\s*.*)?$/s', $query, $regs)))
168 {
169 $affected_sql = 'SELECT COUNT(*) as num_rows_affected FROM ' . $regs[1];
170 if (!empty($regs[2]))
171 {
172 $affected_sql .= ' ' . $regs[2];
173 }
174
175 if (!($temp_q_id = @ibase_query($this->db_connect_id, $affected_sql)))
176 {
177 return false;
178 }
179
180 $temp_result = @ibase_fetch_assoc($temp_q_id);
181 @ibase_free_result($temp_q_id);
182
183 $this->affected_rows = ($temp_result) ? $temp_result['NUM_ROWS_AFFECTED'] : false;
184 }
185
186 if (sizeof($array))
187 {
188 $p_query = @ibase_prepare($this->db_connect_id, $query);
189 array_unshift($array, $p_query);
190 $this->query_result = call_user_func_array('ibase_execute', $array);
191 unset($array);
192
193 if ($this->query_result === false)
194 {
195 $this->sql_error($query);
196 }
197 }
198 else if (($this->query_result = @ibase_query($this->db_connect_id, $query)) === false)
199 {
200 $this->sql_error($query);
201 }
202
203 if (defined('DEBUG_EXTRA'))
204 {
205 $this->sql_report('stop', $query);
206 }
207
208 if (!$this->transaction)
209 {
210 if (function_exists('ibase_commit_ret'))
211 {
212 @ibase_commit_ret();
213 }
214 else
215 {
216 // way cooler than ibase_commit_ret :D
217 @ibase_query('COMMIT RETAIN;');
218 }
219 }
220
221 if ($cache_ttl && method_exists($cache, 'sql_save'))
222 {
223 $this->open_queries[(int) $this->query_result] = $this->query_result;
224 $cache->sql_save($query, $this->query_result, $cache_ttl);
225 }
226 else if (strpos($query, 'SELECT') === 0 && $this->query_result)
227 {
228 $this->open_queries[(int) $this->query_result] = $this->query_result;
229 }
230 }
231 else if (defined('DEBUG_EXTRA'))
232 {
233 $this->sql_report('fromcache', $query);
234 }
235 }
236 else
237 {
238 return false;
239 }
240
241 return ($this->query_result) ? $this->query_result : false;
242 }
243
244 /**
245 * Build LIMIT query
246 */
247 function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
248 {
249 $this->query_result = false;
250
251 $query = 'SELECT FIRST ' . $total . ((!empty($offset)) ? ' SKIP ' . $offset : '') . substr($query, 6);
252
253 return $this->sql_query($query, $cache_ttl);
254 }
255
256 /**
257 * Return number of affected rows
258 */
259 function sql_affectedrows()
260 {
261 // PHP 5+ function
262 if (function_exists('ibase_affected_rows'))
263 {
264 return ($this->db_connect_id) ? @ibase_affected_rows($this->db_connect_id) : false;
265 }
266 else
267 {
268 return $this->affected_rows;
269 }
270 }
271
272 /**
273 * Fetch current row
274 */
275 function sql_fetchrow($query_id = false)
276 {
277 global $cache;
278
279 if ($query_id === false)
280 {
281 $query_id = $this->query_result;
282 }
283
284 if (isset($cache->sql_rowset[$query_id]))
285 {
286 return $cache->sql_fetchrow($query_id);
287 }
288
289 if ($query_id === false)
290 {
291 return false;
292 }
293
294 $row = array();
295 $cur_row = @ibase_fetch_object($query_id, IBASE_TEXT);
296
297 if (!$cur_row)
298 {
299 return false;
300 }
301
302 foreach (get_object_vars($cur_row) as $key => $value)
303 {
304 $row[strtolower($key)] = (is_string($value)) ? trim(str_replace(array("\\0", "\\n"), array("\0", "\n"), $value)) : $value;
305 }
306
307 return (sizeof($row)) ? $row : false;
308 }
309
310 /**
311 * Seek to given row number
312 * rownum is zero-based
313 */
314 function sql_rowseek($rownum, &$query_id)
315 {
316 global $cache;
317
318 if ($query_id === false)
319 {
320 $query_id = $this->query_result;
321 }
322
323 if (isset($cache->sql_rowset[$query_id]))
324 {
325 return $cache->sql_rowseek($rownum, $query_id);
326 }
327
328 if ($query_id === false)
329 {
330 return;
331 }
332
333 $this->sql_freeresult($query_id);
334 $query_id = $this->sql_query($this->last_query_text);
335
336 if ($query_id === false)
337 {
338 return false;
339 }
340
341 // We do not fetch the row for rownum == 0 because then the next resultset would be the second row
342 for ($i = 0; $i < $rownum; $i++)
343 {
344 if (!$this->sql_fetchrow($query_id))
345 {
346 return false;
347 }
348 }
349
350 return true;
351 }
352
353 /**
354 * Get last inserted id after insert statement
355 */
356 function sql_nextid()
357 {
358 $query_id = $this->query_result;
359
360 if ($query_id !== false && $this->last_query_text != '')
361 {
362 if ($this->query_result && preg_match('#^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)#i', $this->last_query_text, $tablename))
363 {
364 $sql = 'SELECT GEN_ID(' . $tablename[1] . '_gen, 0) AS new_id FROM RDB$DATABASE';
365
366 if (!($temp_q_id = @ibase_query($this->db_connect_id, $sql)))
367 {
368 return false;
369 }
370
371 $temp_result = @ibase_fetch_assoc($temp_q_id);
372 @ibase_free_result($temp_q_id);
373
374 return ($temp_result) ? $temp_result['NEW_ID'] : false;
375 }
376 }
377
378 return false;
379 }
380
381 /**
382 * Free sql result
383 */
384 function sql_freeresult($query_id = false)
385 {
386 global $cache;
387
388 if ($query_id === false)
389 {
390 $query_id = $this->query_result;
391 }
392
393 if (isset($cache->sql_rowset[$query_id]))
394 {
395 return $cache->sql_freeresult($query_id);
396 }
397
398 if (isset($this->open_queries[(int) $query_id]))
399 {
400 unset($this->open_queries[(int) $query_id]);
401 return @ibase_free_result($query_id);
402 }
403
404 return false;
405 }
406
407 /**
408 * Escape string used in sql query
409 */
410 function sql_escape($msg)
411 {
412 return str_replace("'", "''", $msg);
413 }
414
415 /**
416 * Build LIKE expression
417 * @access private
418 */
419 function _sql_like_expression($expression)
420 {
421 return $expression . " ESCAPE '\\'";
422 }
423
424 /**
425 * Build db-specific query data
426 * @access private
427 */
428 function _sql_custom_build($stage, $data)
429 {
430 return $data;
431 }
432
433 /**
434 * return sql error array
435 * @access private
436 */
437 function _sql_error()
438 {
439 return array(
440 'message' => @ibase_errmsg(),
441 'code' => (@function_exists('ibase_errcode') ? @ibase_errcode() : '')
442 );
443 }
444
445 /**
446 * Close sql connection
447 * @access private
448 */
449 function _sql_close()
450 {
451 if ($this->service_handle !== false)
452 {
453 @ibase_service_detach($this->service_handle);
454 }
455
456 return @ibase_close($this->db_connect_id);
457 }
458
459 /**
460 * Build db-specific report
461 * @access private
462 */
463 function _sql_report($mode, $query = '')
464 {
465 switch ($mode)
466 {
467 case 'start':
468 break;
469
470 case 'fromcache':
471 $endtime = explode(' ', microtime());
472 $endtime = $endtime[0] + $endtime[1];
473
474 $result = @ibase_query($this->db_connect_id, $query);
475 while ($void = @ibase_fetch_object($result, IBASE_TEXT))
476 {
477 // Take the time spent on parsing rows into account
478 }
479 @ibase_free_result($result);
480
481 $splittime = explode(' ', microtime());
482 $splittime = $splittime[0] + $splittime[1];
483
484 $this->sql_report('record_fromcache', $query, $endtime, $splittime);
485
486 break;
487 }
488 }
489 }
490
491 ?>