Библиотека для cis, online, cms1
This commit is contained in:
commit
3c2e614d87
269 changed files with 39854 additions and 0 deletions
393
creole/drivers/oracle/OCI8Connection.php
Normal file
393
creole/drivers/oracle/OCI8Connection.php
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* $Id: OCI8Connection.php,v 1.18 2005/10/17 19:03:51 dlawson_mi Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
include_once 'creole/drivers/oracle/OCI8ResultSet.php';
|
||||
|
||||
/**
|
||||
* Oracle implementation of Connection.
|
||||
*
|
||||
* @author David Giffin <david@giffin.org>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
* @author Lukas Smith
|
||||
* @version $Revision: 1.18 $
|
||||
* @package creole.drivers.oracle
|
||||
*/
|
||||
class OCI8Connection extends ConnectionCommon implements Connection
|
||||
{
|
||||
protected $lastStmt = null;
|
||||
|
||||
/**
|
||||
* Auto commit mode for oci_execute
|
||||
* @var int
|
||||
*/
|
||||
protected $execMode = OCI_COMMIT_ON_SUCCESS;
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param array $dsn The data source hash.
|
||||
* @param int $flags Any connection flags.
|
||||
* @access public
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
function connect( $dsninfo, $flags = 0 )
|
||||
{
|
||||
if ( !extension_loaded( 'oci8' ) )
|
||||
{
|
||||
throw new SQLException( 'oci8 extension not loaded' );
|
||||
}
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
$persistent =
|
||||
( $flags & Creole::PERSISTENT === Creole::PERSISTENT );
|
||||
|
||||
$user = $dsninfo[ 'username' ];
|
||||
$pw = $dsninfo[ 'password' ];
|
||||
$hostspec = $dsninfo[ 'hostspec' ];
|
||||
$db = $dsninfo[ 'database' ];
|
||||
|
||||
$connect_function = ( $persistent )
|
||||
? 'oci_pconnect'
|
||||
: 'oci_connect';
|
||||
|
||||
$encoding = !empty($dsninfo['encoding']) ? $dsninfo['encoding'] : null;
|
||||
|
||||
@ini_set( 'track_errors', true );
|
||||
|
||||
if ( $db && $hostspec && $user && $pw )
|
||||
{
|
||||
$conn = @$connect_function( $user, $pw, "//$hostspec/$db", $encoding);
|
||||
}
|
||||
elseif ( $hostspec && $user && $pw )
|
||||
{
|
||||
$conn = @$connect_function( $user, $pw, $hostspec, $encoding );
|
||||
}
|
||||
|
||||
elseif ( $user || $pw )
|
||||
{
|
||||
$conn = @$connect_function( $user, $pw, null, $encoding );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$conn = false;
|
||||
}
|
||||
|
||||
@ini_restore( 'track_errors' );
|
||||
|
||||
if ( $conn == false )
|
||||
{
|
||||
$error = oci_error();
|
||||
$error = ( is_array( $error ) )
|
||||
? $error[ 'message' ]
|
||||
: null;
|
||||
|
||||
throw new SQLException( 'connect failed', $error );
|
||||
}
|
||||
|
||||
$this->dblink = $conn;
|
||||
|
||||
//connected ok, need to set a few environment settings
|
||||
//please note, if this is changed, the function setTimestamp and setDate in OCI8PreparedStatement.php
|
||||
//must be changed to match
|
||||
$sql = "ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'";
|
||||
$this->executeQuery($sql);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see Connection::disconnect()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$ret = @oci_close( $this->dblink );
|
||||
$this->dblink = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
function executeQuery( $sql, $fetchmode = null )
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
|
||||
// $result = @oci_parse( $this->dblink, $sql );
|
||||
$result = oci_parse( $this->dblink, $sql );
|
||||
|
||||
if ( ! $result )
|
||||
{
|
||||
throw new SQLException( 'Unable to prepare query'
|
||||
, $this->nativeError()
|
||||
, $sql
|
||||
);
|
||||
}
|
||||
|
||||
$success = oci_execute( $result, $this->execMode );
|
||||
|
||||
if ( ! $success )
|
||||
{
|
||||
throw new SQLException( 'Unable to execute query'
|
||||
, $this->nativeError( $result )
|
||||
, $sql
|
||||
);
|
||||
}
|
||||
|
||||
return new OCI8ResultSet( $this, $result, $fetchmode );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see Connection::simpleUpdate()
|
||||
*/
|
||||
|
||||
function executeUpdate( $sql )
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
|
||||
$statement = oci_parse( $this->dblink, $sql );
|
||||
|
||||
if ( ! $statement )
|
||||
{
|
||||
throw new SQLException( 'Unable to prepare update'
|
||||
, $this->nativeError()
|
||||
, $sql
|
||||
);
|
||||
}
|
||||
|
||||
$success = oci_execute( $statement, $this->execMode );
|
||||
|
||||
if ( ! $success )
|
||||
{
|
||||
throw new SQLException( 'Unable to execute update'
|
||||
, $this->nativeError( $statement )
|
||||
, $sql
|
||||
);
|
||||
}
|
||||
|
||||
$this->lastStmt = $statement;
|
||||
|
||||
return oci_num_rows( $statement );
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
$this->execMode = OCI_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
$result = oci_commit( $this->dblink );
|
||||
|
||||
if ( ! $result )
|
||||
{
|
||||
throw new SQLException( 'Unable to commit transaction'
|
||||
, $this->nativeError()
|
||||
);
|
||||
}
|
||||
|
||||
$this->execMode = OCI_COMMIT_ON_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Roll back ( undo ) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
$result = oci_rollback( $this->dblink );
|
||||
|
||||
if ( ! $result )
|
||||
{
|
||||
throw new SQLException( 'Unable to rollback transaction'
|
||||
, $this->nativeError()
|
||||
);
|
||||
}
|
||||
|
||||
$this->execMode = OCI_COMMIT_ON_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query.
|
||||
*
|
||||
* @return int Number of rows affected by the last query.
|
||||
* @todo -cOCI8Connection Figure out whether getUpdateCount() should throw exception on error or just return 0.
|
||||
*/
|
||||
function getUpdateCount()
|
||||
{
|
||||
if ( ! $this->lastStmt )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
$result = oci_num_rows( $this->lastStmt );
|
||||
|
||||
if ( $result === false )
|
||||
{
|
||||
throw new SQLException( 'Update count failed'
|
||||
, $this->nativeError( $this->lastStmt )
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build Oracle-style query with limit or offset.
|
||||
* If the original SQL is in variable: query then the requlting
|
||||
* SQL looks like this:
|
||||
* <pre>
|
||||
* SELECT B.* FROM (
|
||||
* SELECT A.*, rownum as TORQUE$ROWNUM FROM (
|
||||
* query
|
||||
* ) A
|
||||
* ) B WHERE B.TORQUE$ROWNUM > offset AND B.TORQUE$ROWNUM
|
||||
* <= offset + limit
|
||||
* </pre>
|
||||
*
|
||||
* @param string &$sql the query
|
||||
* @param int $offset
|
||||
* @param int $limit
|
||||
* @return void ( $sql parameter is currently manipulated directly )
|
||||
*/
|
||||
public function applyLimit( &$sql, $offset, $limit )
|
||||
{
|
||||
$sql =
|
||||
'SELECT B.* FROM ( '
|
||||
. 'SELECT A.*, rownum AS CREOLE$ROWNUM FROM ( '
|
||||
. $sql
|
||||
. ' ) A '
|
||||
. ' ) B WHERE ';
|
||||
|
||||
if ( $offset > 0 )
|
||||
{
|
||||
$sql .= ' B.CREOLE$ROWNUM > ' . $offset;
|
||||
|
||||
if ( $limit > 0 )
|
||||
{
|
||||
$sql .= ' AND B.CREOLE$ROWNUM <= '
|
||||
. ( $offset + $limit );
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$sql .= ' B.CREOLE$ROWNUM <= ' . $limit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native Oracle Error Message as a string.
|
||||
*
|
||||
* @param string $msg The Internal Error Message
|
||||
* @param mixed $errno The Oracle Error resource
|
||||
*/
|
||||
public function nativeError( $result = null )
|
||||
{
|
||||
if ( $result !== null )
|
||||
{
|
||||
$error = oci_error( $result );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$error = oci_error( $this->dblink );
|
||||
}
|
||||
|
||||
return $error[ 'code' ] . ': ' . $error[ 'message' ];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/oracle/metadata/OCI8DatabaseInfo.php';
|
||||
|
||||
return new OCI8DatabaseInfo( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
require_once 'creole/drivers/oracle/OCI8IdGenerator.php';
|
||||
|
||||
return new OCI8IdGenerator( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle supports native prepared statements, but the oci_parse call
|
||||
* is actually called by the OCI8PreparedStatement class because
|
||||
* some additional SQL processing may be necessary ( e.g. to apply limit ).
|
||||
* @see OCI8PreparedStatement::executeQuery()
|
||||
* @see OCI8PreparedStatement::executeUpdate()
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement( $sql )
|
||||
{
|
||||
require_once 'creole/drivers/oracle/OCI8PreparedStatement.php';
|
||||
|
||||
return new OCI8PreparedStatement( $this, $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall( $sql )
|
||||
{
|
||||
throw new SQLException( 'Oracle driver does not yet support stored procedures using CallableStatement.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/oracle/OCI8Statement.php';
|
||||
|
||||
return new OCI8Statement( $this );
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue