Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
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 |
mssqlnative.php
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 ));
055
056 return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
057 }
058
059 /**
060 * {@inheritDoc}
061 */
062 function sql_server_info($raw = false, $use_cache = true)
063 {
064 global $cache;
065
066 if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mssql_version')) === false)
067 {
068 $arr_server_info = sqlsrv_server_info($this->db_connect_id);
069 $this->sql_server_version = $arr_server_info['SQLServerVersion'];
070
071 if (!empty($cache) && $use_cache)
072 {
073 $cache->put('mssql_version', $this->sql_server_version);
074 }
075 }
076
077 if ($raw)
078 {
079 return $this->sql_server_version;
080 }
081
082 return ($this->sql_server_version) ? 'MSSQL<br />' . $this->sql_server_version : 'MSSQL';
083 }
084
085 /**
086 * {@inheritDoc}
087 */
088 function sql_buffer_nested_transactions()
089 {
090 return true;
091 }
092
093 /**
094 * SQL Transaction
095 * @access private
096 */
097 function _sql_transaction($status = 'begin')
098 {
099 switch ($status)
100 {
101 case 'begin':
102 return sqlsrv_begin_transaction($this->db_connect_id);
103 break;
104
105 case 'commit':
106 return sqlsrv_commit($this->db_connect_id);
107 break;
108
109 case 'rollback':
110 return sqlsrv_rollback($this->db_connect_id);
111 break;
112 }
113 return true;
114 }
115
116 /**
117 * {@inheritDoc}
118 */
119 function sql_query($query = '', $cache_ttl = 0)
120 {
121 if ($query != '')
122 {
123 global $cache;
124
125 // EXPLAIN only in extra debug mode
126 if (defined('DEBUG'))
127 {
128 $this->sql_report('start', $query);
129 }
130 else if (defined('PHPBB_DISPLAY_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 if (($this->query_result = @sqlsrv_query($this->db_connect_id, $query, array(), $this->query_options)) === false)
142 {
143 $this->sql_error($query);
144 }
145 // reset options for next query
146 $this->query_options = array();
147
148 if (defined('DEBUG'))
149 {
150 $this->sql_report('stop', $query);
151 }
152 else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
153 {
154 $this->sql_time += microtime(true) - $this->curtime;
155 }
156
157 if (!$this->query_result)
158 {
159 return false;
160 }
161
162 if ($cache && $cache_ttl)
163 {
164 $this->open_queries[(int) $this->query_result] = $this->query_result;
165 $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
166 }
167 else if (strpos($query, 'SELECT') === 0)
168 {
169 $this->open_queries[(int) $this->query_result] = $this->query_result;
170 }
171 }
172 else if (defined('DEBUG'))
173 {
174 $this->sql_report('fromcache', $query);
175 }
176 }
177 else
178 {
179 return false;
180 }
181 return $this->query_result;
182 }
183
184 /**
185 * Build LIMIT query
186 */
187 function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
188 {
189 $this->query_result = false;
190
191 // total == 0 means all results - not zero results
192 if ($offset == 0 && $total !== 0)
193 {
194 if (strpos($query, "SELECT") === false)
195 {
196 $query = "TOP {$total} " . $query;
197 }
198 else
199 {
200 $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query);
201 }
202 }
203 else if ($offset > 0)
204 {
205 $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query);
206 $query = 'SELECT *
207 FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3
208 FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3';
209
210 if ($total > 0)
211 {
212 $query .= ' WHERE line3 BETWEEN ' . ($offset+1) . ' AND ' . ($offset + $total);
213 }
214 else
215 {
216 $query .= ' WHERE line3 > ' . $offset;
217 }
218 }
219
220 $result = $this->sql_query($query, $cache_ttl);
221
222 return $result;
223 }
224
225 /**
226 * {@inheritDoc}
227 */
228 function sql_affectedrows()
229 {
230 return ($this->db_connect_id) ? @sqlsrv_rows_affected($this->query_result) : false;
231 }
232
233 /**
234 * {@inheritDoc}
235 */
236 function sql_fetchrow($query_id = false)
237 {
238 global $cache;
239
240 if ($query_id === false)
241 {
242 $query_id = $this->query_result;
243 }
244
245 if ($cache && $cache->sql_exists($query_id))
246 {
247 return $cache->sql_fetchrow($query_id);
248 }
249
250 if (!$query_id)
251 {
252 return false;
253 }
254
255 $row = sqlsrv_fetch_array($query_id, SQLSRV_FETCH_ASSOC);
256
257 if ($row)
258 {
259 foreach ($row as $key => $value)
260 {
261 $row[$key] = ($value === ' ' || $value === null) ? '' : $value;
262 }
263
264 // remove helper values from LIMIT queries
265 if (isset($row['line2']))
266 {
267 unset($row['line2'], $row['line3']);
268 }
269 }
270 return (sizeof($row)) ? $row : false;
271 }
272
273 /**
274 * {@inheritDoc}
275 */
276 function sql_nextid()
277 {
278 $result_id = @sqlsrv_query($this->db_connect_id, 'SELECT @@IDENTITY');
279
280 if ($result_id)
281 {
282 $row = sqlsrv_fetch_array($result_id);
283 $id = $row[0];
284 sqlsrv_free_stmt($result_id);
285 return $id;
286 }
287 else
288 {
289 return false;
290 }
291 }
292
293 /**
294 * {@inheritDoc}
295 */
296 function sql_freeresult($query_id = false)
297 {
298 global $cache;
299
300 if ($query_id === false)
301 {
302 $query_id = $this->query_result;
303 }
304
305 if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
306 {
307 return $cache->sql_freeresult($query_id);
308 }
309
310 if (isset($this->open_queries[(int) $query_id]))
311 {
312 unset($this->open_queries[(int) $query_id]);
313 return sqlsrv_free_stmt($query_id);
314 }
315
316 return false;
317 }
318
319 /**
320 * return sql error array
321 * @access private
322 */
323 function _sql_error()
324 {
325 if (function_exists('sqlsrv_errors'))
326 {
327 $errors = @sqlsrv_errors(SQLSRV_ERR_ERRORS);
328 $error_message = '';
329 $code = 0;
330
331 if ($errors != null)
332 {
333 foreach ($errors as $error)
334 {
335 $error_message .= "SQLSTATE: " . $error['SQLSTATE'] . "\n";
336 $error_message .= "code: " . $error['code'] . "\n";
337 $code = $error['code'];
338 $error_message .= "message: " . $error['message'] . "\n";
339 }
340 $this->last_error_result = $error_message;
341 $error = $this->last_error_result;
342 }
343 else
344 {
345 $error = (isset($this->last_error_result) && $this->last_error_result) ? $this->last_error_result : array();
346 }
347
348 $error = array(
349 'message' => $error,
350 'code' => $code,
351 );
352 }
353 else
354 {
355 $error = array(
356 'message' => $this->connect_error,
357 'code' => '',
358 );
359 }
360
361 return $error;
362 }
363
364 /**
365 * Close sql connection
366 * @access private
367 */
368 function _sql_close()
369 {
370 return @sqlsrv_close($this->db_connect_id);
371 }
372
373 /**
374 * Build db-specific report
375 * @access private
376 */
377 function _sql_report($mode, $query = '')
378 {
379 switch ($mode)
380 {
381 case 'start':
382 $html_table = false;
383 @sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT ON;');
384 if ($result = @sqlsrv_query($this->db_connect_id, $query))
385 {
386 sqlsrv_next_result($result);
387 while ($row = sqlsrv_fetch_array($result))
388 {
389 $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
390 }
391 sqlsrv_free_stmt($result);
392 }
393 @sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT OFF;');
394
395 if ($html_table)
396 {
397 $this->html_hold .= '</table>';
398 }
399 break;
400
401 case 'fromcache':
402 $endtime = explode(' ', microtime());
403 $endtime = $endtime[0] + $endtime[1];
404
405 $result = @sqlsrv_query($this->db_connect_id, $query);
406 if ($result)
407 {
408 while ($void = sqlsrv_fetch_array($result))
409 {
410 // Take the time spent on parsing rows into account
411 }
412 sqlsrv_free_stmt($result);
413 }
414
415 $splittime = explode(' ', microtime());
416 $splittime = $splittime[0] + $splittime[1];
417
418 $this->sql_report('record_fromcache', $query, $endtime, $splittime);
419
420 break;
421 }
422 }
423
424 /**
425 * Utility method used to retrieve number of rows
426 * Emulates mysql_num_rows
427 * Used in acp_database.php -> write_data_mssqlnative()
428 * Requires a static or keyset cursor to be definde via
429 * mssqlnative_set_query_options()
430 */
431 function mssqlnative_num_rows($res)
432 {
433 if ($res !== false)
434 {
435 return sqlsrv_num_rows($res);
436 }
437 else
438 {
439 return false;
440 }
441 }
442
443 /**
444 * Allows setting mssqlnative specific query options passed to sqlsrv_query as 4th parameter.
445 */
446 function mssqlnative_set_query_options($options)
447 {
448 $this->query_options = $options;
449 }
450 }
451