mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-18 18:46:17 +00:00
Refactoring DboSource - removes all SQL from Model, refactoring transaction handling
git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6557 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
d326c6eefe
commit
c1c35b2e13
11 changed files with 278 additions and 390 deletions
|
@ -782,7 +782,8 @@ class TreeBehavior extends ModelBehavior {
|
|||
* @access private
|
||||
*/
|
||||
function __getMax($model, $scope, $right) {
|
||||
list($edge) = array_values($model->find('first', array('conditions' => $scope, 'fields' => 'MAX(' . $right . ') AS ' . $right, 'recursive' => -1)));
|
||||
$db =& ConnectionManager::getDataSource($model->useDbConfig);
|
||||
list($edge) = array_values($model->find('first', array('conditions' => $scope, 'fields' => $db->calculate('max', array($right)), 'recursive' => -1)));
|
||||
return ife(empty ($edge[$right]), 0, $edge[$right]);
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -252,7 +252,7 @@ class DataSource extends Object {
|
|||
* @return boolean True
|
||||
*/
|
||||
function begin() {
|
||||
return true;
|
||||
return !$this->_transactionStarted;
|
||||
}
|
||||
/**
|
||||
* Commit a transaction
|
||||
|
@ -260,7 +260,7 @@ class DataSource extends Object {
|
|||
* @return boolean True
|
||||
*/
|
||||
function commit(&$model) {
|
||||
return true;
|
||||
return $this->_transactionStarted;
|
||||
}
|
||||
/**
|
||||
* Rollback a transaction
|
||||
|
@ -268,7 +268,7 @@ class DataSource extends Object {
|
|||
* @return boolean True
|
||||
*/
|
||||
function rollback(&$model) {
|
||||
return true;
|
||||
return $this->_transactionStarted;
|
||||
}
|
||||
/**
|
||||
* Converts column types to basic types
|
||||
|
@ -499,6 +499,10 @@ class DataSource extends Object {
|
|||
*
|
||||
*/
|
||||
function __destruct() {
|
||||
if ($this->_transactionStarted) {
|
||||
$null = null;
|
||||
$this->rollback($null);
|
||||
}
|
||||
if ($this->connected) {
|
||||
$this->close();
|
||||
}
|
||||
|
|
|
@ -301,40 +301,9 @@ class DboMssql extends DboSource {
|
|||
* (i.e. if the database/model does not support transactions).
|
||||
*/
|
||||
function begin(&$model) {
|
||||
if (parent::begin($model)) {
|
||||
if ($this->execute('BEGIN TRANSACTION')) {
|
||||
$this->_transactionStarted = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 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(&$model) {
|
||||
if (parent::commit($model)) {
|
||||
$this->_transactionStarted = false;
|
||||
return $this->execute('COMMIT');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 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(&$model) {
|
||||
if (parent::rollback($model)) {
|
||||
return $this->execute('ROLLBACK');
|
||||
if (parent::begin($model) && $this->execute('BEGIN TRANSACTION')) {
|
||||
$this->_transactionStarted = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -253,40 +253,9 @@ class DboMysqli extends DboSource {
|
|||
* (i.e. if the database/model does not support transactions).
|
||||
*/
|
||||
function begin(&$model) {
|
||||
if (parent::begin($model)) {
|
||||
if ($this->execute('START TRANSACTION')) {
|
||||
$this->_transactionStarted = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 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(&$model) {
|
||||
if (parent::commit($model)) {
|
||||
$this->_transactionStarted = false;
|
||||
return $this->execute('COMMIT');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 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(&$model) {
|
||||
if (parent::rollback($model)) {
|
||||
return $this->execute('ROLLBACK');
|
||||
if (parent::begin($model) && $this->execute('START TRANSACTION')) {
|
||||
$this->_transactionStarted = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -84,34 +84,36 @@ class DboPostgres extends DboSource {
|
|||
* @return True if successfully connected.
|
||||
*/
|
||||
function connect() {
|
||||
|
||||
$config = $this->config;
|
||||
$connect = $config['connect'];
|
||||
$this->connection = $connect("host='{$config['host']}' port='{$config['port']}' dbname='{$config['database']}' user='{$config['login']}' password='{$config['password']}'");
|
||||
$this->connected = false;
|
||||
|
||||
if ($this->connection) {
|
||||
$this->connected = true;
|
||||
$this->_execute("SET search_path TO " . $config['schema']);
|
||||
} else {
|
||||
$this->connected = false;
|
||||
}
|
||||
if (!empty($config['encoding'])) {
|
||||
$this->setEncoding($config['encoding']);
|
||||
}
|
||||
return $this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects from database.
|
||||
*
|
||||
* @return boolean True if the database could be disconnected, else false
|
||||
*/
|
||||
function disconnect() {
|
||||
@pg_free_result($this->results);
|
||||
$this->connected = !@pg_close($this->connection);
|
||||
if (is_resource($this->results)) {
|
||||
pg_free_result($this->results);
|
||||
}
|
||||
if (is_resource($this->connected)) {
|
||||
$this->connected = !pg_close($this->connection);
|
||||
} else {
|
||||
$this->connected = false;
|
||||
}
|
||||
return !$this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes given SQL statement.
|
||||
*
|
||||
|
@ -265,55 +267,21 @@ class DboPostgres extends DboSource {
|
|||
* (i.e. if the database/model does not support transactions).
|
||||
*/
|
||||
function begin(&$model) {
|
||||
if (parent::begin($model)) {
|
||||
if ($this->execute('BEGIN')) {
|
||||
$this->_transactionStarted = true;
|
||||
return true;
|
||||
}
|
||||
if (parent::begin($model) && $this->execute('BEGIN')) {
|
||||
$this->_transactionStarted = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(&$model) {
|
||||
if (parent::commit($model)) {
|
||||
$this->_transactionStarted = false;
|
||||
return $this->execute('COMMIT');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(&$model) {
|
||||
if (parent::rollback($model)) {
|
||||
return $this->execute('ROLLBACK');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted error message from previous database operation.
|
||||
*
|
||||
* @return string Error message
|
||||
*/
|
||||
function lastError() {
|
||||
$last_error = pg_last_error($this->connection);
|
||||
if ($last_error) {
|
||||
return $last_error;
|
||||
$error = pg_last_error($this->connection);
|
||||
if ($error) {
|
||||
return $error;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -534,7 +534,7 @@ class DboSource extends DataSource {
|
|||
*/
|
||||
function read(&$model, $queryData = array(), $recursive = null) {
|
||||
|
||||
$this->__scrubQueryData($queryData);
|
||||
$queryData = $this->__scrubQueryData($queryData);
|
||||
$null = null;
|
||||
$array = array();
|
||||
$linkedModels = array();
|
||||
|
@ -561,18 +561,12 @@ class DboSource extends DataSource {
|
|||
foreach ($model->{$type} as $assoc => $assocData) {
|
||||
if ($model->recursive > -1) {
|
||||
$linkModel =& $model->{$assoc};
|
||||
|
||||
$external = isset($assocData['external']);
|
||||
if ($model->alias == $linkModel->alias && $type != 'hasAndBelongsToMany' && $type != 'hasMany') {
|
||||
if (true === $this->generateSelfAssociationQuery($model, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null)) {
|
||||
|
||||
if ($model->useDbConfig == $linkModel->useDbConfig) {
|
||||
if (true === $this->generateAssociationQuery($model, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null)) {
|
||||
$linkedModels[] = $type . '/' . $assoc;
|
||||
}
|
||||
} else {
|
||||
if ($model->useDbConfig == $linkModel->useDbConfig) {
|
||||
if (true === $this->generateAssociationQuery($model, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null)) {
|
||||
$linkedModels[] = $type . '/' . $assoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -923,105 +917,21 @@ class DboSource extends DataSource {
|
|||
}
|
||||
}
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param unknown_type $model
|
||||
* @param unknown_type $linkModel
|
||||
* @param unknown_type $type
|
||||
* @param unknown_type $association
|
||||
* @param unknown_type $assocData
|
||||
* @param unknown_type $queryData
|
||||
* @param unknown_type $external
|
||||
* @param unknown_type $resultSet
|
||||
* @return unknown
|
||||
*/
|
||||
function generateSelfAssociationQuery(&$model, &$linkModel, $type, $association = null, $assocData = array(), &$queryData, $external = false, &$resultSet) {
|
||||
$alias = $association;
|
||||
if (empty($alias) && !empty($linkModel)) {
|
||||
$alias = $linkModel->alias;
|
||||
}
|
||||
|
||||
if (!isset($queryData['selfJoin'])) {
|
||||
$queryData['selfJoin'] = array();
|
||||
|
||||
$self = array(
|
||||
'fields' => $this->fields($model, null, $queryData['fields']),
|
||||
'joins' => array(array(
|
||||
'table' => $this->fullTableName($linkModel),
|
||||
'alias' => $alias,
|
||||
'type' => 'LEFT',
|
||||
'conditions' => array(
|
||||
$model->escapeField($assocData['foreignKey']) => '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}'))
|
||||
),
|
||||
'table' => $this->fullTableName($model),
|
||||
'alias' => $model->alias,
|
||||
'limit' => $queryData['limit'],
|
||||
'offset' => $queryData['offset'],
|
||||
'conditions'=> $queryData['conditions'],
|
||||
'order' => $queryData['order']
|
||||
);
|
||||
|
||||
if (isset($assocData['type'])) {
|
||||
$self['joins'][0]['type'] = $assocData['type'];
|
||||
}
|
||||
if (!empty($assocData['conditions'])) {
|
||||
$self['joins'][0]['conditions'] = trim($this->conditions(array_merge($self['joins'][0]['conditions'], (array)$assocData['conditions']), true, false));
|
||||
}
|
||||
|
||||
if (!empty($queryData['joins'])) {
|
||||
foreach ($queryData['joins'] as $join) {
|
||||
$self['joins'][] = $join;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->__bypass === false) {
|
||||
$self['fields'] = array_merge($self['fields'], $this->fields($linkModel, $alias, (isset($assocData['fields']) ? $assocData['fields'] : '')));
|
||||
}
|
||||
|
||||
if (!in_array($self, $queryData['selfJoin'])) {
|
||||
$queryData['selfJoin'][] = $self;
|
||||
return true;
|
||||
}
|
||||
|
||||
} elseif (isset($linkModel)) {
|
||||
return $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
|
||||
|
||||
} else {
|
||||
$result = $queryData['selfJoin'][0];
|
||||
if (!empty($queryData['joins'])) {
|
||||
foreach ($queryData['joins'] as $join) {
|
||||
if (!in_array($join, $result['joins'])) {
|
||||
$result['joins'][] = $join;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($queryData['conditions'])) {
|
||||
$result['conditions'] = trim($this->conditions(array_merge($result['conditions'], $assocData['conditions']), true, false));
|
||||
}
|
||||
if (!empty($queryData['fields'])) {
|
||||
$result['fields'] = array_unique(array_merge($result['fields'], $queryData['fields']));
|
||||
}
|
||||
$sql = $this->buildStatement($result, $model);
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Enter description here...
|
||||
* Generates an array representing a query or part of a query from a single model or two associated models
|
||||
*
|
||||
* @param Model $model
|
||||
* @param unknown_type $linkModel
|
||||
* @param unknown_type $type
|
||||
* @param unknown_type $association
|
||||
* @param unknown_type $assocData
|
||||
* @param unknown_type $queryData
|
||||
* @param unknown_type $external
|
||||
* @param unknown_type $resultSet
|
||||
* @return unknown
|
||||
* @param Model $linkModel
|
||||
* @param string $type
|
||||
* @param string $association
|
||||
* @param array $assocData
|
||||
* @param array $queryData
|
||||
* @param boolean $external
|
||||
* @param array $resultSet
|
||||
* @return mixed
|
||||
*/
|
||||
function generateAssociationQuery(&$model, &$linkModel, $type, $association = null, $assocData = array(), &$queryData, $external = false, &$resultSet) {
|
||||
$this->__scrubQueryData($queryData);
|
||||
$this->__scrubQueryData($assocData);
|
||||
$joinedOnSelf = false;
|
||||
$queryData = $this->__scrubQueryData($queryData);
|
||||
$assocData = $this->__scrubQueryData($assocData);
|
||||
|
||||
if (empty($queryData['fields'])) {
|
||||
$queryData['fields'] = $this->fields($model, $model->alias);
|
||||
|
@ -1033,21 +943,19 @@ class DboSource extends DataSource {
|
|||
$match = strpos($passedFields[0], $assocFields[0]);
|
||||
$match1 = strpos($passedFields[0], 'COUNT(');
|
||||
if ($match === false && $match1 === false) {
|
||||
$queryData['fields'] = array_unique(array_merge($passedFields, $assocFields));
|
||||
$queryData['fields'] = array_merge($passedFields, $assocFields);
|
||||
} else {
|
||||
$queryData['fields'] = $passedFields;
|
||||
}
|
||||
} else {
|
||||
$queryData['fields'] = array_unique(array_merge($passedFields, $assocFields));
|
||||
$queryData['fields'] = array_merge($passedFields, $assocFields);
|
||||
}
|
||||
unset($assocFields, $passedFields);
|
||||
}
|
||||
|
||||
if ($linkModel == null) {
|
||||
if (array_key_exists('selfJoin', $queryData)) {
|
||||
return $this->generateSelfAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
|
||||
} else {
|
||||
return $this->buildStatement(array(
|
||||
return $this->buildStatement(
|
||||
array(
|
||||
'fields' => array_unique($queryData['fields']),
|
||||
'table' => $this->fullTableName($model),
|
||||
'alias' => $model->alias,
|
||||
|
@ -1055,44 +963,33 @@ class DboSource extends DataSource {
|
|||
'offset' => $queryData['offset'],
|
||||
'joins' => $queryData['joins'],
|
||||
'conditions' => $queryData['conditions'],
|
||||
'order' => $queryData['order']), $model
|
||||
);
|
||||
}
|
||||
'order' => $queryData['order']
|
||||
),
|
||||
$model
|
||||
);
|
||||
}
|
||||
if ($external && !empty($assocData['finderQuery'])) {
|
||||
return $assocData['finderQuery'];
|
||||
}
|
||||
|
||||
$alias = $association;
|
||||
|
||||
if ($model->alias == $linkModel->alias) {
|
||||
$joinedOnSelf = true;
|
||||
}
|
||||
|
||||
if ($external && isset($assocData['finderQuery'])) {
|
||||
if (!empty($assocData['finderQuery'])) {
|
||||
return $assocData['finderQuery'];
|
||||
}
|
||||
}
|
||||
$self = ($model->name == $linkModel->name);
|
||||
$fields = array();
|
||||
|
||||
if ((!$external && in_array($type, array('hasOne', 'belongsTo')) && $this->__bypass === false) || $external) {
|
||||
$fields = $this->fields($linkModel, $alias, $assocData['fields']);
|
||||
} else {
|
||||
$fields = array();
|
||||
}
|
||||
$limit = '';
|
||||
|
||||
if (isset($assocData['limit'])) {
|
||||
if ((!isset($assocData['offset']) || (empty($assocData['offset']))) && isset($assocData['page'])) {
|
||||
$assocData['offset'] = ($assocData['page'] - 1) * $assocData['limit'];
|
||||
} elseif (!isset($assocData['offset'])) {
|
||||
$assocData['offset'] = null;
|
||||
}
|
||||
$limit = $this->limit($assocData['limit'], $assocData['offset']);
|
||||
if (empty($assocData['offset']) && !empty($assocData['page'])) {
|
||||
$assocData['offset'] = ($assocData['page'] - 1) * $assocData['limit'];
|
||||
}
|
||||
$assocData['limit'] = $this->limit($assocData['limit'], $assocData['offset']);
|
||||
|
||||
switch($type) {
|
||||
case 'hasOne':
|
||||
case 'belongsTo':
|
||||
$conditions = $this->__mergeConditions(
|
||||
$assocData['conditions'],
|
||||
$this->getConstraint($type, $model, $linkModel, $alias, array_merge($assocData, compact('external')))
|
||||
$this->getConstraint($type, $model, $linkModel, $alias, array_merge($assocData, compact('external', 'self')))
|
||||
);
|
||||
if ($external) {
|
||||
$query = array_merge($assocData, array(
|
||||
|
@ -1101,22 +998,14 @@ class DboSource extends DataSource {
|
|||
'fields' => $fields,
|
||||
'alias' => $alias
|
||||
));
|
||||
|
||||
if ($type == 'belongsTo') {
|
||||
// Dunno if we should be doing this for hasOne also...?
|
||||
// Or maybe not doing it at all...?
|
||||
$query = array_merge($query, array('order' => $assocData['order'], 'limit' => $limit));
|
||||
}
|
||||
$query = array_merge(array('order' => $assocData['order'], 'limit' => $assocData['limit']), $query);
|
||||
} else {
|
||||
$join = array(
|
||||
'table' => $this->fullTableName($linkModel),
|
||||
'alias' => $alias,
|
||||
'type' => 'LEFT',
|
||||
'type' => isset($assocData['type']) ? $assocData['type'] : 'LEFT',
|
||||
'conditions' => trim($this->conditions($conditions, true, false))
|
||||
);
|
||||
if (isset($assocData['type'])) {
|
||||
$join['type'] = $assocData['type'];
|
||||
}
|
||||
$queryData['fields'] = array_merge($queryData['fields'], $fields);
|
||||
|
||||
if (!empty($assocData['order'])) {
|
||||
|
@ -1131,17 +1020,15 @@ class DboSource extends DataSource {
|
|||
case 'hasMany':
|
||||
$assocData['fields'] = $this->fields($linkModel, $alias, $assocData['fields']);
|
||||
if (!empty($assocData['foreignKey'])) {
|
||||
$assocData['fields'] = array_unique(array_merge(
|
||||
$assocData['fields'], $this->fields($linkModel, $alias, array("{$alias}.{$assocData['foreignKey']}"))
|
||||
));
|
||||
$assocData['fields'] = array_merge($assocData['fields'], $this->fields($linkModel, $alias, array("{$alias}.{$assocData['foreignKey']}")));
|
||||
}
|
||||
$query = array(
|
||||
'conditions' => $this->__mergeConditions($this->getConstraint('hasMany', $model, $linkModel, $alias, $assocData), $assocData['conditions']),
|
||||
'fields' => $assocData['fields'],
|
||||
'fields' => array_unique($assocData['fields']),
|
||||
'table' => $this->fullTableName($linkModel),
|
||||
'alias' => $alias,
|
||||
'order' => $assocData['order'],
|
||||
'limit' => $limit
|
||||
'limit' => $assocData['limit']
|
||||
);
|
||||
break;
|
||||
case 'hasAndBelongsToMany':
|
||||
|
@ -1164,7 +1051,7 @@ class DboSource extends DataSource {
|
|||
|
||||
$query = array(
|
||||
'conditions' => $assocData['conditions'],
|
||||
'limit' => $limit,
|
||||
'limit' => $assocData['limit'],
|
||||
'table' => $this->fullTableName($linkModel),
|
||||
'alias' => $alias,
|
||||
'fields' => array_merge($this->fields($linkModel, $alias, $assocData['fields']), $joinFields),
|
||||
|
@ -1191,7 +1078,7 @@ class DboSource extends DataSource {
|
|||
* @return array Conditions array defining the constraint between $model and $association
|
||||
*/
|
||||
function getConstraint($type, $model, $linkModel, $alias, $assoc, $alias2 = null) {
|
||||
$assoc = array_merge(array('external' => false), $assoc);
|
||||
$assoc = array_merge(array('external' => false, 'self' => false), $assoc);
|
||||
|
||||
if (array_key_exists('foreignKey', $assoc) && empty($assoc['foreignKey'])) {
|
||||
return array();
|
||||
|
@ -1459,20 +1346,42 @@ class DboSource extends DataSource {
|
|||
foreach ($joins as $assoc) {
|
||||
if (isset($model->{$assoc}) && $model->useDbConfig == $model->{$assoc}->useDbConfig) {
|
||||
$assocData = $model->getAssociated($assoc);
|
||||
$type = 'LEFT';
|
||||
if (isset($assocData['type'])) {
|
||||
$type = $assocData['type'];
|
||||
}
|
||||
$join[] = $this->buildJoinStatement(array(
|
||||
'table' => $this->fullTableName($model->{$assoc}),
|
||||
'alias' => $assoc,
|
||||
'type' => $type,
|
||||
'type' => isset($assocData['type']) ? $assocData['type'] : 'LEFT',
|
||||
'conditions' => trim($this->conditions($this->getConstraint($assocData['association'], $model, $model->{$assoc}, $assoc, $assocData), true, false))
|
||||
));
|
||||
}
|
||||
}
|
||||
return $join;
|
||||
}
|
||||
/**
|
||||
* Returns the an SQL calculation, i.e. COUNT() or MAX()
|
||||
*
|
||||
* @param string $func Lowercase name of SQL function, i.e. 'count' or 'max'
|
||||
* @param array $params Function parameters (any values must be quoted manually)
|
||||
* @return string An SQL calculation function
|
||||
* @access public
|
||||
*/
|
||||
function calculate($func, $params = array()) {
|
||||
|
||||
switch (strtolower($func)) {
|
||||
case 'count':
|
||||
if (!isset($params[0])) {
|
||||
$params[0] = '*';
|
||||
}
|
||||
if (!isset($params[1])) {
|
||||
$params[1] = 'count';
|
||||
}
|
||||
return 'COUNT(' . $this->name($params[0]) . ') AS ' . $this->name($params[1]);
|
||||
case 'max':
|
||||
if (!isset($params[1])) {
|
||||
$params[1] = $params[0];
|
||||
}
|
||||
return 'MAX(' . $this->name($params[0]) . ') AS ' . $this->name($params[1]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Deletes all the records in a table and resets the count of the auto-incrementing
|
||||
* primary key, where applicable.
|
||||
|
@ -1484,6 +1393,36 @@ class DboSource extends DataSource {
|
|||
function truncate($table) {
|
||||
return $this->execute('TRUNCATE TABLE ' . $this->fullTableName($table));
|
||||
}
|
||||
/**
|
||||
* Commit a transaction
|
||||
*
|
||||
* @param model $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(&$model) {
|
||||
if (parent::commit($model) && $this->execute('COMMIT')) {
|
||||
$this->_transactionStarted = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Rollback a transaction
|
||||
*
|
||||
* @param model $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(&$model) {
|
||||
if (parent::rollback($model) && $this->execute('ROLLBACK')) {
|
||||
$this->_transactionStarted = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Creates a default set of conditions from the model if $conditions is null/empty.
|
||||
*
|
||||
|
@ -1523,26 +1462,19 @@ class DboSource extends DataSource {
|
|||
}
|
||||
return $key;
|
||||
}
|
||||
/**
|
||||
* Returns the column type of a given
|
||||
*
|
||||
* @param Model $model
|
||||
* @param string $field
|
||||
*/
|
||||
function getColumnType(&$model, $field) {
|
||||
return $model->getColumnType($field);
|
||||
}
|
||||
/**
|
||||
* Private helper method to remove query metadata in given data array.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
function __scrubQueryData(&$data) {
|
||||
function __scrubQueryData($data) {
|
||||
foreach (array('conditions', 'fields', 'joins', 'order', 'limit', 'offset') as $key) {
|
||||
if (!isset($data[$key]) || empty($data[$key])) {
|
||||
$data[$key] = array();
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* Generates the fields list of an SQL query.
|
||||
|
@ -1782,14 +1714,12 @@ class DboSource extends DataSource {
|
|||
* @access private
|
||||
*/
|
||||
function __quoteFields($conditions) {
|
||||
$start = null;
|
||||
$end = null;
|
||||
$start = $end = null;
|
||||
$original = $conditions;
|
||||
|
||||
if (!empty($this->startQuote)) {
|
||||
$start = preg_quote($this->startQuote);
|
||||
}
|
||||
|
||||
if (!empty($this->endQuote)) {
|
||||
$end = preg_quote($this->endQuote);
|
||||
}
|
||||
|
@ -1840,8 +1770,7 @@ class DboSource extends DataSource {
|
|||
*/
|
||||
function order($keys, $direction = 'ASC') {
|
||||
if (is_string($keys) && strpos($keys, ',') && !preg_match('/\(.+\,.+\)/', $keys)) {
|
||||
$keys = explode(',', $keys);
|
||||
array_map('trim', $keys);
|
||||
$keys = array_map('trim', explode(',', $keys));
|
||||
}
|
||||
|
||||
if (is_array($keys)) {
|
||||
|
@ -1949,9 +1878,8 @@ class DboSource extends DataSource {
|
|||
|
||||
if (is_array($out)) {
|
||||
return $out[0]['count'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Gets the length of a database-native column description, or null if no length
|
||||
|
@ -1966,7 +1894,6 @@ class DboSource extends DataSource {
|
|||
if (strpos($col, '(') !== false) {
|
||||
list($col, $limit) = explode('(', $col);
|
||||
}
|
||||
|
||||
if ($limit != null) {
|
||||
return intval($limit);
|
||||
}
|
||||
|
@ -1984,25 +1911,10 @@ class DboSource extends DataSource {
|
|||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
if (!empty($data)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return !empty($data);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Destructor. Closes connection to the database.
|
||||
*
|
||||
*/
|
||||
function __destruct() {
|
||||
if ($this->_transactionStarted) {
|
||||
$null = null;
|
||||
$this->rollback($null);
|
||||
}
|
||||
parent::__destruct();
|
||||
}
|
||||
/**
|
||||
* Inserts multiple values into a join table
|
||||
*
|
||||
|
|
|
@ -1549,21 +1549,15 @@ class Model extends Overloadable {
|
|||
$db =& ConnectionManager::getDataSource($this->useDbConfig);
|
||||
|
||||
foreach ($this->hasAndBelongsToMany as $assoc => $data) {
|
||||
if (isset($data['with'])) {
|
||||
$records = $this->{$data['with']}->find('all', array(
|
||||
'conditions' => array($data['foreignKey'] => $id),
|
||||
'fields' => $this->{$data['with']}->primaryKey,
|
||||
'recursive' => -1
|
||||
));
|
||||
if (!empty($records)) {
|
||||
foreach ($records as $record) {
|
||||
$this->{$data['with']}->delete($record[$this->{$data['with']}->alias][$this->{$data['with']}->primaryKey]);
|
||||
}
|
||||
$records = $this->{$data['with']}->find('all', array(
|
||||
'conditions' => array($data['foreignKey'] => $id),
|
||||
'fields' => $this->{$data['with']}->primaryKey,
|
||||
'recursive' => -1
|
||||
));
|
||||
if (!empty($records)) {
|
||||
foreach ($records as $record) {
|
||||
$this->{$data['with']}->delete($record[$this->{$data['with']}->alias][$this->{$data['with']}->primaryKey]);
|
||||
}
|
||||
} else {
|
||||
$table = $db->name($db->fullTableName($data['joinTable']));
|
||||
$conditions = $db->name($data['foreignKey']) . ' = ' . $db->value($id);
|
||||
$db->query("DELETE FROM {$table} WHERE {$conditions}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1785,7 +1779,7 @@ class Model extends Overloadable {
|
|||
if ($state == 'before') {
|
||||
if (empty($query['fields'])) {
|
||||
$db =& ConnectionManager::getDataSource($this->useDbConfig);
|
||||
$query['fields'] = 'COUNT(*) AS ' . $db->name('count');
|
||||
$query['fields'] = $db->calculate('count');
|
||||
}
|
||||
$query['order'] = false;
|
||||
return $query;
|
||||
|
|
|
@ -114,16 +114,27 @@ class DboPostgresTest extends CakeTestCase {
|
|||
* @access public
|
||||
*/
|
||||
function skip() {
|
||||
$this->_initDb();
|
||||
$db = ConnectionManager::getDataSource('test_suite');
|
||||
$this->skipif ($this->db->config['driver'] != 'postgres', 'PostgreSQL connection not available');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up test suite database connection
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function startTest() {
|
||||
$this->_initDb();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a Dbo class instance for testing
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function setUp() {
|
||||
$this->startTest();
|
||||
$db = ConnectionManager::getDataSource('test_suite');
|
||||
$this->db = new DboPostgresTestDb($db->config);
|
||||
$this->model = new PostgresTestModel();
|
||||
|
@ -173,6 +184,11 @@ class DboPostgresTest extends CakeTestCase {
|
|||
$result = $this->db->value('1,2', 'float');
|
||||
$this->assertIdentical($expected, $result);
|
||||
}
|
||||
|
||||
function testColumnParsing() {
|
||||
var_export($this->db->isConnected());
|
||||
var_export($this->db->fetchAll("SELECT table_name as name FROM INFORMATION_SCHEMA.tables;"));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -247,7 +247,7 @@ class TestModel8 extends CakeTestModel {
|
|||
var $hasOne = array(
|
||||
'TestModel9' => array(
|
||||
'className' => 'TestModel9',
|
||||
'foreignKey' => 'test_model9_id',
|
||||
'foreignKey' => 'test_model8_id',
|
||||
'conditions' => 'TestModel9.name != \'mariano\''
|
||||
)
|
||||
);
|
||||
|
@ -678,7 +678,7 @@ class DboSourceTest extends CakeTestCase {
|
|||
$external = isset($assocData['external']);
|
||||
|
||||
if ($this->Model->Category2->alias == $linkModel->alias && $type != 'hasAndBelongsToMany' && $type != 'hasMany') {
|
||||
$result = $this->db->generateSelfAssociationQuery($this->Model->Category2, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null);
|
||||
$result = $this->db->generateAssociationQuery($this->Model->Category2, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null);
|
||||
$this->assertTrue($result);
|
||||
} else {
|
||||
if ($this->Model->Category2->useDbConfig == $linkModel->useDbConfig) {
|
||||
|
@ -690,7 +690,7 @@ class DboSourceTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
$query = $this->db->generateAssociationQuery($this->Model->Category2, $null, null, null, null, $queryData, false, $null);
|
||||
$this->assertPattern('/^SELECT\s+(.+)FROM(.+)`Category2`\.`group_id`\s+=\s+`Group`\.`id`\)\s+WHERE/', $query);
|
||||
$this->assertPattern('/^SELECT\s+(.+)FROM(.+)`Category2`\.`group_id`\s+=\s+`Group`\.`id`\)\s+LEFT JOIN(.+)WHERE\s+1 = 1\s*$/', $query);
|
||||
|
||||
$this->Model = new TestModel4();
|
||||
$this->Model->schema();
|
||||
|
@ -703,10 +703,11 @@ class DboSourceTest extends CakeTestCase {
|
|||
|
||||
$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
|
||||
|
||||
$result = $this->db->generateSelfAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
$_queryData = $queryData;
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$expected = array(array(
|
||||
$expected = array(
|
||||
'fields' => array(
|
||||
'`TestModel4`.`id`',
|
||||
'`TestModel4`.`name`',
|
||||
|
@ -722,18 +723,15 @@ class DboSourceTest extends CakeTestCase {
|
|||
'table' => '`test_model4`',
|
||||
'alias' => 'TestModel4Parent',
|
||||
'type' => 'LEFT',
|
||||
'conditions' => array('`TestModel4`.`parent_id`' => '{$__cakeIdentifier[TestModel4Parent.id]__$}')
|
||||
'conditions' => '`TestModel4`.`parent_id` = `TestModel4Parent`.`id`'
|
||||
)
|
||||
),
|
||||
'table' => '`test_model4`',
|
||||
'alias' => 'TestModel4',
|
||||
'limit' => array(),
|
||||
'offset' => array(),
|
||||
'conditions' => array(),
|
||||
'order' => array()
|
||||
));
|
||||
|
||||
$this->assertEqual($queryData['selfJoin'], $expected);
|
||||
);
|
||||
$this->assertEqual($queryData, $expected);
|
||||
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
|
||||
$this->assertPattern('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);
|
||||
|
@ -743,9 +741,9 @@ class DboSourceTest extends CakeTestCase {
|
|||
|
||||
$params['assocData']['type'] = 'INNER';
|
||||
$this->Model->belongsTo['TestModel4Parent']['type'] = 'INNER';
|
||||
$result = $this->db->generateSelfAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $_queryData, $params['external'], $resultSet);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEqual($queryData['joins'][0]['type'], 'INNER');
|
||||
$this->assertEqual($_queryData['joins'][0]['type'], 'INNER');
|
||||
}
|
||||
|
||||
function testGenerateInnerJoinAssociationQuery() {
|
||||
|
@ -777,16 +775,14 @@ class DboSourceTest extends CakeTestCase {
|
|||
$null = null;
|
||||
|
||||
$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
|
||||
|
||||
$result = $this->db->generateSelfAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
|
||||
$_queryData = $queryData;
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
|
||||
|
||||
$this->assertPattern('/^SELECT\s+`TestModel8`\.`id`, `TestModel8`\.`test_model9_id`, `TestModel8`\.`name`, `TestModel8`\.`created`, `TestModel8`\.`updated`, `TestModel9`\.`id`, `TestModel9`\.`test_model8_id`, `TestModel9`\.`name`, `TestModel9`\.`created`, `TestModel9`\.`updated`\s+/', $result);
|
||||
$this->assertPattern('/FROM\s+`test_model8` AS `TestModel8`\s+LEFT JOIN\s+`test_model9` AS `TestModel9`/', $result);
|
||||
$this->assertPattern('/\s+ON\s+\(`TestModel8`.`test_model9_id` = `TestModel9`.`id`\s+AND\s+`TestModel9`\.`name` != \'mariano\'\)\s+WHERE/', $result);
|
||||
$this->assertPattern('/\s+ON\s+\(`TestModel9`\.`name` != \'mariano\'\s+AND\s+`TestModel9`.`test_model8_id` = `TestModel8`.`id`\)\s+WHERE/', $result);
|
||||
$this->assertPattern('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
|
||||
}
|
||||
|
||||
|
@ -801,16 +797,13 @@ class DboSourceTest extends CakeTestCase {
|
|||
$null = null;
|
||||
|
||||
$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
|
||||
|
||||
$result = $this->db->generateSelfAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
|
||||
|
||||
$this->assertPattern('/^SELECT\s+`TestModel9`\.`id`, `TestModel9`\.`test_model8_id`, `TestModel9`\.`name`, `TestModel9`\.`created`, `TestModel9`\.`updated`, `TestModel8`\.`id`, `TestModel8`\.`test_model9_id`, `TestModel8`\.`name`, `TestModel8`\.`created`, `TestModel8`\.`updated`\s+/', $result);
|
||||
$this->assertPattern('/FROM\s+`test_model9` AS `TestModel9`\s+LEFT JOIN\s+`test_model8` AS `TestModel8`/', $result);
|
||||
$this->assertPattern('/\s+ON\s+\(`TestModel9`.`test_model8_id` = `TestModel8`.`id`\s+AND\s+`TestModel8`\.`name` != \'larry\'\)\s+WHERE/', $result);
|
||||
$this->assertPattern('/\s+ON\s+\(`TestModel8`\.`name` != \'larry\'\s+AND\s+`TestModel9`.`test_model8_id` = `TestModel8`.`id`\)\s+WHERE/', $result);
|
||||
$this->assertPattern('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
|
||||
}
|
||||
|
||||
|
@ -826,8 +819,7 @@ class DboSourceTest extends CakeTestCase {
|
|||
|
||||
$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
|
||||
|
||||
$result = $this->db->generateSelfAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $this->db->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
|
||||
|
@ -857,8 +849,7 @@ class DboSourceTest extends CakeTestCase {
|
|||
|
||||
$params = &$this->_prepareAssociationQuery($this->Featured2, $queryData, $binding);
|
||||
|
||||
$result = $this->db->generateSelfAssociationQuery($this->Featured2, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
|
||||
$result = $this->db->generateAssociationQuery($this->Featured2, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $this->db->generateAssociationQuery($this->Featured2, $null, null, null, null, $queryData, false, $null);
|
||||
|
@ -867,9 +858,10 @@ class DboSourceTest extends CakeTestCase {
|
|||
'/^SELECT\s+`Featured2`\.`id`, `Featured2`\.`article_id`, `Featured2`\.`category_id`, `Featured2`\.`name`,\s+'.
|
||||
'`ArticleFeatured2`\.`id`, `ArticleFeatured2`\.`title`, `ArticleFeatured2`\.`user_id`, `ArticleFeatured2`\.`published`\s+' .
|
||||
'FROM\s+`featured2` AS `Featured2`\s+LEFT JOIN\s+`article_featured` AS `ArticleFeatured2`' .
|
||||
'\s+ON\s+\(`Featured2`\.`article_featured2_id` = `ArticleFeatured2`\.`id`\s+AND\s+`ArticleFeatured2`.`published` = \'Y\'\)' .
|
||||
'\s+ON\s+\(`ArticleFeatured2`.`published` = \'Y\'\s+AND\s+`Featured2`\.`article_featured2_id` = `ArticleFeatured2`\.`id`\)' .
|
||||
'\s+WHERE\s+1\s+=\s+1\s*$/',
|
||||
$result);
|
||||
$result
|
||||
);
|
||||
}
|
||||
|
||||
function testGenerateAssociationQueryHasOne() {
|
||||
|
@ -1367,16 +1359,9 @@ class DboSourceTest extends CakeTestCase {
|
|||
|
||||
$linkModel =& $model->{$className};
|
||||
$external = isset($assocData['external']);
|
||||
$queryData = $this->db->__scrubQueryData($queryData);
|
||||
|
||||
$this->db->__scrubQueryData($queryData);
|
||||
|
||||
$result = array(
|
||||
'linkModel'=> &$linkModel,
|
||||
'type'=> $type,
|
||||
'assoc'=> $assoc,
|
||||
'assocData'=> $assocData,
|
||||
'external'=> $external
|
||||
);
|
||||
$result = array_merge(array('linkModel' => &$linkModel), compact('type', 'assoc', 'assocData', 'external'));
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -2152,6 +2137,29 @@ class DboSourceTest extends CakeTestCase {
|
|||
$result = $this->db->order("Model.name+0 ASC");
|
||||
$this->assertPattern("/^\s*ORDER BY\s+`Model`\.`name`\+0\s+ASC\s*$/", $result);
|
||||
}
|
||||
|
||||
function testCalculations() {
|
||||
$result = $this->db->calculate('count');
|
||||
$this->assertEqual($result, 'COUNT(*) AS `count`');
|
||||
|
||||
$result = $this->db->calculate('count', array('id'));
|
||||
$this->assertEqual($result, 'COUNT(`id`) AS `count`');
|
||||
|
||||
$result = $this->db->calculate('count', array('id', 'id_count'));
|
||||
$this->assertEqual($result, 'COUNT(`id`) AS `id_count`');
|
||||
|
||||
$result = $this->db->calculate('count', array('Model.id', 'id_count'));
|
||||
$this->assertEqual($result, 'COUNT(`Model`.`id`) AS `id_count`');
|
||||
|
||||
$result = $this->db->calculate('max', array('id'));
|
||||
$this->assertEqual($result, 'MAX(`id`) AS `id`');
|
||||
|
||||
$result = $this->db->calculate('max', array('Model.id', 'id'));
|
||||
$this->assertEqual($result, 'MAX(`Model`.`id`) AS `id`');
|
||||
|
||||
$result = $this->db->calculate('max', array('`Model`.`id`', 'id'));
|
||||
$this->assertEqual($result, 'MAX(`Model`.`id`) AS `id`');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -83,6 +83,7 @@ class ModelTest extends CakeTestCase {
|
|||
|
||||
$this->DeviceType->recursive = 2;
|
||||
$result = $this->DeviceType->read(null, 1);
|
||||
|
||||
$expected = array(
|
||||
'DeviceType' => array(
|
||||
'id' => 1, 'device_type_category_id' => 1, 'feature_set_id' => 1, 'exterior_type_category_id' => 1, 'image_id' => 1,
|
||||
|
@ -143,12 +144,33 @@ class ModelTest extends CakeTestCase {
|
|||
$this->assertEqual($result['Tag'], $expected);
|
||||
}
|
||||
|
||||
function testHasManyOptimization() {
|
||||
function testHabtmLimitOptimization() {
|
||||
$this->loadFixtures('Article', 'User', 'Comment', 'Tag', 'ArticlesTag');
|
||||
$this->model =& new Article();
|
||||
|
||||
$this->model->hasAndBelongsToMany['Tag']['limit'] = 1;
|
||||
$result = $this->model->read(null, 2);
|
||||
$expected = array(
|
||||
'Article' => array('id' => '2', 'user_id' => '3', 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
|
||||
'User' => array('id' => '3', 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'),
|
||||
'Comment' => array(
|
||||
array('id' => '5', 'article_id' => '2', 'user_id' => '1', 'comment' => 'First Comment for Second Article', 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'),
|
||||
array('id' => '6', 'article_id' => '2', 'user_id' => '2', 'comment' => 'Second Comment for Second Article', 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31')
|
||||
),
|
||||
'Tag' => array(
|
||||
array('id' => '1', 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
|
||||
array('id' => '3', 'tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31')
|
||||
)
|
||||
);
|
||||
//$this->assertEqual($result, $expected);
|
||||
}
|
||||
|
||||
function testHasManyLimitOptimization() {
|
||||
$this->loadFixtures('Project', 'Thread', 'Message', 'Bid');
|
||||
$this->Project =& new Project();
|
||||
$this->Project->recursive = 3;
|
||||
|
||||
$result = $this->Project->findAll();
|
||||
$result = $this->Project->find('all');
|
||||
$expected = array(
|
||||
array('Project' => array('id' => 1, 'name' => 'Project 1'),
|
||||
'Thread' => array(array('id' => 1, 'project_id' => 1, 'name' => 'Project 1, Thread 1',
|
||||
|
@ -1702,14 +1724,11 @@ class ModelTest extends CakeTestCase {
|
|||
'Tag' => array('Tag' => array(1, 2))
|
||||
);
|
||||
|
||||
$result = $this->model->set($data);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $this->model->save();
|
||||
$this->assertTrue($result);
|
||||
$this->assertTrue($this->model->set($data));
|
||||
$this->assertTrue($this->model->save());
|
||||
|
||||
$this->model->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment')));
|
||||
$result = $this->model->find(array('Article.id'=>2), array('id', 'user_id', 'title', 'body'));
|
||||
$result = $this->model->find(array('Article.id' => 2), array('id', 'user_id', 'title', 'body'));
|
||||
$expected = array(
|
||||
'Article' => array('id' => '2', 'user_id' => '3', 'title' => 'New Second Article', 'body' => 'Second Article Body'),
|
||||
'Tag' => array(
|
||||
|
@ -1981,13 +2000,16 @@ class ModelTest extends CakeTestCase {
|
|||
$this->model =& new Article();
|
||||
$this->model->belongsTo = $this->model->hasAndBelongsToMany = array();
|
||||
|
||||
$this->assertTrue($this->model->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
)));
|
||||
$this->assertTrue($this->model->saveAll(
|
||||
array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array('atomic' => false)
|
||||
));
|
||||
$result = $this->model->findById(2);
|
||||
$expected = array('First Comment for Second Article', 'Second Comment for Second Article', 'First new comment', 'Second new comment');
|
||||
$this->assertEqual(Set::extract($result['Comment'], '{n}.comment'), $expected);
|
||||
|
@ -2000,7 +2022,7 @@ class ModelTest extends CakeTestCase {
|
|||
$data = array(
|
||||
array('id' => '1', 'title' => 'Baleeted First Post', 'body' => 'Baleeted!', 'published' => 'N'),
|
||||
array('id' => '2', 'title' => 'Just update the title'),
|
||||
array('title' => 'Creating a fourth post', 'body' => 'Fourth post body')
|
||||
array('title' => 'Creating a fourth post', 'body' => 'Fourth post body', 'author_id' => 2)
|
||||
);
|
||||
$ts = date('Y-m-d H:i:s');
|
||||
$this->assertTrue($this->model->saveAll($data));
|
||||
|
@ -2010,7 +2032,7 @@ class ModelTest extends CakeTestCase {
|
|||
array('Post' => array('id' => '1', 'author_id' => '1', 'title' => 'Baleeted First Post', 'body' => 'Baleeted!', 'published' => 'N', 'created' => '2007-03-18 10:39:23', 'updated' => $ts)),
|
||||
array('Post' => array('id' => '2', 'author_id' => '3', 'title' => 'Just update the title', 'body' => 'Second Post Body', 'published' => 'N', 'created' => '2007-03-18 10:41:23', 'updated' => $ts)),
|
||||
array('Post' => array('id' => '3', 'author_id' => '1', 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')),
|
||||
array('Post' => array('id' => '4', 'author_id' => '0', 'title' => 'Creating a fourth post', 'body' => 'Fourth post body', 'published' => 'N', 'created' => $ts, 'updated' => $ts))
|
||||
array('Post' => array('id' => '4', 'author_id' => '2', 'title' => 'Creating a fourth post', 'body' => 'Fourth post body', 'published' => 'N', 'created' => $ts, 'updated' => $ts))
|
||||
);
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
|
@ -2077,17 +2099,17 @@ class ModelTest extends CakeTestCase {
|
|||
$this->model =& new Syfile();
|
||||
$this->model2 =& new Item();
|
||||
$this->model2->belongsTo['Syfile']['counterCache'] = true;
|
||||
$this->model2->belongsTo['Syfile']['counterScope'] = 'published = 1';
|
||||
$this->model2->belongsTo['Syfile']['counterScope'] = array('published' => true);
|
||||
|
||||
$result = $this->model->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], null);
|
||||
|
||||
$this->model2->save(array('name' => 'Item 7', 'syfile_id' => 1, 'published'=> 1));
|
||||
$this->model2->save(array('name' => 'Item 7', 'syfile_id' => 1, 'published'=> true));
|
||||
$result = $this->model->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '1');
|
||||
|
||||
$this->model2->id = 1;
|
||||
$this->model2->saveField('published', 1);
|
||||
$this->model2->saveField('published', true);
|
||||
$result = $this->model->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '2');
|
||||
}
|
||||
|
@ -2220,6 +2242,29 @@ class ModelTest extends CakeTestCase {
|
|||
$this->assertEqual($this->model->Comment->find('count'), 2);
|
||||
}
|
||||
|
||||
function testDeleteLinks() {
|
||||
$this->loadFixtures('Article', 'ArticlesTag', 'Tag');
|
||||
$this->model =& new Article();
|
||||
|
||||
$result = $this->model->ArticlesTag->find('all');
|
||||
$expected = array(
|
||||
array('ArticlesTag' => array('article_id' => '1', 'tag_id' => '1')),
|
||||
array('ArticlesTag' => array('article_id' => '1', 'tag_id' => '2')),
|
||||
array('ArticlesTag' => array('article_id' => '2', 'tag_id' => '1')),
|
||||
array('ArticlesTag' => array('article_id' => '2', 'tag_id' => '3'))
|
||||
);
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$this->Article->delete(1);
|
||||
$result = $this->model->ArticlesTag->find('all');
|
||||
|
||||
$expected = array(
|
||||
array('ArticlesTag' => array('article_id' => '2', 'tag_id' => '1')),
|
||||
array('ArticlesTag' => array('article_id' => '2', 'tag_id' => '3'))
|
||||
);
|
||||
$this->assertEqual($result, $expected);
|
||||
}
|
||||
|
||||
function testFindAllThreaded() {
|
||||
$this->loadFixtures('Category');
|
||||
$this->model =& new Category();
|
||||
|
|
|
@ -130,7 +130,7 @@ class ArticleFeatured extends CakeTestModel {
|
|||
var $name = 'ArticleFeatured';
|
||||
var $belongsTo = array('User', 'Category');
|
||||
var $hasOne = array('Featured');
|
||||
var $hasMany = array('Comment' => array('className'=>'Comment', 'dependent' => true));
|
||||
var $hasMany = array('Comment' => array('className' => 'Comment', 'dependent' => true));
|
||||
var $hasAndBelongsToMany = array('Tag');
|
||||
var $validate = array('user_id' => VALID_NUMBER, 'title' => VALID_NOT_EMPTY, 'body' => VALID_NOT_EMPTY);
|
||||
}
|
||||
|
@ -142,10 +142,7 @@ class ArticleFeatured extends CakeTestModel {
|
|||
*/
|
||||
class Featured extends CakeTestModel {
|
||||
var $name = 'Featured';
|
||||
var $belongsTo = array(
|
||||
'ArticleFeatured'=> array('className' => 'ArticleFeatured'),
|
||||
'Category'=> array('className' => 'Category')
|
||||
);
|
||||
var $belongsTo = array('ArticleFeatured', 'Category');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -354,7 +351,7 @@ class NodeNoAfterFind extends CakeTestModel {
|
|||
var $validate = array('name' => VALID_NOT_EMPTY);
|
||||
var $useTable = 'apples';
|
||||
var $hasOne = array('Sample' => array('className' => 'NodeAfterFindSample'));
|
||||
var $hasMany = array('Child' => array( 'className' => 'NodeAfterFind', 'dependent' => true));
|
||||
var $hasMany = array('Child' => array('className' => 'NodeAfterFind', 'dependent' => true));
|
||||
var $belongsTo = array('Parent' => array('className' => 'NodeAfterFind', 'foreignKey' => 'apple_id'));
|
||||
}
|
||||
class ModelA extends CakeTestModel {
|
||||
|
@ -455,6 +452,11 @@ class JoinC extends CakeTestModel {
|
|||
var $name = 'JoinC';
|
||||
var $hasAndBelongsToMany = array('JoinA');
|
||||
}
|
||||
class ThePaper extends CakeTestModel {
|
||||
var $name = 'ThePaper';
|
||||
var $useTable = 'apples';
|
||||
var $hasOne = array('Itself' => array('className' => 'ThePaper', 'foreignKey' => 'apple_id'));
|
||||
}
|
||||
/**
|
||||
* Short description for class.
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue