📄 dbo_oracle.php
字号:
* 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. * * @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; }/** * This method should quote Oracle identifiers. Well it doesn't. * It would break all scaffolding and all of Cake's default assumptions. * * @param unknown_type $var * @return unknown * @access public */ function name($var) { $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); $name = "$model.\"$field\""; } else { $name = "\"$var\""; } } return $name; }/** * Begin a transaction * * @param unknown_type $model * @return boolean True on success, false on fail * (i.e. if the database/model does not support transactions). */ function begin() { $this->__transactionStarted = true; return true; }/** * Rollback a transaction * * @param unknown_type $model * @return boolean True on success, false on fail * (i.e. if the database/model does not support transactions, * or a transaction has not started). */ function rollback() { return ocirollback($this->connection); }/** * Commit a transaction * * @param unknown_type $model * @return boolean True on success, false on fail * (i.e. if the database/model does not support transactions, * or a transaction has not started). */ function commit() { $this->__transactionStarted = false; return ocicommit($this->connection); }/** * 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) { if (is_array($real)) { $col = $real['name']; if (isset($real['limit'])) { $col .= '('.$real['limit'].')'; } return $col; } else { $real = strtolower($real); } $col = str_replace(')', '', $real); $limit = null; if (strpos($col, '(') !== false) { list($col, $limit) = explode('(', $col); } if (in_array($col, array('date', 'timestamp'))) { return $col; } if (strpos($col, 'number') !== false) { return 'integer'; } if (strpos($col, 'integer') !== false) { return 'integer'; } if (strpos($col, 'char') !== false) { return 'string'; } if (strpos($col, 'text') !== false) { return 'text'; } if (strpos($col, 'blob') !== false) { return 'binary'; } if (in_array($col, array('float', 'double', 'decimal'))) { return 'float'; } if ($col == 'boolean') { 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 */ function value($data, $column = null, $safe = false) { $parent = parent::value($data, $column, $safe); if ($parent != null) { return $parent; } if ($data === null) { return 'NULL'; } if ($data === '') { return "''"; } switch($column) { case 'date': $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 : if (is_numeric($data)) { break; } default: $data = str_replace("'", "''", $data); $data = "'$data'"; break; } return $data; }/** * Returns the ID generated from the previous INSERT operation. * * @param string * @return integer * @access public */ function lastInsertId($source) { $sequence = $this->_sequenceMap[$source]; $sql = "SELECT $sequence.currval FROM dual"; if (!$this->execute($sql)) { return false; } while($row = $this->fetchRow()) { return $row[$sequence]['currval']; } return false; }/** * Returns a formatted error message from previous database operation. * * @return string Error message with error number * @access public */ function lastError() { return $this->_error; }/** * 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() { return $this->_statementId ? ocirowcount($this->_statementId): false; }/** * 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; } } /** * 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 = array_merge($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 = 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); $fetch = array_merge($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); } } } }}?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -