[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 /** 15 * This is the MS SQL Server Native database abstraction layer. 16 * PHP mssql native driver required. 17 * @author Chris Pucci 18 * 19 */ 20 21 namespace phpbb\db\driver; 22 23 class mssqlnative extends \phpbb\db\driver\mssql_base 24 { 25 var $m_insert_id = null; 26 var $last_query_text = ''; 27 var $query_options = array(); 28 var $connect_error = ''; 29 30 /** 31 * {@inheritDoc} 32 */ 33 function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) 34 { 35 // Test for driver support, to avoid suppressed fatal error 36 if (!function_exists('sqlsrv_connect')) 37 { 38 $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'; 39 return $this->sql_error(''); 40 } 41 42 //set up connection variables 43 $this->persistency = $persistency; 44 $this->user = $sqluser; 45 $this->dbname = $database; 46 $port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':'; 47 $this->server = $sqlserver . (($port) ? $port_delimiter . $port : ''); 48 49 //connect to database 50 $this->db_connect_id = sqlsrv_connect($this->server, array( 51 'Database' => $this->dbname, 52 'UID' => $this->user, 53 'PWD' => $sqlpassword, 54 'CharacterSet' => 'UTF-8' 55 )); 56 57 return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error(''); 58 } 59 60 /** 61 * {@inheritDoc} 62 */ 63 function sql_server_info($raw = false, $use_cache = true) 64 { 65 global $cache; 66 67 if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mssql_version')) === false) 68 { 69 $arr_server_info = sqlsrv_server_info($this->db_connect_id); 70 $this->sql_server_version = $arr_server_info['SQLServerVersion']; 71 72 if (!empty($cache) && $use_cache) 73 { 74 $cache->put('mssql_version', $this->sql_server_version); 75 } 76 } 77 78 if ($raw) 79 { 80 return $this->sql_server_version; 81 } 82 83 return ($this->sql_server_version) ? 'MSSQL<br />' . $this->sql_server_version : 'MSSQL'; 84 } 85 86 /** 87 * {@inheritDoc} 88 */ 89 function sql_buffer_nested_transactions() 90 { 91 return true; 92 } 93 94 /** 95 * SQL Transaction 96 * @access private 97 */ 98 function _sql_transaction($status = 'begin') 99 { 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |