[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/includes/db/ -> mssql_odbc.php (source)

   1  <?php
   2  /**
   3  *
   4  * @package dbal
   5  * @version $Id$
   6  * @copyright (c) 2005 phpBB Group
   7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
   8  *
   9  */
  10  
  11  /**
  12  * @ignore
  13  */
  14  if (!defined('IN_PHPBB'))
  15  {
  16      exit;
  17  }
  18  
  19  include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx);
  20  
  21  /**
  22  * Unified ODBC functions
  23  * Unified ODBC functions support any database having ODBC driver, for example Adabas D, IBM DB2, iODBC, Solid, Sybase SQL Anywhere...
  24  * Here we only support MSSQL Server 2000+ because of the provided schema
  25  *
  26  * @note number of bytes returned for returning data depends on odbc.defaultlrl php.ini setting.
  27  * If it is limited to 4K for example only 4K of data is returned max, resulting in incomplete theme data for example.
  28  * @note odbc.defaultbinmode may affect UTF8 characters
  29  *
  30  * @package dbal
  31  */
  32  class dbal_mssql_odbc extends dbal
  33  {
  34      var $last_query_text = '';
  35      var $connect_error = '';
  36  
  37      /**
  38      * Connect to server
  39      */
  40  	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
  41      {
  42          $this->persistency = $persistency;
  43          $this->user = $sqluser;
  44          $this->dbname = $database;
  45  
  46          $port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':';
  47          $this->server = $sqlserver . (($port) ? $port_delimiter . $port : '');
  48  
  49          $max_size = @ini_get('odbc.defaultlrl');
  50          if (!empty($max_size))
  51          {
  52              $unit = strtolower(substr($max_size, -1, 1));
  53              $max_size = (int) $max_size;
  54  
  55              if ($unit == 'k')
  56              {
  57                  $max_size = floor($max_size / 1024);
  58              }
  59              else if ($unit == 'g')
  60              {
  61                  $max_size *= 1024;
  62              }
  63              else if (is_numeric($unit))
  64              {
  65                  $max_size = floor((int) ($max_size . $unit) / 1048576);
  66              }
  67              $max_size = max(8, $max_size) . 'M';
  68  
  69              @ini_set('odbc.defaultlrl', $max_size);
  70          }
  71  
  72          if ($this->persistency)
  73          {
  74              if (!function_exists('odbc_pconnect'))
  75              {
  76                  $this->connect_error = 'odbc_pconnect function does not exist, is odbc extension installed?';
  77                  return $this->sql_error('');
  78              }
  79              $this->db_connect_id = @odbc_pconnect($this->server, $this->user, $sqlpassword);
  80          }
  81          else
  82          {
  83              if (!function_exists('odbc_connect'))
  84              {
  85                  $this->connect_error = 'odbc_connect function does not exist, is odbc extension installed?';
  86                  return $this->sql_error('');
  87              }
  88              $this->db_connect_id = @odbc_connect($this->server, $this->user, $sqlpassword);
  89          }
  90  
  91          return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
  92      }
  93  
  94      /**
  95      * Version information about used database
  96      * @param bool $raw if true, only return the fetched sql_server_version
  97      * @param bool $use_cache If true, it is safe to retrieve the value from the cache
  98      * @return string sql server version
  99      */
 100  	function sql_server_info($raw = false, $use_cache = true)
 101      {
 102          global $cache;
 103  
 104          if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mssqlodbc_version')) === false)
 105          {
 106              $result_id = @odbc_exec($this->db_connect_id, "SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY('productlevel'), SERVERPROPERTY('edition')");
 107  
 108              $row = false;
 109              if ($result_id)
 110              {
 111                  $row = @odbc_fetch_array($result_id);
 112                  @odbc_free_result($result_id);
 113              }
 114  
 115              $this->sql_server_version = ($row) ? trim(implode(' ', $row)) : 0;
 116  
 117              if (!empty($cache) && $use_cache)
 118              {
 119                  $cache->put('mssqlodbc_version', $this->sql_server_version);
 120              }
 121          }
 122  
 123          if ($raw)
 124          {
 125              return $this->sql_server_version;
 126          }
 127  
 128          return ($this->sql_server_version) ? 'MSSQL (ODBC)<br />' . $this->sql_server_version : 'MSSQL (ODBC)';
 129      }
 130  
 131      /**
 132      * SQL Transaction
 133      * @access private
 134      */
 135  	function _sql_transaction($status = 'begin')
 136      {
 137          switch ($status)
 138          {
 139              case 'begin':
 140                  return @odbc_exec($this->db_connect_id, 'BEGIN TRANSACTION');
 141              break;
 142  
 143              case 'commit':
 144                  return @odbc_exec($this->db_connect_id, 'COMMIT TRANSACTION');
 145              break;
 146  
 147              case 'rollback':
 148                  return @odbc_exec($this->db_connect_id, 'ROLLBACK TRANSACTION');
 149              break;
 150          }
 151  
 152          return true;
 153      }
 154  
 155      /**
 156      * Base query method
 157      *
 158      * @param    string    $query        Contains the SQL query which shall be executed
 159      * @param    int        $cache_ttl    Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
 160      * @return    mixed                When casted to bool the returned value returns true on success and false on failure
 161      *
 162      * @access    public
 163      */
 164  	function sql_query($query = '', $cache_ttl = 0)
 165      {
 166          if ($query != '')
 167          {
 168              global $cache;
 169  
 170              // EXPLAIN only in extra debug mode
 171              if (defined('DEBUG_EXTRA'))
 172              {
 173                  $this->sql_report('start', $query);
 174              }
 175  
 176              $this->last_query_text = $query;
 177              $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
 178              $this->sql_add_num_queries($this->query_result);
 179  
 180              if ($this->query_result === false)
 181              {
 182                  if (($this->query_result = @odbc_exec($this->db_connect_id, $query)) === false)
 183                  {
 184                      $this->sql_error($query);
 185                  }
 186  
 187                  if (defined('DEBUG_EXTRA'))
 188                  {
 189                      $this->sql_report('stop', $query);
 190                  }
 191  
 192                  if ($cache_ttl && method_exists($cache, 'sql_save'))
 193                  {
 194                      $this->open_queries[(int) $this->query_result] = $this->query_result;
 195                      $cache->sql_save($query, $this->query_result, $cache_ttl);
 196                  }
 197                  else if (strpos($query, 'SELECT') === 0 && $this->query_result)
 198                  {
 199                      $this->open_queries[(int) $this->query_result] = $this->query_result;
 200                  }
 201              }
 202              else if (defined('DEBUG_EXTRA'))
 203              {
 204                  $this->sql_report('fromcache', $query);
 205              }
 206          }
 207          else
 208          {
 209              return false;
 210          }
 211  
 212          return $this->query_result;
 213      }
 214  
 215      /**
 216      * Build LIMIT query
 217      */
 218  	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
 219      {
 220          $this->query_result = false;
 221  
 222          // Since TOP is only returning a set number of rows we won't need it if total is set to 0 (return all rows)
 223          if ($total)
 224          {
 225              // We need to grab the total number of rows + the offset number of rows to get the correct result
 226              if (strpos($query, 'SELECT DISTINCT') === 0)
 227              {
 228                  $query = 'SELECT DISTINCT TOP ' . ($total + $offset) . ' ' . substr($query, 15);
 229              }
 230              else
 231              {
 232                  $query = 'SELECT TOP ' . ($total + $offset) . ' ' . substr($query, 6);
 233              }
 234          }
 235  
 236          $result = $this->sql_query($query, $cache_ttl);
 237  
 238          // Seek by $offset rows
 239          if ($offset)
 240          {
 241              $this->sql_rowseek($offset, $result);
 242          }
 243  
 244          return $result;
 245      }
 246  
 247      /**
 248      * Return number of affected rows
 249      */
 250  	function sql_affectedrows()
 251      {
 252          return ($this->db_connect_id) ? @odbc_num_rows($this->query_result) : false;
 253      }
 254  
 255      /**
 256      * Fetch current row
 257      * @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max.
 258      */
 259  	function sql_fetchrow($query_id = false, $debug = false)
 260      {
 261          global $cache;
 262  
 263          if ($query_id === false)
 264          {
 265              $query_id = $this->query_result;
 266          }
 267  
 268          if (isset($cache->sql_rowset[$query_id]))
 269          {
 270              return $cache->sql_fetchrow($query_id);
 271          }
 272  
 273          return ($query_id !== false) ? @odbc_fetch_array($query_id) : false;
 274      }
 275  
 276      /**
 277      * Get last inserted id after insert statement
 278      */
 279  	function sql_nextid()
 280      {
 281          $result_id = @odbc_exec($this->db_connect_id, 'SELECT @@IDENTITY');
 282  
 283          if ($result_id)
 284          {
 285              if (@odbc_fetch_array($result_id))
 286              {
 287                  $id = @odbc_result($result_id, 1);
 288                  @odbc_free_result($result_id);
 289                  return $id;
 290              }
 291              @odbc_free_result($result_id);
 292          }
 293  
 294          return false;
 295      }
 296  
 297      /**
 298      * Free sql result
 299      */
 300  	function sql_freeresult($query_id = false)
 301      {
 302          global $cache;
 303  
 304          if ($query_id === false)
 305          {
 306              $query_id = $this->query_result;
 307          }
 308  
 309          if (isset($cache->sql_rowset[$query_id]))
 310          {
 311              return $cache->sql_freeresult($query_id);
 312          }
 313  
 314          if (isset($this->open_queries[(int) $query_id]))
 315          {
 316              unset($this->open_queries[(int) $query_id]);
 317              return @odbc_free_result($query_id);
 318          }
 319  
 320          return false;
 321      }
 322  
 323      /**
 324      * Escape string used in sql query
 325      */
 326  	function sql_escape($msg)
 327      {
 328          return str_replace(array("'", "\0"), array("''", ''), $msg);
 329      }
 330  
 331      /**
 332      * {@inheritDoc}
 333      */
 334  	function sql_lower_text($column_name)
 335      {
 336          return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))";
 337      }
 338  
 339      /**
 340      * Build LIKE expression
 341      * @access private
 342      */
 343  	function _sql_like_expression($expression)
 344      {
 345          return $expression . " ESCAPE '\\'";
 346      }
 347  
 348      /**
 349      * Build db-specific query data
 350      * @access private
 351      */
 352  	function _sql_custom_build($stage, $data)
 353      {
 354          return $data;
 355      }
 356  
 357      /**
 358      * return sql error array
 359      * @access private
 360      */
 361  	function _sql_error()
 362      {
 363          if (function_exists('odbc_errormsg'))
 364          {
 365              $error = array(
 366                  'message'    => @odbc_errormsg(),
 367                  'code'        => @odbc_error(),
 368              );
 369          }
 370          else
 371          {
 372              $error = array(
 373                  'message'    => $this->connect_error,
 374                  'code'        => '',
 375              );
 376          }
 377  
 378          return $error;
 379      }
 380  
 381      /**
 382      * Close sql connection
 383      * @access private
 384      */
 385  	function _sql_close()
 386      {
 387          return @odbc_close($this->db_connect_id);
 388      }
 389  
 390      /**
 391      * Build db-specific report
 392      * @access private
 393      */
 394  	function _sql_report($mode, $query = '')
 395      {
 396          switch ($mode)
 397          {
 398              case 'start':
 399              break;
 400  
 401              case 'fromcache':
 402                  $endtime = explode(' ', microtime());
 403                  $endtime = $endtime[0] + $endtime[1];
 404  
 405                  $result = @odbc_exec($this->db_connect_id, $query);
 406                  while ($void = @odbc_fetch_array($result))
 407                  {
 408                      // Take the time spent on parsing rows into account
 409                  }
 410                  @odbc_free_result($result);
 411  
 412                  $splittime = explode(' ', microtime());
 413                  $splittime = $splittime[0] + $splittime[1];
 414  
 415                  $this->sql_report('record_fromcache', $query, $endtime, $splittime);
 416  
 417              break;
 418          }
 419      }
 420  }
 421  
 422  ?>


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1