mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-18 10:36:16 +00:00
Fixed #4206 - lastError now works
Fixed #4181 - model sequence name now respected added constraint() method to enable/disable added truncate() to aid in test suite integration hacked name() to work with ACL git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6903 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
518f26a269
commit
6c44d00642
1 changed files with 194 additions and 33 deletions
|
@ -46,15 +46,12 @@ class DboOracle extends DboSource {
|
|||
* Enter description here...
|
||||
*
|
||||
* @var unknown_type
|
||||
* @access public
|
||||
*/
|
||||
var $alias = '';
|
||||
/**
|
||||
* The name of the model's sequence
|
||||
*
|
||||
* @var unknown_type
|
||||
* Sequence names as introspected from the database
|
||||
*/
|
||||
var $sequence = '';
|
||||
var $_sequences = array();
|
||||
/**
|
||||
* Transaction in progress flag
|
||||
*
|
||||
|
@ -132,6 +129,13 @@ class DboOracle extends DboSource {
|
|||
*/
|
||||
var $_results;
|
||||
|
||||
/**
|
||||
* Last error issued by oci extension
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
var $_error;
|
||||
|
||||
/**
|
||||
* Base configuration settings for MySQL driver
|
||||
*
|
||||
|
@ -146,6 +150,13 @@ class DboOracle extends DboSource {
|
|||
'nls_sort' => '',
|
||||
'nls_sort' => ''
|
||||
);
|
||||
|
||||
/**
|
||||
* Table-sequence map
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
var $_sequenceMap = array();
|
||||
/**
|
||||
* Connects to the database using options in the given configuration array.
|
||||
*
|
||||
|
@ -162,7 +173,8 @@ class DboOracle extends DboSource {
|
|||
} else {
|
||||
$connect = 'ocilogon';
|
||||
}
|
||||
$this->connection = $connect($config['login'], $config['password'], $config['database'], $config['charset']);
|
||||
|
||||
$this->connection = @$connect($config['login'], $config['password'], $config['database'], $config['charset']);
|
||||
|
||||
if ($this->connection) {
|
||||
$this->connected = true;
|
||||
|
@ -176,9 +188,24 @@ class DboOracle extends DboSource {
|
|||
$this->execute("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
|
||||
} else {
|
||||
$this->connected = false;
|
||||
$this->_setError();
|
||||
return false;
|
||||
}
|
||||
return $this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps track of the most recent Oracle error
|
||||
*
|
||||
*/
|
||||
function _setError($source = null) {
|
||||
if ($source) {
|
||||
$e = ocierror($source);
|
||||
} else {
|
||||
$e = ocierror();
|
||||
}
|
||||
$this->_error = $e['message'];
|
||||
}
|
||||
/**
|
||||
* Sets the encoding language of the session
|
||||
*
|
||||
|
@ -298,9 +325,10 @@ class DboOracle extends DboSource {
|
|||
* @access protected
|
||||
*/
|
||||
function _execute($sql) {
|
||||
$this->_statementId = ociparse($this->connection, $sql);
|
||||
$this->_statementId = @ociparse($this->connection, $sql);
|
||||
if (!$this->_statementId) {
|
||||
return null;
|
||||
$this->_setError($this->connection);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->__transactionStarted) {
|
||||
|
@ -309,7 +337,8 @@ class DboOracle extends DboSource {
|
|||
$mode = OCI_COMMIT_ON_SUCCESS;
|
||||
}
|
||||
|
||||
if (!ociexecute($this->_statementId, $mode)) {
|
||||
if (!@ociexecute($this->_statementId, $mode)) {
|
||||
$this->_setError($this->_statementId);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -431,6 +460,15 @@ class DboOracle extends DboSource {
|
|||
* @access public
|
||||
*/
|
||||
function describe(&$model) {
|
||||
|
||||
if (!empty($model->sequence)) {
|
||||
$this->_sequenceMap[$model->table] = $model->sequence;
|
||||
} elseif (!empty($model->table)) {
|
||||
$this->_sequenceMap[$model->table] = $model->table . '_seq';
|
||||
} else {
|
||||
trigger_error(__('Missing table name'));
|
||||
}
|
||||
|
||||
$cache = parent::describe($model);
|
||||
|
||||
if ($cache != null) {
|
||||
|
@ -449,9 +487,134 @@ class DboOracle extends DboSource {
|
|||
'length'=> $row[0]['DATA_LENGTH']);
|
||||
}
|
||||
$this->__cacheDescription($this->fullTableName($model, false), $fields);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all the records in a table and drops all associated auto-increment sequences.
|
||||
* Using DELETE instead of TRUNCATE because it causes locking problems.
|
||||
*
|
||||
* @param mixed $table A string or model class representing the table to be truncated
|
||||
* @param integer $reset If -1, sequences are dropped, if 0 (default), sequences are reset,
|
||||
* and if 1, sequences are not modified
|
||||
* @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
function truncate($table, $reset = 0) {
|
||||
|
||||
if (empty($this->_sequences)) {
|
||||
$sql = "SELECT sequence_name FROM user_sequences";
|
||||
$this->execute($sql);
|
||||
while ($row = $this->fetchRow()) {
|
||||
$this->_sequences[] = strtolower($row[0]['sequence_name']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->execute('DELETE FROM ' . $this->fullTableName($table));
|
||||
if (!isset($this->_sequenceMap[$table]) || !in_array($this->_sequenceMap[$table], $this->_sequences)) {
|
||||
return true;
|
||||
}
|
||||
if ($reset === 0) {
|
||||
$this->execute("SELECT {$this->_sequenceMap[$table]}.nextval FROM dual");
|
||||
$row = $this->fetchRow();
|
||||
$currval = $row[$this->_sequenceMap[$table]]['nextval'];
|
||||
|
||||
$this->execute("SELECT min_value FROM user_sequences WHERE sequence_name = '{$this->_sequenceMap[$table]}'");
|
||||
$row = $this->fetchRow();
|
||||
$min_value = $row[0]['min_value'];
|
||||
|
||||
if ($min_value == 1) $min_value = 0;
|
||||
$offset = -($currval - $min_value);
|
||||
|
||||
$this->execute("ALTER SEQUENCE {$this->_sequenceMap[$table]} INCREMENT BY $offset MINVALUE $min_value");
|
||||
$this->execute("SELECT {$this->_sequenceMap[$table]}.nextval FROM dual");
|
||||
$this->execute("ALTER SEQUENCE {$this->_sequenceMap[$table]} INCREMENT BY 1");
|
||||
} else {
|
||||
#$this->execute("DROP SEQUENCE {$this->_sequenceMap[$table]}");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables, disables, and lists table constraints
|
||||
*
|
||||
* Note: This method could have been written using a subselect for each table,
|
||||
* however the effort Oracle expends to run the constraint introspection is very high.
|
||||
* Therefore, this method caches the result once and loops through the arrays to find
|
||||
* what it needs. It reduced my query time by 50%. YMMV.
|
||||
*
|
||||
* @param string $action
|
||||
* @param string $table
|
||||
* @return mixed boolean true or array of constraints
|
||||
*/
|
||||
function constraint($action, $table) {
|
||||
if (empty($table)) {
|
||||
trigger_error(__('Must specify table to operate on constraints'));
|
||||
}
|
||||
|
||||
$table = strtoupper($table);
|
||||
|
||||
if (empty($this->_keyConstraints)) {
|
||||
$sql = "SELECT
|
||||
table_name,
|
||||
c.constraint_name
|
||||
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)";
|
||||
$this->execute($sql);
|
||||
while ($row = $this->fetchRow()) {
|
||||
$this->_keyConstraints[] = array($row[0]['table_name'], $row['c']['constraint_name']);
|
||||
}
|
||||
}
|
||||
|
||||
$relatedKeys = array();
|
||||
foreach ($this->_keyConstraints as $c) {
|
||||
if ($c[0] == $table) {
|
||||
$relatedKeys[] = $c[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->_constraints)) {
|
||||
$sql = "SELECT
|
||||
table_name,
|
||||
constraint_name,
|
||||
r_constraint_name
|
||||
FROM
|
||||
user_constraints";
|
||||
$this->execute($sql);
|
||||
while ($row = $this->fetchRow()) {
|
||||
$this->_constraints[] = $row[0];
|
||||
}
|
||||
}
|
||||
|
||||
$constraints = array();
|
||||
foreach ($this->_constraints as $c) {
|
||||
if (in_array($c['r_constraint_name'], $relatedKeys)) {
|
||||
$constraints[] = array($c['table_name'], $c['constraint_name']);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($constraints as $c) {
|
||||
list($table, $constraint) = $c;
|
||||
switch ($action) {
|
||||
case 'enable':
|
||||
$this->execute("ALTER TABLE $table ENABLE CONSTRAINT $constraint");
|
||||
break;
|
||||
case 'disable':
|
||||
$this->execute("ALTER TABLE $table DISABLE CONSTRAINT $constraint");
|
||||
break;
|
||||
case 'list':
|
||||
return $constraints;
|
||||
break;
|
||||
default:
|
||||
trigger_error(__('DboOracle::constraint() accepts only enable, disable, or list'));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the indexes in given table name.
|
||||
*
|
||||
|
@ -552,19 +715,20 @@ class DboOracle extends DboSource {
|
|||
* @access public
|
||||
*/
|
||||
function name($var) {
|
||||
switch($var) {
|
||||
case 'Permission._create':
|
||||
case 'Permission._read':
|
||||
case 'Permission._update':
|
||||
case 'Permission._delete':
|
||||
$name = $var;
|
||||
if (strstr($var, '_create') OR
|
||||
strstr($var, '_read') OR
|
||||
strstr($var, '_update') OR
|
||||
strstr($var, '_delete')) {
|
||||
if (strstr($var, '.')) {
|
||||
list($model, $field) = explode('.', $var);
|
||||
return "$model.\"$field\"";
|
||||
break;
|
||||
default:
|
||||
return $var;
|
||||
break;
|
||||
$name = "$model.\"$field\"";
|
||||
} else {
|
||||
$name = "\"$var\"";
|
||||
}
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
/**
|
||||
* Begin a transaction
|
||||
*
|
||||
|
@ -695,7 +859,7 @@ class DboOracle extends DboSource {
|
|||
* @access public
|
||||
*/
|
||||
function lastInsertId($source) {
|
||||
$sequence = (!empty($this->sequence)) ? $this->sequence : $source . '_seq';
|
||||
$sequence = $this->_sequenceMap[$source];
|
||||
$sql = "SELECT $sequence.currval FROM dual";
|
||||
|
||||
if (!$this->execute($sql)) {
|
||||
|
@ -714,12 +878,7 @@ class DboOracle extends DboSource {
|
|||
* @access public
|
||||
*/
|
||||
function lastError() {
|
||||
$errors = ocierror();
|
||||
|
||||
if (($errors != null) && (isset($errors["message"]))) {
|
||||
return($errors["message"]);
|
||||
}
|
||||
return null;
|
||||
return $this->_error;
|
||||
}
|
||||
/**
|
||||
* Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
|
||||
|
@ -777,6 +936,7 @@ class DboOracle extends DboSource {
|
|||
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) . ' ');
|
||||
|
@ -841,12 +1001,13 @@ class DboOracle extends DboSource {
|
|||
$habtmFieldsCount = count($habtmFields);
|
||||
|
||||
if (!empty($ins)) {
|
||||
$fetch = null;
|
||||
$fetch = array();
|
||||
$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);
|
||||
|
|
Loading…
Add table
Reference in a new issue