2006-12-01 02:26:12 +00:00
< ? php
/* SVN FILE: $Id$ */
/**
2007-07-14 21:25:04 +00:00
* Oracle layer for DBO .
2006-12-01 02:26:12 +00:00
*
* Long description for file
*
* PHP versions 4 and 5
*
2007-04-27 06:43:40 +00:00
* CakePHP ( tm ) : Rapid Development Framework < http :// www . cakephp . org />
2008-01-01 22:18:17 +00:00
* Copyright 2005 - 2008 , Cake Software Foundation , Inc .
2006-12-01 02:26:12 +00:00
* 1785 E . Sahara Avenue , Suite 490 - 204
* Las Vegas , Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice .
*
* @ filesource
2008-01-01 22:18:17 +00:00
* @ copyright Copyright 2005 - 2008 , Cake Software Foundation , Inc .
2007-04-27 06:43:40 +00:00
* @ link http :// www . cakefoundation . org / projects / info / cakephp CakePHP ( tm ) Project
2006-12-01 02:26:12 +00:00
* @ package cake
2007-04-27 06:43:40 +00:00
* @ subpackage cake . cake . libs . model . datasources . dbo
* @ since CakePHP v 1.2 . 0.4041
2006-12-01 02:26:12 +00:00
* @ version $Revision $
* @ modifiedby $LastChangedBy $
* @ lastmodified $Date $
* @ license http :// www . opensource . org / licenses / mit - license . php The MIT License
*/
/**
* Short description for class .
*
* Long description for class
*
* @ package cake
2007-04-27 06:43:40 +00:00
* @ subpackage cake . cake . libs . model . datasources . dbo
2006-12-01 02:26:12 +00:00
*/
class DboOracle extends DboSource {
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access public
*/
var $config ;
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access public
*/
var $alias = '' ;
2007-03-16 14:23:54 +00:00
/**
2007-04-27 06:43:40 +00:00
* The name of the model ' s sequence
*
* @ var unknown_type
*/
2007-01-02 20:30:22 +00:00
var $sequence = '' ;
2007-03-16 14:23:54 +00:00
/**
* Transaction in progress flag
*
* @ var boolean
*/
2007-04-27 06:43:40 +00:00
var $__transactionStarted = false ;
2008-02-20 20:02:18 +00:00
2007-04-27 06:43:40 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access public
*/
2007-03-16 14:23:54 +00:00
var $columns = array (
'primary_key' => array ( 'name' => 'number NOT NULL' ),
'string' => array ( 'name' => 'varchar2' , 'limit' => '255' ),
'text' => array ( 'name' => 'varchar2' ),
'integer' => array ( 'name' => 'numeric' ),
'float' => array ( 'name' => 'float' ),
2007-07-14 21:25:04 +00:00
'datetime' => array ( 'name' => 'date' , 'format' => 'Y-m-d H:i:s' ),
'timestamp' => array ( 'name' => 'date' , 'format' => 'Y-m-d H:i:s' ),
'time' => array ( 'name' => 'date' , 'format' => 'Y-m-d H:i:s' ),
'date' => array ( 'name' => 'date' , 'format' => 'Y-m-d H:i:s' ),
2007-03-16 14:23:54 +00:00
'binary' => array ( 'name' => 'bytea' ),
'boolean' => array ( 'name' => 'boolean' ),
'number' => array ( 'name' => 'numeric' ),
2007-04-27 06:43:40 +00:00
'inet' => array ( 'name' => 'inet' ));
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access protected
*/
2007-01-28 20:32:01 +00:00
var $connection ;
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access protected
*/
var $_limit = - 1 ;
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access protected
*/
var $_offset = 0 ;
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access protected
*/
var $_map ;
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access protected
*/
var $_currentRow ;
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access protected
*/
var $_numRows ;
2007-03-16 14:23:54 +00:00
/**
2006-12-01 02:26:12 +00:00
* Enter description here ...
*
* @ var unknown_type
* @ access protected
*/
var $_results ;
2008-02-07 15:46:05 +00:00
/**
* Base configuration settings for MySQL driver
*
* @ var array
*/
var $_baseConfig = array (
'persistent' => true ,
'host' => 'localhost' ,
'login' => 'system' ,
'password' => '' ,
'database' => 'cake' ,
'nls_sort' => '' ,
'nls_sort' => ''
);
2006-12-01 02:26:12 +00:00
/**
* Connects to the database using options in the given configuration array .
*
2007-10-22 16:09:35 +00:00
* @ return boolean True if the database could be connected , else false
2006-12-01 02:26:12 +00:00
* @ access public
*/
function connect () {
2007-04-27 06:43:40 +00:00
$config = $this -> config ;
$this -> connected = false ;
$config [ 'charset' ] = ! empty ( $config [ 'charset' ]) ? $config [ 'charset' ] : null ;
2008-02-07 15:46:05 +00:00
if ( $this -> config [ 'persistent' ]) {
$connect = 'ociplogon' ;
} else {
$connect = 'ocilogon' ;
}
2007-04-27 06:43:40 +00:00
$this -> connection = $connect ( $config [ 'login' ], $config [ 'password' ], $config [ 'database' ], $config [ 'charset' ]);
2006-12-01 02:26:12 +00:00
2007-01-28 20:32:01 +00:00
if ( $this -> connection ) {
2006-12-01 02:26:12 +00:00
$this -> connected = true ;
2007-07-25 04:38:28 +00:00
if ( ! empty ( $config [ 'nls_sort' ])) {
2007-04-27 06:43:40 +00:00
$this -> execute ( 'ALTER SESSION SET NLS_SORT=' . $config [ 'nls_sort' ]);
}
2007-07-25 04:38:28 +00:00
if ( ! empty ( $config [ 'nls_comp' ])) {
2007-04-27 06:43:40 +00:00
$this -> execute ( 'ALTER SESSION SET NLS_COMP=' . $config [ 'nls_comp' ]);
}
$this -> execute ( " ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS' " );
2007-01-28 20:32:01 +00:00
} else {
$this -> connected = false ;
2006-12-01 02:26:12 +00:00
}
2007-01-28 20:32:01 +00:00
return $this -> connected ;
2006-12-01 02:26:12 +00:00
}
2007-04-27 06:43:40 +00:00
/**
* Sets the encoding language of the session
*
* @ param string $lang language constant
2007-10-22 05:52:20 +00:00
* @ return bool
2007-04-27 06:43:40 +00:00
*/
2007-03-16 14:23:54 +00:00
function setEncoding ( $lang ) {
2007-07-25 04:38:28 +00:00
if ( ! $this -> execute ( 'ALTER SESSION SET NLS_LANGUAGE=' . $lang )) {
2007-04-27 06:43:40 +00:00
return false ;
}
return true ;
2007-03-16 14:23:54 +00:00
}
2007-04-27 06:43:40 +00:00
/**
* Gets the current encoding language
*
* @ return string language constant
*/
2007-03-16 14:23:54 +00:00
function getEncoding () {
2007-04-27 06:43:40 +00:00
$sql = 'SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER=\'NLS_LANGUAGE\'' ;
2007-07-25 04:38:28 +00:00
if ( ! $this -> execute ( $sql )) {
2007-04-27 06:43:40 +00:00
return false ;
}
2007-01-02 20:30:22 +00:00
2007-07-25 04:38:28 +00:00
if ( ! $row = $this -> fetchRow ()) {
2007-04-27 06:43:40 +00:00
return false ;
}
return $row [ 0 ][ 'VALUE' ];
}
2006-12-01 02:26:12 +00:00
/**
* Disconnects from database .
*
2007-10-22 16:09:35 +00:00
* @ return boolean True if the database could be disconnected , else false
2006-12-01 02:26:12 +00:00
* @ access public
*/
function disconnect () {
2007-07-25 04:38:28 +00:00
if ( $this -> connection ) {
2007-04-27 06:43:40 +00:00
$this -> connected = ! ocilogoff ( $this -> connection );
return ! $this -> connected ;
2006-12-01 02:26:12 +00:00
}
}
/**
* Scrape the incoming SQL to create the association map . This is an extremely
* experimental method that creates the association maps since Oracle will not tell us .
*
* @ param string $sql
* @ return false if sql is nor a SELECT
* @ access protected
*/
function _scrapeSQL ( $sql ) {
2007-04-27 06:43:40 +00:00
$sql = str_replace ( " \" " , '' , $sql );
$preFrom = preg_split ( '/\bFROM\b/' , $sql );
$preFrom = $preFrom [ 0 ];
$find = array ( 'SELECT' );
$replace = array ( '' );
2006-12-01 02:26:12 +00:00
$fieldList = trim ( str_replace ( $find , $replace , $preFrom ));
2007-04-27 06:43:40 +00:00
$fields = preg_split ( '/,\s+/' , $fieldList ); //explode(', ', $fieldList);
$lastTableName = '' ;
2007-07-14 21:25:04 +00:00
foreach ( $fields as $key => $value ) {
2007-07-25 04:38:28 +00:00
if ( $value != 'COUNT(*) AS count' ) {
if ( preg_match ( '/\s+(\w+(\.\w+)*)$/' , $value , $matches )) {
2007-04-27 06:43:40 +00:00
$fields [ $key ] = $matches [ 1 ];
2007-07-25 04:38:28 +00:00
if ( preg_match ( '/^(\w+\.)/' , $value , $matches )) {
2007-04-27 06:43:40 +00:00
$fields [ $key ] = $matches [ 1 ] . $fields [ $key ];
$lastTableName = $matches [ 1 ];
}
}
/*
2007-07-25 04:38:28 +00:00
if ( preg_match ( '/(([[:alnum:]_]+)\.[[:alnum:]_]+)(\s+AS\s+(\w+))?$/i' , $value , $matches )) {
2007-04-27 06:43:40 +00:00
$fields [ $key ] = isset ( $matches [ 4 ]) ? $matches [ 2 ] . '.' . $matches [ 4 ] : $matches [ 1 ];
}
*/
}
}
2006-12-01 02:26:12 +00:00
$this -> _map = array ();
2007-04-27 06:43:40 +00:00
2007-07-14 21:25:04 +00:00
foreach ( $fields as $f ) {
2006-12-01 02:26:12 +00:00
$e = explode ( '.' , $f );
2007-07-25 04:38:28 +00:00
if ( count ( $e ) > 1 ) {
2006-12-01 02:26:12 +00:00
$table = $e [ 0 ];
$field = strtolower ( $e [ 1 ]);
} else {
$table = 0 ;
$field = $e [ 0 ];
}
$this -> _map [] = array ( $table , $field );
}
}
/**
* Modify a SQL query to limit ( and offset ) the result set
*
2007-10-22 16:11:12 +00:00
* @ param integer $limit Maximum number of rows to return
* @ param integer $offset Row to begin returning
2006-12-01 02:26:12 +00:00
* @ return modified SQL Query
* @ access public
*/
2007-04-27 06:43:40 +00:00
function limit ( $limit = - 1 , $offset = 0 ) {
$this -> _limit = ( int ) $limit ;
$this -> _offset = ( int ) $offset ;
2006-12-01 02:26:12 +00:00
}
/**
* Returns number of rows in previous resultset . If no previous resultset exists ,
* this returns false .
*
2007-10-22 16:54:36 +00:00
* @ return integer Number of rows in resultset
2006-12-01 02:26:12 +00:00
* @ access public
*/
function lastNumRows () {
return $this -> _numRows ;
}
/**
* Executes given SQL statement . This is an overloaded method .
*
* @ param string $sql SQL statement
* @ return resource Result resource identifier or null
* @ access protected
*/
2007-03-16 14:23:54 +00:00
function _execute ( $sql ) {
2007-01-28 20:32:01 +00:00
$this -> _statementId = ociparse ( $this -> connection , $sql );
2007-07-25 04:38:28 +00:00
if ( ! $this -> _statementId ) {
2006-12-01 02:26:12 +00:00
return null ;
}
2007-04-27 06:43:40 +00:00
2007-07-25 04:38:28 +00:00
if ( $this -> __transactionStarted ) {
2006-12-01 02:26:12 +00:00
$mode = OCI_DEFAULT ;
} else {
$mode = OCI_COMMIT_ON_SUCCESS ;
}
2007-04-27 06:43:40 +00:00
2007-07-25 04:38:28 +00:00
if ( ! ociexecute ( $this -> _statementId , $mode )) {
2006-12-01 02:26:12 +00:00
return false ;
}
2007-04-27 06:43:40 +00:00
switch ( ocistatementtype ( $this -> _statementId )) {
case 'DESCRIBE' :
case 'SELECT' :
$this -> _scrapeSQL ( $sql );
break ;
default :
return $this -> _statementId ;
break ;
}
2007-07-25 04:38:28 +00:00
if ( $this -> _limit >= 1 ) {
2006-12-01 02:26:12 +00:00
ocisetprefetch ( $this -> _statementId , $this -> _limit );
} else {
ocisetprefetch ( $this -> _statementId , 3000 );
}
$this -> _numRows = ocifetchstatement ( $this -> _statementId , $this -> _results , $this -> _offset , $this -> _limit , OCI_NUM | OCI_FETCHSTATEMENT_BY_ROW );
2007-04-27 06:43:40 +00:00
$this -> _currentRow = 0 ;
$this -> limit ();
2006-12-01 02:26:12 +00:00
return $this -> _statementId ;
}
/**
* Enter description here ...
*
* @ return unknown
* @ access public
*/
function fetchRow () {
2007-07-25 04:38:28 +00:00
if ( $this -> _currentRow >= $this -> _numRows ) {
2007-04-27 06:43:40 +00:00
ocifreestatement ( $this -> _statementId );
$this -> _map = null ;
$this -> _results = null ;
$this -> _currentRow = null ;
$this -> _numRows = null ;
2006-12-01 02:26:12 +00:00
return false ;
}
$resultRow = array ();
2007-04-27 06:43:40 +00:00
2007-07-14 21:25:04 +00:00
foreach ( $this -> _results [ $this -> _currentRow ] as $index => $field ) {
2006-12-01 02:26:12 +00:00
list ( $table , $column ) = $this -> _map [ $index ];
2007-04-27 06:43:40 +00:00
2007-07-25 04:38:28 +00:00
if ( strpos ( $column , ' count' )) {
2006-12-01 02:26:12 +00:00
$resultRow [ 0 ][ 'count' ] = $field ;
} else {
$resultRow [ $table ][ $column ] = $this -> _results [ $this -> _currentRow ][ $index ];
}
}
$this -> _currentRow ++ ;
return $resultRow ;
}
/**
2007-01-28 20:32:01 +00:00
* Checks to see if a named sequence exists
2006-12-01 02:26:12 +00:00
*
2007-01-28 20:32:01 +00:00
* @ param string $sequence
2007-10-22 05:52:20 +00:00
* @ return bool
2006-12-01 02:26:12 +00:00
* @ access public
*/
2007-01-28 20:32:01 +00:00
function sequenceExists ( $sequence ) {
2007-04-27 06:43:40 +00:00
$sql = " SELECT SEQUENCE_NAME FROM USER_SEQUENCES WHERE SEQUENCE_NAME = ' $sequence ' " ;
2007-07-25 04:38:28 +00:00
if ( ! $this -> execute ( $sql )) {
2007-04-27 06:43:40 +00:00
return false ;
}
return $this -> fetchRow ();
2007-01-28 20:32:01 +00:00
}
/**
* Creates a database sequence
*
* @ param string $sequence
2007-10-22 05:52:20 +00:00
* @ return bool
2007-01-28 20:32:01 +00:00
* @ access public
*/
2007-04-27 06:43:40 +00:00
function createSequence ( $sequence ) {
$sql = " CREATE SEQUENCE $sequence " ;
return $this -> execute ( $sql );
}
/**
* Enter description here ...
*
* @ param unknown_type $table
* @ return unknown
* @ access public
*/
function createTrigger ( $table ) {
$sql = " CREATE OR REPLACE TRIGGER pk_ $table " . " _trigger BEFORE INSERT ON $table FOR EACH ROW BEGIN SELECT pk_ $table .NEXTVAL INTO :NEW.ID FROM DUAL; END; " ;
return $this -> execute ( $sql );
}
2006-12-01 02:26:12 +00:00
/**
* Returns an array of tables in the database . If there are no tables , an error is
* raised and the application exits .
*
* @ return array tablenames in the database
* @ access public
*/
function listSources () {
2007-04-27 06:43:40 +00:00
$cache = parent :: listSources ();
2007-07-25 04:38:28 +00:00
if ( $cache != null ) {
2007-01-28 20:32:01 +00:00
return $cache ;
}
2006-12-01 02:26:12 +00:00
$sql = 'SELECT view_name AS name FROM user_views UNION SELECT table_name AS name FROM user_tables' ;
2007-04-27 06:43:40 +00:00
2007-07-25 04:38:28 +00:00
if ( ! $this -> execute ( $sql )) {
2007-04-27 06:43:40 +00:00
return false ;
2006-12-01 02:26:12 +00:00
}
2007-01-28 20:32:01 +00:00
$sources = array ();
2007-04-27 06:43:40 +00:00
2007-07-14 21:25:04 +00:00
while ( $r = $this -> fetchRow ()) {
2008-01-29 14:25:48 +00:00
$sources [] = strtolower ( $r [ 0 ][ 'name' ]);
2006-12-01 02:26:12 +00:00
}
2007-01-28 20:32:01 +00:00
parent :: listSources ( $sources );
return $sources ;
2006-12-01 02:26:12 +00:00
}
/**
* Returns an array of the fields in given table name .
*
* @ param object instance of a model to inspect
* @ return array Fields in table . Keys are name and type
* @ access public
*/
function describe ( & $model ) {
$cache = parent :: describe ( $model );
2007-04-27 06:43:40 +00:00
2007-07-25 04:38:28 +00:00
if ( $cache != null ) {
2006-12-01 02:26:12 +00:00
return $cache ;
}
2007-07-14 21:25:04 +00:00
$sql = 'SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH FROM user_tab_columns WHERE table_name = \'' ;
2007-03-16 14:23:54 +00:00
$sql .= strtoupper ( $this -> fullTableName ( $model )) . '\'' ;
2007-04-27 06:43:40 +00:00
2007-07-25 04:38:28 +00:00
if ( ! $this -> execute ( $sql )) {
2007-04-27 06:43:40 +00:00
return false ;
}
2006-12-01 02:26:12 +00:00
$fields = array ();
2007-04-27 06:43:40 +00:00
2007-07-14 21:25:04 +00:00
for ( $i = 0 ; $row = $this -> fetchRow (); $i ++ ) {
2007-08-21 21:46:59 +00:00
$fields [ strtolower ( $row [ 0 ][ 'COLUMN_NAME' ])] = array ( 'type' => $this -> column ( $row [ 0 ][ 'DATA_TYPE' ]),
'length' => $row [ 0 ][ 'DATA_LENGTH' ]);
2006-12-01 02:26:12 +00:00
}
2007-03-16 14:23:54 +00:00
$this -> __cacheDescription ( $this -> fullTableName ( $model , false ), $fields );
2006-12-01 02:26:12 +00:00
return $fields ;
}
2008-01-29 14:25:48 +00:00
/**
* Returns an array of the indexes in given table name .
*
* @ param string $model Name of model to inspect
* @ return array Fields in table . Keys are column and unique
*/
function index ( $model ) {
$index = array ();
$table = $this -> fullTableName ( $model , false );
if ( $table ) {
$indexes = $this -> query ( ' SELECT
cc . table_name ,
cc . column_name ,
cc . constraint_name ,
c . constraint_type ,
i . index_name ,
i . uniqueness
FROM user_cons_columns cc
LEFT JOIN user_indexes i ON ( cc . constraint_name = i . index_name )
LEFT JOIN user_constraints c ON ( c . constraint_name = cc . constraint_name )
WHERE cc . table_name = \ '' . strtoupper ( $table ) . '\'' );
foreach ( $indexes as $i => $idx ) {
if ( $idx [ 'c' ][ 'constraint_type' ] == 'P' ) {
$key = 'PRIMARY' ;
} else {
continue ;
}
if ( ! isset ( $index [ $key ])) {
$index [ $key ][ 'column' ] = strtolower ( $idx [ 'cc' ][ 'column_name' ]);
$index [ $key ][ 'unique' ] = ife ( $idx [ 'i' ][ 'uniqueness' ] == 'UNIQUE' , 1 , 0 );
} else {
if ( ! is_array ( $index [ $key ][ 'column' ])) {
$col [] = $index [ $key ][ 'column' ];
}
$col [] = strtolower ( $idx [ 'cc' ][ 'column_name' ]);
$index [ $key ][ 'column' ] = $col ;
}
}
}
return $index ;
}
/**
* Generate a Oracle Alter Table syntax for the given Schema comparison
*
* @ param unknown_type $schema
* @ return unknown
*/
function alterSchema ( $compare , $table = null ) {
if ( ! is_array ( $compare )) {
return false ;
}
$out = '' ;
$colList = array ();
foreach ( $compare as $curTable => $types ) {
if ( ! $table || $table == $curTable ) {
$out .= 'ALTER TABLE ' . $this -> fullTableName ( $curTable ) . " \n " ;
foreach ( $types as $type => $column ) {
switch ( $type ) {
case 'add' :
foreach ( $column as $field => $col ) {
$col [ 'name' ] = $field ;
$alter = 'ADD ' . $this -> buildColumn ( $col );
if ( isset ( $col [ 'after' ])) {
$alter .= ' AFTER ' . $this -> name ( $col [ 'after' ]);
}
$colList [] = $alter ;
}
break ;
case 'drop' :
foreach ( $column as $field => $col ) {
$col [ 'name' ] = $field ;
$colList [] = 'DROP ' . $this -> name ( $field );
}
break ;
case 'change' :
foreach ( $column as $field => $col ) {
if ( ! isset ( $col [ 'name' ])) {
$col [ 'name' ] = $field ;
}
$colList [] = 'CHANGE ' . $this -> name ( $field ) . ' ' . $this -> buildColumn ( $col );
}
break ;
}
}
$out .= " \t " . join ( " , \n \t " , $colList ) . " ; \n \n " ;
}
}
return $out ;
}
2006-12-01 02:26:12 +00:00
/**
2007-04-27 06:43:40 +00:00
* This method should quote Oracle identifiers . Well it doesn ' t .
2007-01-28 20:32:01 +00:00
* It would break all scaffolding and all of Cake ' s default assumptions .
2006-12-01 02:26:12 +00:00
*
* @ param unknown_type $var
* @ return unknown
* @ access public
*/
function name ( $var ) {
2007-04-27 06:43:40 +00:00
switch ( $var ) {
2008-03-03 18:34:15 +00:00
case 'Permission._create' :
case 'Permission._read' :
case 'Permission._update' :
case 'Permission._delete' :
list ( $model , $field ) = explode ( '.' , $var );
return " $model . \" $field\ " " ;
2007-04-27 06:43:40 +00:00
break ;
default :
return $var ;
break ;
}
2006-12-01 02:26:12 +00:00
}
2007-01-02 20:30:22 +00:00
/**
* Begin a transaction
*
* @ param unknown_type $model
2007-10-22 16:09:35 +00:00
* @ return boolean True on success , false on fail
2007-01-02 20:30:22 +00:00
* ( i . e . if the database / model does not support transactions ) .
*/
2007-03-16 14:23:54 +00:00
function begin () {
2007-04-27 06:43:40 +00:00
$this -> __transactionStarted = true ;
return true ;
2007-01-02 20:30:22 +00:00
}
/**
* Rollback a transaction
*
* @ param unknown_type $model
2007-10-22 16:09:35 +00:00
* @ return boolean True on success , false on fail
2007-01-02 20:30:22 +00:00
* ( i . e . if the database / model does not support transactions ,
* or a transaction has not started ) .
*/
2007-01-28 20:32:01 +00:00
function rollback () {
2007-04-27 06:43:40 +00:00
return ocirollback ( $this -> connection );
2007-01-02 20:30:22 +00:00
}
/**
* Commit a transaction
*
* @ param unknown_type $model
2007-10-22 16:09:35 +00:00
* @ return boolean True on success , false on fail
2007-01-02 20:30:22 +00:00
* ( i . e . if the database / model does not support transactions ,
* or a transaction has not started ) .
*/
2007-03-16 14:23:54 +00:00
function commit () {
2007-04-27 06:43:40 +00:00
$this -> __transactionStarted = false ;
return ocicommit ( $this -> connection );
2007-01-02 20:30:22 +00:00
}
2006-12-01 02:26:12 +00:00
/**
* Converts database - layer column types to basic types
*
* @ param string $real Real database - layer column type ( i . e . " varchar(255) " )
* @ return string Abstract column type ( i . e . " string " )
* @ access public
*/
function column ( $real ) {
2007-07-25 04:38:28 +00:00
if ( is_array ( $real )) {
2006-12-01 02:26:12 +00:00
$col = $real [ 'name' ];
2007-07-25 04:38:28 +00:00
if ( isset ( $real [ 'limit' ])) {
2006-12-01 02:26:12 +00:00
$col .= '(' . $real [ 'limit' ] . ')' ;
}
return $col ;
2007-01-02 20:30:22 +00:00
} else {
$real = strtolower ( $real );
2006-12-01 02:26:12 +00:00
}
2007-12-08 06:08:03 +00:00
$col = str_replace ( ')' , '' , $real );
2006-12-01 02:26:12 +00:00
$limit = null ;
@ list ( $col , $limit ) = explode ( '(' , $col );
2007-07-25 04:38:28 +00:00
if ( in_array ( $col , array ( 'date' , 'timestamp' ))) {
2006-12-01 02:26:12 +00:00
return $col ;
}
2007-07-25 04:38:28 +00:00
if ( strpos ( $col , 'number' ) !== false ) {
2006-12-01 02:26:12 +00:00
return 'integer' ;
}
2007-07-25 04:38:28 +00:00
if ( strpos ( $col , 'integer' ) !== false ) {
2006-12-01 02:26:12 +00:00
return 'integer' ;
}
2007-07-25 04:38:28 +00:00
if ( strpos ( $col , 'char' ) !== false ) {
2006-12-01 02:26:12 +00:00
return 'string' ;
}
2007-07-25 04:38:28 +00:00
if ( strpos ( $col , 'text' ) !== false ) {
2006-12-01 02:26:12 +00:00
return 'text' ;
}
2007-07-25 04:38:28 +00:00
if ( strpos ( $col , 'blob' ) !== false ) {
2006-12-01 02:26:12 +00:00
return 'binary' ;
}
2007-07-25 04:38:28 +00:00
if ( in_array ( $col , array ( 'float' , 'double' , 'decimal' ))) {
2006-12-01 02:26:12 +00:00
return 'float' ;
}
2007-07-25 04:38:28 +00:00
if ( $col == 'boolean' ) {
2006-12-01 02:26:12 +00:00
return $col ;
}
return 'text' ;
}
/**
* Returns a quoted and escaped string of $data for use in an SQL statement .
*
* @ param string $data String to be prepared for use in an SQL statement
* @ return string Quoted and escaped
* @ access public
*/
2007-07-14 21:25:04 +00:00
function value ( $data , $column = null , $safe = false ) {
$parent = parent :: value ( $data , $column , $safe );
2007-07-25 04:38:28 +00:00
2007-07-14 21:25:04 +00:00
if ( $parent != null ) {
return $parent ;
}
if ( $data === null ) {
return 'NULL' ;
}
2007-07-25 04:38:28 +00:00
if ( $data === '' ) {
2007-07-14 21:25:04 +00:00
return " '' " ;
}
2007-07-25 04:38:28 +00:00
2007-07-14 21:25:04 +00:00
switch ( $column ) {
2007-01-02 20:30:22 +00:00
case 'date' :
2007-07-14 21:25:04 +00:00
$data = date ( 'Y-m-d H:i:s' , strtotime ( $data ));
$data = " TO_DATE(' $data ', 'YYYY-MM-DD HH24:MI:SS') " ;
break ;
case 'integer' :
case 'float' :
case null :
2007-07-25 04:38:28 +00:00
if ( is_numeric ( $data )) {
2007-07-14 21:25:04 +00:00
break ;
2007-07-09 02:57:56 +00:00
}
2007-07-14 21:25:04 +00:00
default :
$data = str_replace ( " ' " , " '' " , $data );
$data = " ' $data ' " ;
break ;
2007-01-02 20:30:22 +00:00
}
2007-07-14 21:25:04 +00:00
return $data ;
2006-12-01 02:26:12 +00:00
}
/**
* Returns the ID generated from the previous INSERT operation .
*
* @ param string
2007-10-22 16:54:36 +00:00
* @ return integer
2006-12-01 02:26:12 +00:00
* @ access public
*/
function lastInsertId ( $source ) {
2007-04-27 06:43:40 +00:00
$sequence = ( ! empty ( $this -> sequence )) ? $this -> sequence : $source . '_seq' ;
2007-01-02 20:30:22 +00:00
$sql = " SELECT $sequence .currval FROM dual " ;
2007-04-27 06:43:40 +00:00
2007-07-25 04:38:28 +00:00
if ( ! $this -> execute ( $sql )) {
2007-04-27 06:43:40 +00:00
return false ;
2006-12-01 02:26:12 +00:00
}
2007-04-27 06:43:40 +00:00
2007-07-14 21:25:04 +00:00
while ( $row = $this -> fetchRow ()) {
2007-04-27 06:43:40 +00:00
return $row [ $sequence ][ 'currval' ];
2006-12-01 02:26:12 +00:00
}
2007-01-28 20:32:01 +00:00
return false ;
2006-12-01 02:26:12 +00:00
}
/**
* Returns a formatted error message from previous database operation .
*
* @ return string Error message with error number
* @ access public
*/
function lastError () {
$errors = ocierror ();
2007-04-27 06:43:40 +00:00
2007-07-25 04:38:28 +00:00
if (( $errors != null ) && ( isset ( $errors [ " message " ]))) {
2006-12-01 02:26:12 +00:00
return ( $errors [ " message " ]);
}
return null ;
}
/**
* Returns number of affected rows in previous database operation . If no previous operation exists , this returns false .
*
* @ return int Number of affected rows
* @ access public
*/
function lastAffected () {
2007-01-28 20:32:01 +00:00
return $this -> _statementId ? ocirowcount ( $this -> _statementId ) : false ;
2006-12-01 02:26:12 +00:00
}
2007-07-25 04:38:28 +00:00
/**
* Inserts multiple values into a join table
*
* @ param string $table
* @ param string $fields
* @ param array $values
*/
function insertMulti ( $table , $fields , $values ) {
2008-01-01 23:57:17 +00:00
parent :: __insertMulti ( $table , $fields , $values );
2007-07-25 04:38:28 +00:00
}
2008-01-11 22:40:44 +00:00
/**
* Renders a final SQL statement by putting together the component parts in the correct order
*
* @ param string $type
* @ param array $data
* @ return string
*/
function renderStatement ( $type , $data ) {
extract ( $data );
$aliases = null ;
switch ( strtolower ( $type )) {
case 'select' :
return " SELECT { $fields } FROM { $table } { $alias } { $joins } { $conditions } { $order } { $limit } " ;
break ;
case 'update' :
if ( ! empty ( $alias )) {
$aliases = " { $this -> alias } { $alias } " ;
}
return " UPDATE { $table } { $aliases } SET { $fields } { $conditions } " ;
break ;
case 'delete' :
if ( ! empty ( $alias )) {
$aliases = " { $this -> alias } { $alias } " ;
}
return " DELETE FROM { $table } { $aliases } { $conditions } " ;
break ;
}
}
2008-01-29 02:38:54 +00:00
/**
* Enter description here ...
*
* @ param Model $model
* @ param unknown_type $linkModel
* @ param string $type Association type
* @ param unknown_type $association
* @ param unknown_type $assocData
* @ param unknown_type $queryData
* @ param unknown_type $external
* @ param unknown_type $resultSet
* @ param integer $recursive Number of levels of association
* @ param array $stack
*/
function queryAssociation ( & $model , & $linkModel , $type , $association , $assocData , & $queryData , $external = false , & $resultSet , $recursive , $stack ) {
if ( $query = $this -> generateAssociationQuery ( $model , $linkModel , $type , $association , $assocData , $queryData , $external , $resultSet )) {
if ( ! isset ( $resultSet ) || ! is_array ( $resultSet )) {
if ( Configure :: read () > 0 ) {
e ( '<div style = "font: Verdana bold 12px; color: #FF0000">' . sprintf ( __ ( 'SQL Error in model %s:' , true ), $model -> alias ) . ' ' );
if ( isset ( $this -> error ) && $this -> error != null ) {
e ( $this -> error );
}
e ( '</div>' );
}
return null ;
}
$count = count ( $resultSet );
if ( $type === 'hasMany' && ( ! isset ( $assocData [ 'limit' ]) || empty ( $assocData [ 'limit' ]))) {
$ins = $fetch = array ();
for ( $i = 0 ; $i < $count ; $i ++ ) {
if ( $in = $this -> insertQueryData ( '{$__cakeID__$}' , $resultSet [ $i ], $association , $assocData , $model , $linkModel , $stack )) {
$ins [] = $in ;
}
}
if ( ! empty ( $ins )) {
$fetch = array ();
$ins = array_chunk ( $ins , 1000 );
foreach ( $ins as $i ) {
$q = str_replace ( '{$__cakeID__$}' , join ( ', ' , $i ), $query );
$res = $this -> fetchAll ( $q , $model -> cacheQueries , $model -> alias );
$fetch = am ( $fetch , $res );
}
}
if ( ! empty ( $fetch ) && is_array ( $fetch )) {
if ( $recursive > 0 ) {
foreach ( $linkModel -> __associations as $type1 ) {
foreach ( $linkModel -> { $type1 } as $assoc1 => $assocData1 ) {
$deepModel =& $linkModel -> { $assoc1 };
$tmpStack = $stack ;
$tmpStack [] = $assoc1 ;
if ( $linkModel -> useDbConfig === $deepModel -> useDbConfig ) {
$db =& $this ;
} else {
$db =& ConnectionManager :: getDataSource ( $deepModel -> useDbConfig );
}
$db -> queryAssociation ( $linkModel , $deepModel , $type1 , $assoc1 , $assocData1 , $queryData , true , $fetch , $recursive - 1 , $tmpStack );
}
}
}
}
return $this -> __mergeHasMany ( $resultSet , $fetch , $association , $model , $linkModel , $recursive );
} elseif ( $type === 'hasAndBelongsToMany' ) {
$ins = $fetch = array ();
for ( $i = 0 ; $i < $count ; $i ++ ) {
if ( $in = $this -> insertQueryData ( '{$__cakeID__$}' , $resultSet [ $i ], $association , $assocData , $model , $linkModel , $stack )) {
$ins [] = $in ;
}
}
$foreignKey = $model -> hasAndBelongsToMany [ $association ][ 'foreignKey' ];
$joinKeys = array ( $foreignKey , $model -> hasAndBelongsToMany [ $association ][ 'associationForeignKey' ]);
list ( $with , $habtmFields ) = $model -> joinModel ( $model -> hasAndBelongsToMany [ $association ][ 'with' ], $joinKeys );
$habtmFieldsCount = count ( $habtmFields );
if ( ! empty ( $ins )) {
$fetch = null ;
$ins = array_chunk ( $ins , 1000 );
foreach ( $ins as $i ) {
$q = str_replace ( '{$__cakeID__$}' , '(' . join ( ', ' , $i ) . ')' , $query );
$q = str_replace ( '= (' , 'IN (' , $q );
$q = str_replace ( ' WHERE 1 = 1' , '' , $q );
$q = $this -> insertQueryData ( $q , null , $association , $assocData , $model , $linkModel , $stack );
if ( $q != false ) {
$res = $this -> fetchAll ( $q , $model -> cacheQueries , $model -> alias );
$fetch = am ( $fetch , $res );
}
}
}
}
for ( $i = 0 ; $i < $count ; $i ++ ) {
$row =& $resultSet [ $i ];
if ( $type !== 'hasAndBelongsToMany' ) {
$q = $this -> insertQueryData ( $query , $resultSet [ $i ], $association , $assocData , $model , $linkModel , $stack );
if ( $q != false ) {
$fetch = $this -> fetchAll ( $q , $model -> cacheQueries , $model -> alias );
} else {
$fetch = null ;
}
}
if ( ! empty ( $fetch ) && is_array ( $fetch )) {
if ( $recursive > 0 ) {
foreach ( $linkModel -> __associations as $type1 ) {
foreach ( $linkModel -> { $type1 } as $assoc1 => $assocData1 ) {
$deepModel =& $linkModel -> { $assoc1 };
if (( $type1 === 'belongsTo' ) || ( $deepModel -> alias === $model -> alias && $type === 'belongsTo' ) || ( $deepModel -> alias != $model -> alias )) {
$tmpStack = $stack ;
$tmpStack [] = $assoc1 ;
if ( $linkModel -> useDbConfig == $deepModel -> useDbConfig ) {
$db =& $this ;
} else {
$db =& ConnectionManager :: getDataSource ( $deepModel -> useDbConfig );
}
$db -> queryAssociation ( $linkModel , $deepModel , $type1 , $assoc1 , $assocData1 , $queryData , true , $fetch , $recursive - 1 , $tmpStack );
}
}
}
}
if ( $type == 'hasAndBelongsToMany' ) {
$merge = array ();
foreach ( $fetch as $j => $data ) {
if ( isset ( $data [ $with ]) && $data [ $with ][ $foreignKey ] === $row [ $model -> alias ][ $model -> primaryKey ]) {
if ( $habtmFieldsCount > 2 ) {
$merge [] = $data ;
} else {
$merge [] = Set :: diff ( $data , array ( $with => $data [ $with ]));
}
}
}
if ( empty ( $merge ) && ! isset ( $row [ $association ])) {
$row [ $association ] = $merge ;
} else {
$this -> __mergeAssociation ( $resultSet [ $i ], $merge , $association , $type );
}
} else {
$this -> __mergeAssociation ( $resultSet [ $i ], $fetch , $association , $type );
}
$resultSet [ $i ][ $association ] = $linkModel -> afterfind ( $resultSet [ $i ][ $association ]);
} else {
$tempArray [ 0 ][ $association ] = false ;
$this -> __mergeAssociation ( $resultSet [ $i ], $tempArray , $association , $type );
}
}
}
}
2006-12-01 02:26:12 +00:00
}
2008-01-01 23:57:17 +00:00
2007-07-25 04:38:28 +00:00
?>