Merge branch '1.3' into merger

Conflicts:
	cake/basics.php
	cake/console/libs/tasks/extract.php
	cake/libs/view/helpers/js.php
	cake/tests/cases/console/libs/tasks/extract.test.php
	cake/tests/cases/libs/model/datasources/dbo/dbo_mysql.test.php
	cake/tests/cases/libs/model/datasources/dbo_source.test.php
	cake/tests/test_app/views/pages/extract.ctp
	lib/Cake/Cache/Engine/MemcacheEngine.php
	lib/Cake/Model/Behavior/ContainableBehavior.php
	lib/Cake/Model/Datasource/Database/Mysql.php
	lib/Cake/Model/Datasource/DboSource.php
	lib/Cake/Model/Model.php
	lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php
	lib/Cake/Test/Case/Model/CakeSchemaTest.php
	lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php
	lib/Cake/Test/Case/View/Helper/FormHelperTest.php
	lib/Cake/Test/Case/View/Helper/TimeHelperTest.php
This commit is contained in:
mark_story 2011-09-18 12:09:04 -04:00
commit 6a4e7558fc
12 changed files with 110 additions and 38 deletions

View file

@ -89,12 +89,15 @@ class MemcacheEngine extends CacheEngine {
/**
* Parses the server address into the host/port. Handles both IPv6 and IPv4
* addresses
* addresses and Unix sockets
*
* @param string $server The server address string.
* @return array Array containing host, port
*/
protected function _parseServerString($server) {
if ($server[0] == 'u') {
return array($server, 0);
}
if (substr($server, 0, 1) == '[') {
$position = strpos($server, ']:');
if ($position !== false) {

View file

@ -148,8 +148,6 @@ class ContainableBehavior extends ModelBehavior {
if (!empty($unbind)) {
if (!$reset && empty($instance->__backOriginalAssociation)) {
$instance->__backOriginalAssociation = $backupBindings;
} else if ($reset && empty($instance->__backContainableAssociation)) {
$instance->__backContainableAssociation = $backupBindings;
}
$instance->unbindModel(array($type => $unbind), $reset);
}
@ -221,24 +219,6 @@ class ContainableBehavior extends ModelBehavior {
return $query;
}
/**
* Resets original associations on models that may have receive multiple,
* subsequent unbindings.
*
* @param Model $Model Model on which we are resetting
* @param array $results Results of the find operation
* @param boolean $primary true if this is the primary model that issued the find operation, false otherwise
* @return void
*/
public function afterFind($Model, $results, $primary) {
if (!empty($Model->__backContainableAssociation)) {
foreach ($Model->__backContainableAssociation as $relation => $bindings) {
$Model->{$relation} = $bindings;
unset($Model->__backContainableAssociation);
}
}
}
/**
* Unbinds all relations from a model except the specified ones. Calling this function without
* parameters unbinds all related models.

View file

@ -480,11 +480,7 @@ class Postgres extends DboSource {
case 'add':
foreach ($column as $field => $col) {
$col['name'] = $field;
$alter = 'ADD COLUMN '.$this->buildColumn($col);
if (isset($col['after'])) {
$alter .= ' AFTER '. $this->name($col['after']);
}
$colList[] = $alter;
$colList[] = 'ADD COLUMN '.$this->buildColumn($col);
}
break;
case 'drop':
@ -503,8 +499,7 @@ class Postgres extends DboSource {
$default = isset($col['default']) ? $col['default'] : null;
$nullable = isset($col['null']) ? $col['null'] : null;
unset($col['default'], $col['null']);
$colList[] = 'ALTER COLUMN '. $fieldName .' TYPE ' . str_replace($fieldName, '', $this->buildColumn($col));
$colList[] = 'ALTER COLUMN '. $fieldName .' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col));
if (isset($nullable)) {
$nullable = ($nullable) ? 'DROP NOT NULL' : 'SET NOT NULL';
$colList[] = 'ALTER COLUMN '. $fieldName .' ' . $nullable;

View file

@ -328,7 +328,7 @@ class DboSource extends DataSource {
return 'NULL';
}
if (is_float($data)) {
return sprintf('%F', $data);
return str_replace(',', '.', sprintf('%G', $data));
}
if ((is_int($data) || $data === '0') || (
is_numeric($data) && strpos($data, ',') === false &&
@ -2381,8 +2381,8 @@ class DboSource extends DataSource {
* @return string
*/
protected function _parseKey($model, $key, $value) {
$operatorMatch = '/^((' . implode(')|(', $this->_sqlOps);
$operatorMatch .= '\\x20)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)/is';
$operatorMatch = '/^(((' . implode(')|(', $this->_sqlOps);
$operatorMatch .= ')\\x20?)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)/is';
$bound = (strpos($key, '?') !== false || (is_array($value) && strpos($key, ':') !== false));
if (strpos($key, ' ') === false) {

View file

@ -2432,6 +2432,8 @@ class Model extends Object {
* - If three fields are specified, they are used (in order) for key, value and group.
* - Otherwise, first and second fields are used for key and value.
*
* Note: find(list) + database views have issues with MySQL 5.0. Try upgrading to MySQL 5.1 if you
* have issues with database views.
* @param string $type Type of find operation (all / first / count / neighbors / list / threaded)
* @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks)
* @return array Array of records

View file

@ -164,6 +164,17 @@ class MemcacheEngineTest extends CakeTestCase {
$this->assertEqual($result, array('sülül', '1111'));
}
/**
* test unix sockets.
*
* @return void
*/
function testParseServerStringUnix() {
$Memcache =& new TestMemcacheEngine();
$result = $Memcache->parseServerString('unix:///path/to/memcached.sock');
$this->assertEqual($result, array('unix:///path/to/memcached.sock', 0));
}
/**
* testReadAndWriteCache method
*

View file

@ -36,7 +36,8 @@ class ContainableBehaviorTest extends CakeTestCase {
public $fixtures = array(
'core.article', 'core.article_featured', 'core.article_featureds_tags',
'core.articles_tag', 'core.attachment', 'core.category',
'core.comment', 'core.featured', 'core.tag', 'core.user'
'core.comment', 'core.featured', 'core.tag', 'core.user',
'core.join_a', 'core.join_b', 'core.join_c', 'core.join_a_c', 'core.join_a_b'
);
/**
@ -3303,6 +3304,21 @@ class ContainableBehaviorTest extends CakeTestCase {
$this->assertEqual($expected, array_keys($result));
$this->assertTrue(empty($this->Article->hasMany['ArticlesTag']));
$this->JoinA =& ClassRegistry::init('JoinA');
$this->JoinB =& ClassRegistry::init('JoinB');
$this->JoinC =& ClassRegistry::init('JoinC');
$this->JoinA->Behaviors->attach('Containable');
$this->JoinB->Behaviors->attach('Containable');
$this->JoinC->Behaviors->attach('Containable');
$this->JoinA->JoinB->find('all', array('contain' => array('JoinA')));
$this->JoinA->bindModel(array('hasOne' => array('JoinAsJoinC' => array('joinTable' => 'as_cs'))), false);
$result = $this->JoinA->hasOne;
$this->JoinA->find('all');
$resultAfter = $this->JoinA->hasOne;
$this->assertEqual($result, $resultAfter);
}
/**

View file

@ -150,14 +150,33 @@ class MysqlTest extends CakeTestCase {
setlocale(LC_ALL, 'de_DE');
$result = $this->Dbo->value(3.141593, 'float');
$this->assertEqual((string)$result, '3.141593');
$this->assertTrue(strpos((string)$result, ',') === false);
$result = $this->Dbo->value(3.141593);
$this->assertEqual((string)$result, '3.141593');
$this->assertTrue(strpos((string)$result, ',') === false);
$result = $this->db->value(2.2E-54, 'float');
$this->assertEqual('2.2E-54', (string)$result);
$result = $this->db->value(2.2E-54);
$this->assertEqual('2.2E-54', (string)$result);
setlocale(LC_ALL, $restore);
}
/**
* test that scientific notations are working correctly
*
* @return void
*/
function testScientificNotation() {
$result = $this->db->value(2.2E-54, 'float');
$this->assertEqual('2.2E-54', (string)$result);
$result = $this->db->value(2.2E-54);
$this->assertEqual('2.2E-54', (string)$result);
}
/**
* testTinyintCasting method
*
@ -1856,6 +1875,11 @@ class MysqlTest extends CakeTestCase {
$result = $this->Dbo->conditions($conditions);
$expected = " WHERE `Artist`.`name` = 'JUDY AND MARY'";
$this->assertEqual($expected, $result);
$conditions = array('Company.name similar to ' => 'a word');
$result = $this->Dbo->conditions($conditions);
$expected = " WHERE `Company`.`name` similar to 'a word'";
$this->assertEqual($result, $expected);
}
/**
@ -2006,11 +2030,11 @@ class MysqlTest extends CakeTestCase {
$this->assertEqual($expected, $result);
$result = $this->Dbo->conditions(array('score BETWEEN ? AND ?' => array(90.1, 95.7)));
$expected = " WHERE `score` BETWEEN 90.100000 AND 95.700000";
$expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
$this->assertEqual($expected, $result);
$result = $this->Dbo->conditions(array('Post.title' => 1.1));
$expected = " WHERE `Post`.`title` = 1.100000";
$expected = " WHERE `Post`.`title` = 1.1";
$this->assertEqual($expected, $result);
$result = $this->Dbo->conditions(array('Post.title' => 1.1), true, true, new Post());
@ -2025,6 +2049,10 @@ class MysqlTest extends CakeTestCase {
$expected = " WHERE MAX(`Post`.`rating`) > '50'";
$this->assertEqual($expected, $result);
$result = $this->Dbo->conditions(array('lower(Article.title)' => 'secrets'));
$expected = " WHERE lower(`Article`.`title`) = 'secrets'";
$this->assertEqual($result, $expected);
$result = $this->Dbo->conditions(array('title LIKE' => '%hello'));
$expected = " WHERE `title` LIKE '%hello'";
$this->assertEqual($expected, $result);

View file

@ -656,6 +656,22 @@ class PostgresTest extends CakeTestCase {
$this->assertEqual($result['title']['null'], false);
$this->Dbo->query($this->Dbo->dropSchema($New));
$New = new CakeSchema(array(
'connection' => 'test_suite',
'name' => 'AlterPosts',
'alter_posts' => array(
'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
'author_id' => array('type' => 'integer', 'null' => false),
'title' => array('type' => 'string', 'null' => true),
'body' => array('type' => 'text'),
'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
'created' => array('type' => 'datetime'),
'updated' => array('type' => 'datetime'),
)
));
$result = $this->Dbo->alterSchema($New->compare($Old), 'alter_posts');
$this->assertNoPattern('/varchar\(36\) NOT NULL/i', $result);
}
/**

View file

@ -396,6 +396,16 @@ class TimeHelperTest extends CakeTestCase {
*/
public function testToRss() {
$this->assertEqual(date('r'), $this->Time->toRss(time()));
if (!$this->skipIf(!class_exists('DateTimeZone'), '%s DateTimeZone class not available.')) {
$timezones = array('Europe/London', 'Europe/Brussels', 'UTC', 'America/Denver', 'America/Caracas', 'Asia/Kathmandu');
foreach($timezones as $timezone) {
$yourTimezone = new DateTimeZone($timezone);
$yourTime = new DateTime('now', $yourTimezone);
$userOffset = $yourTimezone->getOffset($yourTime) / HOUR;
$this->assertEqual($yourTime->format('r'), $this->Time->toRss(time(), $userOffset));
}
}
}
/**

View file

@ -74,7 +74,7 @@ class JsHelper extends AppHelper {
*
* @var string
*/
public $setVariable = APP_DIR;
public $setVariable = 'app';
/**
* Constructor - determines engine helper
@ -419,4 +419,4 @@ class JsHelper extends AppHelper {
}
return array($options, $htmlOptions);
}
}
}

View file

@ -454,6 +454,17 @@ class TimeHelper extends AppHelper {
*/
public function toRSS($dateString, $userOffset = null) {
$date = $this->fromString($dateString, $userOffset);
if(!is_null($userOffset)) {
if($userOffset == 0) {
$timezone = '+0000';
} else {
$hours = (int) floor(abs($userOffset));
$minutes = (int) (fmod(abs($userOffset), $hours) * 60);
$timezone = ($userOffset < 0 ? '-' : '+') . str_pad($hours, 2, '0', STR_PAD_LEFT) . str_pad($minutes, 2, '0', STR_PAD_LEFT);
}
return date('D, d M Y H:i:s', $date) . ' ' . $timezone;
}
return date("r", $date);
}