Skip to content
Permalink
Browse files

Ensure that only one typecaster is attached.

If multiple type casters are attached we waste cycles. More importantly,
we also cause fatal errors for folks loading datetimes in non-english
locales.

Refs #8157
  • Loading branch information...
markstory committed Feb 3, 2016
1 parent 0b33513 commit 0571c5c65f8cec892e13c7a93d61e7482c7a73c5
Showing with 31 additions and 2 deletions.
  1. +10 −1 src/Database/Query.php
  2. +0 −1 tests/TestCase/Database/QueryTest.php
  3. +21 −0 tests/TestCase/ORM/QueryTest.php
@@ -129,6 +129,13 @@ class Query implements ExpressionInterface, IteratorAggregate
*/
protected $_selectTypeMap;
/**
* Tracking flag to ensure only one type caster is appended.
*
* @var bool
*/
protected $_typeCastAttached = false;
/**
* Constructor.
*
@@ -183,8 +190,9 @@ public function execute()
$driver = $this->_connection->driver();
$typeMap = $this->selectTypeMap();
if ($typeMap->toArray()) {
if ($typeMap->toArray() && $this->_typeCastAttached === false) {
$this->decorateResults(new FieldTypeConverter($typeMap, $driver));
$this->_typeCastAttached = true;
}
$this->_iterator = $this->_decorateStatement($statement);
@@ -1630,6 +1638,7 @@ public function decorateResults($callback, $overwrite = false)
{
if ($overwrite) {
$this->_resultDecorators = [];
$this->_typeCastAttached = false;
}
if ($callback !== null) {
@@ -3547,7 +3547,6 @@ public function testSelectTypeMap()
public function testSelectTypeConversion()
{
$query = new Query($this->connection);
$time = new \DateTime('2007-03-18 10:50:00');
$query
->select(['id', 'comment', 'the_date' => 'created'])
->from('comments')
@@ -3197,4 +3197,25 @@ public function testNotMatchingNested()
];
$this->assertEquals($expected, $results->first());
}
/**
* Test that type conversion is only applied once.
*
* @return void
*/
public function testAllNoDuplicateTypeCasting()
{
$table = TableRegistry::get('Comments');
$query = $table->find()
->select(['id', 'comment', 'created']);
// Convert to an array and make the query dirty again.
$result = $query->all()->toArray();
$query->limit(99);
// Get results a second time.
$result2 = $query->all()->toArray();
$this->assertEquals(1, $query->__debugInfo()['decorators'], 'Only one typecaster should exist');
}
}

0 comments on commit 0571c5c

Please sign in to comment.
You can’t perform that action at this time.