Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

postgres.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 11.15 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb\db\driver;
015   
016  /**
017  * PostgreSQL Database Abstraction Layer
018  * Minimum Requirement is Version 8.3+
019  */
020  class postgres extends \phpbb\db\driver\driver
021  {
022      var $multi_insert = true;
023      var $last_query_text = '';
024      var $connect_error = '';
025   
026      /**
027      * {@inheritDoc}
028      */
029      function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
030      {
031          $connect_string = '';
032   
033          if ($sqluser)
034          {
035              $connect_string .= "user=$sqluser ";
036          }
037   
038          if ($sqlpassword)
039          {
040              $connect_string .= "password='$sqlpassword";
041          }
042   
043          if ($sqlserver)
044          {
045              // $sqlserver can carry a port separated by : for compatibility reasons
046              // If $sqlserver has more than one : it's probably an IPv6 address.
047              // In this case we only allow passing a port via the $port variable.
048              if (substr_count($sqlserver, ':') === 1)
049              {
050                  list($sqlserver, $port) = explode(':', $sqlserver);
051              }
052   
053              if ($sqlserver !== 'localhost')
054              {
055                  $connect_string .= "host=$sqlserver ";
056              }
057   
058              if ($port)
059              {
060                  $connect_string .= "port=$port ";
061              }
062          }
063   
064          $schema = '';
065   
066          if ($database)
067          {
068              $this->dbname = $database;
069              if (strpos($database, '.') !== false)
070              {
071                  list($database, $schema) = explode('.', $database);
072              }
073              $connect_string .= "dbname=$database";
074          }
075   
076          $this->persistency = $persistency;
077   
078          if ($this->persistency)
079          {
080              if (!function_exists('pg_pconnect'))
081              {
082                  $this->connect_error = 'pg_pconnect function does not exist, is pgsql extension installed?';
083                  return $this->sql_error('');
084              }
085              $collector = new \phpbb\error_collector;
086              $collector->install();
087              $this->db_connect_id = (!$new_link) ? @pg_pconnect($connect_string) : @pg_pconnect($connect_string, PGSQL_CONNECT_FORCE_NEW);
088          }
089          else
090          {
091              if (!function_exists('pg_connect'))
092              {
093                  $this->connect_error = 'pg_connect function does not exist, is pgsql extension installed?';
094                  return $this->sql_error('');
095              }
096              $collector = new \phpbb\error_collector;
097              $collector->install();
098              $this->db_connect_id = (!$new_link) ? @pg_connect($connect_string) : @pg_connect($connect_string, PGSQL_CONNECT_FORCE_NEW);
099          }
100   
101          $collector->uninstall();
102   
103          if ($this->db_connect_id)
104          {
105              if ($schema !== '')
106              {
107                  @pg_query($this->db_connect_id, 'SET search_path TO ' . $schema);
108              }
109              return $this->db_connect_id;
110          }
111   
112          $this->connect_error = $collector->format_errors();
113          return $this->sql_error('');
114      }
115   
116      /**
117      * {@inheritDoc}
118      */
119      function sql_server_info($raw = false, $use_cache = true)
120      {
121          global $cache;
122   
123          if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('pgsql_version')) === false)
124          {
125              $query_id = @pg_query($this->db_connect_id, 'SELECT VERSION() AS version');
126              if ($query_id)
127              {
128                  $row = pg_fetch_assoc($query_id, null);
129                  pg_free_result($query_id);
130   
131                  $this->sql_server_version = (!empty($row['version'])) ? trim(substr($row['version'], 10)) : 0;
132   
133                  if (!empty($cache) && $use_cache)
134                  {
135                      $cache->put('pgsql_version', $this->sql_server_version);
136                  }
137              }
138          }
139   
140          return ($raw) ? $this->sql_server_version : 'PostgreSQL ' . $this->sql_server_version;
141      }
142   
143      /**
144      * SQL Transaction
145      * @access private
146      */
147      function _sql_transaction($status = 'begin')
148      {
149          switch ($status)
150          {
151              case 'begin':
152                  return @pg_query($this->db_connect_id, 'BEGIN');
153              break;
154   
155              case 'commit':
156                  return @pg_query($this->db_connect_id, 'COMMIT');
157              break;
158   
159              case 'rollback':
160                  return @pg_query($this->db_connect_id, 'ROLLBACK');
161              break;
162          }
163   
164          return true;
165      }
166   
167      /**
168      * {@inheritDoc}
169      */
170      function sql_query($query = '', $cache_ttl = 0)
171      {
172          if ($query != '')
173          {
174              global $cache;
175   
176              if ($this->debug_sql_explain)
177              {
178                  $this->sql_report('start', $query);
179              }
180              else if ($this->debug_load_time)
181              {
182                  $this->curtime = microtime(true);
183              }
184   
185              $this->last_query_text = $query;
186              $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
187              $this->sql_add_num_queries($this->query_result);
188   
189              if ($this->query_result === false)
190              {
191                  try
192                  {
193                      $this->query_result = @pg_query($this->db_connect_id, $query);
194                  }
195                  catch (\Error $e)
196                  {
197                      // Do nothing as SQL driver will report the error
198                  }
199   
200                  if ($this->query_result === false)
201                  {
202                      $this->sql_error($query);
203                  }
204   
205                  if ($this->debug_sql_explain)
206                  {
207                      $this->sql_report('stop', $query);
208                  }
209                  else if ($this->debug_load_time)
210                  {
211                      $this->sql_time += microtime(true) - $this->curtime;
212                  }
213   
214                  if (!$this->query_result)
215                  {
216                      return false;
217                  }
218   
219                  $safe_query_id = $this->clean_query_id($this->query_result);
220   
221                  if ($cache && $cache_ttl)
222                  {
223                      $this->open_queries[$safe_query_id] = $this->query_result;
224                      $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
225                  }
226                  else if (strpos($query, 'SELECT') === 0)
227                  {
228                      $this->open_queries[$safe_query_id] = $this->query_result;
229                  }
230              }
231              else if ($this->debug_sql_explain)
232              {
233                  $this->sql_report('fromcache', $query);
234              }
235          }
236          else
237          {
238              return false;
239          }
240   
241          return $this->query_result;
242      }
243   
244      /**
245      * Build db-specific query data
246      * @access private
247      */
248      function _sql_custom_build($stage, $data)
249      {
250          return $data;
251      }
252   
253      /**
254      * Build LIMIT query
255      */
256      function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
257      {
258          $this->query_result = false;
259   
260          // if $total is set to 0 we do not want to limit the number of rows
261          if ($total == 0)
262          {
263              $total = 'ALL';
264          }
265   
266          $query .= "\n LIMIT $total OFFSET $offset";
267   
268          return $this->sql_query($query, $cache_ttl);
269      }
270   
271      /**
272      * {@inheritDoc}
273      */
274      function sql_affectedrows()
275      {
276          return ($this->query_result) ? @pg_affected_rows($this->query_result) : false;
277      }
278   
279      /**
280      * {@inheritDoc}
281      */
282      function sql_fetchrow($query_id = false)
283      {
284          global $cache;
285   
286          if ($query_id === false)
287          {
288              $query_id = $this->query_result;
289          }
290   
291          $safe_query_id = $this->clean_query_id($query_id);
292          if ($cache && $cache->sql_exists($safe_query_id))
293          {
294              return $cache->sql_fetchrow($safe_query_id);
295          }
296   
297          return ($query_id) ? pg_fetch_assoc($query_id, null) : false;
298      }
299   
300      /**
301      * {@inheritDoc}
302      */
303      function sql_rowseek($rownum, &$query_id)
304      {
305          global $cache;
306   
307          if ($query_id === false)
308          {
309              $query_id = $this->query_result;
310          }
311   
312          $safe_query_id = $this->clean_query_id($query_id);
313          if ($cache && $cache->sql_exists($safe_query_id))
314          {
315              return $cache->sql_rowseek($rownum, $safe_query_id);
316          }
317   
318          return ($query_id) ? @pg_result_seek($query_id, $rownum) : false;
319      }
320   
321      /**
322       * {@inheritDoc}
323       */
324      function sql_fetchfield($field, $rownum = false, $query_id = false)
325      {
326          global $cache;
327   
328          if ($query_id === false)
329          {
330              $query_id = $this->query_result;
331          }
332   
333          if ($query_id)
334          {
335              if ($rownum !== false)
336              {
337                  $this->sql_rowseek($rownum, $query_id);
338              }
339   
340              $safe_query_id = $this->clean_query_id($query_id);
341              if ($cache && !is_object($query_id) && $cache->sql_exists($safe_query_id))
342              {
343                  return $cache->sql_fetchfield($safe_query_id, $field);
344              }
345   
346              $row = $this->sql_fetchrow($query_id);
347              return (isset($row[$field])) ? $row[$field] : false;
348          }
349   
350          return false;
351      }
352   
353      /**
354       * {@inheritdoc}
355       */
356      public function sql_last_inserted_id()
357      {
358          $query_id = $this->query_result;
359   
360          if ($query_id !== false && $this->last_query_text != '')
361          {
362              if (preg_match("/^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)/is", $this->last_query_text, $tablename))
363              {
364                  $query = "SELECT currval('" . $tablename[1] . "_seq') AS last_value";
365                  $temp_q_id = @pg_query($this->db_connect_id, $query);
366   
367                  if (!$temp_q_id)
368                  {
369                      return false;
370                  }
371   
372                  $temp_result = pg_fetch_assoc($temp_q_id, null);
373                  pg_free_result($query_id);
374   
375                  return ($temp_result) ? $temp_result['last_value'] : false;
376              }
377          }
378   
379          return false;
380      }
381   
382      /**
383      * {@inheritDoc}
384      */
385      function sql_freeresult($query_id = false)
386      {
387          global $cache;
388   
389          if ($query_id === false)
390          {
391              $query_id = $this->query_result;
392          }
393   
394          $safe_query_id = $this->clean_query_id($query_id);
395          if ($cache && !is_object($query_id) && $cache->sql_exists($safe_query_id))
396          {
397              return $cache->sql_freeresult($safe_query_id);
398          }
399   
400          if (isset($this->open_queries[$safe_query_id]))
401          {
402              unset($this->open_queries[$safe_query_id]);
403              return pg_free_result($query_id);
404          }
405   
406          return false;
407      }
408   
409      /**
410      * {@inheritDoc}
411      */
412      function sql_escape($msg)
413      {
414          return @pg_escape_string($msg);
415      }
416   
417      /**
418      * Build LIKE expression
419      * @access private
420      */
421      function _sql_like_expression($expression)
422      {
423          return $expression;
424      }
425   
426      /**
427      * Build NOT LIKE expression
428      * @access private
429      */
430      function _sql_not_like_expression($expression)
431      {
432          return $expression;
433      }
434   
435      /**
436      * {@inheritDoc}
437      */
438      function cast_expr_to_bigint($expression)
439      {
440          return 'CAST(' . $expression . ' as DECIMAL(255, 0))';
441      }
442   
443      /**
444      * {@inheritDoc}
445      */
446      function cast_expr_to_string($expression)
447      {
448          return 'CAST(' . $expression . ' as VARCHAR(255))';
449      }
450   
451      /**
452      * return sql error array
453      * @access private
454      */
455      function _sql_error()
456      {
457          // pg_last_error only works when there is an established connection.
458          // Connection errors have to be tracked by us manually.
459          if ($this->db_connect_id)
460          {
461              $message = @pg_last_error($this->db_connect_id);
462          }
463          else
464          {
465              $message = $this->connect_error;
466          }
467   
468          return array(
469              'message'    => $message,
470              'code'        => ''
471          );
472      }
473   
474      /**
475      * Close sql connection
476      * @access private
477      */
478      function _sql_close()
479      {
480          // Released resources are already closed, return true in this case
481          if (!is_resource($this->db_connect_id))
482          {
483              return true;
484          }
485          return @pg_close($this->db_connect_id);
486      }
487   
488      /**
489      * Build db-specific report
490      * @access private
491      */
492      function _sql_report($mode, $query = '')
493      {
494          switch ($mode)
495          {
496              case 'start':
497   
498                  $explain_query = $query;
499                  if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
500                  {
501                      $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
502                  }
503                  else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
504                  {
505                      $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
506                  }
507   
508                  if (preg_match('/^SELECT/', $explain_query))
509                  {
510                      $html_table = false;
511   
512                      if ($result = @pg_query($this->db_connect_id, "EXPLAIN $explain_query"))
513                      {
514                          while ($row = pg_fetch_assoc($result, null))
515                          {
516                              $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
517                          }
518                          pg_free_result($result);
519                      }
520   
521                      if ($html_table)
522                      {
523                          $this->html_hold .= '</table>';
524                      }
525                  }
526   
527              break;
528   
529              case 'fromcache':
530                  $endtime = explode(' ', microtime());
531                  $endtime = $endtime[0] + $endtime[1];
532   
533                  $result = @pg_query($this->db_connect_id, $query);
534                  if ($result)
535                  {
536                      while ($void = pg_fetch_assoc($result, null))
537                      {
538                          // Take the time spent on parsing rows into account
539                      }
540                      pg_free_result($result);
541                  }
542   
543                  $splittime = explode(' ', microtime());
544                  $splittime = $splittime[0] + $splittime[1];
545   
546                  $this->sql_report('record_fromcache', $query, $endtime, $splittime);
547   
548              break;
549          }
550      }
551   
552      /**
553      * {@inheritDoc}
554      */
555      function sql_quote($msg)
556      {
557          return '"' . $msg . '"';
558      }
559  }
560