aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/db/mssql_odbc.php
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes/db/mssql_odbc.php')
-rw-r--r--phpBB/includes/db/mssql_odbc.php286
1 files changed, 111 insertions, 175 deletions
diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php
index cb2b05c937..e9b2a9b03e 100644
--- a/phpBB/includes/db/mssql_odbc.php
+++ b/phpBB/includes/db/mssql_odbc.php
@@ -19,17 +19,17 @@ if (!defined('SQL_LAYER'))
/**
* @package dbal
-* MSSQL ODBC Database Abstraction Layer for MSSQL
-* Minimum Requirement is Version 2000+
+* Unified ODBC functions
+* Unified ODBC functions support any database having ODBC driver, for example Adabas D, IBM DB2, iODBC, Solid, Sybase SQL Anywhere...
+* Here we only support MSSQL Server 2000+ because of the provided schema
*/
class dbal_mssql_odbc extends dbal
{
- var $result_rowset = array();
- var $field_names = array();
- var $field_types = array();
- var $num_rows = array();
- var $current_row = array();
+ var $last_query_text = '';
+ /**
+ * Connect to server
+ */
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false)
{
$this->persistency = $persistency;
@@ -42,41 +42,9 @@ class dbal_mssql_odbc extends dbal
return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
}
- //
- // Other base methods
- //
- function sql_close()
- {
- if (!$this->db_connect_id)
- {
- return false;
- }
-
- if ($this->transaction)
- {
- @odbc_commit($this->db_connect_id);
- }
-
- if (sizeof($this->result_rowset))
- {
- unset($this->result_rowset);
- unset($this->field_names);
- unset($this->field_types);
- unset($this->num_rows);
- unset($this->current_row);
- }
-
- if (sizeof($this->open_queries))
- {
- foreach ($this->open_queries as $i_query_id => $query_id)
- {
- @odbc_free_result($query_id);
- }
- }
-
- return @odbc_close($this->db_connect_id);
- }
-
+ /**
+ * sql transaction
+ */
function sql_transaction($status = 'begin')
{
switch ($status)
@@ -111,7 +79,9 @@ class dbal_mssql_odbc extends dbal
return $result;
}
- // Base query method
+ /**
+ * Base query method
+ */
function sql_query($query = '', $cache_ttl = 0)
{
if ($query != '')
@@ -124,13 +94,14 @@ class dbal_mssql_odbc extends dbal
$this->sql_report('start', $query);
}
+ $this->last_query_text = $query;
$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
if (!$this->query_result)
{
$this->num_queries++;
- if (($this->query_result = $this->_odbc_execute_query($query)) === false)
+ if (($this->query_result = @odbc_exec($this->db_connect_id, $query)) === false)
{
$this->sql_error($query);
}
@@ -144,7 +115,6 @@ class dbal_mssql_odbc extends dbal
{
$this->open_queries[(int) $this->query_result] = $this->query_result;
$cache->sql_save($query, $this->query_result, $cache_ttl);
- // odbc_free_result called within sql_save()
}
else if (strpos($query, 'SELECT') !== false && $this->query_result)
{
@@ -164,76 +134,9 @@ class dbal_mssql_odbc extends dbal
return ($this->query_result) ? $this->query_result : false;
}
- function _odbc_execute_query($query)
- {
- $result = false;
-
- if (eregi("^SELECT ", $query))
- {
- $result = @odbc_exec($this->db_connect_id, $query);
-
- if ($result)
- {
- if (empty($this->field_names[$result]))
- {
- for ($i = 1, $j = @odbc_num_fields($result) + 1; $i < $j; $i++)
- {
- $this->field_names[$result][] = @odbc_field_name($result, $i);
- $this->field_types[$result][] = @odbc_field_type($result, $i);
- }
- }
-
- $this->current_row[$result] = 0;
- $this->result_rowset[$result] = array();
-
- $row_outer = (isset($row_offset)) ? $row_offset + 1 : 1;
- $row_outer_max = (isset($num_rows)) ? $row_offset + $num_rows + 1 : 1E9;
- $row_inner = 0;
-
- while (@odbc_fetch_row($result, $row_outer) && $row_outer < $row_outer_max)
- {
- for ($i = 0, $j = sizeof($this->field_names[$result]); $i < $j; $i++)
- {
- $this->result_rowset[$result][$row_inner][$this->field_names[$result][$i]] = stripslashes(@odbc_result($result, $i + 1));
- }
-
- $row_outer++;
- $row_inner++;
- }
-
- $this->num_rows[$result] = sizeof($this->result_rowset[$result]);
- }
- }
- else if (eregi("^INSERT ", $query))
- {
- $result = @odbc_exec($this->db_connect_id, $query);
-
- if ($result)
- {
- $result_id = @odbc_exec($this->db_connect_id, 'SELECT @@IDENTITY');
- if ($result_id)
- {
- if (@odbc_fetch_row($result_id))
- {
- $this->next_id[$this->db_connect_id] = @odbc_result($result_id, 1);
- $this->affected_rows[$this->db_connect_id] = @odbc_num_rows($result);
- }
- }
- }
- }
- else
- {
- $result = @odbc_exec($this->db_connect_id, $query);
-
- if ($result)
- {
- $this->affected_rows[$this->db_connect_id] = @odbc_num_rows($result);
- }
- }
-
- return $result;
- }
-
+ /**
+ * Build LIMIT query
+ */
function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
{
if ($query != '')
@@ -259,10 +162,10 @@ class dbal_mssql_odbc extends dbal
}
}
- // Other query methods
- //
- // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
- // don't want this here by a middle Milestone
+ /**
+ * Return number of rows
+ * Not used within core code
+ */
function sql_numrows($query_id = false)
{
if (!$query_id)
@@ -270,14 +173,20 @@ class dbal_mssql_odbc extends dbal
$query_id = $this->query_result;
}
- return ($query_id) ? @$this->num_rows($query_id) : false;
+ return ($query_id) ? @odbc_num_rows($query_id) : false;
}
+ /**
+ * Return number of affected rows
+ */
function sql_affectedrows()
{
- return ($this->affected_rows[$this->db_connect_id]) ? $this->affected_rows[$this->db_connect_id] : false;
+ return ($this->db_connect_id) ? @odbc_num_rows($this->query_result) : false;
}
+ /**
+ * Fetch current row
+ */
function sql_fetchrow($query_id = false)
{
global $cache;
@@ -291,21 +200,15 @@ class dbal_mssql_odbc extends dbal
{
return $cache->sql_fetchrow($query_id);
}
-
- return ($this->num_rows[$query_id] && $this->current_row[$query_id] < $this->num_rows[$query_id]) ? $this->result_rowset[$query_id][$this->current_row[$query_id]++] : false;
- }
-
- function sql_fetchrowset($query_id = false)
- {
- if (!$query_id)
- {
- $query_id = $this->query_result;
- }
-
- return ($this->num_rows[$query_id]) ? $this->result_rowset[$query_id] : false;
+
+ return ($query_id) ? @odbc_fetch_array($result_id) : false;
}
- function sql_fetchfield($field, $rownum = -1, $query_id = false)
+ /**
+ * Fetch field
+ * if rownum is false, the current row is used, else it is pointing to the row (zero-based)
+ */
+ function sql_fetchfield($field, $rownum = false, $query_id = false)
{
if (!$query_id)
{
@@ -314,17 +217,22 @@ class dbal_mssql_odbc extends dbal
if ($query_id)
{
- if ($rownum < $this->num_rows[$query_id])
+ if ($rownum !== false)
{
- $getrow = ($rownum == -1) ? $this->current_row[$query_id] - 1 : $rownum;
-
- return $this->result_rowset[$query_id][$getrow][$this->field_names[$query_id][$field]];
+ $this->sql_rowseek($rownum, $query_id);
}
+
+ $row = $this->sql_fetchrow($query_id);
+ return isset($row[$field]) ? $row[$field] : false;
}
return false;
}
+ /**
+ * Seek to given row number
+ * rownum is zero-based
+ */
function sql_rowseek($rownum, $query_id = false)
{
if (!$query_id)
@@ -332,20 +240,50 @@ class dbal_mssql_odbc extends dbal
$query_id = $this->query_result;
}
- if (isset($this->current_row[$query_id]))
+ $this->sql_freeresult($query_id);
+ $query_id = $this->sql_query($this->last_query_text);
+
+ if (!$query_id)
+ {
+ return false;
+ }
+
+ // We do not fetch the row for rownum == 0 because then the next resultset would be the second row
+ for ($i = 0; $i < $rownum; $i++)
{
- $this->current_row[$query_id] = $rownum;
- return true;
+ if (!$this->sql_fetchrow($query_id))
+ {
+ return false;
+ }
}
- return false;
+ return true;
}
+ /**
+ * Get last inserted id after insert statement
+ */
function sql_nextid()
{
- return ($this->next_id[$this->db_connect_id]) ? $this->next_id[$this->db_connect_id] : false;
+ $result_id = @odbc_exec($this->db_connect_id, 'SELECT @@IDENTITY');
+
+ if ($result_id)
+ {
+ if (@odbc_fetch_array($result_id))
+ {
+ $id = @odbc_result($result_id, 1);
+ @odbc_free_result($result_id);
+ return $id;
+ }
+ @odbc_free_result($result_id);
+ }
+
+ return false;
}
+ /**
+ * Free sql result
+ */
function sql_freeresult($query_id = false)
{
if (!$query_id)
@@ -356,24 +294,25 @@ class dbal_mssql_odbc extends dbal
if (isset($this->open_queries[(int) $query_id]))
{
unset($this->open_queries[(int) $query_id]);
- unset($this->num_rows[$query_id]);
- unset($this->current_row[$query_id]);
- unset($this->result_rowset[$query_id]);
- unset($this->field_names[$query_id]);
- unset($this->field_types[$query_id]);
-
return @odbc_free_result($query_id);
}
return false;
}
+ /**
+ * Escape string used in sql query
+ */
function sql_escape($msg)
{
return str_replace("'", "''", str_replace('\\', '\\\\', $msg));
}
- function db_sql_error()
+ /**
+ * return sql error array
+ * @private
+ */
+ function _sql_error()
{
return array(
'message' => @odbc_errormsg(),
@@ -381,46 +320,43 @@ class dbal_mssql_odbc extends dbal
);
}
- function _sql_report($mode, $query = '')
+ /**
+ * Close sql connection
+ * @private
+ */
+ function _sql_close()
{
- global $cache, $starttime, $phpbb_root_path;
- static $curtime, $query_hold, $html_hold;
- static $sql_report = '';
- static $cache_num_queries = 0;
+ return @odbc_close($this->db_connect_id);
+ }
+ /**
+ * Build db-specific report
+ * @private
+ */
+ function _sql_report($mode, $query = '')
+ {
switch ($mode)
{
case 'start':
- $query_hold = $query;
- $html_hold = '';
-
- $curtime = explode(' ', microtime());
- $curtime = $curtime[0] + $curtime[1];
- break;
+ break;
case 'fromcache':
$endtime = explode(' ', microtime());
$endtime = $endtime[0] + $endtime[1];
- $result = $this->_odbc_execute_query($query);
+ $result = @odbc_exec($this->db_connect_id, $query);
+ while ($void = @odbc_fetch_array($result))
+ {
+ // Take the time spent on parsing rows into account
+ }
+ @odbc_free_result($result);
$splittime = explode(' ', microtime());
$splittime = $splittime[0] + $splittime[1];
- $time_cache = $endtime - $curtime;
- $time_db = $splittime - $endtime;
- $color = ($time_db > $time_cache) ? 'green' : 'red';
+ $this->sql_report('record_fromcache', $query, $endtime, $splittime);
- $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query results obtained from the cache</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table><p align="center">';
-
- $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p>';
-
- // Pad the start time to not interfere with page timing
- $starttime += $time_db;
-
- @odbc_free_result($result);
- $cache_num_queries++;
- break;
+ break;
}
}