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

mssqlnative.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 9.76 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  /**
015  * This is the MS SQL Server Native database abstraction layer.
016  * PHP mssql native driver required.
017  * @author Chris Pucci
018  *
019  */
020   
021  namespace phpbb\db\driver;
022   
023  class mssqlnative extends \phpbb\db\driver\mssql_base
024  {
025      var $m_insert_id = null;
026      var $last_query_text = '';
027      var $query_options = array();
028      var $connect_error = '';
029   
030      /**
031      * {@inheritDoc}
032      */
033      function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
034      {
035          // Test for driver support, to avoid suppressed fatal error
036          if (!function_exists('sqlsrv_connect'))
037          {
038              $this->connect_error = 'Native MS SQL Server driver for PHP is missing or needs to be updated. Version 1.1 or later is required to install phpBB3. You can download the driver from: http://www.microsoft.com/sqlserver/2005/en/us/PHP-Driver.aspx';
039              return $this->sql_error('');
040          }
041   
042          //set up connection variables
043          $this->persistency = $persistency;
044          $this->user = $sqluser;
045          $this->dbname = $database;
046          $port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':';
047          $this->server = $sqlserver . (($port) ? $port_delimiter . $port : '');
048   
049          //connect to database
050          $this->db_connect_id = sqlsrv_connect($this->server, array(
051              'Database' => $this->dbname,
052              'UID' => $this->user,
053              'PWD' => $sqlpassword,
054              'CharacterSet' => 'UTF-8'
055          ));
056   
057          return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
058      }
059   
060      /**
061      * {@inheritDoc}
062      */
063      function sql_server_info($raw = false, $use_cache = true)
064      {
065          global $cache;
066   
067          if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mssql_version')) === false)
068          {
069              $arr_server_info = sqlsrv_server_info($this->db_connect_id);
070              $this->sql_server_version = $arr_server_info['SQLServerVersion'];
071   
072              if (!empty($cache) && $use_cache)
073              {
074                  $cache->put('mssql_version', $this->sql_server_version);
075              }
076          }
077   
078          if ($raw)
079          {
080              return $this->sql_server_version;
081          }
082   
083          return ($this->sql_server_version) ? 'MSSQL<br />' . $this->sql_server_version : 'MSSQL';
084      }
085   
086      /**
087      * {@inheritDoc}
088      */
089      function sql_buffer_nested_transactions()
090      {
091          return true;
092      }
093   
094      /**
095      * SQL Transaction
096      * @access private
097      */
098      function _sql_transaction($status = 'begin')
099      {
100          switch ($status)
101          {
102              case 'begin':
103                  return sqlsrv_begin_transaction($this->db_connect_id);
104              break;
105   
106              case 'commit':
107                  return sqlsrv_commit($this->db_connect_id);
108              break;
109   
110              case 'rollback':
111                  return sqlsrv_rollback($this->db_connect_id);
112              break;
113          }
114          return true;
115      }
116   
117      /**
118      * {@inheritDoc}
119      */
120      function sql_query($query = '', $cache_ttl = 0)
121      {
122          if ($query != '')
123          {
124              global $cache;
125   
126              if ($this->debug_sql_explain)
127              {
128                  $this->sql_report('start', $query);
129              }
130              else if ($this->debug_load_time)
131              {
132                  $this->curtime = microtime(true);
133              }
134   
135              $this->last_query_text = $query;
136              $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
137              $this->sql_add_num_queries($this->query_result);
138   
139              if ($this->query_result === false)
140              {
141                  try
142                  {
143                      $this->query_result = @sqlsrv_query($this->db_connect_id, $query, array(), $this->query_options);
144                  }
145                  catch (\Error $e)
146                  {
147                      // Do nothing as SQL driver will report the error
148                  }
149   
150                  if ($this->query_result === false)
151                  {
152                      $this->sql_error($query);
153                  }
154   
155                  // Reset options for the next query
156                  $this->query_options = [];
157   
158                  if ($this->debug_sql_explain)
159                  {
160                      $this->sql_report('stop', $query);
161                  }
162                  else if ($this->debug_load_time)
163                  {
164                      $this->sql_time += microtime(true) - $this->curtime;
165                  }
166   
167                  if (!$this->query_result)
168                  {
169                      return false;
170                  }
171   
172                  $safe_query_id = $this->clean_query_id($this->query_result);
173   
174                  if ($cache && $cache_ttl)
175                  {
176                      $this->open_queries[$safe_query_id] = $this->query_result;
177                      $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
178                  }
179                  else if (strpos($query, 'SELECT') === 0)
180                  {
181                      $this->open_queries[$safe_query_id] = $this->query_result;
182                  }
183              }
184              else if ($this->debug_sql_explain)
185              {
186                  $this->sql_report('fromcache', $query);
187              }
188          }
189          else
190          {
191              return false;
192          }
193          return $this->query_result;
194      }
195   
196      /**
197      * Build LIMIT query
198      */
199      function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
200      {
201          $this->query_result = false;
202   
203          // total == 0 means all results - not zero results
204          if ($offset == 0 && $total !== 0)
205          {
206              if (strpos($query, "SELECT") === false)
207              {
208                  $query = "TOP {$total} " . $query;
209              }
210              else
211              {
212                  $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query);
213              }
214          }
215          else if ($offset > 0)
216          {
217              $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query);
218              $query = 'SELECT *
219                      FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3
220                      FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3';
221   
222              if ($total > 0)
223              {
224                  $query .= ' WHERE line3 BETWEEN ' . ($offset+1) . ' AND ' . ($offset + $total);
225              }
226              else
227              {
228                  $query .= ' WHERE line3 > ' . $offset;
229              }
230          }
231   
232          $result = $this->sql_query($query, $cache_ttl);
233   
234          return $result;
235      }
236   
237      /**
238      * {@inheritDoc}
239      */
240      function sql_affectedrows()
241      {
242          return ($this->db_connect_id) ? @sqlsrv_rows_affected($this->query_result) : false;
243      }
244   
245      /**
246      * {@inheritDoc}
247      */
248      function sql_fetchrow($query_id = false)
249      {
250          global $cache;
251   
252          if ($query_id === false)
253          {
254              $query_id = $this->query_result;
255          }
256   
257          $safe_query_id = $this->clean_query_id($query_id);
258          if ($cache && $cache->sql_exists($safe_query_id))
259          {
260              return $cache->sql_fetchrow($safe_query_id);
261          }
262   
263          if (!$query_id)
264          {
265              return false;
266          }
267   
268          $row = sqlsrv_fetch_array($query_id, SQLSRV_FETCH_ASSOC);
269   
270          if ($row)
271          {
272              foreach ($row as $key => $value)
273              {
274                  $row[$key] = ($value === ' ' || $value === null) ? '' : $value;
275              }
276   
277              // remove helper values from LIMIT queries
278              if (isset($row['line2']))
279              {
280                  unset($row['line2'], $row['line3']);
281              }
282          }
283          return ($row !== null) ? $row : false;
284      }
285   
286      /**
287       * {@inheritdoc}
288       */
289      public function sql_last_inserted_id()
290      {
291          $result_id = @sqlsrv_query($this->db_connect_id, 'SELECT @@IDENTITY');
292   
293          if ($result_id)
294          {
295              $row = sqlsrv_fetch_array($result_id);
296              $id = $row[0];
297              sqlsrv_free_stmt($result_id);
298              return $id;
299          }
300          else
301          {
302              return false;
303          }
304      }
305   
306      /**
307      * {@inheritDoc}
308      */
309      function sql_freeresult($query_id = false)
310      {
311          global $cache;
312   
313          if ($query_id === false)
314          {
315              $query_id = $this->query_result;
316          }
317   
318          $safe_query_id = $this->clean_query_id($query_id);
319          if ($cache && $cache->sql_exists($safe_query_id))
320          {
321              return $cache->sql_freeresult($safe_query_id);
322          }
323   
324          if (isset($this->open_queries[$safe_query_id]))
325          {
326              unset($this->open_queries[$safe_query_id]);
327              return sqlsrv_free_stmt($query_id);
328          }
329   
330          return false;
331      }
332   
333      /**
334      * return sql error array
335      * @access private
336      */
337      function _sql_error()
338      {
339          if (function_exists('sqlsrv_errors'))
340          {
341              $errors = @sqlsrv_errors(SQLSRV_ERR_ERRORS);
342              $error_message = '';
343              $code = 0;
344   
345              if ($errors != null)
346              {
347                  foreach ($errors as $error)
348                  {
349                      $error_message .= "SQLSTATE: " . $error['SQLSTATE'] . "\n";
350                      $error_message .= "code: " . $error['code'] . "\n";
351                      $code = $error['code'];
352                      $error_message .= "message: " . $error['message'] . "\n";
353                  }
354                  $this->last_error_result = $error_message;
355                  $error = $this->last_error_result;
356              }
357              else
358              {
359                  $error = (isset($this->last_error_result) && $this->last_error_result) ? $this->last_error_result : array();
360              }
361   
362              $error = array(
363                  'message'    => $error,
364                  'code'        => $code,
365              );
366          }
367          else
368          {
369              $error = array(
370                  'message'    => $this->connect_error,
371                  'code'        => '',
372              );
373          }
374   
375          return $error;
376      }
377   
378      /**
379      * Close sql connection
380      * @access private
381      */
382      function _sql_close()
383      {
384          return @sqlsrv_close($this->db_connect_id);
385      }
386   
387      /**
388      * Build db-specific report
389      * @access private
390      */
391      function _sql_report($mode, $query = '')
392      {
393          switch ($mode)
394          {
395              case 'start':
396                  $html_table = false;
397                  @sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT ON;');
398                  if ($result = @sqlsrv_query($this->db_connect_id, $query))
399                  {
400                      sqlsrv_next_result($result);
401                      while ($row = sqlsrv_fetch_array($result))
402                      {
403                          $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
404                      }
405                      sqlsrv_free_stmt($result);
406                  }
407                  @sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT OFF;');
408   
409                  if ($html_table)
410                  {
411                      $this->html_hold .= '</table>';
412                  }
413              break;
414   
415              case 'fromcache':
416                  $endtime = explode(' ', microtime());
417                  $endtime = $endtime[0] + $endtime[1];
418   
419                  $result = @sqlsrv_query($this->db_connect_id, $query);
420                  if ($result)
421                  {
422                      while ($void = sqlsrv_fetch_array($result))
423                      {
424                          // Take the time spent on parsing rows into account
425                      }
426                      sqlsrv_free_stmt($result);
427                  }
428   
429                  $splittime = explode(' ', microtime());
430                  $splittime = $splittime[0] + $splittime[1];
431   
432                  $this->sql_report('record_fromcache', $query, $endtime, $splittime);
433   
434              break;
435          }
436      }
437   
438      /**
439      * Utility method used to retrieve number of rows
440      * Emulates mysql_num_rows
441      * Used in acp_database.php -> write_data_mssqlnative()
442      * Requires a static or keyset cursor to be definde via
443      * mssqlnative_set_query_options()
444      */
445      function mssqlnative_num_rows($res)
446      {
447          if ($res !== false)
448          {
449              return sqlsrv_num_rows($res);
450          }
451          else
452          {
453              return false;
454          }
455      }
456   
457      /**
458      * Allows setting mssqlnative specific query options passed to sqlsrv_query as 4th parameter.
459      */
460      function mssqlnative_set_query_options($options)
461      {
462          $this->query_options = $options;
463      }
464  }
465