mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Merge branch 'feature/2.0/pdo' into 2.0-class-loading
This commit is contained in:
commit
8678661b9c
35 changed files with 5102 additions and 5813 deletions
|
@ -299,7 +299,7 @@ class SchemaShell extends Shell {
|
|||
*
|
||||
* @access private
|
||||
*/
|
||||
function __create(&$Schema, $table = null) {
|
||||
function __create($Schema, $table = null) {
|
||||
$db = ConnectionManager::getDataSource($this->Schema->connection);
|
||||
|
||||
$drop = $create = array();
|
||||
|
|
|
@ -106,7 +106,7 @@ class DbConfigTask extends Shell {
|
|||
}
|
||||
}
|
||||
|
||||
$driver = $this->in('Driver:', array('db2', 'firebird', 'mssql', 'mysql', 'mysqli', 'odbc', 'oracle', 'postgres', 'sqlite', 'sybase'), 'mysql');
|
||||
$driver = $this->in('Driver:', array('db2', 'firebird', 'mssql', 'mysql', 'odbc', 'oracle', 'postgres', 'sqlite', 'sybase'), 'mysql');
|
||||
|
||||
$persistent = $this->in('Persistent Connection?', array('y', 'n'), 'n');
|
||||
if (strtolower($persistent) == 'n') {
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
*
|
||||
* driver => The name of a supported driver; valid options are as follows:
|
||||
* mysql - MySQL 4 & 5,
|
||||
* mysqli - MySQL 4 & 5 Improved Interface (PHP5 only),
|
||||
* sqlite - SQLite (PHP5 only),
|
||||
* postgres - PostgreSQL 7 and higher,
|
||||
* mssql - Microsoft SQL Server 2000 and higher,
|
||||
|
@ -67,7 +66,7 @@
|
|||
* 'public', DB2 defaults to empty.
|
||||
*
|
||||
* encoding =>
|
||||
* For MySQL, MySQLi, Postgres and DB2, specifies the character encoding to use when connecting to the
|
||||
* For MySQL, Postgres and DB2, specifies the character encoding to use when connecting to the
|
||||
* database. Uses database default.
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -89,6 +89,7 @@ class TranslateBehavior extends ModelBehavior {
|
|||
* @return array Modified query
|
||||
*/
|
||||
public function beforeFind(&$model, $query) {
|
||||
$this->runtime[$model->alias]['virtualFields'] = $model->virtualFields;
|
||||
$locale = $this->_getLocale($model);
|
||||
if (empty($locale)) {
|
||||
return $query;
|
||||
|
@ -115,48 +116,28 @@ class TranslateBehavior extends ModelBehavior {
|
|||
);
|
||||
return $query;
|
||||
}
|
||||
$autoFields = false;
|
||||
|
||||
if (empty($query['fields'])) {
|
||||
$query['fields'] = array($model->alias.'.*');
|
||||
|
||||
$recursive = $model->recursive;
|
||||
if (isset($query['recursive'])) {
|
||||
$recursive = $query['recursive'];
|
||||
}
|
||||
|
||||
if ($recursive >= 0) {
|
||||
foreach (array('hasOne', 'belongsTo') as $type) {
|
||||
foreach ($model->{$type} as $key => $value) {
|
||||
|
||||
if (empty($value['fields'])) {
|
||||
$query['fields'][] = $key.'.*';
|
||||
} else {
|
||||
foreach ($value['fields'] as $field) {
|
||||
$query['fields'][] = $key.'.'.$field;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$autoFields = true;
|
||||
}
|
||||
$fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']);
|
||||
$addFields = array();
|
||||
if (is_array($query['fields'])) {
|
||||
if (empty($query['fields'])) {
|
||||
$addFields = $fields;
|
||||
} else if (is_array($query['fields'])) {
|
||||
foreach ($fields as $key => $value) {
|
||||
$field = (is_numeric($key)) ? $value : $key;
|
||||
|
||||
if (in_array($model->alias.'.*', $query['fields']) || $autoFields || in_array($model->alias.'.'.$field, $query['fields']) || in_array($field, $query['fields'])) {
|
||||
if (in_array($model->alias.'.*', $query['fields']) || in_array($model->alias.'.'.$field, $query['fields']) || in_array($field, $query['fields'])) {
|
||||
$addFields[] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->runtime[$model->alias]['virtualFields'] = $model->virtualFields;
|
||||
if ($addFields) {
|
||||
foreach ($addFields as $field) {
|
||||
foreach (array($field, $model->alias.'.'.$field) as $_field) {
|
||||
$key = array_search($_field, $query['fields']);
|
||||
foreach ($addFields as $_f => $field) {
|
||||
$aliasField = is_numeric($_f) ? $field : $_f;
|
||||
|
||||
foreach (array($aliasField, $model->alias.'.'.$aliasField) as $_field) {
|
||||
$key = array_search($_field, (array)$query['fields']);
|
||||
|
||||
if ($key !== false) {
|
||||
unset($query['fields'][$key]);
|
||||
|
@ -165,7 +146,10 @@ class TranslateBehavior extends ModelBehavior {
|
|||
|
||||
if (is_array($locale)) {
|
||||
foreach ($locale as $_locale) {
|
||||
$query['fields'][] = 'I18n__'.$field.'__'.$_locale.'.content';
|
||||
$model->virtualFields['i18n_'.$field.'_'.$_locale] = 'I18n__'.$field.'__'.$_locale.'.content';
|
||||
if (!empty($query['fields'])) {
|
||||
$query['fields'][] = 'i18n_'.$field.'_'.$_locale;
|
||||
}
|
||||
$query['joins'][] = array(
|
||||
'type' => 'LEFT',
|
||||
'alias' => 'I18n__'.$field.'__'.$_locale,
|
||||
|
@ -173,13 +157,16 @@ class TranslateBehavior extends ModelBehavior {
|
|||
'conditions' => array(
|
||||
$model->alias . '.' . $model->primaryKey => $db->identifier("I18n__{$field}__{$_locale}.foreign_key"),
|
||||
'I18n__'.$field.'__'.$_locale.'.model' => $model->name,
|
||||
'I18n__'.$field.'__'.$_locale.'.'.$RuntimeModel->displayField => $field,
|
||||
'I18n__'.$field.'__'.$_locale.'.'.$RuntimeModel->displayField => $aliasField,
|
||||
'I18n__'.$field.'__'.$_locale.'.locale' => $_locale
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$query['fields'][] = 'I18n__'.$field.'.content';
|
||||
$model->virtualFields['i18n_'.$field] = 'I18n__'.$field.'.content';
|
||||
if (!empty($query['fields'])) {
|
||||
$query['fields'][] = 'i18n_'.$field;
|
||||
}
|
||||
$query['joins'][] = array(
|
||||
'type' => 'LEFT',
|
||||
'alias' => 'I18n__'.$field,
|
||||
|
@ -187,7 +174,7 @@ class TranslateBehavior extends ModelBehavior {
|
|||
'conditions' => array(
|
||||
$model->alias . '.' . $model->primaryKey => $db->identifier("I18n__{$field}.foreign_key"),
|
||||
'I18n__'.$field.'.model' => $model->name,
|
||||
'I18n__'.$field.'.'.$RuntimeModel->displayField => $field
|
||||
'I18n__'.$field.'.'.$RuntimeModel->displayField => $aliasField
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -199,9 +186,6 @@ class TranslateBehavior extends ModelBehavior {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (is_array($query['fields'])) {
|
||||
$query['fields'] = array_merge($query['fields']);
|
||||
}
|
||||
$this->runtime[$model->alias]['beforeFind'] = $addFields;
|
||||
return $query;
|
||||
}
|
||||
|
@ -215,7 +199,8 @@ class TranslateBehavior extends ModelBehavior {
|
|||
* @return array Modified results
|
||||
*/
|
||||
public function afterFind(&$model, $results, $primary) {
|
||||
$this->runtime[$model->alias]['fields'] = array();
|
||||
$model->virtualFields = $this->runtime[$model->alias]['virtualFields'];
|
||||
$this->runtime[$model->alias]['virtualFields'] = $this->runtime[$model->alias]['fields'] = array();
|
||||
$locale = $this->_getLocale($model);
|
||||
|
||||
if (empty($locale) || empty($results) || empty($this->runtime[$model->alias]['beforeFind'])) {
|
||||
|
@ -223,28 +208,30 @@ class TranslateBehavior extends ModelBehavior {
|
|||
}
|
||||
$beforeFind = $this->runtime[$model->alias]['beforeFind'];
|
||||
|
||||
foreach ($results as $key => $row) {
|
||||
$results[$key][$model->alias]['locale'] = (is_array($locale)) ? @$locale[0] : $locale;
|
||||
foreach ($results as $key => &$row) {
|
||||
$results[$key][$model->alias]['locale'] = (is_array($locale)) ? current($locale) : $locale;
|
||||
foreach ($beforeFind as $_f => $field) {
|
||||
$aliasField = is_numeric($_f) ? $field : $_f;
|
||||
|
||||
foreach ($beforeFind as $field) {
|
||||
if (is_array($locale)) {
|
||||
foreach ($locale as $_locale) {
|
||||
if (!isset($results[$key][$model->alias][$field]) && !empty($results[$key]['I18n__'.$field.'__'.$_locale]['content'])) {
|
||||
$results[$key][$model->alias][$field] = $results[$key]['I18n__'.$field.'__'.$_locale]['content'];
|
||||
if (!isset($row[$model->alias][$aliasField]) && !empty($row[$model->alias]['i18n_'.$field.'_'.$_locale])) {
|
||||
$row[$model->alias][$aliasField] = $row[$model->alias]['i18n_'.$field.'_'.$_locale];
|
||||
$row[$model->alias]['locale'] = $_locale;
|
||||
}
|
||||
unset($results[$key]['I18n__'.$field.'__'.$_locale]);
|
||||
unset($row[$model->alias]['i18n_'.$field.'_'.$_locale]);
|
||||
}
|
||||
|
||||
if (!isset($results[$key][$model->alias][$field])) {
|
||||
$results[$key][$model->alias][$field] = '';
|
||||
if (!isset($row[$model->alias][$aliasField])) {
|
||||
$row[$model->alias][$aliasField] = '';
|
||||
}
|
||||
} else {
|
||||
$value = '';
|
||||
if (!empty($results[$key]['I18n__'.$field]['content'])) {
|
||||
$value = $results[$key]['I18n__'.$field]['content'];
|
||||
if (!empty($row[$model->alias]['i18n_' . $field])) {
|
||||
$value = $row[$model->alias]['i18n_' . $field];
|
||||
}
|
||||
$results[$key][$model->alias][$field] = $value;
|
||||
unset($results[$key]['I18n__'.$field]);
|
||||
$row[$model->alias][$aliasField] = $value;
|
||||
unset($row[$model->alias]['i18n_' . $field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,8 +367,7 @@ class TranslateBehavior extends ModelBehavior {
|
|||
} elseif (empty($model->translateTable) && empty($model->translateModel)) {
|
||||
$this->runtime[$model->alias]['model']->setSource('i18n');
|
||||
}
|
||||
$model =& $this->runtime[$model->alias]['model'];
|
||||
return $model;
|
||||
return $this->runtime[$model->alias]['model'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,7 +65,7 @@ class TreeBehavior extends ModelBehavior {
|
|||
|
||||
if (in_array($settings['scope'], $Model->getAssociated('belongsTo'))) {
|
||||
$data = $Model->getAssociated($settings['scope']);
|
||||
$parent =& $Model->{$settings['scope']};
|
||||
$parent = $Model->{$settings['scope']};
|
||||
$settings['scope'] = $Model->alias . '.' . $data['foreignKey'] . ' = ' . $parent->alias . '.' . $parent->primaryKey;
|
||||
$settings['recursive'] = 0;
|
||||
}
|
||||
|
@ -599,7 +599,7 @@ class TreeBehavior extends ModelBehavior {
|
|||
$this->_setParent($Model, $array[$Model->alias][$parent]);
|
||||
}
|
||||
} else {
|
||||
$db =& ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
$db = ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey, $parent), 'order' => $left)) as $array) {
|
||||
$path = $this->getPath($Model, $array[$Model->alias][$Model->primaryKey]);
|
||||
if ($path == null || count($path) < 2) {
|
||||
|
@ -702,7 +702,7 @@ class TreeBehavior extends ModelBehavior {
|
|||
$parentNode[$right] = $node[$right] + 1;
|
||||
}
|
||||
|
||||
$db =& ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
$db = ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
$Model->updateAll(
|
||||
array($parent => $db->value($node[$parent], $parent)),
|
||||
array($Model->escapeField($parent) => $node[$Model->primaryKey])
|
||||
|
@ -888,7 +888,7 @@ class TreeBehavior extends ModelBehavior {
|
|||
* @access private
|
||||
*/
|
||||
function __getMax($Model, $scope, $right, $recursive = -1, $created = false) {
|
||||
$db =& ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
$db = ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
if ($created) {
|
||||
if (is_string($scope)) {
|
||||
$scope .= " AND {$Model->alias}.{$Model->primaryKey} <> ";
|
||||
|
@ -916,7 +916,7 @@ class TreeBehavior extends ModelBehavior {
|
|||
* @access private
|
||||
*/
|
||||
function __getMin($Model, $scope, $left, $recursive = -1) {
|
||||
$db =& ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
$db = ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
$name = $Model->alias . '.' . $left;
|
||||
list($edge) = array_values($Model->find('first', array(
|
||||
'conditions' => $scope,
|
||||
|
|
|
@ -95,11 +95,7 @@ class CakeSchema extends Object {
|
|||
}
|
||||
|
||||
if (empty($options['path'])) {
|
||||
if (is_dir(CONFIGS . 'schema')) {
|
||||
$this->path = CONFIGS . 'schema';
|
||||
} else {
|
||||
$this->path = CONFIGS . 'sql';
|
||||
}
|
||||
$this->path = CONFIGS . 'schema';
|
||||
}
|
||||
|
||||
$options = array_merge(get_object_vars($this), $options);
|
||||
|
@ -161,7 +157,7 @@ class CakeSchema extends Object {
|
|||
* @param array $options schema object properties
|
||||
* @return array Set of name and tables
|
||||
*/
|
||||
public function &load($options = array()) {
|
||||
public function load($options = array()) {
|
||||
if (is_string($options)) {
|
||||
$options = array('path' => $options);
|
||||
}
|
||||
|
@ -183,8 +179,8 @@ class CakeSchema extends Object {
|
|||
$Schema = new $class($options);
|
||||
return $Schema;
|
||||
}
|
||||
$false = false;
|
||||
return $false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,7 +295,9 @@ class CakeSchema extends Object {
|
|||
$systemTables = array(
|
||||
'aros', 'acos', 'aros_acos', Configure::read('Session.table'), 'i18n'
|
||||
);
|
||||
|
||||
if (get_class($Object) === 'AppModel') {
|
||||
continue;
|
||||
}
|
||||
if (in_array($table, $systemTables)) {
|
||||
$tables[$Object->table] = $this->__columns($Object);
|
||||
$tables[$Object->table]['indexes'] = $db->index($Object);
|
||||
|
|
|
@ -19,19 +19,42 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Provides common base for MySQL & MySQLi connections
|
||||
* MySQL DBO driver object
|
||||
*
|
||||
* Provides connection and SQL generation for MySQL RDMS
|
||||
*
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs.model.datasources.dbo
|
||||
*/
|
||||
class DboMysqlBase extends DboSource {
|
||||
class DboMysql extends DboSource {
|
||||
|
||||
/**
|
||||
* Description property.
|
||||
* Datasource description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = "MySQL DBO Base Driver";
|
||||
public $description = "MySQL DBO Driver";
|
||||
|
||||
/**
|
||||
* Base configuration settings for MySQL driver
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_baseConfig = array(
|
||||
'persistent' => true,
|
||||
'host' => 'localhost',
|
||||
'login' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'cake',
|
||||
'port' => '3306'
|
||||
);
|
||||
|
||||
/**
|
||||
* Reference to the PDO object connection
|
||||
*
|
||||
* @var PDO $_connection
|
||||
*/
|
||||
protected $_connection = null;
|
||||
|
||||
/**
|
||||
* Start quote
|
||||
|
@ -110,49 +133,190 @@ class DboMysqlBase extends DboSource {
|
|||
'boolean' => array('name' => 'tinyint', 'limit' => '1')
|
||||
);
|
||||
|
||||
/**
|
||||
* Connects to the database using options in the given configuration array.
|
||||
*
|
||||
* @return boolean True if the database could be connected, else false
|
||||
*/
|
||||
function connect() {
|
||||
$config = $this->config;
|
||||
$this->connected = false;
|
||||
try {
|
||||
$flags = array(
|
||||
PDO::ATTR_PERSISTENT => $config['persistent'],
|
||||
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
|
||||
);
|
||||
if (!empty($config['encoding'])) {
|
||||
$flags[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['encoding'];
|
||||
}
|
||||
$this->_connection = new PDO(
|
||||
"mysql:{$config['host']};port={$config['port']};dbname={$config['database']}",
|
||||
$config['login'],
|
||||
$config['password'],
|
||||
$flags
|
||||
);
|
||||
$this->connected = true;
|
||||
} catch (PDOException $e) {
|
||||
$this->errors[] = $e->getMessage();
|
||||
}
|
||||
|
||||
$this->_useAlias = (bool)version_compare($this->getVersion(), "4.1", ">=");
|
||||
|
||||
return $this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the MySQL extension is installed/loaded
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function enabled() {
|
||||
return in_array('mysql', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of sources (tables) in the database.
|
||||
*
|
||||
* @return array Array of tablenames in the database
|
||||
*/
|
||||
function listSources($data = null) {
|
||||
$cache = parent::listSources();
|
||||
if ($cache != null) {
|
||||
return $cache;
|
||||
}
|
||||
$result = $this->_execute('SHOW TABLES FROM ' . $this->config['database']);
|
||||
|
||||
if (!$result) {
|
||||
$result->closeCursor();
|
||||
return array();
|
||||
} else {
|
||||
$tables = array();
|
||||
|
||||
while ($line = $result->fetch()) {
|
||||
$tables[] = $line[0];
|
||||
}
|
||||
|
||||
$result->closeCursor();
|
||||
parent::listSources($tables);
|
||||
return $tables;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a map of the columns contained in a result
|
||||
*
|
||||
* @param PDOStatement $results
|
||||
*/
|
||||
function resultSet($results) {
|
||||
$this->map = array();
|
||||
$numFields = $results->columnCount();
|
||||
$index = 0;
|
||||
$j = 0;
|
||||
|
||||
while ($j < $numFields) {
|
||||
$column = $results->getColumnMeta($j);
|
||||
if (!empty($column['table']) && strpos($column['name'], $this->virtualFieldSeparator) === false) {
|
||||
$this->map[$index++] = array($column['table'], $column['name']);
|
||||
} else {
|
||||
$this->map[$index++] = array(0, $column['name']);
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the next row from the current result set
|
||||
*
|
||||
* @return mixed array with results fetched and mapped to column names or false if there is no results left to fetch
|
||||
*/
|
||||
function fetchResult() {
|
||||
if ($row = $this->_result->fetch()) {
|
||||
$resultRow = array();
|
||||
foreach ($this->map as $col => $meta) {
|
||||
list($table, $column) = $meta;
|
||||
$resultRow[$table][$column] = $row[$col];
|
||||
}
|
||||
return $resultRow;
|
||||
} else {
|
||||
$this->_result->closeCursor();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database encoding
|
||||
*
|
||||
* @return string The database encoding
|
||||
*/
|
||||
public function getEncoding() {
|
||||
return $this->_execute('SHOW VARIABLES LIKE ?', array('character_set_client'))->fetchObject()->Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version string of the database server
|
||||
*
|
||||
* @return string The database encoding
|
||||
*/
|
||||
public function getVersion() {
|
||||
return $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query charset by collation
|
||||
*
|
||||
* @param string $name Collation name
|
||||
* @return string Character set name
|
||||
*/
|
||||
public function getCharsetName($name) {
|
||||
if ((bool)version_compare($this->getVersion(), "5", ">=")) {
|
||||
$r = $this->_execute('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME = ?', array($name));
|
||||
$cols = $r->fetch();
|
||||
|
||||
if (isset($cols['CHARACTER_SET_NAME'])) {
|
||||
return $cols['CHARACTER_SET_NAME'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the fields in given table name.
|
||||
*
|
||||
* @param string $tableName Name of database table to inspect
|
||||
* @param mixed $tableName Name of database table to inspect or model instance
|
||||
* @return array Fields in table. Keys are name and type
|
||||
*/
|
||||
function describe(&$model) {
|
||||
function describe($model) {
|
||||
$cache = parent::describe($model);
|
||||
if ($cache != null) {
|
||||
return $cache;
|
||||
}
|
||||
$fields = false;
|
||||
$cols = $this->query('SHOW FULL COLUMNS FROM ' . $this->fullTableName($model));
|
||||
$cols = $this->_execute('SHOW FULL COLUMNS FROM ' . $this->fullTableName($model));
|
||||
|
||||
foreach ($cols as $column) {
|
||||
$colKey = array_keys($column);
|
||||
if (isset($column[$colKey[0]]) && !isset($column[0])) {
|
||||
$column[0] = $column[$colKey[0]];
|
||||
$fields[$column->Field] = array(
|
||||
'type' => $this->column($column->Type),
|
||||
'null' => ($column->Null == 'YES' ? true : false),
|
||||
'default' => $column->Default,
|
||||
'length' => $this->length($column->Type),
|
||||
);
|
||||
if (!empty($column->Key) && isset($this->index[$column->Key])) {
|
||||
$fields[$column->Field]['key'] = $this->index[$column->Key];
|
||||
}
|
||||
if (isset($column[0])) {
|
||||
$fields[$column[0]['Field']] = array(
|
||||
'type' => $this->column($column[0]['Type']),
|
||||
'null' => ($column[0]['Null'] == 'YES' ? true : false),
|
||||
'default' => $column[0]['Default'],
|
||||
'length' => $this->length($column[0]['Type']),
|
||||
);
|
||||
if (!empty($column[0]['Key']) && isset($this->index[$column[0]['Key']])) {
|
||||
$fields[$column[0]['Field']]['key'] = $this->index[$column[0]['Key']];
|
||||
foreach ($this->fieldParameters as $name => $value) {
|
||||
if (!empty($column->{$value['column']})) {
|
||||
$fields[$column->Field][$name] = $column->{$value['column']};
|
||||
}
|
||||
foreach ($this->fieldParameters as $name => $value) {
|
||||
if (!empty($column[0][$value['column']])) {
|
||||
$fields[$column[0]['Field']][$name] = $column[0][$value['column']];
|
||||
}
|
||||
}
|
||||
if (isset($fields[$column[0]['Field']]['collate'])) {
|
||||
$charset = $this->getCharsetName($fields[$column[0]['Field']]['collate']);
|
||||
if ($charset) {
|
||||
$fields[$column[0]['Field']]['charset'] = $charset;
|
||||
}
|
||||
}
|
||||
if (isset($fields[$column->Field]['collate'])) {
|
||||
$charset = $this->getCharsetName($fields[$column->Field]['collate']);
|
||||
if ($charset) {
|
||||
$fields[$column->Field]['charset'] = $charset;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->__cacheDescription($this->fullTableName($model, false), $fields);
|
||||
$cols->closeCursor();
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
@ -249,26 +413,26 @@ class DboMysqlBase extends DboSource {
|
|||
function index($model) {
|
||||
$index = array();
|
||||
$table = $this->fullTableName($model);
|
||||
$old = version_compare($this->getVersion(), '4.1', '<=');
|
||||
if ($table) {
|
||||
$indexes = $this->query('SHOW INDEX FROM ' . $table);
|
||||
if (isset($indexes[0]['STATISTICS'])) {
|
||||
$keys = Set::extract($indexes, '{n}.STATISTICS');
|
||||
} else {
|
||||
$keys = Set::extract($indexes, '{n}.0');
|
||||
}
|
||||
foreach ($keys as $i => $key) {
|
||||
if (!isset($index[$key['Key_name']])) {
|
||||
$indices = $this->_execute('SHOW INDEX FROM ' . $table);
|
||||
while ($idx = $indices->fetch()) {
|
||||
if ($old) {
|
||||
$idx = (object) current((array)$idx);
|
||||
}
|
||||
if (!isset($index[$idx->Key_name]['column'])) {
|
||||
$col = array();
|
||||
$index[$key['Key_name']]['column'] = $key['Column_name'];
|
||||
$index[$key['Key_name']]['unique'] = intval($key['Non_unique'] == 0);
|
||||
$index[$idx->Key_name]['column'] = $idx->Column_name;
|
||||
$index[$idx->Key_name]['unique'] = intval($idx->Non_unique == 0);
|
||||
} else {
|
||||
if (!is_array($index[$key['Key_name']]['column'])) {
|
||||
$col[] = $index[$key['Key_name']]['column'];
|
||||
if (!empty($index[$idx->Key_name]['column']) && !is_array($index[$idx->Key_name]['column'])) {
|
||||
$col[] = $index[$idx->Key_name]['column'];
|
||||
}
|
||||
$col[] = $key['Column_name'];
|
||||
$index[$key['Key_name']]['column'] = $col;
|
||||
$col[] = $idx->Column_name;
|
||||
$index[$idx->Key_name]['column'] = $col;
|
||||
}
|
||||
}
|
||||
$indices->closeCursor();
|
||||
}
|
||||
return $index;
|
||||
}
|
||||
|
@ -412,21 +576,6 @@ class DboMysqlBase extends DboSource {
|
|||
return $alter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts multiple values into a table
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $fields
|
||||
* @param array $values
|
||||
*/
|
||||
function insertMulti($table, $fields, $values) {
|
||||
$table = $this->fullTableName($table);
|
||||
if (is_array($fields)) {
|
||||
$fields = implode(', ', array_map(array(&$this, 'name'), $fields));
|
||||
}
|
||||
$values = implode(', ', $values);
|
||||
$this->query("INSERT INTO {$table} ({$fields}) VALUES {$values}");
|
||||
}
|
||||
/**
|
||||
* Returns an detailed array of sources (tables) in the database.
|
||||
*
|
||||
|
@ -435,23 +584,29 @@ class DboMysqlBase extends DboSource {
|
|||
*/
|
||||
function listDetailedSources($name = null) {
|
||||
$condition = '';
|
||||
$params = array();
|
||||
if (is_string($name)) {
|
||||
$condition = ' LIKE ' . $this->value($name);
|
||||
$condition = ' WHERE name = ?' ;
|
||||
$params = array($name);
|
||||
}
|
||||
$result = $this->query('SHOW TABLE STATUS FROM ' . $this->name($this->config['database']) . $condition . ';');
|
||||
$result = $this->_execute('SHOW TABLE STATUS ' . $condition, $params);
|
||||
|
||||
if (!$result) {
|
||||
$result->closeCursor();
|
||||
return array();
|
||||
} else {
|
||||
$tables = array();
|
||||
foreach ($result as $row) {
|
||||
$tables[$row['TABLES']['Name']] = $row['TABLES'];
|
||||
if (!empty($row['TABLES']['Collation'])) {
|
||||
$charset = $this->getCharsetName($row['TABLES']['Collation']);
|
||||
while ($row = $result->fetch()) {
|
||||
$tables[$row->Name] = (array) $row;
|
||||
unset($tables[$row->Name]['queryString']);
|
||||
if (!empty($row->Collation)) {
|
||||
$charset = $this->getCharsetName($row->Collation);
|
||||
if ($charset) {
|
||||
$tables[$row['TABLES']['Name']]['charset'] = $charset;
|
||||
$tables[$row->Name]['charset'] = $charset;
|
||||
}
|
||||
}
|
||||
}
|
||||
$result->closeCursor();
|
||||
if (is_string($name)) {
|
||||
return $tables[$name];
|
||||
}
|
||||
|
@ -507,292 +662,3 @@ class DboMysqlBase extends DboSource {
|
|||
return 'text';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL DBO driver object
|
||||
*
|
||||
* Provides connection and SQL generation for MySQL RDMS
|
||||
*
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs.model.datasources.dbo
|
||||
*/
|
||||
class DboMysql extends DboMysqlBase {
|
||||
|
||||
/**
|
||||
* Datasource description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = "MySQL DBO Driver";
|
||||
|
||||
/**
|
||||
* Base configuration settings for MySQL driver
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_baseConfig = array(
|
||||
'persistent' => true,
|
||||
'host' => 'localhost',
|
||||
'login' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'cake',
|
||||
'port' => '3306'
|
||||
);
|
||||
|
||||
/**
|
||||
* Connects to the database using options in the given configuration array.
|
||||
*
|
||||
* @return boolean True if the database could be connected, else false
|
||||
*/
|
||||
function connect() {
|
||||
$config = $this->config;
|
||||
$this->connected = false;
|
||||
|
||||
if (!$config['persistent']) {
|
||||
$this->connection = mysql_connect($config['host'] . ':' . $config['port'], $config['login'], $config['password'], true);
|
||||
$config['connect'] = 'mysql_connect';
|
||||
} else {
|
||||
$this->connection = mysql_pconnect($config['host'] . ':' . $config['port'], $config['login'], $config['password']);
|
||||
}
|
||||
|
||||
if (mysql_select_db($config['database'], $this->connection)) {
|
||||
$this->connected = true;
|
||||
}
|
||||
|
||||
if (!empty($config['encoding'])) {
|
||||
$this->setEncoding($config['encoding']);
|
||||
}
|
||||
|
||||
$this->_useAlias = (bool)version_compare(mysql_get_server_info($this->connection), "4.1", ">=");
|
||||
|
||||
return $this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the MySQL extension is installed/loaded
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function enabled() {
|
||||
return extension_loaded('mysql');
|
||||
}
|
||||
/**
|
||||
* Disconnects from database.
|
||||
*
|
||||
* @return boolean True if the database could be disconnected, else false
|
||||
*/
|
||||
function disconnect() {
|
||||
if (isset($this->results) && is_resource($this->results)) {
|
||||
mysql_free_result($this->results);
|
||||
}
|
||||
$this->connected = !@mysql_close($this->connection);
|
||||
return !$this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes given SQL statement.
|
||||
*
|
||||
* @param string $sql SQL statement
|
||||
* @return resource Result resource identifier
|
||||
*/
|
||||
protected function _execute($sql) {
|
||||
return mysql_query($sql, $this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of sources (tables) in the database.
|
||||
*
|
||||
* @return array Array of tablenames in the database
|
||||
*/
|
||||
function listSources() {
|
||||
$cache = parent::listSources();
|
||||
if ($cache != null) {
|
||||
return $cache;
|
||||
}
|
||||
$result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
|
||||
|
||||
if (!$result) {
|
||||
return array();
|
||||
} else {
|
||||
$tables = array();
|
||||
|
||||
while ($line = mysql_fetch_row($result)) {
|
||||
$tables[] = $line[0];
|
||||
}
|
||||
parent::listSources($tables);
|
||||
return $tables;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param string $column The column into which this data will be inserted
|
||||
* @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
|
||||
* @return string Quoted and escaped data
|
||||
*/
|
||||
function value($data, $column = null, $safe = false) {
|
||||
$parent = parent::value($data, $column, $safe);
|
||||
|
||||
if ($parent != null) {
|
||||
return $parent;
|
||||
}
|
||||
if ($data === null || (is_array($data) && empty($data))) {
|
||||
return 'NULL';
|
||||
}
|
||||
if ($data === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') {
|
||||
return "''";
|
||||
}
|
||||
if (empty($column)) {
|
||||
$column = $this->introspectType($data);
|
||||
}
|
||||
|
||||
switch ($column) {
|
||||
case 'boolean':
|
||||
return $this->boolean((bool)$data);
|
||||
break;
|
||||
case 'integer':
|
||||
case 'float':
|
||||
if ($data === '') {
|
||||
return 'NULL';
|
||||
}
|
||||
if (is_float($data)) {
|
||||
return sprintf('%F', $data);
|
||||
}
|
||||
if ((is_int($data) || $data === '0') || (
|
||||
is_numeric($data) && strpos($data, ',') === false &&
|
||||
$data[0] != '0' && strpos($data, 'e') === false)
|
||||
) {
|
||||
return $data;
|
||||
}
|
||||
default:
|
||||
return "'" . mysql_real_escape_string($data, $this->connection) . "'";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted error message from previous database operation.
|
||||
*
|
||||
* @return string Error message with error number
|
||||
*/
|
||||
function lastError() {
|
||||
if (mysql_errno($this->connection)) {
|
||||
return mysql_errno($this->connection).': '.mysql_error($this->connection);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of affected rows in previous database operation. If no previous operation exists,
|
||||
* this returns false.
|
||||
*
|
||||
* @return integer Number of affected rows
|
||||
*/
|
||||
function lastAffected() {
|
||||
if ($this->_result) {
|
||||
return mysql_affected_rows($this->connection);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of rows in previous resultset. If no previous resultset exists,
|
||||
* this returns false.
|
||||
*
|
||||
* @return integer Number of rows in resultset
|
||||
*/
|
||||
function lastNumRows() {
|
||||
if ($this->hasResult()) {
|
||||
return mysql_num_rows($this->_result);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID generated from the previous INSERT operation.
|
||||
*
|
||||
* @param unknown_type $source
|
||||
* @return in
|
||||
*/
|
||||
function lastInsertId($source = null) {
|
||||
$id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
|
||||
if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
|
||||
return $id[0]['insertID'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param unknown_type $results
|
||||
*/
|
||||
function resultSet(&$results) {
|
||||
if (isset($this->results) && is_resource($this->results) && $this->results != $results) {
|
||||
mysql_free_result($this->results);
|
||||
}
|
||||
$this->results =& $results;
|
||||
$this->map = array();
|
||||
$numFields = mysql_num_fields($results);
|
||||
$index = 0;
|
||||
$j = 0;
|
||||
|
||||
while ($j < $numFields) {
|
||||
$column = mysql_fetch_field($results, $j);
|
||||
if (!empty($column->table) && strpos($column->name, $this->virtualFieldSeparator) === false) {
|
||||
$this->map[$index++] = array($column->table, $column->name);
|
||||
} else {
|
||||
$this->map[$index++] = array(0, $column->name);
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the next row from the current result set
|
||||
*
|
||||
* @return unknown
|
||||
*/
|
||||
function fetchResult() {
|
||||
if ($row = mysql_fetch_row($this->results)) {
|
||||
$resultRow = array();
|
||||
$i = 0;
|
||||
foreach ($row as $index => $field) {
|
||||
list($table, $column) = $this->map[$index];
|
||||
$resultRow[$table][$column] = $row[$index];
|
||||
$i++;
|
||||
}
|
||||
return $resultRow;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database encoding
|
||||
*
|
||||
* @return string The database encoding
|
||||
*/
|
||||
function getEncoding() {
|
||||
return mysql_client_encoding($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query charset by collation
|
||||
*
|
||||
* @param string $name Collation name
|
||||
* @return string Character set name
|
||||
*/
|
||||
function getCharsetName($name) {
|
||||
if ((bool)version_compare(mysql_get_server_info($this->connection), "5", ">=")) {
|
||||
$cols = $this->query('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME= ' . $this->value($name) . ';');
|
||||
if (isset($cols[0]['COLLATIONS']['CHARACTER_SET_NAME'])) {
|
||||
return $cols[0]['COLLATIONS']['CHARACTER_SET_NAME'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,336 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* MySQLi layer for DBO
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs.model.datasources.dbo
|
||||
* @since CakePHP(tm) v 1.1.4.2974
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
App::import('Datasource', 'DboMysql');
|
||||
|
||||
/**
|
||||
* MySQLi DBO driver object
|
||||
*
|
||||
* Provides connection and SQL generation for MySQL RDMS using PHP's MySQLi Interface
|
||||
*
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs.model.datasources.dbo
|
||||
*/
|
||||
class DboMysqli extends DboMysqlBase {
|
||||
|
||||
/**
|
||||
* Datasource Description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description = "Mysqli DBO Driver";
|
||||
|
||||
/**
|
||||
* Base configuration settings for Mysqli driver
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_baseConfig = array(
|
||||
'persistent' => true,
|
||||
'host' => 'localhost',
|
||||
'login' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'cake',
|
||||
'port' => '3306'
|
||||
);
|
||||
|
||||
/**
|
||||
* Connects to the database using options in the given configuration array.
|
||||
*
|
||||
* @return boolean True if the database could be connected, else false
|
||||
*/
|
||||
function connect() {
|
||||
$config = $this->config;
|
||||
$this->connected = false;
|
||||
|
||||
if (is_numeric($config['port'])) {
|
||||
$config['socket'] = null;
|
||||
} else {
|
||||
$config['socket'] = $config['port'];
|
||||
$config['port'] = null;
|
||||
}
|
||||
|
||||
$this->connection = mysqli_connect($config['host'], $config['login'], $config['password'], $config['database'], $config['port'], $config['socket']);
|
||||
|
||||
if ($this->connection !== false) {
|
||||
$this->connected = true;
|
||||
}
|
||||
|
||||
$this->_useAlias = (bool)version_compare(mysqli_get_server_info($this->connection), "4.1", ">=");
|
||||
|
||||
if (!empty($config['encoding'])) {
|
||||
$this->setEncoding($config['encoding']);
|
||||
}
|
||||
return $this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that MySQLi is installed/enabled
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function enabled() {
|
||||
return extension_loaded('mysqli');
|
||||
}
|
||||
/**
|
||||
* Disconnects from database.
|
||||
*
|
||||
* @return boolean True if the database could be disconnected, else false
|
||||
*/
|
||||
function disconnect() {
|
||||
if (isset($this->results) && is_resource($this->results)) {
|
||||
mysqli_free_result($this->results);
|
||||
}
|
||||
$this->connected = !@mysqli_close($this->connection);
|
||||
return !$this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes given SQL statement.
|
||||
*
|
||||
* @param string $sql SQL statement
|
||||
* @return resource Result resource identifier
|
||||
*/
|
||||
protected function _execute($sql) {
|
||||
if (preg_match('/^\s*call/i', $sql)) {
|
||||
return $this->_executeProcedure($sql);
|
||||
}
|
||||
return mysqli_query($this->connection, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes given SQL statement (procedure call).
|
||||
*
|
||||
* @param string $sql SQL statement (procedure call)
|
||||
* @return resource Result resource identifier for first recordset
|
||||
*/
|
||||
protected function _executeProcedure($sql) {
|
||||
$answer = mysqli_multi_query($this->connection, $sql);
|
||||
|
||||
$firstResult = mysqli_store_result($this->connection);
|
||||
|
||||
if (mysqli_more_results($this->connection)) {
|
||||
while ($lastResult = mysqli_next_result($this->connection));
|
||||
}
|
||||
return $firstResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of sources (tables) in the database.
|
||||
*
|
||||
* @return array Array of tablenames in the database
|
||||
*/
|
||||
function listSources() {
|
||||
$cache = parent::listSources();
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
$result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
|
||||
|
||||
if (!$result) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$tables = array();
|
||||
|
||||
while ($line = mysqli_fetch_row($result)) {
|
||||
$tables[] = $line[0];
|
||||
}
|
||||
parent::listSources($tables);
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param string $column The column into which this data will be inserted
|
||||
* @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
|
||||
* @return string Quoted and escaped data
|
||||
*/
|
||||
function value($data, $column = null, $safe = false) {
|
||||
$parent = parent::value($data, $column, $safe);
|
||||
|
||||
if ($parent != null) {
|
||||
return $parent;
|
||||
}
|
||||
if ($data === null || (is_array($data) && empty($data))) {
|
||||
return 'NULL';
|
||||
}
|
||||
if ($data === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') {
|
||||
return "''";
|
||||
}
|
||||
if (empty($column)) {
|
||||
$column = $this->introspectType($data);
|
||||
}
|
||||
|
||||
switch ($column) {
|
||||
case 'boolean':
|
||||
return $this->boolean((bool)$data);
|
||||
break;
|
||||
case 'integer' :
|
||||
case 'float' :
|
||||
case null :
|
||||
if ($data === '') {
|
||||
return 'NULL';
|
||||
}
|
||||
if ((is_int($data) || is_float($data) || $data === '0') || (
|
||||
is_numeric($data) && strpos($data, ',') === false &&
|
||||
$data[0] != '0' && strpos($data, 'e') === false)) {
|
||||
return $data;
|
||||
}
|
||||
default:
|
||||
$data = "'" . mysqli_real_escape_string($this->connection, $data) . "'";
|
||||
break;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted error message from previous database operation.
|
||||
*
|
||||
* @return string Error message with error number
|
||||
*/
|
||||
function lastError() {
|
||||
if (mysqli_errno($this->connection)) {
|
||||
return mysqli_errno($this->connection).': '.mysqli_error($this->connection);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of affected rows in previous database operation. If no previous operation exists,
|
||||
* this returns false.
|
||||
*
|
||||
* @return integer Number of affected rows
|
||||
*/
|
||||
function lastAffected() {
|
||||
if ($this->_result) {
|
||||
return mysqli_affected_rows($this->connection);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of rows in previous resultset. If no previous resultset exists,
|
||||
* this returns false.
|
||||
*
|
||||
* @return integer Number of rows in resultset
|
||||
*/
|
||||
function lastNumRows() {
|
||||
if ($this->hasResult()) {
|
||||
return mysqli_num_rows($this->_result);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID generated from the previous INSERT operation.
|
||||
*
|
||||
* @param unknown_type $source
|
||||
* @return in
|
||||
*/
|
||||
function lastInsertId($source = null) {
|
||||
$id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
|
||||
if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
|
||||
return $id[0]['insertID'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param unknown_type $results
|
||||
*/
|
||||
function resultSet(&$results) {
|
||||
if (isset($this->results) && is_resource($this->results) && $this->results != $results) {
|
||||
mysqli_free_result($this->results);
|
||||
}
|
||||
$this->results =& $results;
|
||||
$this->map = array();
|
||||
$numFields = mysqli_num_fields($results);
|
||||
$index = 0;
|
||||
$j = 0;
|
||||
while ($j < $numFields) {
|
||||
$column = mysqli_fetch_field_direct($results, $j);
|
||||
if (!empty($column->table)) {
|
||||
$this->map[$index++] = array($column->table, $column->name);
|
||||
} else {
|
||||
$this->map[$index++] = array(0, $column->name);
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the next row from the current result set
|
||||
*
|
||||
* @return unknown
|
||||
*/
|
||||
function fetchResult() {
|
||||
if ($row = mysqli_fetch_row($this->results)) {
|
||||
$resultRow = array();
|
||||
foreach ($row as $index => $field) {
|
||||
$table = $column = null;
|
||||
if (count($this->map[$index]) === 2) {
|
||||
list($table, $column) = $this->map[$index];
|
||||
}
|
||||
$resultRow[$table][$column] = $row[$index];
|
||||
}
|
||||
return $resultRow;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database encoding
|
||||
*
|
||||
* @return string The database encoding
|
||||
*/
|
||||
function getEncoding() {
|
||||
return mysqli_client_encoding($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query charset by collation
|
||||
*
|
||||
* @param string $name Collation name
|
||||
* @return string Character set name
|
||||
*/
|
||||
function getCharsetName($name) {
|
||||
if ((bool)version_compare(mysqli_get_server_info($this->connection), "5", ">=")) {
|
||||
$cols = $this->query('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME= ' . $this->value($name) . ';');
|
||||
if (isset($cols[0]['COLLATIONS']['CHARACTER_SET_NAME'])) {
|
||||
return $cols[0]['COLLATIONS']['CHARACTER_SET_NAME'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the result is valid
|
||||
*
|
||||
* @return boolean True if the result is valid, else false
|
||||
*/
|
||||
function hasResult() {
|
||||
return is_object($this->_result);
|
||||
}
|
||||
}
|
|
@ -112,23 +112,29 @@ class DboPostgres extends DboSource {
|
|||
*/
|
||||
function connect() {
|
||||
$config = $this->config;
|
||||
$conn = "host='{$config['host']}' port='{$config['port']}' dbname='{$config['database']}' ";
|
||||
$conn .= "user='{$config['login']}' password='{$config['password']}'";
|
||||
|
||||
if (!$config['persistent']) {
|
||||
$this->connection = pg_connect($conn, PGSQL_CONNECT_FORCE_NEW);
|
||||
} else {
|
||||
$this->connection = pg_pconnect($conn);
|
||||
}
|
||||
$this->connected = false;
|
||||
try {
|
||||
$flags = array(
|
||||
PDO::ATTR_PERSISTENT => $config['persistent']
|
||||
);
|
||||
$this->_connection = new PDO(
|
||||
"pgsql:host={$config['host']};port={$config['port']};dbname={$config['database']}",
|
||||
$config['login'],
|
||||
$config['password'],
|
||||
$flags
|
||||
);
|
||||
|
||||
if ($this->connection) {
|
||||
$this->connected = true;
|
||||
$this->_execute("SET search_path TO " . $config['schema']);
|
||||
}
|
||||
if (!empty($config['encoding'])) {
|
||||
$this->setEncoding($config['encoding']);
|
||||
if (!empty($config['encoding'])) {
|
||||
$this->setEncoding($config['encoding']);
|
||||
}
|
||||
if (!empty($config['schema'])) {
|
||||
$this->_execute('SET search_path TO ' . $config['schema']);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$this->errors[] = $e->getMessage();
|
||||
}
|
||||
|
||||
return $this->connected;
|
||||
}
|
||||
|
||||
|
@ -138,33 +144,7 @@ class DboPostgres extends DboSource {
|
|||
* @return boolean
|
||||
*/
|
||||
function enabled() {
|
||||
return extension_loaded('pgsql');
|
||||
}
|
||||
/**
|
||||
* Disconnects from database.
|
||||
*
|
||||
* @return boolean True if the database could be disconnected, else false
|
||||
*/
|
||||
function disconnect() {
|
||||
if ($this->hasResult()) {
|
||||
pg_free_result($this->_result);
|
||||
}
|
||||
if (is_resource($this->connection)) {
|
||||
$this->connected = !pg_close($this->connection);
|
||||
} else {
|
||||
$this->connected = false;
|
||||
}
|
||||
return !$this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes given SQL statement.
|
||||
*
|
||||
* @param string $sql SQL statement
|
||||
* @return resource Result resource identifier
|
||||
*/
|
||||
function _execute($sql) {
|
||||
return pg_query($this->connection, $sql);
|
||||
return in_array('pgsql', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,18 +160,20 @@ class DboPostgres extends DboSource {
|
|||
}
|
||||
|
||||
$schema = $this->config['schema'];
|
||||
$sql = "SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE table_schema = '{$schema}';";
|
||||
$result = $this->fetchAll($sql, false);
|
||||
$sql = "SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE table_schema = ?";
|
||||
$result = $this->_execute($sql, array($schema));
|
||||
|
||||
if (!$result) {
|
||||
$result->closeCursor();
|
||||
return array();
|
||||
} else {
|
||||
$tables = array();
|
||||
|
||||
foreach ($result as $item) {
|
||||
$tables[] = $item[0]['name'];
|
||||
$tables[] = $item->name;
|
||||
}
|
||||
|
||||
$result->closeCursor();
|
||||
parent::listSources($tables);
|
||||
return $tables;
|
||||
}
|
||||
|
@ -209,61 +191,56 @@ class DboPostgres extends DboSource {
|
|||
$this->_sequenceMap[$table] = array();
|
||||
|
||||
if ($fields === null) {
|
||||
$cols = $this->fetchAll(
|
||||
$cols = $this->_execute(
|
||||
"SELECT DISTINCT column_name AS name, data_type AS type, is_nullable AS null,
|
||||
column_default AS default, ordinal_position AS position, character_maximum_length AS char_length,
|
||||
character_octet_length AS oct_length FROM information_schema.columns
|
||||
WHERE table_name = " . $this->value($table) . " AND table_schema = " .
|
||||
$this->value($this->config['schema'])." ORDER BY position",
|
||||
false
|
||||
WHERE table_name = ? AND table_schema = ? ORDER BY position",
|
||||
array($table, $this->config['schema'])
|
||||
);
|
||||
|
||||
foreach ($cols as $column) {
|
||||
$colKey = array_keys($column);
|
||||
|
||||
if (isset($column[$colKey[0]]) && !isset($column[0])) {
|
||||
$column[0] = $column[$colKey[0]];
|
||||
}
|
||||
|
||||
if (isset($column[0])) {
|
||||
$c = $column[0];
|
||||
|
||||
if (!empty($c['char_length'])) {
|
||||
$length = intval($c['char_length']);
|
||||
} elseif (!empty($c['oct_length'])) {
|
||||
if ($c['type'] == 'character varying') {
|
||||
$length = null;
|
||||
$c['type'] = 'text';
|
||||
} else {
|
||||
$length = intval($c['oct_length']);
|
||||
}
|
||||
foreach ($cols as $c) {
|
||||
$type = $c->type;
|
||||
if (!empty($c->oct_length) && $c->char_length === null) {
|
||||
if ($c->type == 'character varying') {
|
||||
$length = null;
|
||||
$type = 'text';
|
||||
} else {
|
||||
$length = $this->length($c['type']);
|
||||
$length = intval($c->oct_length);
|
||||
}
|
||||
$fields[$c['name']] = array(
|
||||
'type' => $this->column($c['type']),
|
||||
'null' => ($c['null'] == 'NO' ? false : true),
|
||||
'default' => preg_replace(
|
||||
"/^'(.*)'$/",
|
||||
"$1",
|
||||
preg_replace('/::.*/', '', $c['default'])
|
||||
),
|
||||
'length' => $length
|
||||
);
|
||||
if ($c['name'] == $model->primaryKey) {
|
||||
$fields[$c['name']]['key'] = 'primary';
|
||||
if ($fields[$c['name']]['type'] !== 'string') {
|
||||
$fields[$c['name']]['length'] = 11;
|
||||
} elseif (!empty($c->char_length)) {
|
||||
$length = intval($c->char_length);
|
||||
} else {
|
||||
$length = $this->length($c->type);
|
||||
}
|
||||
if (empty($length)) {
|
||||
$length = null;
|
||||
}
|
||||
$fields[$c->name] = array(
|
||||
'type' => $this->column($type),
|
||||
'null' => ($c->null == 'NO' ? false : true),
|
||||
'default' => preg_replace(
|
||||
"/^'(.*)'$/",
|
||||
"$1",
|
||||
preg_replace('/::.*/', '', $c->default)
|
||||
),
|
||||
'length' => $length
|
||||
);
|
||||
if ($model instanceof Model) {
|
||||
if ($c->name == $model->primaryKey) {
|
||||
$fields[$c->name]['key'] = 'primary';
|
||||
if ($fields[$c->name]['type'] !== 'string') {
|
||||
$fields[$c->name]['length'] = 11;
|
||||
}
|
||||
}
|
||||
if (
|
||||
$fields[$c['name']]['default'] == 'NULL' ||
|
||||
preg_match('/nextval\([\'"]?([\w.]+)/', $c['default'], $seq)
|
||||
) {
|
||||
$fields[$c['name']]['default'] = null;
|
||||
if (!empty($seq) && isset($seq[1])) {
|
||||
$this->_sequenceMap[$table][$c['name']] = $seq[1];
|
||||
}
|
||||
}
|
||||
if (
|
||||
$fields[$c->name]['default'] == 'NULL' ||
|
||||
preg_match('/nextval\([\'"]?([\w.]+)/', $c->default, $seq)
|
||||
) {
|
||||
$fields[$c->name]['default'] = null;
|
||||
if (!empty($seq) && isset($seq[1])) {
|
||||
$this->_sequenceMap[$table][$c->default] = $seq[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,93 +249,11 @@ class DboPostgres extends DboSource {
|
|||
if (isset($model->sequence)) {
|
||||
$this->_sequenceMap[$table][$model->primaryKey] = $model->sequence;
|
||||
}
|
||||
|
||||
$cols->closeCursor();
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param string $column The column into which this data will be inserted
|
||||
* @param boolean $read Value to be used in READ or WRITE context
|
||||
* @return string Quoted and escaped
|
||||
* @todo Add logic that formats/escapes data based on column type
|
||||
*/
|
||||
function value($data, $column = null, $read = true) {
|
||||
|
||||
$parent = parent::value($data, $column);
|
||||
if ($parent != null) {
|
||||
return $parent;
|
||||
}
|
||||
|
||||
if ($data === null || (is_array($data) && empty($data))) {
|
||||
return 'NULL';
|
||||
}
|
||||
if (empty($column)) {
|
||||
$column = $this->introspectType($data);
|
||||
}
|
||||
|
||||
switch($column) {
|
||||
case 'binary':
|
||||
$data = pg_escape_bytea($data);
|
||||
break;
|
||||
case 'boolean':
|
||||
if ($data === true || $data === 't' || $data === 'true') {
|
||||
return 'TRUE';
|
||||
} elseif ($data === false || $data === 'f' || $data === 'false') {
|
||||
return 'FALSE';
|
||||
}
|
||||
return (!empty($data) ? 'TRUE' : 'FALSE');
|
||||
break;
|
||||
case 'float':
|
||||
if (is_float($data)) {
|
||||
$data = sprintf('%F', $data);
|
||||
}
|
||||
case 'inet':
|
||||
case 'integer':
|
||||
case 'date':
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
case 'time':
|
||||
if ($data === '') {
|
||||
return $read ? 'NULL' : 'DEFAULT';
|
||||
}
|
||||
default:
|
||||
$data = pg_escape_string($data);
|
||||
break;
|
||||
}
|
||||
return "'" . $data . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted error message from previous database operation.
|
||||
*
|
||||
* @return string Error message
|
||||
*/
|
||||
function lastError() {
|
||||
$error = pg_last_error($this->connection);
|
||||
return ($error) ? $error : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
|
||||
*
|
||||
* @return integer Number of affected rows
|
||||
*/
|
||||
function lastAffected() {
|
||||
return ($this->_result) ? pg_affected_rows($this->_result) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of rows in previous resultset. If no previous resultset exists,
|
||||
* this returns false.
|
||||
*
|
||||
* @return integer Number of rows in resultset
|
||||
*/
|
||||
function lastNumRows() {
|
||||
return ($this->_result) ? pg_num_rows($this->_result) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID generated from the previous INSERT operation.
|
||||
*
|
||||
|
@ -368,8 +263,7 @@ class DboPostgres extends DboSource {
|
|||
*/
|
||||
function lastInsertId($source, $field = 'id') {
|
||||
$seq = $this->getSequence($source, $field);
|
||||
$data = $this->fetchRow("SELECT currval('{$seq}') as max");
|
||||
return $data[0]['max'];
|
||||
return $this->_connection->lastInsertId($seq);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -394,20 +288,22 @@ class DboPostgres extends DboSource {
|
|||
* Deletes all the records in a table and drops all associated auto-increment sequences
|
||||
*
|
||||
* @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,
|
||||
* @param boolean $reset true for resseting the sequence, false to leave it as is.
|
||||
* and if 1, sequences are not modified
|
||||
* @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
|
||||
*/
|
||||
public function truncate($table, $reset = 0) {
|
||||
public function truncate($table, $reset = true) {
|
||||
$table = $this->fullTableName($table, false);
|
||||
if (!isset($this->_sequenceMap[$table])) {
|
||||
$cache = $this->cacheSources;
|
||||
$this->cacheSources = false;
|
||||
$this->describe($table);
|
||||
$this->cacheSources = $cache;
|
||||
}
|
||||
if (parent::truncate($table)) {
|
||||
$table = $this->fullTableName($table, false);
|
||||
if (isset($this->_sequenceMap[$table]) && $reset !== 1) {
|
||||
if (isset($this->_sequenceMap[$table]) && $reset) {
|
||||
foreach ($this->_sequenceMap[$table] as $field => $sequence) {
|
||||
if ($reset === 0) {
|
||||
$this->execute("ALTER SEQUENCE \"{$sequence}\" RESTART WITH 1");
|
||||
} elseif ($reset === -1) {
|
||||
$this->execute("DROP SEQUENCE IF EXISTS \"{$sequence}\"");
|
||||
}
|
||||
$this->_execute("ALTER SEQUENCE \"{$sequence}\" RESTART WITH 1");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -447,7 +343,7 @@ class DboPostgres extends DboSource {
|
|||
}
|
||||
$count = count($fields);
|
||||
|
||||
if ($count >= 1 && strpos($fields[0], 'COUNT(*)') === false) {
|
||||
if ($count >= 1 && !preg_match('/^\s*COUNT\(\*/', $fields[0])) {
|
||||
$result = array();
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if (!preg_match('/^.+\\(.*\\)/', $fields[$i]) && !preg_match('/\s+AS\s+/', $fields[$i])) {
|
||||
|
@ -781,20 +677,18 @@ class DboPostgres extends DboSource {
|
|||
* @param unknown_type $results
|
||||
*/
|
||||
function resultSet(&$results) {
|
||||
$this->results =& $results;
|
||||
$this->map = array();
|
||||
$num_fields = pg_num_fields($results);
|
||||
$numFields = $results->columnCount();
|
||||
$index = 0;
|
||||
$j = 0;
|
||||
|
||||
while ($j < $num_fields) {
|
||||
$columnName = pg_field_name($results, $j);
|
||||
|
||||
if (strpos($columnName, '__')) {
|
||||
$parts = explode('__', $columnName);
|
||||
$this->map[$index++] = array($parts[0], $parts[1]);
|
||||
while ($j < $numFields) {
|
||||
$column = $results->getColumnMeta($j);
|
||||
if (strpos($column['name'], '__')) {
|
||||
list($table, $name) = explode('__', $column['name']);
|
||||
$this->map[$index++] = array($table, $name, $column['native_type']);
|
||||
} else {
|
||||
$this->map[$index++] = array(0, $columnName);
|
||||
$this->map[$index++] = array(0, $column['name'], $column['native_type']);
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
|
@ -806,12 +700,11 @@ class DboPostgres extends DboSource {
|
|||
* @return unknown
|
||||
*/
|
||||
function fetchResult() {
|
||||
if ($row = pg_fetch_row($this->results)) {
|
||||
if ($row = $this->_result->fetch()) {
|
||||
$resultRow = array();
|
||||
|
||||
foreach ($row as $index => $field) {
|
||||
list($table, $column) = $this->map[$index];
|
||||
$type = pg_field_type($this->results, $index);
|
||||
foreach ($this->map as $index => $meta) {
|
||||
list($table, $column, $type) = $meta;
|
||||
|
||||
switch ($type) {
|
||||
case 'bool':
|
||||
|
@ -819,7 +712,7 @@ class DboPostgres extends DboSource {
|
|||
break;
|
||||
case 'binary':
|
||||
case 'bytea':
|
||||
$resultRow[$table][$column] = pg_unescape_bytea($row[$index]);
|
||||
$resultRow[$table][$column] = stream_get_contents($row[$index]);
|
||||
break;
|
||||
default:
|
||||
$resultRow[$table][$column] = $row[$index];
|
||||
|
@ -828,6 +721,7 @@ class DboPostgres extends DboSource {
|
|||
}
|
||||
return $resultRow;
|
||||
} else {
|
||||
$this->_result->closeCursor();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -835,24 +729,33 @@ class DboPostgres extends DboSource {
|
|||
/**
|
||||
* Translates between PHP boolean values and PostgreSQL boolean values
|
||||
*
|
||||
* @param mixed $data Value to be translated
|
||||
* @param boolean $quote True to quote value, false otherwise
|
||||
* @return mixed Converted boolean value
|
||||
* @param mixed $data Value to be translated
|
||||
* @param boolean $quote true to quote a boolean to be used in a query, flase to return the boolean value
|
||||
* @return boolean Converted boolean value
|
||||
*/
|
||||
function boolean($data, $quote = true) {
|
||||
switch (true) {
|
||||
case ($data === true || $data === false):
|
||||
return $data;
|
||||
$result = $data;
|
||||
break;
|
||||
case ($data === 't' || $data === 'f'):
|
||||
return ($data === 't');
|
||||
$result = ($data === 't');
|
||||
break;
|
||||
case ($data === 'true' || $data === 'false'):
|
||||
return ($data === 'true');
|
||||
$result = ($data === 'true');
|
||||
break;
|
||||
case ($data === 'TRUE' || $data === 'FALSE'):
|
||||
return ($data === 'TRUE');
|
||||
$result = ($data === 'TRUE');
|
||||
break;
|
||||
default:
|
||||
return (bool)$data;
|
||||
$result = (bool) $data;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($quote) {
|
||||
return ($result) ? 'TRUE' : 'FALSE';
|
||||
}
|
||||
return (int) $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -862,7 +765,10 @@ class DboPostgres extends DboSource {
|
|||
* @return boolean True on success, false on failure
|
||||
*/
|
||||
function setEncoding($enc) {
|
||||
return pg_set_client_encoding($this->connection, $enc) == 0;
|
||||
if ($this->_execute('SET NAMES ?', array($enc))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -871,7 +777,7 @@ class DboPostgres extends DboSource {
|
|||
* @return string The database encoding
|
||||
*/
|
||||
function getEncoding() {
|
||||
return pg_client_encoding($this->connection);
|
||||
$cosa = $this->_execute('SHOW client_encoding')->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* DBO implementation for the SQLite DBMS.
|
||||
* DBO implementation for the SQLite3 DBMS.
|
||||
*
|
||||
* Long description for class
|
||||
* A DboSource adapter for SQLite 3 using PDO
|
||||
*
|
||||
* @package cake
|
||||
* @package datasources
|
||||
* @subpackage cake.cake.libs.model.datasources.dbo
|
||||
*/
|
||||
class DboSqlite extends DboSource {
|
||||
|
@ -32,63 +32,48 @@ class DboSqlite extends DboSource {
|
|||
* Datasource Description
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $description = "SQLite DBO Driver";
|
||||
var $description = "SQLite DBO Driver";
|
||||
|
||||
/**
|
||||
* Opening quote for quoted identifiers
|
||||
* Quote Start
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $startQuote = '"';
|
||||
var $startQuote = '"';
|
||||
|
||||
/**
|
||||
* Closing quote for quoted identifiers
|
||||
* Quote End
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $endQuote = '"';
|
||||
var $endQuote = '"';
|
||||
|
||||
/**
|
||||
* Keeps the transaction statistics of CREATE/UPDATE/DELETE queries
|
||||
* Base configuration settings for SQLite3 driver
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
* @access public
|
||||
*/
|
||||
protected $_queryStats = array();
|
||||
|
||||
/**
|
||||
* Base configuration settings for SQLite driver
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_baseConfig = array(
|
||||
'persistent' => true,
|
||||
var $_baseConfig = array(
|
||||
'persistent' => false,
|
||||
'database' => null
|
||||
);
|
||||
|
||||
/**
|
||||
* Index of basic SQL commands
|
||||
* SQLite3 column definition
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
* @access public
|
||||
*/
|
||||
protected $_commands = array(
|
||||
'begin' => 'BEGIN TRANSACTION',
|
||||
'commit' => 'COMMIT TRANSACTION',
|
||||
'rollback' => 'ROLLBACK TRANSACTION'
|
||||
);
|
||||
|
||||
/**
|
||||
* SQLite column definition
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $columns = array(
|
||||
'primary_key' => array('name' => 'integer primary key'),
|
||||
var $columns = array(
|
||||
'primary_key' => array('name' => 'integer primary key autoincrement'),
|
||||
'string' => array('name' => 'varchar', 'limit' => '255'),
|
||||
'text' => array('name' => 'text'),
|
||||
'integer' => array('name' => 'integer', 'limit' => 11, 'formatter' => 'intval'),
|
||||
'integer' => array('name' => 'integer', 'limit' => null, 'formatter' => 'intval'),
|
||||
'float' => array('name' => 'float', 'formatter' => 'floatval'),
|
||||
'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
|
||||
'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
|
||||
|
@ -104,12 +89,12 @@ class DboSqlite extends DboSource {
|
|||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $fieldParameters = array(
|
||||
var $fieldParameters = array(
|
||||
'collate' => array(
|
||||
'value' => 'COLLATE',
|
||||
'quote' => false,
|
||||
'join' => ' ',
|
||||
'column' => 'Collate',
|
||||
'join' => ' ',
|
||||
'column' => 'Collate',
|
||||
'position' => 'afterDefault',
|
||||
'options' => array(
|
||||
'BINARY', 'NOCASE', 'RTRIM'
|
||||
|
@ -122,83 +107,46 @@ class DboSqlite extends DboSource {
|
|||
*
|
||||
* @param array $config Configuration array for connecting
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function connect() {
|
||||
$config = $this->config;
|
||||
if (!$config['persistent']) {
|
||||
$this->connection = sqlite_open($config['database']);
|
||||
} else {
|
||||
$this->connection = sqlite_popen($config['database']);
|
||||
$flags = array(PDO::ATTR_PERSISTENT => $config['persistent']);
|
||||
try {
|
||||
$this->_connection = new PDO('sqlite:' . $config['database'], null, null, $flags);
|
||||
$this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->connected = true;
|
||||
}
|
||||
$this->connected = is_resource($this->connection);
|
||||
|
||||
if ($this->connected) {
|
||||
$this->_execute('PRAGMA count_changes = 1;');
|
||||
catch(PDOException $e) {
|
||||
$this->errors[] = $e->getMessage();
|
||||
}
|
||||
return $this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that SQLite is enabled/installed
|
||||
* Check whether the MySQL extension is installed/loaded
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function enabled() {
|
||||
return extension_loaded('sqlite');
|
||||
}
|
||||
/**
|
||||
* Disconnects from database.
|
||||
*
|
||||
* @return boolean True if the database could be disconnected, else false
|
||||
*/
|
||||
function disconnect() {
|
||||
@sqlite_close($this->connection);
|
||||
$this->connected = false;
|
||||
return $this->connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes given SQL statement.
|
||||
*
|
||||
* @param string $sql SQL statement
|
||||
* @return resource Result resource identifier
|
||||
*/
|
||||
function _execute($sql) {
|
||||
$result = sqlite_query($this->connection, $sql);
|
||||
|
||||
if (preg_match('/^(INSERT|UPDATE|DELETE)/', $sql)) {
|
||||
$this->resultSet($result);
|
||||
list($this->_queryStats) = $this->fetchResult();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides DboSource::execute() to correctly handle query statistics
|
||||
*
|
||||
* @param string $sql
|
||||
* @return unknown
|
||||
*/
|
||||
function execute($sql) {
|
||||
$result = parent::execute($sql);
|
||||
$this->_queryStats = array();
|
||||
return $result;
|
||||
return in_array('sqlite', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
|
||||
*
|
||||
* @return array Array of tablenames in the database
|
||||
* @access public
|
||||
*/
|
||||
function listSources() {
|
||||
$cache = parent::listSources();
|
||||
|
||||
if ($cache != null) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$result = $this->fetchAll("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;", false);
|
||||
|
||||
if (empty($result)) {
|
||||
if (!$result || empty($result)) {
|
||||
return array();
|
||||
} else {
|
||||
$tables = array();
|
||||
|
@ -216,6 +164,7 @@ class DboSqlite extends DboSource {
|
|||
*
|
||||
* @param string $tableName Name of database table to inspect
|
||||
* @return array Fields in table. Keys are name and type
|
||||
* @access public
|
||||
*/
|
||||
function describe(&$model) {
|
||||
$cache = parent::describe($model);
|
||||
|
@ -223,65 +172,32 @@ class DboSqlite extends DboSource {
|
|||
return $cache;
|
||||
}
|
||||
$fields = array();
|
||||
$result = $this->fetchAll('PRAGMA table_info(' . $this->fullTableName($model) . ')');
|
||||
$result = $this->_execute('PRAGMA table_info(' . $model->tablePrefix . $model->table . ')');
|
||||
|
||||
foreach ($result as $column) {
|
||||
$fields[$column[0]['name']] = array(
|
||||
'type' => $this->column($column[0]['type']),
|
||||
'null' => !$column[0]['notnull'],
|
||||
'default' => $column[0]['dflt_value'],
|
||||
'length' => $this->length($column[0]['type'])
|
||||
$column = (array) $column;
|
||||
$default = ($column['dflt_value'] === 'NULL') ? null : trim($column['dflt_value'], "'");
|
||||
|
||||
$fields[$column['name']] = array(
|
||||
'type' => $this->column($column['type']),
|
||||
'null' => !$column['notnull'],
|
||||
'default' => $default,
|
||||
'length' => $this->length($column['type'])
|
||||
);
|
||||
if ($column[0]['pk'] == 1) {
|
||||
$colLength = $this->length($column[0]['type']);
|
||||
$fields[$column[0]['name']] = array(
|
||||
'type' => $fields[$column[0]['name']]['type'],
|
||||
'null' => false,
|
||||
'default' => $column[0]['dflt_value'],
|
||||
'key' => $this->index['PRI'],
|
||||
'length'=> ($colLength != null) ? $colLength : 11
|
||||
);
|
||||
if ($column['pk'] == 1) {
|
||||
$fields[$column['name']]['key'] = $this->index['PRI'];
|
||||
$fields[$column['name']]['null'] = false;
|
||||
if (empty($fields[$column['name']]['length'])) {
|
||||
$fields[$column['name']]['length'] = 11;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result->closeCursor();
|
||||
$this->__cacheDescription($model->tablePrefix . $model->table, $fields);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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 === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') {
|
||||
return "''";
|
||||
}
|
||||
switch ($column) {
|
||||
case 'boolean':
|
||||
$data = $this->boolean((bool)$data);
|
||||
break;
|
||||
case 'integer':
|
||||
case 'float':
|
||||
if ($data === '') {
|
||||
return 'NULL';
|
||||
}
|
||||
default:
|
||||
$data = sqlite_escape_string($data);
|
||||
break;
|
||||
}
|
||||
return "'" . $data . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and executes an SQL UPDATE statement for given model, fields, and values.
|
||||
*
|
||||
|
@ -290,6 +206,7 @@ class DboSqlite extends DboSource {
|
|||
* @param array $values
|
||||
* @param mixed $conditions
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function update(&$model, $fields = array(), $values = null, $conditions = null) {
|
||||
if (empty($values) && !empty($fields)) {
|
||||
|
@ -302,8 +219,7 @@ class DboSqlite extends DboSource {
|
|||
}
|
||||
}
|
||||
}
|
||||
$result = parent::update($model, $fields, $values, $conditions);
|
||||
return $result;
|
||||
return parent::update($model, $fields, $values, $conditions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -312,60 +228,11 @@ class DboSqlite extends DboSource {
|
|||
*
|
||||
* @param mixed $table A string or model class representing the table to be truncated
|
||||
* @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
|
||||
* @access public
|
||||
*/
|
||||
public function truncate($table) {
|
||||
return $this->execute('DELETE From ' . $this->fullTableName($table));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted error message from previous database operation.
|
||||
*
|
||||
* @return string Error message
|
||||
*/
|
||||
function lastError() {
|
||||
$error = sqlite_last_error($this->connection);
|
||||
if ($error) {
|
||||
return $error.': '.sqlite_error_string($error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
|
||||
*
|
||||
* @return integer Number of affected rows
|
||||
*/
|
||||
function lastAffected() {
|
||||
if (!empty($this->_queryStats)) {
|
||||
foreach (array('rows inserted', 'rows updated', 'rows deleted') as $key) {
|
||||
if (array_key_exists($key, $this->_queryStats)) {
|
||||
return $this->_queryStats[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of rows in previous resultset. If no previous resultset exists,
|
||||
* this returns false.
|
||||
*
|
||||
* @return integer Number of rows in resultset
|
||||
*/
|
||||
function lastNumRows() {
|
||||
if ($this->hasResult()) {
|
||||
sqlite_num_rows($this->_result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID generated from the previous INSERT operation.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function lastInsertId() {
|
||||
return sqlite_last_insert_rowid($this->connection);
|
||||
function truncate($table) {
|
||||
$this->_execute('DELETE FROM sqlite_sequence where name=' . $this->fullTableName($table));
|
||||
return $this->execute('DELETE FROM ' . $this->fullTableName($table));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -373,6 +240,7 @@ class DboSqlite extends DboSource {
|
|||
*
|
||||
* @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)) {
|
||||
|
@ -385,9 +253,7 @@ class DboSqlite extends DboSource {
|
|||
|
||||
$col = strtolower(str_replace(')', '', $real));
|
||||
$limit = null;
|
||||
if (strpos($col, '(') !== false) {
|
||||
list($col, $limit) = explode('(', $col);
|
||||
}
|
||||
@list($col, $limit) = explode('(', $col);
|
||||
|
||||
if (in_array($col, array('text', 'integer', 'float', 'boolean', 'timestamp', 'date', 'datetime', 'time'))) {
|
||||
return $col;
|
||||
|
@ -398,29 +264,55 @@ class DboSqlite extends DboSource {
|
|||
if (in_array($col, array('blob', 'clob'))) {
|
||||
return 'binary';
|
||||
}
|
||||
if (strpos($col, 'numeric') !== false) {
|
||||
if (strpos($col, 'numeric') !== false || strpos($col, 'decimal') !== false) {
|
||||
return 'float';
|
||||
}
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
* Generate ResultSet
|
||||
*
|
||||
* @param unknown_type $results
|
||||
* @param mixed $results
|
||||
* @access public
|
||||
*/
|
||||
function resultSet(&$results) {
|
||||
$this->results =& $results;
|
||||
function resultSet($results) {
|
||||
$this->results = $results;
|
||||
$this->map = array();
|
||||
$fieldCount = sqlite_num_fields($results);
|
||||
$index = $j = 0;
|
||||
$num_fields = $results->columnCount();
|
||||
$index = 0;
|
||||
$j = 0;
|
||||
|
||||
while ($j < $fieldCount) {
|
||||
$columnName = str_replace('"', '', sqlite_field_name($results, $j));
|
||||
//PDO::getColumnMeta is experimental and does not work with sqlite3,
|
||||
// so try to figure it out based on the querystring
|
||||
$querystring = $results->queryString;
|
||||
if (stripos($querystring, 'SELECT') === 0) {
|
||||
$last = stripos($querystring, 'FROM');
|
||||
if ($last !== false) {
|
||||
$selectpart = substr($querystring, 7, $last - 8);
|
||||
$selects = explode(',', $selectpart);
|
||||
}
|
||||
} elseif (strpos($querystring, 'PRAGMA table_info') === 0) {
|
||||
$selects = array('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk');
|
||||
} elseif(strpos($querystring, 'PRAGMA index_list') === 0) {
|
||||
$selects = array('seq', 'name', 'unique');
|
||||
} elseif(strpos($querystring, 'PRAGMA index_info') === 0) {
|
||||
$selects = array('seqno', 'cid', 'name');
|
||||
}
|
||||
while ($j < $num_fields) {
|
||||
if (preg_match('/\bAS\s+(.*)/i', $selects[$j], $matches)) {
|
||||
$columnName = trim($matches[1],'"');
|
||||
} else {
|
||||
$columnName = trim(str_replace('"', '', $selects[$j]));
|
||||
}
|
||||
|
||||
if (strpos($selects[$j], 'DISTINCT') === 0) {
|
||||
$columnName = str_ireplace('DISTINCT', '', $columnName);
|
||||
}
|
||||
|
||||
if (strpos($columnName, '.')) {
|
||||
$parts = explode('.', $columnName);
|
||||
$this->map[$index++] = array($parts[0], $parts[1]);
|
||||
$this->map[$index++] = array(trim($parts[0]), trim($parts[1]));
|
||||
} else {
|
||||
$this->map[$index++] = array(0, $columnName);
|
||||
}
|
||||
|
@ -431,34 +323,30 @@ class DboSqlite extends DboSource {
|
|||
/**
|
||||
* Fetches the next row from the current result set
|
||||
*
|
||||
* @return unknown
|
||||
* @return mixed array with results fetched and mapped to column names or false if there is no results left to fetch
|
||||
*/
|
||||
function fetchResult() {
|
||||
if ($row = sqlite_fetch_array($this->results, SQLITE_ASSOC)) {
|
||||
if ($row = $this->_result->fetch()) {
|
||||
$resultRow = array();
|
||||
$i = 0;
|
||||
|
||||
foreach ($row as $index => $field) {
|
||||
if (strpos($index, '.')) {
|
||||
list($table, $column) = explode('.', str_replace('"', '', $index));
|
||||
$resultRow[$table][$column] = $row[$index];
|
||||
} else {
|
||||
$resultRow[0][str_replace('"', '', $index)] = $row[$index];
|
||||
}
|
||||
$i++;
|
||||
foreach ($this->map as $col => $meta) {
|
||||
list($table, $column) = $meta;
|
||||
$resultRow[$table][$column] = $row[$col];
|
||||
}
|
||||
return $resultRow;
|
||||
} else {
|
||||
$this->_result->closeCursor();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a limit statement in the correct format for the particular database.
|
||||
*
|
||||
* @param integer $limit Limit of results returned
|
||||
* @param integer $offset Offset from which to start results
|
||||
* @return string SQL limit/offset statement
|
||||
* @access public
|
||||
*/
|
||||
function limit($limit, $offset = null) {
|
||||
if ($limit) {
|
||||
|
@ -479,8 +367,9 @@ class DboSqlite extends DboSource {
|
|||
* Generate a database-native column schema string
|
||||
*
|
||||
* @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
|
||||
* where options can be 'default', 'length', or 'key'.
|
||||
* where options can be 'default', 'length', or 'key'.
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function buildColumn($column) {
|
||||
$name = $type = null;
|
||||
|
@ -488,12 +377,12 @@ class DboSqlite extends DboSource {
|
|||
extract($column);
|
||||
|
||||
if (empty($name) || empty($type)) {
|
||||
trigger_error(__('Column name or type not defined in schema'), E_USER_WARNING);
|
||||
trigger_error('Column name or type not defined in schema', E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isset($this->columns[$type])) {
|
||||
trigger_error(sprintf(__('Column type %s does not exist'), $type), E_USER_WARNING);
|
||||
trigger_error("Column type {$type} does not exist", E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -509,6 +398,7 @@ class DboSqlite extends DboSource {
|
|||
* Sets the database encoding
|
||||
*
|
||||
* @param string $enc Database encoding
|
||||
* @access public
|
||||
*/
|
||||
function setEncoding($enc) {
|
||||
if (!in_array($enc, array("UTF-8", "UTF-16", "UTF-16le", "UTF-16be"))) {
|
||||
|
@ -521,6 +411,7 @@ class DboSqlite extends DboSource {
|
|||
* Gets the database encoding
|
||||
*
|
||||
* @return string The database encoding
|
||||
* @access public
|
||||
*/
|
||||
function getEncoding() {
|
||||
return $this->fetchRow('PRAGMA encoding');
|
||||
|
@ -532,6 +423,7 @@ class DboSqlite extends DboSource {
|
|||
* @param array $indexes
|
||||
* @param string $table
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function buildIndex($indexes, $table = null) {
|
||||
$join = array();
|
||||
|
@ -547,11 +439,12 @@ class DboSqlite extends DboSource {
|
|||
$out .= 'UNIQUE ';
|
||||
}
|
||||
if (is_array($value['column'])) {
|
||||
$value['column'] = implode(', ', array_map(array(&$this, 'name'), $value['column']));
|
||||
$value['column'] = join(', ', array_map(array(&$this, 'name'), $value['column']));
|
||||
} else {
|
||||
$value['column'] = $this->name($value['column']);
|
||||
}
|
||||
$out .= "INDEX {$name} ON {$table}({$value['column']});";
|
||||
$t = trim($table, '"');
|
||||
$out .= "INDEX {$t}_{$name} ON {$table}({$value['column']});";
|
||||
$join[] = $out;
|
||||
}
|
||||
return $join;
|
||||
|
@ -563,13 +456,17 @@ class DboSqlite extends DboSource {
|
|||
*
|
||||
* @param string $model Name of model to inspect
|
||||
* @return array Fields in table. Keys are column and unique
|
||||
* @access public
|
||||
*/
|
||||
function index(&$model) {
|
||||
$index = array();
|
||||
$table = $this->fullTableName($model);
|
||||
if ($table) {
|
||||
$indexes = $this->query('PRAGMA index_list(' . $table . ')');
|
||||
$tableInfo = $this->query('PRAGMA table_info(' . $table . ')');
|
||||
|
||||
if (is_bool($indexes)) {
|
||||
return array();
|
||||
}
|
||||
foreach ($indexes as $i => $info) {
|
||||
$key = array_pop($info);
|
||||
$keyInfo = $this->query('PRAGMA index_info("' . $key['name'] . '")');
|
||||
|
@ -600,16 +497,17 @@ class DboSqlite extends DboSource {
|
|||
* @param string $type
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function renderStatement($type, $data) {
|
||||
switch (strtolower($type)) {
|
||||
case 'schema':
|
||||
extract($data);
|
||||
|
||||
foreach (array('columns', 'indexes') as $var) {
|
||||
if (is_array(${$var})) {
|
||||
${$var} = "\t" . implode(",\n\t", array_filter(${$var}));
|
||||
}
|
||||
if (is_array($columns)) {
|
||||
$columns = "\t" . join(",\n\t", array_filter($columns));
|
||||
}
|
||||
if (is_array($indexes)) {
|
||||
$indexes = "\t" . join("\n\t", array_filter($indexes));
|
||||
}
|
||||
return "CREATE TABLE {$table} (\n{$columns});\n{$indexes}";
|
||||
break;
|
||||
|
@ -618,4 +516,32 @@ class DboSqlite extends DboSource {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PDO deals in objects, not resources, so overload accordingly.
|
||||
*
|
||||
* @return boolean
|
||||
* @access public
|
||||
*/
|
||||
function hasResult() {
|
||||
return is_object($this->_result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a "drop table" statement for the given Schema object
|
||||
*
|
||||
* @param object $schema An instance of a subclass of CakeSchema
|
||||
* @param string $table Optional. If specified only the table name given will be generated.
|
||||
* Otherwise, all tables defined in the schema are generated.
|
||||
* @return string
|
||||
*/
|
||||
public function dropSchema(CakeSchema $schema, $table = null) {
|
||||
$out = '';
|
||||
foreach ($schema->tables as $curTable => $columns) {
|
||||
if (!$table || $table == $curTable) {
|
||||
$out .= 'DROP TABLE IF EXISTS ' . $this->fullTableName($curTable) . ";\n";
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
|
@ -44,8 +44,6 @@ class AclShellTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
Configure::write('Acl.database', 'test');
|
||||
Configure::write('Acl.classname', 'DbAcl');
|
||||
|
||||
|
@ -59,7 +57,6 @@ class AclShellTest extends CakeTestCase {
|
|||
);
|
||||
$collection = new ComponentCollection();
|
||||
$this->Task->Acl = new AclComponent($collection);
|
||||
|
||||
$this->Task->params['datasource'] = 'test';
|
||||
}
|
||||
|
||||
|
@ -206,8 +203,9 @@ class AclShellTest extends CakeTestCase {
|
|||
$this->Task->expects($this->at(0))->method('out')
|
||||
->with($this->matchesRegularExpression('/granted/'), true);
|
||||
$this->Task->grant();
|
||||
$node = $this->Task->Acl->Aro->node(array('model' => 'AuthUser', 'foreign_key' => 2));
|
||||
$node = $this->Task->Acl->Aro->read(null, $node[0]['Aro']['id']);
|
||||
|
||||
$node = $this->Task->Acl->Aro->read(null, 4);
|
||||
$this->assertFalse(empty($node['Aco'][0]));
|
||||
$this->assertEqual($node['Aco'][0]['Permission']['_create'], 1);
|
||||
}
|
||||
|
@ -224,7 +222,8 @@ class AclShellTest extends CakeTestCase {
|
|||
|
||||
$this->Task->deny();
|
||||
|
||||
$node = $this->Task->Acl->Aro->read(null, 4);
|
||||
$node = $this->Task->Acl->Aro->node(array('model' => 'AuthUser', 'foreign_key' => 2));
|
||||
$node = $this->Task->Acl->Aro->read(null, $node[0]['Aro']['id']);
|
||||
$this->assertFalse(empty($node['Aco'][0]));
|
||||
$this->assertEqual($node['Aco'][0]['Permission']['_create'], -1);
|
||||
}
|
||||
|
@ -274,7 +273,8 @@ class AclShellTest extends CakeTestCase {
|
|||
$this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'all');
|
||||
$this->Task->inherit();
|
||||
|
||||
$node = $this->Task->Acl->Aro->read(null, 4);
|
||||
$node = $this->Task->Acl->Aro->node(array('model' => 'AuthUser', 'foreign_key' => 2));
|
||||
$node = $this->Task->Acl->Aro->read(null, $node[0]['Aro']['id']);
|
||||
$this->assertFalse(empty($node['Aco'][0]));
|
||||
$this->assertEqual($node['Aco'][0]['Permission']['_create'], 0);
|
||||
}
|
||||
|
@ -286,9 +286,13 @@ class AclShellTest extends CakeTestCase {
|
|||
*/
|
||||
public function testGetPath() {
|
||||
$this->Task->args = array('aro', 'AuthUser.2');
|
||||
$this->Task->expects($this->at(2))->method('out')->with('[1] ROOT');
|
||||
$this->Task->expects($this->at(3))->method('out')->with(' [2] admins');
|
||||
$this->Task->expects($this->at(4))->method('out')->with(' [4] Elrond');
|
||||
$node = $this->Task->Acl->Aro->node(array('model' => 'AuthUser', 'foreign_key' => 2));
|
||||
$first = $node[0]['Aro']['id'];
|
||||
$second = $node[1]['Aro']['id'];
|
||||
$last = $node[2]['Aro']['id'];
|
||||
$this->Task->expects($this->at(2))->method('out')->with('['.$last.'] ROOT');
|
||||
$this->Task->expects($this->at(3))->method('out')->with(' ['.$second.'] admins');
|
||||
$this->Task->expects($this->at(4))->method('out')->with(' ['.$first.'] Elrond');
|
||||
$this->Task->getPath();
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ class BakeShellTest extends CakeTestCase {
|
|||
|
||||
$this->Shell->expects($this->at(1))->method('out')->with('Bake All');
|
||||
$this->Shell->expects($this->at(3))->method('out')->with('User Model was baked.');
|
||||
$this->Shell->expects($this->at(5))->method('out')->with('User Controller was baked.');
|
||||
$this->Shell->expects($this->at(5))->method('out')->with('<success>Bake All complete</success>');
|
||||
$this->Shell->expects($this->at(7))->method('out')->with('User Views were baked.');
|
||||
$this->Shell->expects($this->at(8))->method('out')->with('Bake All complete');
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ class SchemaShellTest extends CakeTestCase {
|
|||
$this->file = new File(TMP . 'tests' . DS . 'i18n.sql');
|
||||
$contents = $this->file->read();
|
||||
$this->assertPattern('/DROP TABLE/', $contents);
|
||||
$this->assertPattern('/CREATE TABLE `i18n`/', $contents);
|
||||
$this->assertPattern('/CREATE TABLE.*?i18n/', $contents);
|
||||
$this->assertPattern('/id/', $contents);
|
||||
$this->assertPattern('/model/', $contents);
|
||||
$this->assertPattern('/field/', $contents);
|
||||
|
@ -253,7 +253,7 @@ class SchemaShellTest extends CakeTestCase {
|
|||
$this->file = new File(TMP . 'tests' . DS . 'dump_test.sql');
|
||||
$contents = $this->file->read();
|
||||
|
||||
$this->assertPattern('/CREATE TABLE `test_plugin_acos`/', $contents);
|
||||
$this->assertPattern('/CREATE TABLE.*?test_plugin_acos/', $contents);
|
||||
$this->assertPattern('/id/', $contents);
|
||||
$this->assertPattern('/model/', $contents);
|
||||
|
||||
|
@ -339,6 +339,7 @@ class SchemaShellTest extends CakeTestCase {
|
|||
), true);
|
||||
App::objects('plugin', null, false);
|
||||
|
||||
$this->db->cacheSources = false;
|
||||
$this->Shell->params = array(
|
||||
'plugin' => 'TestPlugin',
|
||||
'connection' => 'test'
|
||||
|
@ -366,8 +367,7 @@ class SchemaShellTest extends CakeTestCase {
|
|||
*/
|
||||
public function testCreateNoArgs() {
|
||||
$this->Shell->params = array(
|
||||
'connection' => 'test',
|
||||
'path' => APP . 'config' . DS . 'sql'
|
||||
'connection' => 'test'
|
||||
);
|
||||
$this->Shell->args = array('i18n');
|
||||
$this->Shell->startup();
|
||||
|
@ -375,6 +375,8 @@ class SchemaShellTest extends CakeTestCase {
|
|||
$this->Shell->create();
|
||||
|
||||
$db = ConnectionManager::getDataSource('test');
|
||||
|
||||
$db->cacheSources = false;
|
||||
$sources = $db->listSources();
|
||||
$this->assertTrue(in_array($db->config['prefix'] . 'i18n', $sources));
|
||||
|
||||
|
@ -396,7 +398,7 @@ class SchemaShellTest extends CakeTestCase {
|
|||
$this->Shell->params = array(
|
||||
'connection' => 'test',
|
||||
'name' => 'DbAcl',
|
||||
'path' => APP . 'config' . DS . 'schema'
|
||||
'path' => CONFIGS . 'schema'
|
||||
);
|
||||
$this->Shell->args = array('DbAcl', 'acos');
|
||||
$this->Shell->startup();
|
||||
|
@ -404,6 +406,7 @@ class SchemaShellTest extends CakeTestCase {
|
|||
$this->Shell->create();
|
||||
|
||||
$db = ConnectionManager::getDataSource('test');
|
||||
$db->cacheSources = false;
|
||||
$sources = $db->listSources();
|
||||
$this->assertTrue(in_array($db->config['prefix'] . 'acos', $sources), 'acos should be present.');
|
||||
$this->assertFalse(in_array($db->config['prefix'] . 'aros', $sources), 'aros should not be found.');
|
||||
|
|
|
@ -37,8 +37,15 @@ class AllDatabaseTest extends PHPUnit_Framework_TestSuite {
|
|||
$suite = new PHPUnit_Framework_TestSuite('Datasources, Schema and DbAcl tests');
|
||||
|
||||
$path = CORE_TEST_CASES . DS . 'libs' . DS . 'model' . DS;
|
||||
|
||||
$tasks = array('db_acl', 'cake_schema', 'connection_manager', 'datasources' . DS . 'dbo_source');
|
||||
$tasks = array(
|
||||
'db_acl',
|
||||
'cake_schema',
|
||||
'connection_manager',
|
||||
'datasources' . DS . 'dbo_source',
|
||||
'datasources' . DS . 'dbo' . DS . 'dbo_mysql',
|
||||
'datasources' . DS . 'dbo' . DS . 'dbo_postgres',
|
||||
'datasources' . DS . 'dbo' . DS . 'dbo_sqlite'
|
||||
);
|
||||
foreach ($tasks as $task) {
|
||||
$suite->addTestFile($path . $task . '.test.php');
|
||||
}
|
||||
|
|
|
@ -546,6 +546,7 @@ class BehaviorCollectionTest extends CakeTestCase {
|
|||
*/
|
||||
function testBehaviorToggling() {
|
||||
$Apple = new Apple();
|
||||
$expected = $Apple->find('all');
|
||||
$this->assertIdentical($Apple->Behaviors->enabled(), array());
|
||||
|
||||
$Apple->Behaviors->init('Apple', array('Test' => array('key' => 'value')));
|
||||
|
|
|
@ -185,6 +185,7 @@ class TranslateBehaviorTest extends CakeTestCase {
|
|||
|
||||
$TestModel = new TranslatedItem();
|
||||
$TestModel->locale = 'eng';
|
||||
|
||||
$result = $TestModel->read(null, 1);
|
||||
$expected = array(
|
||||
'TranslatedItem' => array(
|
||||
|
@ -313,17 +314,17 @@ class TranslateBehaviorTest extends CakeTestCase {
|
|||
$result = $TestModel->find('all', array('fields' => array('TranslatedItem.title')));
|
||||
$expected = array(
|
||||
array(
|
||||
'TranslatedItem' => array('id' => 1, 'locale' => 'eng', 'title' => 'Title #1'),
|
||||
'TranslatedItem' => array('id' => 1, 'locale' => 'eng', 'title' => 'Title #1', 'slug' => 'first_translated'),
|
||||
'Title' => array(array('foreign_key' => 1, 'content' => 'Title #1')),
|
||||
'Content' => array(array('foreign_key' => 1, 'content' => 'Content #1'))
|
||||
),
|
||||
array(
|
||||
'TranslatedItem' => array('id' => 2, 'locale' => 'eng', 'title' => 'Title #2'),
|
||||
'TranslatedItem' => array('id' => 2, 'locale' => 'eng', 'title' => 'Title #2', 'slug' => 'second_translated'),
|
||||
'Title' => array(array('foreign_key' => 2, 'content' => 'Title #2')),
|
||||
'Content' => array(array('foreign_key' => 2, 'content' => 'Content #2'))
|
||||
),
|
||||
array(
|
||||
'TranslatedItem' => array('id' => 3, 'locale' => 'eng', 'title' => 'Title #3'),
|
||||
'TranslatedItem' => array('id' => 3, 'locale' => 'eng', 'title' => 'Title #3','slug' => 'third_translated'),
|
||||
'Title' => array(array('foreign_key' => 3, 'content' => 'Title #3')),
|
||||
'Content' => array(array('foreign_key' => 3, 'content' => 'Content #3'))
|
||||
)
|
||||
|
@ -342,16 +343,7 @@ class TranslateBehaviorTest extends CakeTestCase {
|
|||
|
||||
$TestModel = new TranslatedItem();
|
||||
$TestModel->locale = array('deu', 'eng', 'cze');
|
||||
$delete = array(
|
||||
array('locale' => 'deu'),
|
||||
array('foreign_key' => 1, 'field' => 'title', 'locale' => 'eng'),
|
||||
array('foreign_key' => 1, 'field' => 'content', 'locale' => 'cze'),
|
||||
array('foreign_key' => 2, 'field' => 'title', 'locale' => 'cze'),
|
||||
array('foreign_key' => 2, 'field' => 'content', 'locale' => 'eng'),
|
||||
array('foreign_key' => 3, 'field' => 'title')
|
||||
);
|
||||
$I18nModel = ClassRegistry::getObject('TranslateTestModel');
|
||||
$I18nModel->deleteAll(array('or' => $delete));
|
||||
|
||||
|
||||
$result = $TestModel->read(null, 1);
|
||||
$expected = array(
|
||||
|
@ -359,8 +351,8 @@ class TranslateBehaviorTest extends CakeTestCase {
|
|||
'id' => 1,
|
||||
'slug' => 'first_translated',
|
||||
'locale' => 'deu',
|
||||
'title' => 'Titulek #1',
|
||||
'content' => 'Content #1'
|
||||
'title' => 'Titel #1',
|
||||
'content' => 'Inhalt #1'
|
||||
)
|
||||
);
|
||||
$this->assertEqual($result, $expected);
|
||||
|
@ -371,28 +363,29 @@ class TranslateBehaviorTest extends CakeTestCase {
|
|||
'TranslatedItem' => array(
|
||||
'slug' => 'first_translated',
|
||||
'locale' => 'deu',
|
||||
'title' => 'Titulek #1',
|
||||
'content' => 'Content #1'
|
||||
'content' => 'Inhalt #1',
|
||||
'title' => 'Titel #1'
|
||||
)
|
||||
),
|
||||
array(
|
||||
'TranslatedItem' => array(
|
||||
'slug' => 'second_translated',
|
||||
'locale' => 'deu',
|
||||
'title' => 'Title #2',
|
||||
'content' => 'Obsah #2'
|
||||
'title' => 'Titel #2',
|
||||
'content' => 'Inhalt #2'
|
||||
)
|
||||
),
|
||||
array(
|
||||
'TranslatedItem' => array(
|
||||
'slug' => 'third_translated',
|
||||
'locale' => 'deu',
|
||||
'title' => '',
|
||||
'content' => 'Content #3'
|
||||
'title' => 'Titel #3',
|
||||
'content' => 'Inhalt #3'
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$this->assertEquals($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -640,6 +633,8 @@ class TranslateBehaviorTest extends CakeTestCase {
|
|||
$translations = array('title' => 'Title', 'content' => 'Content');
|
||||
$TestModel->bindTranslation($translations, false);
|
||||
$result = $TestModel->read(null, 1);
|
||||
$result['Title'] = Set::sort($result['Title'], '{n}.id', 'asc');
|
||||
$result['Content'] = Set::sort($result['Content'], '{n}.id', 'asc');
|
||||
$expected = array(
|
||||
'TranslatedItem' => array('id' => 1, 'slug' => 'first_translated', 'locale' => 'cze', 'title' => 'Titulek #1', 'content' => 'Upraveny obsah #1'),
|
||||
'Title' => array(
|
||||
|
|
|
@ -1431,7 +1431,6 @@ class ScopedTreeTest extends CakeTestCase {
|
|||
function testTranslatingTree() {
|
||||
$this->Tree = new FlagTree();
|
||||
$this->Tree->cacheQueries = false;
|
||||
$this->Tree->translateModel = 'TranslateTreeTestModel';
|
||||
$this->Tree->Behaviors->attach('Translate', array('name'));
|
||||
|
||||
//Save
|
||||
|
|
|
@ -210,7 +210,7 @@ class TestAppSchema extends CakeSchema {
|
|||
*/
|
||||
public $datatypes = array(
|
||||
'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
|
||||
'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''),
|
||||
'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => '', 'collate' => null, 'comment' => null),
|
||||
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
|
||||
'tableParameters' => array()
|
||||
);
|
||||
|
@ -523,6 +523,7 @@ class CakeSchemaTest extends CakeTestCase {
|
|||
*/
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
ConnectionManager::getDataSource('test')->cacheSources = false;
|
||||
$this->Schema = new TestAppSchema();
|
||||
}
|
||||
|
||||
|
@ -577,18 +578,28 @@ class CakeSchemaTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
$this->assertEqual(
|
||||
$read['tables']['datatypes']['float_field'],
|
||||
$this->Schema->tables['datatypes']['float_field']
|
||||
$read['tables']['datatypes']['float_field']['length'],
|
||||
$this->Schema->tables['datatypes']['float_field']['length']
|
||||
);
|
||||
|
||||
$db =& ConnectionManager::getDataSource('test');
|
||||
$this->assertEqual(
|
||||
$read['tables']['datatypes']['float_field']['type'],
|
||||
$this->Schema->tables['datatypes']['float_field']['type']
|
||||
);
|
||||
|
||||
$this->assertEqual(
|
||||
$read['tables']['datatypes']['float_field']['null'],
|
||||
$this->Schema->tables['datatypes']['float_field']['null']
|
||||
);
|
||||
|
||||
$db = ConnectionManager::getDataSource('test');
|
||||
$config = $db->config;
|
||||
$config['prefix'] = 'schema_test_prefix_';
|
||||
ConnectionManager::create('schema_prefix', $config);
|
||||
$read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
|
||||
$this->assertTrue(empty($read['tables']));
|
||||
|
||||
$SchemaPost =& ClassRegistry::init('SchemaPost');
|
||||
$SchemaPost = ClassRegistry::init('SchemaPost');
|
||||
$SchemaPost->table = 'sts';
|
||||
$SchemaPost->tablePrefix = 'po';
|
||||
$read = $this->Schema->read(array(
|
||||
|
@ -612,7 +623,7 @@ class CakeSchemaTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
function testSchemaReadWithTablePrefix() {
|
||||
$model =& new SchemaPrefixAuthUser();
|
||||
$model = new SchemaPrefixAuthUser();
|
||||
|
||||
$Schema = new CakeSchema();
|
||||
$read = $Schema->read(array(
|
||||
|
@ -684,7 +695,7 @@ class CakeSchemaTest extends CakeTestCase {
|
|||
return;
|
||||
}
|
||||
|
||||
$db2 =& ConnectionManager::getDataSource('test2');
|
||||
$db2 = ConnectionManager::getDataSource('test2');
|
||||
$fixture = new SchemaCrossDatabaseFixture();
|
||||
$fixture->create($db2);
|
||||
$fixture->insert($db2);
|
||||
|
@ -953,7 +964,7 @@ class CakeSchemaTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
function testSchemaLoading() {
|
||||
$Other =& $this->Schema->load(array('name' => 'MyOtherApp', 'path' => TMP . 'tests'));
|
||||
$Other = $this->Schema->load(array('name' => 'MyOtherApp', 'path' => TMP . 'tests'));
|
||||
$this->assertEqual($Other->name, 'MyOtherApp');
|
||||
$this->assertEqual($Other->tables, $this->Schema->tables);
|
||||
}
|
||||
|
@ -967,7 +978,7 @@ class CakeSchemaTest extends CakeTestCase {
|
|||
App::build(array(
|
||||
'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS)
|
||||
));
|
||||
$Other =& $this->Schema->load(array('name' => 'TestPluginApp', 'plugin' => 'TestPlugin'));
|
||||
$Other = $this->Schema->load(array('name' => 'TestPluginApp', 'plugin' => 'TestPlugin'));
|
||||
$this->assertEqual($Other->name, 'TestPluginApp');
|
||||
$this->assertEqual(array_keys($Other->tables), array('test_plugin_acos'));
|
||||
|
||||
|
@ -981,7 +992,7 @@ class CakeSchemaTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
function testSchemaCreateTable() {
|
||||
$db =& ConnectionManager::getDataSource('test');
|
||||
$db = ConnectionManager::getDataSource('test');
|
||||
$db->cacheSources = false;
|
||||
|
||||
$Schema = new CakeSchema(array(
|
||||
|
|
|
@ -226,7 +226,6 @@ class ConnectionManagerTest extends CakeTestCase {
|
|||
function testLoadDataSource() {
|
||||
$connections = array(
|
||||
array('classname' => 'DboMysql', 'filename' => 'dbo' . DS . 'dbo_mysql'),
|
||||
array('classname' => 'DboMysqli', 'filename' => 'dbo' . DS . 'dbo_mysqli'),
|
||||
array('classname' => 'DboMssql', 'filename' => 'dbo' . DS . 'dbo_mssql'),
|
||||
array('classname' => 'DboOracle', 'filename' => 'dbo' . DS . 'dbo_oracle'),
|
||||
);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,328 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* DboMysqliTest file
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs
|
||||
* @since CakePHP(tm) v 1.2.0
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::import('Core', array('Model', 'DataSource', 'DboSource', 'DboMysqli'));
|
||||
|
||||
/**
|
||||
* DboMysqliTestDb class
|
||||
*
|
||||
* @package cake
|
||||
* @subpackage cake.tests.cases.libs.model.datasources
|
||||
*/
|
||||
class DboMysqliTestDb extends DboMysqli {
|
||||
|
||||
/**
|
||||
* simulated property
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $simulated = array();
|
||||
|
||||
/**
|
||||
* testing property
|
||||
*
|
||||
* @var bool true
|
||||
* @access public
|
||||
*/
|
||||
public $testing = true;
|
||||
|
||||
/**
|
||||
* execute method
|
||||
*
|
||||
* @param mixed $sql
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
function _execute($sql) {
|
||||
if ($this->testing) {
|
||||
$this->simulated[] = $sql;
|
||||
return null;
|
||||
}
|
||||
return parent::_execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* getLastQuery method
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function getLastQuery() {
|
||||
return $this->simulated[count($this->simulated) - 1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MysqliTestModel class
|
||||
*
|
||||
* @package cake
|
||||
* @subpackage cake.tests.cases.libs.model.datasources
|
||||
*/
|
||||
class MysqliTestModel extends Model {
|
||||
|
||||
/**
|
||||
* name property
|
||||
*
|
||||
* @var string 'MysqlTestModel'
|
||||
* @access public
|
||||
*/
|
||||
public $name = 'MysqliTestModel';
|
||||
|
||||
/**
|
||||
* useTable property
|
||||
*
|
||||
* @var bool false
|
||||
* @access public
|
||||
*/
|
||||
public $useTable = false;
|
||||
|
||||
/**
|
||||
* schema method
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function schema() {
|
||||
return array(
|
||||
'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
|
||||
'client_id' => array('type' => 'integer', 'null' => '', 'default' => '0', 'length' => '11'),
|
||||
'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
|
||||
'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
|
||||
'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
|
||||
'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
|
||||
'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'),
|
||||
'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
|
||||
'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
|
||||
'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
|
||||
'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
|
||||
'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
|
||||
'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
|
||||
'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
|
||||
'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''),
|
||||
'last_login'=> array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
|
||||
'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
|
||||
'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DboMysqliTest class
|
||||
*
|
||||
* @package cake
|
||||
* @subpackage cake.tests.cases.libs.model.datasources.dbo
|
||||
*/
|
||||
class DboMysqliTest extends CakeTestCase {
|
||||
public $fixtures = array('core.datatype');
|
||||
/**
|
||||
* The Dbo instance to be tested
|
||||
*
|
||||
* @var DboSource
|
||||
* @access public
|
||||
*/
|
||||
public $Dbo = null;
|
||||
|
||||
/**
|
||||
* Sets up a Dbo class instance for testing
|
||||
*
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->Dbo = ConnectionManager::getDataSource('test');
|
||||
if ($this->Dbo->config['driver'] !== 'mysqli') {
|
||||
$this->markTestSkipped('The MySQLi extension is not available.');
|
||||
}
|
||||
$this->model = new MysqliTestModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a Dbo class instance for testing
|
||||
*
|
||||
*/
|
||||
public function tearDown() {
|
||||
unset($this->model);
|
||||
ClassRegistry::flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* testIndexDetection method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIndexDetection() {
|
||||
$this->Dbo->cacheSources = false;
|
||||
|
||||
$name = $this->Dbo->fullTableName('simple');
|
||||
$this->Dbo->query('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
|
||||
$expected = array('PRIMARY' => array('column' => 'id', 'unique' => 1));
|
||||
$result = $this->Dbo->index($name, false);
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->Dbo->query('DROP TABLE ' . $name);
|
||||
|
||||
$name = $this->Dbo->fullTableName('with_a_key');
|
||||
$this->Dbo->query('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ));');
|
||||
$expected = array(
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1),
|
||||
'pointless_bool' => array('column' => 'bool', 'unique' => 0),
|
||||
);
|
||||
$result = $this->Dbo->index($name, false);
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->Dbo->query('DROP TABLE ' . $name);
|
||||
|
||||
$name = $this->Dbo->fullTableName('with_two_keys');
|
||||
$this->Dbo->query('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ));');
|
||||
$expected = array(
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1),
|
||||
'pointless_bool' => array('column' => 'bool', 'unique' => 0),
|
||||
'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
|
||||
);
|
||||
$result = $this->Dbo->index($name, false);
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->Dbo->query('DROP TABLE ' . $name);
|
||||
|
||||
$name = $this->Dbo->fullTableName('with_compound_keys');
|
||||
$this->Dbo->query('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ), KEY `one_way` ( `bool`, `small_int` ));');
|
||||
$expected = array(
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1),
|
||||
'pointless_bool' => array('column' => 'bool', 'unique' => 0),
|
||||
'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
|
||||
'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
|
||||
);
|
||||
$result = $this->Dbo->index($name, false);
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->Dbo->query('DROP TABLE ' . $name);
|
||||
|
||||
$name = $this->Dbo->fullTableName('with_multiple_compound_keys');
|
||||
$this->Dbo->query('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ), KEY `one_way` ( `bool`, `small_int` ), KEY `other_way` ( `small_int`, `bool` ));');
|
||||
$expected = array(
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1),
|
||||
'pointless_bool' => array('column' => 'bool', 'unique' => 0),
|
||||
'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
|
||||
'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
|
||||
'other_way' => array('column' => array('small_int', 'bool'), 'unique' => 0),
|
||||
);
|
||||
$result = $this->Dbo->index($name, false);
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->Dbo->query('DROP TABLE ' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* testColumn method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testColumn() {
|
||||
$result = $this->Dbo->column('varchar(50)');
|
||||
$expected = 'string';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('text');
|
||||
$expected = 'text';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('int(11)');
|
||||
$expected = 'integer';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('int(11) unsigned');
|
||||
$expected = 'integer';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('tinyint(1)');
|
||||
$expected = 'boolean';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('boolean');
|
||||
$expected = 'boolean';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('float');
|
||||
$expected = 'float';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('float unsigned');
|
||||
$expected = 'float';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('double unsigned');
|
||||
$expected = 'float';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Dbo->column('decimal(14,7) unsigned');
|
||||
$expected = 'float';
|
||||
$this->assertEqual($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* test transaction commands.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTransactions() {
|
||||
$this->Dbo->testing = false;
|
||||
$result = $this->Dbo->begin($this->model);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$log = $this->Dbo->getLog();
|
||||
$beginSqlCalls = Set::extract('/.[query=START TRANSACTION]', $log['log']);
|
||||
$this->assertEqual(1, count($beginSqlCalls));
|
||||
|
||||
$result = $this->Dbo->commit($this->model);
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
/**
|
||||
* test that float values are correctly identified
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testFloatParsing() {
|
||||
$model = new Model(array('ds' => 'test', 'table' => 'datatypes', 'name' => 'Datatype'));
|
||||
$result = $this->Dbo->describe($model);
|
||||
$this->assertEqual((string)$result['float_field']['length'], '5,2');
|
||||
}
|
||||
|
||||
/**
|
||||
* test that tableParameters like collation, charset and engine are functioning.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function testReadTableParameters() {
|
||||
$table = 'tinyint' . uniqid();
|
||||
$this->Dbo->cacheSources = $this->Dbo->testing = false;
|
||||
$this->Dbo->query('CREATE TABLE ' . $this->Dbo->fullTableName($table) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;');
|
||||
$result = $this->Dbo->readTableParameters($table);
|
||||
$expected = array(
|
||||
'charset' => 'utf8',
|
||||
'collate' => 'utf8_unicode_ci',
|
||||
'engine' => 'InnoDB');
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$this->Dbo->query('DROP TABLE ' . $this->Dbo->fullTableName($table));
|
||||
$this->Dbo->query('CREATE TABLE ' . $this->Dbo->fullTableName($table) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id)) ENGINE=MyISAM DEFAULT CHARSET=cp1250 COLLATE=cp1250_general_ci;');
|
||||
$result = $this->Dbo->readTableParameters($table);
|
||||
$expected = array(
|
||||
'charset' => 'cp1250',
|
||||
'collate' => 'cp1250_general_ci',
|
||||
'engine' => 'MyISAM');
|
||||
$this->assertEqual($result, $expected);
|
||||
$this->Dbo->query('DROP TABLE ' . $this->Dbo->fullTableName($table));
|
||||
}
|
||||
}
|
|
@ -244,6 +244,7 @@ class DboPostgresTest extends CakeTestCase {
|
|||
public function setUp() {
|
||||
Configure::write('Cache.disable', true);
|
||||
$this->Dbo = ConnectionManager::getDataSource('test');
|
||||
$this->skipIf(!($this->Dbo instanceof DboPostgres));
|
||||
$this->Dbo2 = new DboPostgresTestDb($this->Dbo->config, false);
|
||||
$this->skipUnless($this->Dbo->config['driver'] == 'postgres', 'PostgreSQL connection not available');
|
||||
$this->model = new PostgresTestModel();
|
||||
|
@ -330,30 +331,30 @@ class DboPostgresTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
function testValueQuoting() {
|
||||
$this->assertIdentical($this->db2->value(1.2, 'float'), "'1.200000'");
|
||||
$this->assertEqual($this->db2->value('1,2', 'float'), "'1,2'");
|
||||
$this->assertEqual($this->Dbo->value(1.2, 'float'), "1.200000");
|
||||
$this->assertEqual($this->Dbo->value('1,2', 'float'), "'1,2'");
|
||||
|
||||
$this->assertEqual($this->Dbo2->value('0', 'integer'), "'0'");
|
||||
$this->assertEqual($this->Dbo2->value('', 'integer'), 'NULL');
|
||||
$this->assertEqual($this->Dbo2->value('', 'float'), 'NULL');
|
||||
$this->assertEqual($this->Dbo2->value('', 'integer', false), "DEFAULT");
|
||||
$this->assertEqual($this->Dbo2->value('', 'float', false), "DEFAULT");
|
||||
$this->assertEqual($this->Dbo2->value('0.0', 'float'), "'0.0'");
|
||||
$this->assertEqual($this->Dbo->value('0', 'integer'), "0");
|
||||
$this->assertEqual($this->Dbo->value('', 'integer'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value('', 'float'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value('', 'integer', false), "NULL");
|
||||
$this->assertEqual($this->Dbo->value('', 'float', false), "NULL");
|
||||
$this->assertEqual($this->Dbo->value('0.0', 'float'), "'0.0'");
|
||||
|
||||
$this->assertEqual($this->Dbo2->value('t', 'boolean'), "TRUE");
|
||||
$this->assertEqual($this->Dbo2->value('f', 'boolean'), "FALSE");
|
||||
$this->assertEqual($this->Dbo2->value(true), "TRUE");
|
||||
$this->assertEqual($this->Dbo2->value(false), "FALSE");
|
||||
$this->assertEqual($this->Dbo2->value('t'), "'t'");
|
||||
$this->assertEqual($this->Dbo2->value('f'), "'f'");
|
||||
$this->assertEqual($this->Dbo2->value('true', 'boolean'), 'TRUE');
|
||||
$this->assertEqual($this->Dbo2->value('false', 'boolean'), 'FALSE');
|
||||
$this->assertEqual($this->Dbo2->value('', 'boolean'), 'FALSE');
|
||||
$this->assertEqual($this->Dbo2->value(0, 'boolean'), 'FALSE');
|
||||
$this->assertEqual($this->Dbo2->value(1, 'boolean'), 'TRUE');
|
||||
$this->assertEqual($this->Dbo2->value('1', 'boolean'), 'TRUE');
|
||||
$this->assertEqual($this->Dbo2->value(null, 'boolean'), "NULL");
|
||||
$this->assertEqual($this->Dbo2->value(array()), "NULL");
|
||||
$this->assertEqual($this->Dbo->value('t', 'boolean'), "'TRUE'");
|
||||
$this->assertEqual($this->Dbo->value('f', 'boolean'), "'FALSE'");
|
||||
$this->assertEqual($this->Dbo->value(true), "'TRUE'");
|
||||
$this->assertEqual($this->Dbo->value(false), "'FALSE'");
|
||||
$this->assertEqual($this->Dbo->value('t'), "'t'");
|
||||
$this->assertEqual($this->Dbo->value('f'), "'f'");
|
||||
$this->assertEqual($this->Dbo->value('true', 'boolean'), "'TRUE'");
|
||||
$this->assertEqual($this->Dbo->value('false', 'boolean'), "'FALSE'");
|
||||
$this->assertEqual($this->Dbo->value('', 'boolean'), "'FALSE'");
|
||||
$this->assertEqual($this->Dbo->value(0, 'boolean'), "'FALSE'");
|
||||
$this->assertEqual($this->Dbo->value(1, 'boolean'), "'TRUE'");
|
||||
$this->assertEqual($this->Dbo->value('1', 'boolean'), "'TRUE'");
|
||||
$this->assertEqual($this->Dbo->value(null, 'boolean'), "NULL");
|
||||
$this->assertEqual($this->Dbo->value(array()), "NULL");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -366,10 +367,10 @@ class DboPostgresTest extends CakeTestCase {
|
|||
setlocale(LC_ALL, 'de_DE');
|
||||
|
||||
$result = $this->db->value(3.141593, 'float');
|
||||
$this->assertEqual((string)$result, "'3.141593'");
|
||||
$this->assertEqual((string)$result, "3.141593");
|
||||
|
||||
$result = $this->db->value(3.14);
|
||||
$this->assertEqual((string)$result, "'3.140000'");
|
||||
$this->assertEqual((string)$result, "3.140000");
|
||||
|
||||
setlocale(LC_ALL, $restore);
|
||||
}
|
||||
|
@ -380,17 +381,17 @@ class DboPostgresTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
function testDateAndTimeAsNull() {
|
||||
$this->assertEqual($this->Dbo2->value(null, 'date'), 'NULL');
|
||||
$this->assertEqual($this->Dbo2->value('', 'date'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value(null, 'date'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value('', 'date'), 'NULL');
|
||||
|
||||
$this->assertEqual($this->Dbo2->value('', 'datetime'), 'NULL');
|
||||
$this->assertEqual($this->Dbo2->value(null, 'datetime'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value('', 'datetime'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value(null, 'datetime'), 'NULL');
|
||||
|
||||
$this->assertEqual($this->Dbo2->value('', 'timestamp'), 'NULL');
|
||||
$this->assertEqual($this->Dbo2->value(null, 'timestamp'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value('', 'timestamp'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value(null, 'timestamp'), 'NULL');
|
||||
|
||||
$this->assertEqual($this->Dbo2->value('', 'time'), 'NULL');
|
||||
$this->assertEqual($this->Dbo2->value(null, 'time'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value('', 'time'), 'NULL');
|
||||
$this->assertEqual($this->Dbo->value(null, 'time'), 'NULL');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -400,19 +401,19 @@ class DboPostgresTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
function testBooleanNormalization() {
|
||||
$this->assertTrue($this->Dbo2->boolean('t'));
|
||||
$this->assertTrue($this->Dbo2->boolean('true'));
|
||||
$this->assertTrue($this->Dbo2->boolean('TRUE'));
|
||||
$this->assertTrue($this->Dbo2->boolean(true));
|
||||
$this->assertTrue($this->Dbo2->boolean(1));
|
||||
$this->assertTrue($this->Dbo2->boolean(" "));
|
||||
$this->assertEquals(1, $this->Dbo2->boolean('t', false));
|
||||
$this->assertEquals(1, $this->Dbo2->boolean('true', false));
|
||||
$this->assertEquals(1, $this->Dbo2->boolean('TRUE', false));
|
||||
$this->assertEquals(1, $this->Dbo2->boolean(true, false));
|
||||
$this->assertEquals(1, $this->Dbo2->boolean(1, false));
|
||||
$this->assertEquals(1, $this->Dbo2->boolean(" ", false));
|
||||
|
||||
$this->assertFalse($this->Dbo2->boolean('f'));
|
||||
$this->assertFalse($this->Dbo2->boolean('false'));
|
||||
$this->assertFalse($this->Dbo2->boolean('FALSE'));
|
||||
$this->assertFalse($this->Dbo2->boolean(false));
|
||||
$this->assertFalse($this->Dbo2->boolean(0));
|
||||
$this->assertFalse($this->Dbo2->boolean(''));
|
||||
$this->assertEquals(0, $this->Dbo2->boolean('f', false));
|
||||
$this->assertEquals(0, $this->Dbo2->boolean('false', false));
|
||||
$this->assertEquals(0, $this->Dbo2->boolean('FALSE', false));
|
||||
$this->assertEquals(0, $this->Dbo2->boolean(false, false));
|
||||
$this->assertEquals(0, $this->Dbo2->boolean(0, false));
|
||||
$this->assertEquals(0, $this->Dbo2->boolean('', false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -427,7 +428,7 @@ class DboPostgresTest extends CakeTestCase {
|
|||
|
||||
$db2 = clone $db1;
|
||||
$db2->connect();
|
||||
$this->assertNotEqual($db1->connection, $db2->connection);
|
||||
$this->assertNotSame($db1->getConnection(), $db2->getConnection());
|
||||
|
||||
$table = $db1->fullTableName('users', false);
|
||||
$password = '5f4dcc3b5aa765d61d8327deb882cf99';
|
||||
|
@ -556,12 +557,12 @@ class DboPostgresTest extends CakeTestCase {
|
|||
$db1 = ConnectionManager::getDataSource('test');
|
||||
$db1->cacheSources = false;
|
||||
$db1->reconnect(array('persistent' => false));
|
||||
$db1->query('CREATE TABLE ' . $db1->fullTableName('datatypes') . ' (
|
||||
$db1->rawQuery('CREATE TABLE ' . $db1->fullTableName('datatypes') . ' (
|
||||
id serial NOT NULL,
|
||||
"varchar" character varying(40) NOT NULL,
|
||||
"full_length" character varying NOT NULL,
|
||||
"timestamp" timestamp without time zone,
|
||||
date date,
|
||||
"date" date,
|
||||
CONSTRAINT test_data_types_pkey PRIMARY KEY (id)
|
||||
)');
|
||||
$model = new Model(array('name' => 'Datatype', 'ds' => 'test'));
|
||||
|
@ -570,21 +571,21 @@ class DboPostgresTest extends CakeTestCase {
|
|||
'connection' => 'test',
|
||||
'models' => array('Datatype')
|
||||
));
|
||||
$schema->tables = array('datatypes' => $result['tables']['datatypes']);
|
||||
|
||||
$schema->tables = array('datatypes' => $result['tables']['missing']['datatypes']);
|
||||
$result = $db1->createSchema($schema, 'datatypes');
|
||||
$db1->rawQuery('DROP TABLE ' . $db1->fullTableName('datatypes'));
|
||||
|
||||
$this->assertNoPattern('/timestamp DEFAULT/', $result);
|
||||
$this->assertPattern('/\"full_length\"\s*text\s.*,/', $result);
|
||||
$this->assertPattern('/timestamp\s*,/', $result);
|
||||
|
||||
$db1->query('DROP TABLE ' . $db1->fullTableName('datatypes'));
|
||||
|
||||
$db1->query($result);
|
||||
$result2 = $schema->read(array(
|
||||
'connection' => 'test',
|
||||
'models' => array('Datatype')
|
||||
));
|
||||
$schema->tables = array('datatypes' => $result2['tables']['datatypes']);
|
||||
$schema->tables = array('datatypes' => $result2['tables']['missing']['datatypes']);
|
||||
$result2 = $db1->createSchema($schema, 'datatypes');
|
||||
$this->assertEqual($result, $result2);
|
||||
|
||||
|
@ -602,25 +603,25 @@ class DboPostgresTest extends CakeTestCase {
|
|||
$this->Dbo->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
|
||||
$this->Dbo->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
|
||||
$expected = array(
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => true),
|
||||
'pointless_bool' => array('column' => 'bool', 'unique' => false),
|
||||
'char_index' => array('column' => 'small_char', 'unique' => true),
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1),
|
||||
'pointless_bool' => array('column' => 'bool', 'unique' => 0),
|
||||
'char_index' => array('column' => 'small_char', 'unique' => 1),
|
||||
|
||||
);
|
||||
$result = $this->Dbo->index($name);
|
||||
$this->Dbo->query('DROP TABLE ' . $name);
|
||||
$this->assertEqual($expected, $result);
|
||||
|
||||
$this->Dbo->query('DROP TABLE ' . $name);
|
||||
$name = $this->Dbo->fullTableName('index_test_2', false);
|
||||
$this->Dbo->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
|
||||
$this->Dbo->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
|
||||
$expected = array(
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => true),
|
||||
'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => true),
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1),
|
||||
'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => 1),
|
||||
);
|
||||
$result = $this->Dbo->index($name);
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->Dbo->query('DROP TABLE ' . $name);
|
||||
$this->assertEqual($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -691,21 +692,21 @@ class DboPostgresTest extends CakeTestCase {
|
|||
'group2' => array('type' => 'integer', 'null' => true)
|
||||
)
|
||||
));
|
||||
$this->Dbo->query($this->Dbo->createSchema($schema1));
|
||||
$this->Dbo->rawQuery($this->Dbo->createSchema($schema1));
|
||||
|
||||
$schema2 = new CakeSchema(array(
|
||||
'name' => 'AlterTest2',
|
||||
'connection' => 'test',
|
||||
'altertest' => array(
|
||||
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
|
||||
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
|
||||
'group1' => array('type' => 'integer', 'null' => true),
|
||||
'group2' => array('type' => 'integer', 'null' => true),
|
||||
'id' => array('type' => 'integer', 'null' => 0, 'default' => 0),
|
||||
'name' => array('type' => 'string', 'null' => 0, 'length' => 50),
|
||||
'group1' => array('type' => 'integer', 'null' => 1),
|
||||
'group2' => array('type' => 'integer', 'null' => 1),
|
||||
'indexes' => array(
|
||||
'name_idx' => array('column' => 'name', 'unique' => false),
|
||||
'group_idx' => array('column' => 'group1', 'unique' => false),
|
||||
'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => false),
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => true)
|
||||
'name_idx' => array('column' => 'name', 'unique' => 0),
|
||||
'group_idx' => array('column' => 'group1', 'unique' => 0),
|
||||
'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0),
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1)
|
||||
)
|
||||
)
|
||||
));
|
||||
|
@ -719,15 +720,15 @@ class DboPostgresTest extends CakeTestCase {
|
|||
'name' => 'AlterTest3',
|
||||
'connection' => 'test',
|
||||
'altertest' => array(
|
||||
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
|
||||
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
|
||||
'group1' => array('type' => 'integer', 'null' => true),
|
||||
'group2' => array('type' => 'integer', 'null' => true),
|
||||
'id' => array('type' => 'integer', 'null' => 0, 'default' => 0),
|
||||
'name' => array('type' => 'string', 'null' => 0, 'length' => 50),
|
||||
'group1' => array('type' => 'integer', 'null' => 1),
|
||||
'group2' => array('type' => 'integer', 'null' => 1),
|
||||
'indexes' => array(
|
||||
'name_idx' => array('column' => 'name', 'unique' => true),
|
||||
'group_idx' => array('column' => 'group2', 'unique' => false),
|
||||
'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => false),
|
||||
'another_idx' => array('column' => array('group1', 'name'), 'unique' => false))
|
||||
'name_idx' => array('column' => 'name', 'unique' => 1),
|
||||
'group_idx' => array('column' => 'group2', 'unique' => 0),
|
||||
'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0),
|
||||
'another_idx' => array('column' => array('group1', 'name'), 'unique' => 0))
|
||||
)));
|
||||
|
||||
$this->Dbo->query($this->Dbo->alterSchema($schema3->compare($schema2)));
|
||||
|
|
|
@ -90,14 +90,6 @@ class DboSqliteTest extends CakeTestCase {
|
|||
*/
|
||||
public $Dbo = null;
|
||||
|
||||
/**
|
||||
* Simulated DB connection used in testing
|
||||
*
|
||||
* @var DboSource
|
||||
* @access public
|
||||
*/
|
||||
public $Dbo2 = null;
|
||||
|
||||
/**
|
||||
* Sets up a Dbo class instance for testing
|
||||
*
|
||||
|
@ -108,7 +100,6 @@ class DboSqliteTest extends CakeTestCase {
|
|||
if ($this->Dbo->config['driver'] !== 'sqlite') {
|
||||
$this->markTestSkipped('The Sqlite extension is not available.');
|
||||
}
|
||||
$this->Dbo2 = new DboSqliteTestDb($this->Dbo->config, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,7 +108,6 @@ class DboSqliteTest extends CakeTestCase {
|
|||
*/
|
||||
public function tearDown() {
|
||||
Configure::write('Cache.disable', false);
|
||||
unset($this->Dbo2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,10 +117,11 @@ class DboSqliteTest extends CakeTestCase {
|
|||
public function testTableListCacheDisabling() {
|
||||
$this->assertFalse(in_array('foo_test', $this->Dbo->listSources()));
|
||||
|
||||
$this->Dbo->query('CREATE TABLE foo_test (test VARCHAR(255));');
|
||||
$this->Dbo->query('CREATE TABLE foo_test (test VARCHAR(255))');
|
||||
$this->assertTrue(in_array('foo_test', $this->Dbo->listSources()));
|
||||
|
||||
$this->Dbo->query('DROP TABLE foo_test;');
|
||||
$this->Dbo->cacheSources = false;
|
||||
$this->Dbo->query('DROP TABLE foo_test');
|
||||
$this->assertFalse(in_array('foo_test', $this->Dbo->listSources()));
|
||||
}
|
||||
|
||||
|
@ -207,7 +198,7 @@ class DboSqliteTest extends CakeTestCase {
|
|||
'null' => false,
|
||||
);
|
||||
$result = $this->Dbo->buildColumn($data);
|
||||
$expected = '"int_field" integer(11) NOT NULL';
|
||||
$expected = '"int_field" integer NOT NULL';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$data = array(
|
||||
|
@ -251,7 +242,7 @@ class DboSqliteTest extends CakeTestCase {
|
|||
'null' => false,
|
||||
);
|
||||
$result = $this->Dbo->buildColumn($data);
|
||||
$expected = '"testName" integer(10) DEFAULT \'10\' NOT NULL';
|
||||
$expected = '"testName" integer(10) DEFAULT 10 NOT NULL';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$data = array(
|
||||
|
@ -263,7 +254,7 @@ class DboSqliteTest extends CakeTestCase {
|
|||
'collate' => 'BADVALUE'
|
||||
);
|
||||
$result = $this->Dbo->buildColumn($data);
|
||||
$expected = '"testName" integer(10) DEFAULT \'10\' NOT NULL';
|
||||
$expected = '"testName" integer(10) DEFAULT 10 NOT NULL';
|
||||
$this->assertEqual($result, $expected);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -184,7 +184,7 @@ class ModelIntegrationTest extends BaseModelTest {
|
|||
*/
|
||||
function testPkInHabtmLinkModel() {
|
||||
//Test Nonconformant Models
|
||||
$this->loadFixtures('Content', 'ContentAccount', 'Account', 'JoinC', 'JoinAC');
|
||||
$this->loadFixtures('Content', 'ContentAccount', 'Account', 'JoinC', 'JoinAC', 'ItemsPortfolio');
|
||||
$TestModel = new Content();
|
||||
$this->assertEqual($TestModel->ContentAccount->primaryKey, 'iContentAccountsId');
|
||||
|
||||
|
@ -1867,7 +1867,7 @@ class ModelIntegrationTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
function testCreation() {
|
||||
$this->loadFixtures('Article', 'ArticleFeaturedsTags');
|
||||
$this->loadFixtures('Article', 'ArticleFeaturedsTags', 'User', 'Featured');
|
||||
$TestModel = new Test();
|
||||
$result = $TestModel->create();
|
||||
$expected = array('Test' => array('notes' => 'write some notes here'));
|
||||
|
@ -1882,9 +1882,10 @@ class ModelIntegrationTest extends BaseModelTest {
|
|||
} else {
|
||||
$intLength = 11;
|
||||
}
|
||||
foreach (array('collate', 'charset') as $type) {
|
||||
unset($result['user'][$type]);
|
||||
unset($result['password'][$type]);
|
||||
foreach (array('collate', 'charset', 'comment') as $type) {
|
||||
foreach ($result as $i => $r) {
|
||||
unset($result[$i][$type]);
|
||||
}
|
||||
}
|
||||
|
||||
$expected = array(
|
||||
|
@ -1946,8 +1947,8 @@ class ModelIntegrationTest extends BaseModelTest {
|
|||
'Featured' => array(
|
||||
'article_featured_id' => 1,
|
||||
'category_id' => 1,
|
||||
'published_date' => '2008-6-11 00:00:00',
|
||||
'end_date' => '2008-6-20 00:00:00'
|
||||
'published_date' => '2008-06-11 00:00:00',
|
||||
'end_date' => '2008-06-20 00:00:00'
|
||||
));
|
||||
|
||||
$this->assertEqual($FeaturedModel->create($data), $expected);
|
||||
|
@ -1969,8 +1970,8 @@ class ModelIntegrationTest extends BaseModelTest {
|
|||
|
||||
$expected = array(
|
||||
'Featured' => array(
|
||||
'published_date' => '2008-6-11 00:00:00',
|
||||
'end_date' => '2008-6-20 00:00:00',
|
||||
'published_date' => '2008-06-11 00:00:00',
|
||||
'end_date' => '2008-06-20 00:00:00',
|
||||
'article_featured_id' => 1,
|
||||
'category_id' => 1
|
||||
));
|
||||
|
|
|
@ -52,15 +52,17 @@ class ModelReadTest extends BaseModelTest {
|
|||
)
|
||||
);
|
||||
|
||||
|
||||
$Something->JoinThing->create($joinThingData);
|
||||
$Something->JoinThing->save();
|
||||
|
||||
$result = $Something->JoinThing->find('all', array('conditions' => array('something_else_id' => 2)));
|
||||
|
||||
$this->assertEqual($result[0]['JoinThing']['doomed'], '1');
|
||||
$this->assertEqual($result[1]['JoinThing']['doomed'], '0');
|
||||
$this->assertEqual((bool)$result[0]['JoinThing']['doomed'], true);
|
||||
$this->assertEqual((bool)$result[1]['JoinThing']['doomed'], false);
|
||||
|
||||
$result = $Something->find('first');
|
||||
|
||||
$this->assertEqual(count($result['SomethingElse']), 2);
|
||||
|
||||
$doomed = Set::extract('/JoinThing/doomed', $result['SomethingElse']);
|
||||
|
@ -79,7 +81,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
*/
|
||||
function testGroupBy() {
|
||||
$db = ConnectionManager::getDataSource('test');
|
||||
$isStrictGroupBy = in_array($db->config['driver'], array('postgres', 'oracle'));
|
||||
$isStrictGroupBy = in_array($db->config['driver'], array('postgres', 'oracle', 'sqlite'));
|
||||
$message = '%s Postgres and Oracle have strict GROUP BY and are incompatible with this test.';
|
||||
|
||||
if ($this->skipIf($isStrictGroupBy, $message )) {
|
||||
|
@ -279,13 +281,6 @@ class ModelReadTest extends BaseModelTest {
|
|||
$this->loadFixtures('Article', 'User', 'Tag', 'ArticlesTag');
|
||||
$Article = new Article();
|
||||
|
||||
$finalQuery = 'SELECT title, published FROM ';
|
||||
$finalQuery .= $this->db->fullTableName('articles');
|
||||
$finalQuery .= ' WHERE ' . $this->db->fullTableName('articles');
|
||||
$finalQuery .= '.id = ' . $this->db->value(1);
|
||||
$finalQuery .= ' AND ' . $this->db->fullTableName('articles');
|
||||
$finalQuery .= '.published = ' . $this->db->value('Y');
|
||||
|
||||
$query = 'SELECT title, published FROM ';
|
||||
$query .= $this->db->fullTableName('articles');
|
||||
$query .= ' WHERE ' . $this->db->fullTableName('articles');
|
||||
|
@ -305,14 +300,9 @@ class ModelReadTest extends BaseModelTest {
|
|||
}
|
||||
|
||||
$this->assertEqual($result, $expected);
|
||||
$result = $this->db->getQueryCache($finalQuery);
|
||||
$result = $this->db->getQueryCache($query, $params);
|
||||
$this->assertFalse(empty($result));
|
||||
|
||||
$finalQuery = 'SELECT id, created FROM ';
|
||||
$finalQuery .= $this->db->fullTableName('articles');
|
||||
$finalQuery .= ' WHERE ' . $this->db->fullTableName('articles');
|
||||
$finalQuery .= '.title = ' . $this->db->value('First Article');
|
||||
|
||||
$query = 'SELECT id, created FROM ';
|
||||
$query .= $this->db->fullTableName('articles');
|
||||
$query .= ' WHERE ' . $this->db->fullTableName('articles') . '.title = ?';
|
||||
|
@ -324,7 +314,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
isset($result[0][$this->db->fullTableName('articles', false)])
|
||||
|| isset($result[0][0])
|
||||
);
|
||||
$result = $this->db->getQueryCache($finalQuery);
|
||||
$result = $this->db->getQueryCache($query, $params);
|
||||
$this->assertTrue(empty($result));
|
||||
|
||||
$query = 'SELECT title FROM ';
|
||||
|
@ -345,10 +335,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
$params = array('First? Article', 'Y');
|
||||
$Article->query($query, $params);
|
||||
|
||||
$expected = 'SELECT title FROM ';
|
||||
$expected .= $this->db->fullTableName('articles');
|
||||
$expected .= " WHERE title = 'First? Article' AND published = 'Y'";
|
||||
$result = $this->db->getQueryCache($expected);
|
||||
$result = $this->db->getQueryCache($query, $params);
|
||||
$this->assertFalse($result === false);
|
||||
|
||||
}
|
||||
|
@ -5091,7 +5078,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
'typ' => 2
|
||||
)));
|
||||
|
||||
$this->assertEqual($result, $expected);
|
||||
$this->assertEqual($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5661,7 +5648,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
'name' => 'computer'
|
||||
))))));
|
||||
|
||||
$this->assertIdentical($result, $expected);
|
||||
$this->assertEquals($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7478,7 +7465,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
$result = $Post->field('other_field');
|
||||
$this->assertEqual($result, 4);
|
||||
|
||||
if ($this->skipIf($this->db->config['driver'] == 'postgres', 'The rest of virtualFieds test is not compatible with Postgres')) {
|
||||
if ($this->skipIf($this->db->config['driver'] != 'mysql', 'The rest of virtualFieds test is not compatible with Postgres')) {
|
||||
return;
|
||||
}
|
||||
ClassRegistry::flush();
|
||||
|
@ -7486,20 +7473,20 @@ class ModelReadTest extends BaseModelTest {
|
|||
|
||||
$Post->create();
|
||||
$Post->virtualFields = array(
|
||||
'year' => 'YEAR(Post.created)',
|
||||
'low_title' => 'lower(Post.title)',
|
||||
'unique_test_field' => 'COUNT(Post.id)'
|
||||
);
|
||||
|
||||
$expectation = array(
|
||||
'Post' => array(
|
||||
'year' => 2007,
|
||||
'unique_test_field' => 3
|
||||
'low_title' => 'first post',
|
||||
'unique_test_field' => 1
|
||||
)
|
||||
);
|
||||
|
||||
$result = $Post->find('first', array(
|
||||
'fields' => array_keys($Post->virtualFields),
|
||||
'group' => array('year')
|
||||
'group' => array('low_title')
|
||||
));
|
||||
|
||||
$this->assertEqual($result, $expectation);
|
||||
|
|
|
@ -201,8 +201,8 @@ class ModelWriteTest extends BaseModelTest {
|
|||
$TestModel->create(array());
|
||||
$TestModel->save();
|
||||
$result = $TestModel->findById($TestModel->id);
|
||||
$this->assertIdentical($result['DataTest']['count'], '0');
|
||||
$this->assertIdentical($result['DataTest']['float'], '0');
|
||||
$this->assertEquals($result['DataTest']['count'], 0);
|
||||
$this->assertEquals($result['DataTest']['float'], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,20 +286,20 @@ class ModelWriteTest extends BaseModelTest {
|
|||
));
|
||||
|
||||
$result = $TestModel->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '2');
|
||||
$this->assertEquals($result['Syfile']['item_count'], 2);
|
||||
|
||||
$TestModel2->delete(1);
|
||||
$result = $TestModel->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '1');
|
||||
$this->assertEquals($result['Syfile']['item_count'], 1);
|
||||
|
||||
$TestModel2->id = 2;
|
||||
$TestModel2->saveField('syfile_id', 1);
|
||||
|
||||
$result = $TestModel->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '2');
|
||||
$this->assertEquals($result['Syfile']['item_count'], 2);
|
||||
|
||||
$result = $TestModel->findById(2);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '0');
|
||||
$this->assertEquals($result['Syfile']['item_count'], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -437,7 +437,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
function testSaveWithCounterCacheScope() {
|
||||
$this->loadFixtures('Syfile', 'Item');
|
||||
$this->loadFixtures('Syfile', 'Item', 'Image', 'ItemsPortfolio', 'Portfolio');
|
||||
$TestModel = new Syfile();
|
||||
$TestModel2 = new Item();
|
||||
$TestModel2->belongsTo['Syfile']['counterCache'] = true;
|
||||
|
@ -453,12 +453,13 @@ class ModelWriteTest extends BaseModelTest {
|
|||
));
|
||||
|
||||
$result = $TestModel->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '1');
|
||||
|
||||
$this->assertEquals($result['Syfile']['item_count'], 1);
|
||||
|
||||
$TestModel2->id = 1;
|
||||
$TestModel2->saveField('published', true);
|
||||
$result = $TestModel->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '2');
|
||||
$this->assertEquals($result['Syfile']['item_count'], 2);
|
||||
|
||||
$TestModel2->save(array(
|
||||
'id' => 1,
|
||||
|
@ -467,7 +468,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
));
|
||||
|
||||
$result = $TestModel->findById(1);
|
||||
$this->assertIdentical($result['Syfile']['item_count'], '1');
|
||||
$this->assertEquals($result['Syfile']['item_count'], 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1013,6 +1014,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
function testSaveFromXml() {
|
||||
$this->markTestSkipped('This feature needs to be fixed or dropped');
|
||||
$this->loadFixtures('Article');
|
||||
App::import('Core', 'Xml');
|
||||
|
||||
|
@ -1579,7 +1581,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
'DoomedSomethingElse' => array(
|
||||
'className' => 'SomethingElse',
|
||||
'joinTable' => 'join_things',
|
||||
'conditions' => 'JoinThing.doomed = true',
|
||||
'conditions' => array('JoinThing.doomed' => true),
|
||||
'unique' => true
|
||||
),
|
||||
'NotDoomedSomethingElse' => array(
|
||||
|
@ -2434,7 +2436,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
function testSaveAll() {
|
||||
$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
|
||||
$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
|
||||
$TestModel = new Post();
|
||||
|
||||
$result = $TestModel->find('all');
|
||||
|
@ -2574,7 +2576,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
function testSaveAllHabtm() {
|
||||
$this->loadFixtures('Article', 'Tag', 'Comment', 'User');
|
||||
$this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
|
||||
$data = array(
|
||||
'Article' => array(
|
||||
'user_id' => 1,
|
||||
|
@ -3839,8 +3841,8 @@ class ModelWriteTest extends BaseModelTest {
|
|||
*/
|
||||
function testProductUpdateAll() {
|
||||
$this->skipIf(
|
||||
$this->db->config['driver'] == 'postgres',
|
||||
'%s Currently, there is no way of doing joins in an update statement in postgresql'
|
||||
$this->db->config['driver'] != 'mysql',
|
||||
'%s Currently, there is no way of doing joins in an update statement in postgresql or sqlite'
|
||||
);
|
||||
$this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
|
||||
$ProductUpdateAll = new ProductUpdateAll();
|
||||
|
@ -3890,7 +3892,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
*/
|
||||
function testProductUpdateAllWithoutForeignKey() {
|
||||
$this->skipIf(
|
||||
$this->db->config['driver'] == 'postgres',
|
||||
$this->db->config['driver'] != 'mysql',
|
||||
'%s Currently, there is no way of doing joins in an update statement in postgresql'
|
||||
);
|
||||
$this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
|
||||
|
|
File diff suppressed because it is too large
Load diff
24
cake/tests/fixtures/aco_fixture.php
vendored
24
cake/tests/fixtures/aco_fixture.php
vendored
|
@ -57,17 +57,17 @@ class AcoFixture extends CakeTestFixture {
|
|||
* @access public
|
||||
*/
|
||||
public $records = array(
|
||||
array('parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'ROOT', 'lft' => 1, 'rght' => 24),
|
||||
array('parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Controller1', 'lft' => 2, 'rght' => 9),
|
||||
array('parent_id' => 2, 'model' => null, 'foreign_key' => null, 'alias' => 'action1', 'lft' => 3, 'rght' => 6),
|
||||
array('parent_id' => 3, 'model' => null, 'foreign_key' => null, 'alias' => 'record1', 'lft' => 4, 'rght' => 5),
|
||||
array('parent_id' => 2, 'model' => null, 'foreign_key' => null, 'alias' => 'action2', 'lft' => 7, 'rght' => 8),
|
||||
array('parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Controller2','lft' => 10, 'rght' => 17),
|
||||
array('parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'action1', 'lft' => 11, 'rght' => 14),
|
||||
array('parent_id' => 7, 'model' => null, 'foreign_key' => null, 'alias' => 'record1', 'lft' => 12, 'rght' => 13),
|
||||
array('parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'action2', 'lft' => 15, 'rght' => 16),
|
||||
array('parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Users', 'lft' => 18, 'rght' => 23),
|
||||
array('parent_id' => 9, 'model' => null, 'foreign_key' => null, 'alias' => 'Users', 'lft' => 19, 'rght' => 22),
|
||||
array('parent_id' => 10, 'model' => null, 'foreign_key' => null, 'alias' => 'view', 'lft' => 20, 'rght' => 21),
|
||||
array('id' => 1, 'parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'ROOT', 'lft' => 1, 'rght' => 24),
|
||||
array('id' => 2, 'parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Controller1', 'lft' => 2, 'rght' => 9),
|
||||
array('id' => 3, 'parent_id' => 2, 'model' => null, 'foreign_key' => null, 'alias' => 'action1', 'lft' => 3, 'rght' => 6),
|
||||
array('id' => 4, 'parent_id' => 3, 'model' => null, 'foreign_key' => null, 'alias' => 'record1', 'lft' => 4, 'rght' => 5),
|
||||
array('id' => 5, 'parent_id' => 2, 'model' => null, 'foreign_key' => null, 'alias' => 'action2', 'lft' => 7, 'rght' => 8),
|
||||
array('id' => 6, 'parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Controller2','lft' => 10, 'rght' => 17),
|
||||
array('id' => 7, 'parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'action1', 'lft' => 11, 'rght' => 14),
|
||||
array('id' => 8, 'parent_id' => 7, 'model' => null, 'foreign_key' => null, 'alias' => 'record1', 'lft' => 12, 'rght' => 13),
|
||||
array('id' => 9, 'parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'action2', 'lft' => 15, 'rght' => 16),
|
||||
array('id' => 10, 'parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Users', 'lft' => 18, 'rght' => 23),
|
||||
array('id' => 11, 'parent_id' => 9, 'model' => null, 'foreign_key' => null, 'alias' => 'Users', 'lft' => 19, 'rght' => 22),
|
||||
array('id' => 12, 'parent_id' => 10, 'model' => null, 'foreign_key' => null, 'alias' => 'view', 'lft' => 20, 'rght' => 21),
|
||||
);
|
||||
}
|
||||
|
|
36
cake/tests/fixtures/translate_fixture.php
vendored
36
cake/tests/fixtures/translate_fixture.php
vendored
|
@ -64,23 +64,23 @@ class TranslateFixture extends CakeTestFixture {
|
|||
* @access public
|
||||
*/
|
||||
public $records = array(
|
||||
array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
|
||||
array('id' => 2, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
|
||||
array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
|
||||
array('id' => 4, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
|
||||
array('id' => 5, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1'),
|
||||
array('id' => 6, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Obsah #1'),
|
||||
array('id' => 7, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title #2'),
|
||||
array('id' => 8, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Content #2'),
|
||||
array('id' => 9, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titel #2'),
|
||||
array('id' => 10, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Inhalt #2'),
|
||||
array('id' => 11, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titulek #2'),
|
||||
array('id' => 12, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Obsah #2'),
|
||||
array('id' => 13, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title #3'),
|
||||
array('id' => 14, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Content #3'),
|
||||
array('id' => 15, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titel #3'),
|
||||
array('id' => 16, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Inhalt #3'),
|
||||
array('id' => 17, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titulek #3'),
|
||||
array('id' => 18, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Obsah #3')
|
||||
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
|
||||
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
|
||||
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
|
||||
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
|
||||
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1'),
|
||||
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Obsah #1'),
|
||||
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title #2'),
|
||||
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Content #2'),
|
||||
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titel #2'),
|
||||
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Inhalt #2'),
|
||||
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titulek #2'),
|
||||
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Obsah #2'),
|
||||
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title #3'),
|
||||
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Content #3'),
|
||||
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titel #3'),
|
||||
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Inhalt #3'),
|
||||
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titulek #3'),
|
||||
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Obsah #3')
|
||||
);
|
||||
}
|
||||
|
|
|
@ -177,8 +177,8 @@ class CakeFixtureManager {
|
|||
|
||||
$cacheSources = $db->cacheSources;
|
||||
$db->cacheSources = false;
|
||||
$db->cacheSources = $cacheSources;
|
||||
$sources = $db->listSources();
|
||||
$db->cacheSources = $cacheSources;
|
||||
$table = $db->config['prefix'] . $fixture->table;
|
||||
|
||||
if ($drop && in_array($table, $sources)) {
|
||||
|
@ -206,6 +206,7 @@ class CakeFixtureManager {
|
|||
return;
|
||||
}
|
||||
|
||||
$test->db->begin();
|
||||
foreach ($fixtures as $f) {
|
||||
if (!empty($this->_loaded[$f])) {
|
||||
$fixture = $this->_loaded[$f];
|
||||
|
@ -213,6 +214,7 @@ class CakeFixtureManager {
|
|||
$fixture->insert($test->db);
|
||||
}
|
||||
}
|
||||
$test->db->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -165,11 +165,10 @@ class CakeTestFixture {
|
|||
public function insert(&$db) {
|
||||
if (!isset($this->_insert)) {
|
||||
$values = array();
|
||||
|
||||
if (isset($this->records) && !empty($this->records)) {
|
||||
foreach ($this->records as $record) {
|
||||
$fields = array_keys($record);
|
||||
$values[] = '(' . implode(', ', array_map(array(&$db, 'value'), array_values($record))) . ')';
|
||||
$values[] = array_values($record);
|
||||
}
|
||||
return $db->insertMulti($this->table, $fields, $values);
|
||||
}
|
||||
|
|
|
@ -263,7 +263,7 @@ class DataSource extends Object {
|
|||
* @param Model $model
|
||||
* @return array Array of Metadata for the $model
|
||||
*/
|
||||
public function describe(&$model) {
|
||||
public function describe($model) {
|
||||
if ($this->cacheSources === false) {
|
||||
return null;
|
||||
}
|
||||
|
@ -556,7 +556,7 @@ class DataSource extends Object {
|
|||
* @param string $key Key name to make
|
||||
* @return string Key name for model.
|
||||
*/
|
||||
public function resolveKey(&$model, $key) {
|
||||
public function resolveKey($model, $key) {
|
||||
return $model->alias . $key;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,22 @@ class DboSource extends DataSource {
|
|||
*/
|
||||
private $__sqlOps = array('like', 'ilike', 'or', 'not', 'in', 'between', 'regexp', 'similar to');
|
||||
|
||||
/**
|
||||
* Indicates that a transaction have been started
|
||||
*
|
||||
* @var boolean
|
||||
* @access protected
|
||||
*/
|
||||
protected $_transactionStarted = false;
|
||||
|
||||
/**
|
||||
* Indicates the level of nested transactions
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
protected $_transactionNesting = 0;
|
||||
|
||||
/**
|
||||
* Index of basic SQL commands
|
||||
*
|
||||
|
@ -160,18 +176,37 @@ class DboSource extends DataSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Prepares a value, or an array of values for database queries by quoting and escaping them.
|
||||
* Disconnects from database.
|
||||
*
|
||||
* @param mixed $data A value or an array of values to prepare.
|
||||
* @param string $column The column into which this data will be inserted
|
||||
* @param boolean $read Value to be used in READ or WRITE context
|
||||
* @return mixed Prepared value or array of values.
|
||||
* @return boolean True if the database could be disconnected, else false
|
||||
*/
|
||||
public function value($data, $column = null, $read = true) {
|
||||
function disconnect() {
|
||||
if (is_a($this->_result, 'PDOStatement')) {
|
||||
$this->_result->closeCursor();
|
||||
}
|
||||
unset($this->_connection);
|
||||
$this->connected = false;
|
||||
return !$this->connected;
|
||||
}
|
||||
|
||||
public function getConnection() {
|
||||
return $this->_connection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param string $column The column into which this data will be inserted
|
||||
* @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
|
||||
* @return string Quoted and escaped data
|
||||
*/
|
||||
function value($data, $column = null, $safe = false) {
|
||||
if (is_array($data) && !empty($data)) {
|
||||
return array_map(
|
||||
array(&$this, 'value'),
|
||||
$data, array_fill(0, count($data), $column), array_fill(0, count($data), $read)
|
||||
$data, array_fill(0, count($data), $column), array_fill(0, count($data), $safe)
|
||||
);
|
||||
} elseif (is_object($data) && isset($data->type)) {
|
||||
if ($data->type == 'identifier') {
|
||||
|
@ -181,11 +216,45 @@ class DboSource extends DataSource {
|
|||
}
|
||||
} elseif (in_array($data, array('{$__cakeID__$}', '{$__cakeForeignKey__$}'), true)) {
|
||||
return $data;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($data === null || (is_array($data) && empty($data))) {
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
if (empty($column)) {
|
||||
$column = $this->introspectType($data);
|
||||
}
|
||||
|
||||
switch ($column) {
|
||||
case 'binary':
|
||||
return $this->_connection->quote($data, PDO::PARAM_LOB);
|
||||
break;
|
||||
case 'boolean':
|
||||
return $this->_connection->quote($this->boolean($data), PDO::PARAM_BOOL);
|
||||
break;
|
||||
case 'string':
|
||||
case 'text':
|
||||
return $this->_connection->quote($data, PDO::PARAM_STR);
|
||||
default:
|
||||
if ($data === '') {
|
||||
return 'NULL';
|
||||
}
|
||||
if (is_float($data)) {
|
||||
return sprintf('%F', $data);
|
||||
}
|
||||
if ((is_int($data) || $data === '0') || (
|
||||
is_numeric($data) && strpos($data, ',') === false &&
|
||||
$data[0] != '0' && strpos($data, 'e') === false)
|
||||
) {
|
||||
return $data;
|
||||
}
|
||||
return $this->_connection->quote($data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an object to represent a database identifier in a query
|
||||
*
|
||||
|
@ -218,9 +287,9 @@ class DboSource extends DataSource {
|
|||
* @param string $sql SQL statement
|
||||
* @return boolean
|
||||
*/
|
||||
public function rawQuery($sql) {
|
||||
public function rawQuery($sql, $params = array()) {
|
||||
$this->took = $this->error = $this->numRows = false;
|
||||
return $this->execute($sql);
|
||||
return $this->execute($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,28 +299,23 @@ class DboSource extends DataSource {
|
|||
*
|
||||
* ### Options
|
||||
*
|
||||
* - stats - Collect meta data stats for this query. Stats include time take, rows affected,
|
||||
* any errors, and number of rows returned. Defaults to `true`.
|
||||
* - log - Whether or not the query should be logged to the memory log.
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $options
|
||||
* @param array $params values to be bided to the query
|
||||
* @return mixed Resource or object representing the result set, or false on failure
|
||||
*/
|
||||
public function execute($sql, $options = array()) {
|
||||
$defaults = array('stats' => true, 'log' => $this->fullDebug);
|
||||
$options = array_merge($defaults, $options);
|
||||
public function execute($sql, $options = array(), $params = array()) {
|
||||
$options = $options + array('log' => $this->fullDebug);
|
||||
$this->error = null;
|
||||
|
||||
$t = microtime(true);
|
||||
$this->_result = $this->_execute($sql);
|
||||
if ($options['stats']) {
|
||||
$this->took = round((microtime(true) - $t) * 1000, 0);
|
||||
$this->affected = $this->lastAffected();
|
||||
$this->error = $this->lastError();
|
||||
$this->numRows = $this->lastNumRows();
|
||||
}
|
||||
$this->_result = $this->_execute($sql, $params);
|
||||
|
||||
if ($options['log']) {
|
||||
$this->took = round((microtime(true) - $t) * 1000, 0);
|
||||
$this->numRows = $this->affected = $this->lastAffected();
|
||||
$this->logQuery($sql);
|
||||
}
|
||||
|
||||
|
@ -262,6 +326,83 @@ class DboSource extends DataSource {
|
|||
return $this->_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes given SQL statement.
|
||||
*
|
||||
* @param string $sql SQL statement
|
||||
* @param array $params list of params to be bound to query
|
||||
* @return PDOStatement if query executes with no problem, true as the result of a succesfull
|
||||
* query returning no rows, suchs as a CREATE statement, false otherwise
|
||||
*/
|
||||
protected function _execute($sql, $params = array()) {
|
||||
$sql = trim($sql);
|
||||
if (preg_match('/^CREATE|^ALTER|^DROP/i', $sql)) {
|
||||
$statements = array_filter(explode(';', $sql));
|
||||
if (count($statements) > 1) {
|
||||
$result = array_map(array($this, '_execute'), $statements);
|
||||
return array_search(false, $result) === false;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$query = $this->_connection->prepare($sql);
|
||||
$query->setFetchMode(PDO::FETCH_LAZY);
|
||||
if (!$query->execute($params)) {
|
||||
$this->_results = $query;
|
||||
$this->error = $this->lastError($query);
|
||||
$query->closeCursor();
|
||||
return false;
|
||||
}
|
||||
if (!$query->columnCount()) {
|
||||
$query->closeCursor();
|
||||
return true;
|
||||
}
|
||||
return $query;
|
||||
} catch (PDOException $e) {
|
||||
$this->_results = null;
|
||||
$this->error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted error message from previous database operation.
|
||||
*
|
||||
* @param PDOStatement $query the query to extract the error from if any
|
||||
* @return string Error message with error number
|
||||
*/
|
||||
function lastError(PDOStatement $query = null) {
|
||||
$error = $query->errorInfo();
|
||||
if (empty($error[2])) {
|
||||
return null;
|
||||
}
|
||||
return $error[1] . ': ' . $error[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of affected rows in previous database operation. If no previous operation exists,
|
||||
* this returns false.
|
||||
*
|
||||
* @return integer Number of affected rows
|
||||
*/
|
||||
function lastAffected($source = null) {
|
||||
if ($this->hasResult()) {
|
||||
return $this->_result->rowCount();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of rows in previous resultset. If no previous resultset exists,
|
||||
* this returns false.
|
||||
*
|
||||
* @return integer Number of rows in resultset
|
||||
*/
|
||||
function lastNumRows($source = null) {
|
||||
return $this->lastAffected($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataSource Query abstraction
|
||||
*
|
||||
|
@ -352,8 +493,7 @@ class DboSource extends DataSource {
|
|||
} else {
|
||||
$cache = true;
|
||||
}
|
||||
$args[1] = array_map(array(&$this, 'value'), $args[1]);
|
||||
return $this->fetchAll(String::insert($args[0], $args[1]), $cache);
|
||||
return $this->fetchAll($args[0], $args[1], array('cache' => $cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,16 +526,31 @@ class DboSource extends DataSource {
|
|||
* Returns an array of all result rows for a given SQL query.
|
||||
* Returns false if no rows matched.
|
||||
*
|
||||
*
|
||||
* ### Options
|
||||
*
|
||||
* - cache - Returns the cached version of the query, if exists and stores the result in cache
|
||||
*
|
||||
* @param string $sql SQL statement
|
||||
* @param boolean $cache Enables returning/storing cached query results
|
||||
* @param array $params parameters to be bound as values for the SQL statement
|
||||
* @param array $options additional options for the query.
|
||||
* @return array Array of resultset rows, or false if no rows matched
|
||||
*/
|
||||
public function fetchAll($sql, $cache = true, $modelName = null) {
|
||||
if ($cache && ($cached = $this->getQueryCache($sql)) !== false) {
|
||||
public function fetchAll($sql, $params = array(), $options = array()) {
|
||||
if (is_string($options)) {
|
||||
$options = array('modelName' => $options);
|
||||
}
|
||||
if (is_bool($params)) {
|
||||
$options['cache'] = $params;
|
||||
$params = array();
|
||||
}
|
||||
$defaults = array('cache' => true);
|
||||
$options = $options + $defaults;
|
||||
$cache = $options['cache'];
|
||||
if ($cache && ($cached = $this->getQueryCache($sql, $params)) !== false) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
if ($this->execute($sql)) {
|
||||
if ($result = $this->execute($sql, array(), $params)) {
|
||||
$out = array();
|
||||
|
||||
$first = $this->fetchRow();
|
||||
|
@ -407,9 +562,10 @@ class DboSource extends DataSource {
|
|||
$out[] = $item;
|
||||
}
|
||||
|
||||
if ($cache) {
|
||||
$this->_writeQueryCache($sql, $out);
|
||||
if (!is_bool($result) && $cache) {
|
||||
$this->_writeQueryCache($sql, $out, $params);
|
||||
}
|
||||
|
||||
if (empty($out) && is_bool($this->_result)) {
|
||||
return $this->_result;
|
||||
}
|
||||
|
@ -576,7 +732,7 @@ class DboSource extends DataSource {
|
|||
* @return boolean True if the result is valid else false
|
||||
*/
|
||||
public function hasResult() {
|
||||
return is_resource($this->_result);
|
||||
return is_a($this->_result, 'PDOStatement');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -784,7 +940,7 @@ class DboSource extends DataSource {
|
|||
|
||||
foreach ($_associations as $type) {
|
||||
foreach ($model->{$type} as $assoc => $assocData) {
|
||||
$linkModel =& $model->{$assoc};
|
||||
$linkModel = $model->{$assoc};
|
||||
$external = isset($assocData['external']);
|
||||
|
||||
if ($model->useDbConfig == $linkModel->useDbConfig) {
|
||||
|
@ -795,9 +951,9 @@ class DboSource extends DataSource {
|
|||
}
|
||||
}
|
||||
|
||||
$query = $this->generateAssociationQuery($model, $null, null, null, null, $queryData, false, $null);
|
||||
$query = trim($this->generateAssociationQuery($model, $null, null, null, null, $queryData, false, $null));
|
||||
|
||||
$resultSet = $this->fetchAll($query, $model->cacheQueries, $model->alias);
|
||||
$resultSet = $this->fetchAll($query, $model->cacheQueries);
|
||||
|
||||
if ($resultSet === false) {
|
||||
$model->onError();
|
||||
|
@ -809,16 +965,16 @@ class DboSource extends DataSource {
|
|||
if ($model->recursive > -1) {
|
||||
foreach ($_associations as $type) {
|
||||
foreach ($model->{$type} as $assoc => $assocData) {
|
||||
$linkModel =& $model->{$assoc};
|
||||
$linkModel = $model->{$assoc};
|
||||
|
||||
if (empty($linkedModels[$type . '/' . $assoc])) {
|
||||
if ($model->useDbConfig == $linkModel->useDbConfig) {
|
||||
$db =& $this;
|
||||
$db = $this;
|
||||
} else {
|
||||
$db =& ConnectionManager::getDataSource($linkModel->useDbConfig);
|
||||
$db = ConnectionManager::getDataSource($linkModel->useDbConfig);
|
||||
}
|
||||
} elseif ($model->recursive > 1 && ($type == 'belongsTo' || $type == 'hasOne')) {
|
||||
$db =& $this;
|
||||
$db = $this;
|
||||
}
|
||||
|
||||
if (isset($db) && method_exists($db, 'queryAssociation')) {
|
||||
|
@ -924,14 +1080,14 @@ class DboSource extends DataSource {
|
|||
if ($recursive > 0) {
|
||||
foreach ($linkModel->associations() as $type1) {
|
||||
foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
|
||||
$deepModel =& $linkModel->{$assoc1};
|
||||
$deepModel = $linkModel->{$assoc1};
|
||||
$tmpStack = $stack;
|
||||
$tmpStack[] = $assoc1;
|
||||
|
||||
if ($linkModel->useDbConfig === $deepModel->useDbConfig) {
|
||||
$db =& $this;
|
||||
$db = $this;
|
||||
} else {
|
||||
$db =& ConnectionManager::getDataSource($deepModel->useDbConfig);
|
||||
$db = ConnectionManager::getDataSource($deepModel->useDbConfig);
|
||||
}
|
||||
$db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
|
||||
}
|
||||
|
@ -966,7 +1122,7 @@ class DboSource extends DataSource {
|
|||
$q = $this->insertQueryData($query, null, $association, $assocData, $model, $linkModel, $stack);
|
||||
|
||||
if ($q != false) {
|
||||
$fetch = $this->fetchAll($q, $model->cacheQueries, $model->alias);
|
||||
$fetch = $this->fetchAll($q, $model->cacheQueries);
|
||||
} else {
|
||||
$fetch = null;
|
||||
}
|
||||
|
@ -978,7 +1134,7 @@ class DboSource extends DataSource {
|
|||
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);
|
||||
$fetch = $this->fetchAll($q, $model->cacheQueries);
|
||||
} else {
|
||||
$fetch = null;
|
||||
}
|
||||
|
@ -993,15 +1149,15 @@ class DboSource extends DataSource {
|
|||
if ($recursive > 0) {
|
||||
foreach ($linkModel->associations() as $type1) {
|
||||
foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
|
||||
$deepModel =& $linkModel->{$assoc1};
|
||||
$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;
|
||||
$db = $this;
|
||||
} else {
|
||||
$db =& ConnectionManager::getDataSource($deepModel->useDbConfig);
|
||||
$db = ConnectionManager::getDataSource($deepModel->useDbConfig);
|
||||
}
|
||||
$db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
|
||||
}
|
||||
|
@ -1053,7 +1209,7 @@ class DboSource extends DataSource {
|
|||
if (count($ids) > 1) {
|
||||
$query = str_replace('= (', 'IN (', $query);
|
||||
}
|
||||
return $this->fetchAll($query, $model->cacheQueries, $model->alias);
|
||||
return $this->fetchAll($query, $model->cacheQueries);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1764,14 +1920,14 @@ class DboSource extends DataSource {
|
|||
/**
|
||||
* Begin 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).
|
||||
*/
|
||||
public function begin(&$model) {
|
||||
if (parent::begin($model) && $this->execute($this->_commands['begin'])) {
|
||||
public function begin() {
|
||||
if ($this->_transactionStarted || $this->_connection->beginTransaction()) {
|
||||
$this->_transactionStarted = true;
|
||||
$this->_transactionNesting++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1780,14 +1936,18 @@ class DboSource extends DataSource {
|
|||
/**
|
||||
* 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).
|
||||
*/
|
||||
public function commit(&$model) {
|
||||
if (parent::commit($model) && $this->execute($this->_commands['commit'])) {
|
||||
$this->_transactionStarted = false;
|
||||
public function commit() {
|
||||
if ($this->_transactionStarted) {
|
||||
$this->_transactionNesting--;
|
||||
if ($this->_transactionNesting <= 0) {
|
||||
$this->_transactionStarted = false;
|
||||
$this->_transactionNesting = 0;
|
||||
return $this->_connection->commit();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1796,19 +1956,29 @@ class DboSource extends DataSource {
|
|||
/**
|
||||
* 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).
|
||||
*/
|
||||
public function rollback(&$model) {
|
||||
if (parent::rollback($model) && $this->execute($this->_commands['rollback'])) {
|
||||
public function rollback() {
|
||||
if ($this->_transactionStarted && $this->_connection->rollBack()) {
|
||||
$this->_transactionStarted = false;
|
||||
$this->_transactionNesting = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID generated from the previous INSERT operation.
|
||||
*
|
||||
* @param unknown_type $source
|
||||
* @return in
|
||||
*/
|
||||
function lastInsertId($source = null) {
|
||||
return $this->_connection->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a default set of conditions from the model if $conditions is null/empty.
|
||||
* If conditions are supplied then they will be returned. If a model doesn't exist and no conditions
|
||||
|
@ -2524,7 +2694,7 @@ class DboSource extends DataSource {
|
|||
* Translates between PHP boolean values and Database (faked) boolean values
|
||||
*
|
||||
* @param mixed $data Value to be translated
|
||||
* @return mixed Converted boolean value
|
||||
* @return int Converted boolean value
|
||||
*/
|
||||
public function boolean($data) {
|
||||
if ($data === true || $data === false) {
|
||||
|
@ -2533,7 +2703,7 @@ class DboSource extends DataSource {
|
|||
}
|
||||
return 0;
|
||||
} else {
|
||||
return !empty($data);
|
||||
return (int) !empty($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2546,13 +2716,18 @@ class DboSource extends DataSource {
|
|||
*/
|
||||
public function insertMulti($table, $fields, $values) {
|
||||
$table = $this->fullTableName($table);
|
||||
if (is_array($fields)) {
|
||||
$fields = implode(', ', array_map(array(&$this, 'name'), $fields));
|
||||
}
|
||||
$holder = implode(',', array_fill(0, count($fields), '?'));
|
||||
$fields = implode(', ', array_map(array(&$this, 'name'), $fields));
|
||||
|
||||
$count = count($values);
|
||||
$sql = "INSERT INTO {$table} ({$fields}) VALUES ({$holder})";
|
||||
$statement = $this->_connection->prepare($sql);
|
||||
$this->begin();
|
||||
for ($x = 0; $x < $count; $x++) {
|
||||
$this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
|
||||
$statement->execute($values[$x]);
|
||||
$statement->closeCursor();
|
||||
}
|
||||
return $this->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2867,11 +3042,12 @@ class DboSource extends DataSource {
|
|||
*
|
||||
* @param string $sql SQL query
|
||||
* @param mixed $data result of $sql query
|
||||
* @param array $params query params bound as values
|
||||
* @return void
|
||||
*/
|
||||
protected function _writeQueryCache($sql, $data) {
|
||||
if (strpos(trim(strtolower($sql)), 'select') !== false) {
|
||||
$this->_queryCache[$sql] = $data;
|
||||
protected function _writeQueryCache($sql, $data, $params = array()) {
|
||||
if (preg_match('/^\s*select/i', $sql)) {
|
||||
$this->_queryCache[$sql][serialize($params)] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2879,11 +3055,15 @@ class DboSource extends DataSource {
|
|||
* Returns the result for a sql query if it is already cached
|
||||
*
|
||||
* @param string $sql SQL query
|
||||
* @param array $params query params bound as values
|
||||
* @return mixed results for query if it is cached, false otherwise
|
||||
*/
|
||||
public function getQueryCache($sql = null) {
|
||||
public function getQueryCache($sql, $params = array()) {
|
||||
if (isset($this->_queryCache[$sql]) && preg_match('/^\s*select/i', $sql)) {
|
||||
return $this->_queryCache[$sql];
|
||||
$serialized = serialize($params);
|
||||
if (isset($this->_queryCache[$sql][$serialized])) {
|
||||
return $this->_queryCache[$sql][$serialized];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -904,9 +904,6 @@ class Model extends Object {
|
|||
|
||||
$dateFields = array('Y' => 'year', 'm' => 'month', 'd' => 'day', 'H' => 'hour', 'i' => 'min', 's' => 'sec');
|
||||
$timeFields = array('H' => 'hour', 'i' => 'min', 's' => 'sec');
|
||||
|
||||
$db = $this->getDataSource();
|
||||
$format = $db->columns[$type]['format'];
|
||||
$date = array();
|
||||
|
||||
if (isset($data['hour']) && isset($data['meridian']) && $data['hour'] != 12 && 'pm' == $data['meridian']) {
|
||||
|
@ -949,9 +946,13 @@ class Model extends Object {
|
|||
}
|
||||
}
|
||||
}
|
||||
$date = str_replace(array_keys($date), array_values($date), $format);
|
||||
|
||||
$format = $this->getDataSource()->columns[$type]['format'];
|
||||
$day = empty($date['Y']) ? null : $date['Y'] . '-' . $date['m'] . '-' . $date['d'] . ' ';
|
||||
$hour = empty($date['H']) ? null : $date['H'] . ':' . $date['i'] . ':' . $date['s'];
|
||||
$date = new DateTime($day . $hour);
|
||||
if ($useNewDate && !empty($date)) {
|
||||
return $date;
|
||||
return $date->format($format);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
|
@ -1449,15 +1450,11 @@ class Model extends Object {
|
|||
|
||||
foreach ((array)$data as $row) {
|
||||
if ((is_string($row) && (strlen($row) == 36 || strlen($row) == 16)) || is_numeric($row)) {
|
||||
$values = array(
|
||||
$db->value($id, $this->getColumnType($this->primaryKey)),
|
||||
$db->value($row)
|
||||
);
|
||||
$values = array($id, $row);
|
||||
if ($isUUID && $primaryAdded) {
|
||||
$values[] = $db->value(String::uuid());
|
||||
$values[] = String::uuid();
|
||||
}
|
||||
$values = implode(',', $values);
|
||||
$newValues[] = "({$values})";
|
||||
$newValues[] = $values;
|
||||
unset($values);
|
||||
} elseif (isset($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
|
||||
$newData[] = $row;
|
||||
|
@ -1496,7 +1493,6 @@ class Model extends Object {
|
|||
}
|
||||
|
||||
if (!empty($newValues)) {
|
||||
$fields = implode(',', $fields);
|
||||
$db->insertMulti($this->{$join}, $fields, $newValues);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue