2003-03-17 10:54:23 +00:00
< ? php
2005-04-09 12:26:45 +00:00
/**
*
2005-08-17 15:57:50 +00:00
* @ package dbal
2005-04-09 12:26:45 +00:00
* @ version $Id $
* @ copyright ( c ) 2005 phpBB Group
* @ license http :// opensource . org / licenses / gpl - license . php GNU Public License
*
*/
2003-03-17 10:54:23 +00:00
2006-03-19 14:23:21 +00:00
/**
2006-10-14 14:56:46 +00:00
* @ ignore
2006-03-19 14:23:21 +00:00
*/
if ( ! defined ( 'IN_PHPBB' ))
{
exit ;
}
2006-10-14 14:56:46 +00:00
include_once ( $phpbb_root_path . 'includes/db/dbal.' . $phpEx );
2003-03-17 10:54:23 +00:00
2005-04-09 12:26:45 +00:00
/**
* Oracle Database Abstraction Layer
2006-06-13 21:06:29 +00:00
* @ package dbal
2005-04-09 12:26:45 +00:00
*/
2005-08-17 15:57:50 +00:00
class dbal_oracle extends dbal
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
var $last_query_text = '' ;
2005-10-07 23:00:41 +00:00
/**
* Connect to server
*/
2007-02-19 04:12:13 +00:00
function sql_connect ( $sqlserver , $sqluser , $sqlpassword , $database , $port = false , $persistency = false , $new_link = false )
2003-03-17 10:54:23 +00:00
{
$this -> persistency = $persistency ;
$this -> user = $sqluser ;
2005-05-05 17:01:07 +00:00
$this -> server = $sqlserver . (( $port ) ? ':' . $port : '' );
2003-03-17 10:54:23 +00:00
$this -> dbname = $database ;
2005-05-05 17:01:07 +00:00
2007-03-06 21:11:23 +00:00
$this -> db_connect_id = ( $new_link ) ? @ ocinlogon ( $this -> user , $sqlpassword , $this -> dbname , 'UTF8' ) : (( $this -> persistency ) ? @ ociplogon ( $this -> user , $sqlpassword , $this -> dbname , 'UTF8' ) : @ ocinlogon ( $this -> user , $sqlpassword , $this -> dbname , 'UTF8' ));
2003-03-17 10:54:23 +00:00
2005-05-05 17:01:07 +00:00
return ( $this -> db_connect_id ) ? $this -> db_connect_id : $this -> sql_error ( '' );
2003-03-17 10:54:23 +00:00
}
2006-07-09 16:23:57 +00:00
/**
* Version information about used database
*/
function sql_server_info ()
{
2007-01-27 12:30:54 +00:00
return @ ociserverversion ( $this -> db_connect_id );
2006-07-09 16:23:57 +00:00
}
2005-10-07 23:00:41 +00:00
/**
2006-06-06 20:53:46 +00:00
* SQL Transaction
2006-08-22 21:26:06 +00:00
* @ access private
2005-10-07 23:00:41 +00:00
*/
2006-06-06 20:53:46 +00:00
function _sql_transaction ( $status = 'begin' )
2005-05-05 17:01:07 +00:00
{
switch ( $status )
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
case 'begin' :
2006-06-06 20:53:46 +00:00
return true ;
2006-06-02 13:26:27 +00:00
break ;
2005-05-05 17:01:07 +00:00
case 'commit' :
2006-06-06 20:53:46 +00:00
return @ ocicommit ( $this -> db_connect_id );
2006-06-02 13:26:27 +00:00
break ;
2005-05-05 17:01:07 +00:00
case 'rollback' :
2006-06-06 20:53:46 +00:00
return @ ocirollback ( $this -> db_connect_id );
2006-06-02 13:26:27 +00:00
break ;
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
2006-06-06 20:53:46 +00:00
return true ;
2003-03-17 10:54:23 +00:00
}
2005-10-07 23:00:41 +00:00
/**
* Base query method
2006-08-01 16:14:14 +00:00
*
* @ param string $query Contains the SQL query which shall be executed
* @ param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
* @ return mixed When casted to bool the returned value returns true on success and false on failure
*
* @ access public
2005-10-07 23:00:41 +00:00
*/
2005-05-05 17:01:07 +00:00
function sql_query ( $query = '' , $cache_ttl = 0 )
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
if ( $query != '' )
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
global $cache ;
2003-03-17 10:54:23 +00:00
2005-05-05 17:01:07 +00:00
// EXPLAIN only in extra debug mode
if ( defined ( 'DEBUG_EXTRA' ))
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
$this -> sql_report ( 'start' , $query );
}
2006-06-02 13:26:27 +00:00
2005-05-05 17:01:07 +00:00
$this -> last_query_text = $query ;
$this -> query_result = ( $cache_ttl && method_exists ( $cache , 'sql_load' )) ? $cache -> sql_load ( $query ) : false ;
2006-05-20 13:20:38 +00:00
$this -> sql_add_num_queries ( $this -> query_result );
2006-10-03 20:38:03 +00:00
if ( $this -> query_result === false )
2005-05-05 17:01:07 +00:00
{
$in_transaction = false ;
if ( ! $this -> transaction )
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
$this -> sql_transaction ( 'begin' );
2003-03-17 10:54:23 +00:00
}
else
{
2005-05-05 17:01:07 +00:00
$in_transaction = true ;
2003-03-17 10:54:23 +00:00
}
2006-09-19 04:50:02 +00:00
// We overcome Oracle's 4000 char limit by binding vars
2007-04-11 02:23:21 +00:00
if ( strlen ( $query ) > 4000 )
2006-09-19 04:50:02 +00:00
{
2007-04-11 02:23:21 +00:00
$array = array ();
if ( preg_match ( '/^(INSERT INTO[^(]+)\\(([^()]+)\\) VALUES[^(]+\\((.*?)\\)$/s' , $query , $regs ))
2006-09-19 04:50:02 +00:00
{
2007-04-11 02:23:21 +00:00
if ( strlen ( $regs [ 3 ]) > 4000 )
{
$cols = explode ( ', ' , $regs [ 2 ]);
preg_match_all ( '/\'(?:[^\']++|\'\')*+\'|\\d+/' , $regs [ 3 ], $vals , PREG_PATTERN_ORDER );
2007-02-03 00:44:58 +00:00
2007-04-11 02:23:21 +00:00
$inserts = $vals [ 0 ];
unset ( $vals );
2007-02-03 00:44:58 +00:00
2007-04-11 02:23:21 +00:00
foreach ( $inserts as $key => $value )
2006-09-19 04:50:02 +00:00
{
2007-04-11 02:23:21 +00:00
if ( ! empty ( $value ) && $value [ 0 ] === " ' " && strlen ( $value ) > 4002 ) // check to see if this thing is greater than the max + 'x2
{
$inserts [ $key ] = ':' . strtoupper ( $cols [ $key ]);
$array [ $inserts [ $key ]] = str_replace ( " '' " , " ' " , substr ( $value , 1 , - 1 ));
}
2006-09-19 04:50:02 +00:00
}
2007-04-11 02:23:21 +00:00
$query = $regs [ 1 ] . '(' . $regs [ 2 ] . ') VALUES (' . implode ( ', ' , $inserts ) . ')' ;
unset ( $art );
2006-09-19 04:50:02 +00:00
}
}
2007-04-11 02:23:21 +00:00
else if ( preg_match_all ( '/^(UPDATE [\\w_]++\\s+SET )(\\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+)(?:, \\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+))*+)\\s+(WHERE.*)$/s' , $query , $data , PREG_SET_ORDER ))
2006-09-19 04:50:02 +00:00
{
2007-04-11 02:23:21 +00:00
if ( strlen ( $data [ 0 ][ 2 ]) > 4000 )
2006-09-19 04:50:02 +00:00
{
2007-04-11 02:23:21 +00:00
$update = $data [ 0 ][ 1 ];
$where = $data [ 0 ][ 3 ];
preg_match_all ( '/(\\w++) = (\'(?:[^\']++|\'\')*+\'|\\d++)/' , $data [ 0 ][ 2 ], $temp , PREG_SET_ORDER );
unset ( $data );
$art = array ();
foreach ( $temp as $value )
2006-09-19 04:50:02 +00:00
{
2007-04-11 02:23:21 +00:00
if ( ! empty ( $value [ 2 ]) && $value [ 2 ][ 0 ] === " ' " && strlen ( $value [ 2 ]) > 4002 ) // check to see if this thing is greater than the max + 'x2
{
$art [] = $value [ 1 ] . '=:' . strtoupper ( $value [ 1 ]);
$array [ $value [ 1 ]] = str_replace ( " '' " , " ' " , substr ( $value [ 2 ], 1 , - 1 ));
}
else
{
$art [] = $value [ 1 ] . '=' . $value [ 2 ];
}
2006-09-19 04:50:02 +00:00
}
2007-04-11 02:23:21 +00:00
$query = $update . implode ( ', ' , $art ) . ' ' . $where ;
unset ( $art );
}
2006-09-19 04:50:02 +00:00
}
}
2005-05-05 17:01:07 +00:00
$this -> query_result = @ ociparse ( $this -> db_connect_id , $query );
2006-09-19 04:50:02 +00:00
foreach ( $array as $key => $value )
{
@ ocibindbyname ( $this -> query_result , $key , $array [ $key ], - 1 );
}
2005-05-05 17:01:07 +00:00
$success = @ ociexecute ( $this -> query_result , OCI_DEFAULT );
2003-03-17 10:54:23 +00:00
2005-05-05 17:01:07 +00:00
if ( ! $success )
{
$this -> sql_error ( $query );
$this -> query_result = false ;
}
else
{
if ( ! $in_transaction )
{
$this -> sql_transaction ( 'commit' );
}
}
2006-06-02 13:26:27 +00:00
2005-05-05 17:01:07 +00:00
if ( defined ( 'DEBUG_EXTRA' ))
{
$this -> sql_report ( 'stop' , $query );
}
if ( $cache_ttl && method_exists ( $cache , 'sql_save' ))
{
$this -> open_queries [( int ) $this -> query_result ] = $this -> query_result ;
$cache -> sql_save ( $query , $this -> query_result , $cache_ttl );
}
2006-03-17 12:51:32 +00:00
else if ( strpos ( $query , 'SELECT' ) === 0 && $this -> query_result )
2005-05-05 17:01:07 +00:00
{
$this -> open_queries [( int ) $this -> query_result ] = $this -> query_result ;
}
}
else if ( defined ( 'DEBUG_EXTRA' ))
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
$this -> sql_report ( 'fromcache' , $query );
2003-03-17 10:54:23 +00:00
}
}
else
{
return false ;
}
2005-05-05 17:01:07 +00:00
return ( $this -> query_result ) ? $this -> query_result : false ;
2003-03-17 10:54:23 +00:00
}
2005-10-07 23:00:41 +00:00
/**
* Build LIMIT query
*/
2007-01-17 18:41:49 +00:00
function _sql_query_limit ( $query , $total , $offset = 0 , $cache_ttl = 0 )
2006-06-02 13:26:27 +00:00
{
2007-01-17 18:41:49 +00:00
$this -> query_result = false ;
2005-05-05 17:01:07 +00:00
2007-01-17 18:41:49 +00:00
$query = 'SELECT * FROM (SELECT /*+ FIRST_ROWS */ rownum AS xrownum, a.* FROM (' . $query . ') a WHERE rownum <= ' . ( $offset + $total ) . ') WHERE xrownum >= ' . $offset ;
2005-05-05 17:01:07 +00:00
2007-01-17 18:41:49 +00:00
return $this -> sql_query ( $query , $cache_ttl );
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
/**
* Return number of affected rows
*/
2005-05-05 17:01:07 +00:00
function sql_affectedrows ()
2003-03-17 10:54:23 +00:00
{
2005-10-07 23:00:41 +00:00
return ( $this -> query_result ) ? @ ocirowcount ( $this -> query_result ) : false ;
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
/**
* Fetch current row
*/
2005-05-05 17:01:07 +00:00
function sql_fetchrow ( $query_id = false )
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
global $cache ;
2006-10-04 15:15:40 +00:00
if ( $query_id === false )
2003-03-17 10:54:23 +00:00
{
$query_id = $this -> query_result ;
}
2005-05-05 17:01:07 +00:00
if ( isset ( $cache -> sql_rowset [ $query_id ]))
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
return $cache -> sql_fetchrow ( $query_id );
2003-03-17 10:54:23 +00:00
}
2006-06-02 13:26:27 +00:00
2006-10-04 15:15:40 +00:00
if ( $query_id !== false )
2003-03-17 10:54:23 +00:00
{
2006-10-04 15:15:40 +00:00
$row = array ();
$result = @ ocifetchinto ( $query_id , $row , OCI_ASSOC + OCI_RETURN_NULLS );
2003-03-17 10:54:23 +00:00
2006-10-04 15:15:40 +00:00
if ( ! $result || ! $row )
2003-03-17 10:54:23 +00:00
{
2006-10-04 15:15:40 +00:00
return false ;
2003-03-17 10:54:23 +00:00
}
2006-06-02 13:26:27 +00:00
2006-10-04 15:15:40 +00:00
$result_row = array ();
foreach ( $row as $key => $value )
2006-08-01 16:14:14 +00:00
{
2006-10-04 15:15:40 +00:00
// OCI->CLOB?
if ( is_object ( $value ))
{
$value = $value -> load ();
}
$result_row [ strtolower ( $key )] = $value ;
2006-08-01 16:14:14 +00:00
}
2006-10-04 15:15:40 +00:00
return $result_row ;
2003-03-17 10:54:23 +00:00
}
2006-06-02 13:26:27 +00:00
2005-05-05 17:01:07 +00:00
return false ;
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
/**
* Seek to given row number
* rownum is zero - based
*/
function sql_rowseek ( $rownum , $query_id = false )
2003-03-17 10:54:23 +00:00
{
2006-08-01 16:14:14 +00:00
global $cache ;
2006-10-04 15:15:40 +00:00
if ( $query_id === false )
2003-03-17 10:54:23 +00:00
{
$query_id = $this -> query_result ;
}
2005-05-05 17:01:07 +00:00
2006-08-01 16:14:14 +00:00
if ( isset ( $cache -> sql_rowset [ $query_id ]))
{
2006-09-23 11:10:37 +00:00
return $cache -> sql_rowseek ( $rownum , $query_id );
2006-08-01 16:14:14 +00:00
}
2006-10-04 15:15:40 +00:00
if ( $query_id === false )
2003-03-17 10:54:23 +00:00
{
2005-10-07 23:00:41 +00:00
return false ;
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
// Reset internal pointer
@ ociexecute ( $query_id , OCI_DEFAULT );
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
// 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 ++ )
{
if ( ! $this -> sql_fetchrow ( $query_id ))
2005-05-05 17:01:07 +00:00
{
2005-10-07 23:00:41 +00:00
return false ;
2005-05-05 17:01:07 +00:00
}
2003-03-17 10:54:23 +00:00
}
2005-10-07 23:00:41 +00:00
return true ;
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
/**
* Get last inserted id after insert statement
*/
2005-05-05 17:01:07 +00:00
function sql_nextid ()
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
$query_id = $this -> query_result ;
2006-10-04 15:15:40 +00:00
if ( $query_id !== false && $this -> last_query_text != '' )
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
if ( preg_match ( '#^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)#is' , $this -> last_query_text , $tablename ))
2003-03-17 10:54:23 +00:00
{
2006-04-15 14:48:36 +00:00
$query = 'SELECT ' . $tablename [ 1 ] . '_seq.currval FROM DUAL' ;
2005-05-05 17:01:07 +00:00
$stmt = @ ociparse ( $this -> db_connect_id , $query );
2006-09-19 04:50:02 +00:00
@ ociexecute ( $stmt , OCI_DEFAULT );
2005-05-05 17:01:07 +00:00
2006-06-03 20:34:40 +00:00
$temp_result = @ ocifetchinto ( $stmt , $temp_array , OCI_ASSOC + OCI_RETURN_NULLS );
2005-10-07 23:00:41 +00:00
@ ocifreestatement ( $stmt );
2005-05-05 17:01:07 +00:00
if ( $temp_result )
2003-03-17 10:54:23 +00:00
{
2006-06-03 20:34:40 +00:00
return $temp_array [ 'CURRVAL' ];
2003-03-17 10:54:23 +00:00
}
else
{
return false ;
}
}
}
2005-05-05 17:01:07 +00:00
return false ;
2003-03-17 10:54:23 +00:00
}
2005-10-07 23:00:41 +00:00
/**
* Free sql result
*/
2005-05-05 17:01:07 +00:00
function sql_freeresult ( $query_id = false )
2003-03-17 10:54:23 +00:00
{
2006-08-01 16:14:14 +00:00
global $cache ;
2006-10-04 15:15:40 +00:00
if ( $query_id === false )
2003-03-17 10:54:23 +00:00
{
$query_id = $this -> query_result ;
}
2006-08-01 16:14:14 +00:00
if ( isset ( $cache -> sql_rowset [ $query_id ]))
{
return $cache -> sql_freeresult ( $query_id );
}
2005-05-05 17:01:07 +00:00
if ( isset ( $this -> open_queries [( int ) $query_id ]))
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
unset ( $this -> open_queries [( int ) $query_id ]);
return @ ocifreestatement ( $query_id );
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
return false ;
}
2003-03-17 10:54:23 +00:00
2005-10-07 23:00:41 +00:00
/**
* Escape string used in sql query
*/
2005-05-05 17:01:07 +00:00
function sql_escape ( $msg )
{
2006-06-06 20:53:46 +00:00
return str_replace ( " ' " , " '' " , $msg );
2005-05-05 17:01:07 +00:00
}
2003-03-17 10:54:23 +00:00
2006-05-05 22:06:17 +00:00
function _sql_custom_build ( $stage , $data )
{
return $data ;
}
2005-10-07 23:00:41 +00:00
/**
* return sql error array
2006-08-22 21:26:06 +00:00
* @ access private
2005-10-07 23:00:41 +00:00
*/
function _sql_error ()
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
$error = @ ocierror ();
$error = ( ! $error ) ? @ ocierror ( $this -> query_result ) : $error ;
$error = ( ! $error ) ? @ ocierror ( $this -> db_connect_id ) : $error ;
if ( $error )
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
$this -> last_error_result = $error ;
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
else
2003-03-17 10:54:23 +00:00
{
2005-05-05 17:01:07 +00:00
$error = ( isset ( $this -> last_error_result ) && $this -> last_error_result ) ? $this -> last_error_result : array ();
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
return $error ;
2003-03-17 10:54:23 +00:00
}
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
/**
* Close sql connection
2006-08-22 21:26:06 +00:00
* @ access private
2005-10-07 23:00:41 +00:00
*/
function _sql_close ()
2003-03-17 10:54:23 +00:00
{
2005-10-07 23:00:41 +00:00
return @ ocilogoff ( $this -> db_connect_id );
}
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
/**
* Build db - specific report
2006-08-22 21:26:06 +00:00
* @ access private
2005-10-07 23:00:41 +00:00
*/
function _sql_report ( $mode , $query = '' )
{
2005-05-05 17:01:07 +00:00
switch ( $mode )
{
case 'start' :
2005-10-07 23:00:41 +00:00
break ;
2005-05-05 17:01:07 +00:00
case 'fromcache' :
$endtime = explode ( ' ' , microtime ());
$endtime = $endtime [ 0 ] + $endtime [ 1 ];
$result = @ ociparse ( $this -> db_connect_id , $query );
$success = @ ociexecute ( $result , OCI_DEFAULT );
$row = array ();
2006-03-21 19:23:34 +00:00
while ( @ ocifetchinto ( $result , $row , OCI_ASSOC + OCI_RETURN_NULLS ))
2005-05-05 17:01:07 +00:00
{
// Take the time spent on parsing rows into account
}
2005-10-07 23:00:41 +00:00
@ ocifreestatement ( $result );
2005-05-05 17:01:07 +00:00
$splittime = explode ( ' ' , microtime ());
$splittime = $splittime [ 0 ] + $splittime [ 1 ];
2005-10-07 23:00:41 +00:00
$this -> sql_report ( 'record_fromcache' , $query , $endtime , $splittime );
2005-05-05 17:01:07 +00:00
2005-10-07 23:00:41 +00:00
break ;
2003-03-17 10:54:23 +00:00
}
}
2005-08-17 15:57:50 +00:00
}
2003-03-17 10:54:23 +00:00
?>