Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add HydratingResultSet::toEntityArray() #2024

Closed
wants to merge 4 commits into from

6 participants

@EvanDotPro
Collaborator

No description provided.

@ralphschindler
Collaborator

I think I'd rather see toArray($useHydrator = true), where you can simple do $rs->toArray(false) (or optionally more explicitly: $rs->toArray($rs::UNHYDRATED);, and the default be toArray(self::HYDRATED)

The word "entity" is purely a term that should reside in the "modeling" layer, not in the Db layer.

@travisbot

This pull request passes (merged 25d000e into 37b25cf).

@EvanDotPro
Collaborator

@ralphschindler, updated and added unit tests for the HydratingResultSet.

@adamlundrigan adamlundrigan commented on the diff
library/Zend/Db/ResultSet/HydratingResultSet.php
((10 lines not shown))
{
$return = array();
foreach ($this as $row) {
- $return[] = $this->getHydrator()->extract($row);
+ if ($useHydrator === self::ARRAY_RAW) {

This feels backwards to me. Specifying ARRAY_HYDRATE returns an array extracted from the hydrated object whereas ARRAY_RAW returns the hydrated objects themselves. Should the naming be flipped, or am I misunderstanding the terminology?

The only change I had to make to have this work as I expect is to sub this in at L120:

if ($useHydrator === self::ARRAY_HYDRATE) {
@EvanDotPro Collaborator

Ping @ralphschindler. Thoughts?

Edit: I'd have to say I agree with @adamlundrigan on this one.

@ralphschindler Collaborator

I don't follow you :).

If $useHydrator = true/self::ARRAY_HYDRATE, it runs

$return[] = $this->getHydrator()->extract($row);

In all other cases (false, or self::ARRAY_ROW), it runs

$return[] = $row;

Or am I missing something?

Here's a practical example, using ZfcUser:
($mapper is instance of ZfcBase\Mapper\AbstractDbMapper)

$select = new \Zend\Db\Sql\Select();
$select->from('user');
var_dump($mapper->selectWith($select)->toArray($mode));

var_dump output when $mode = HydratingResultSet::ARRAY_RAW:

array (size=2)
  0 => 
    object(ZfcUser\Entity\User)[500]
      protected 'id' => int 1
      protected 'username' => string 'PS158749' (length=8)
      protected 'email' => string 'adamlundrigan@cdli.ca' (length=21)
      protected 'displayName' => string 'Lundrigan, Adam' (length=15)
      protected 'password' => string '*****' (length=60)
  1 => 
    object(ZfcUser\Entity\User)[505]
      protected 'id' => int 2
      protected 'username' => string 'PS842124' (length=8)
      protected 'email' => string 'foo@bar.com' (length=11)
      protected 'displayName' => string 'McTesterson, Testy' (length=18)
      protected 'password' => string '*****' (length=60)

var_dump output when $mode = HydratingResultSet::ARRAY_HYDRATE:

array (size=2)
  0 => 
    array (size=5)
      'username' => string 'PS158749' (length=8)
      'email' => string 'adamlundrigan@cdli.ca' (length=21)
      'display_name' => string 'Lundrigan, Adam' (length=15)
      'password' => string '*****' (length=60)
      'user_id' => int 1
  1 => 
    array (size=5)
      'username' => string 'PS842124' (length=8)
      'email' => string 'foo@bar.com' (length=11)
      'display_name' => string 'McTesterson, Testy' (length=18)
      'password' => string '*****' (length=60)
      'user_id' => int 2

I would expect the behaviour to be opposite. Currently, RAW reutrns hydrated objects and HYDRATE returns raw rows.

@ralphschindler Collaborator

Right, I discussed with @EvanDotPro - I see whats going on. Basically, we shouldn't be iterating $this, if we want raw values. We should be iterating the datasource. When iterating $this, current() is called, thus the hydrator is used. I don't think this is the desired behavior, or, if it is, it needs to have a special flag.

We need to update this PR such that it will actually return unadulterated raw values from the datasource instead of passing through the hydrator.

@EvanDotPro Collaborator

Will look into this later today or tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@Maks3w
Collaborator

Hi,

We have renamed the folder for tests from Zend to ZendTest.

Can you rebase your PR to catch this change?

Thanks in advance.

@ralphschindler
Collaborator

At this point, I think this commit will need to wait until 2.1.

@weierophinney

@EvanDotPro what's the status of this? Last comment I see from you indicates more work was pending, but I see no new commits. Want to get this into 2.1?

@weierophinney weierophinney reopened this
@weierophinney

Closing, per instructions from @EvanDotPro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
22 library/Zend/Db/ResultSet/HydratingResultSet.php
@@ -21,6 +21,8 @@
*/
class HydratingResultSet extends AbstractResultSet
{
+ const ARRAY_HYDRATE = true;
+ const ARRAY_RAW = false;
/**
* @var HydratorInterface
*/
@@ -62,6 +64,16 @@ public function setObjectPrototype($objectPrototype)
}
/**
+ * Get the object prototype
+ *
+ * @return objet
+ */
+ public function getObjectPrototype()
+ {
+ return $this->objectPrototype;
+ }
+
+ /**
* Set the hydrator to use for each row object
*
* @param HydratorInterface $rowObjectHydrator
@@ -97,16 +109,20 @@ public function current()
/**
* Cast result set to array of arrays
*
+ * @param bool $useHydrator
* @return array
* @throws Exception\RuntimeException if any row is not castable to an array
*/
- public function toArray()
+ public function toArray($useHydrator = self::ARRAY_HYDRATE)
{
$return = array();
foreach ($this as $row) {
- $return[] = $this->getHydrator()->extract($row);
+ if ($useHydrator === self::ARRAY_RAW) {

This feels backwards to me. Specifying ARRAY_HYDRATE returns an array extracted from the hydrated object whereas ARRAY_RAW returns the hydrated objects themselves. Should the naming be flipped, or am I misunderstanding the terminology?

The only change I had to make to have this work as I expect is to sub this in at L120:

if ($useHydrator === self::ARRAY_HYDRATE) {
@EvanDotPro Collaborator

Ping @ralphschindler. Thoughts?

Edit: I'd have to say I agree with @adamlundrigan on this one.

@ralphschindler Collaborator

I don't follow you :).

If $useHydrator = true/self::ARRAY_HYDRATE, it runs

$return[] = $this->getHydrator()->extract($row);

In all other cases (false, or self::ARRAY_ROW), it runs

$return[] = $row;

Or am I missing something?

Here's a practical example, using ZfcUser:
($mapper is instance of ZfcBase\Mapper\AbstractDbMapper)

$select = new \Zend\Db\Sql\Select();
$select->from('user');
var_dump($mapper->selectWith($select)->toArray($mode));

var_dump output when $mode = HydratingResultSet::ARRAY_RAW:

array (size=2)
  0 => 
    object(ZfcUser\Entity\User)[500]
      protected 'id' => int 1
      protected 'username' => string 'PS158749' (length=8)
      protected 'email' => string 'adamlundrigan@cdli.ca' (length=21)
      protected 'displayName' => string 'Lundrigan, Adam' (length=15)
      protected 'password' => string '*****' (length=60)
  1 => 
    object(ZfcUser\Entity\User)[505]
      protected 'id' => int 2
      protected 'username' => string 'PS842124' (length=8)
      protected 'email' => string 'foo@bar.com' (length=11)
      protected 'displayName' => string 'McTesterson, Testy' (length=18)
      protected 'password' => string '*****' (length=60)

var_dump output when $mode = HydratingResultSet::ARRAY_HYDRATE:

array (size=2)
  0 => 
    array (size=5)
      'username' => string 'PS158749' (length=8)
      'email' => string 'adamlundrigan@cdli.ca' (length=21)
      'display_name' => string 'Lundrigan, Adam' (length=15)
      'password' => string '*****' (length=60)
      'user_id' => int 1
  1 => 
    array (size=5)
      'username' => string 'PS842124' (length=8)
      'email' => string 'foo@bar.com' (length=11)
      'display_name' => string 'McTesterson, Testy' (length=18)
      'password' => string '*****' (length=60)
      'user_id' => int 2

I would expect the behaviour to be opposite. Currently, RAW reutrns hydrated objects and HYDRATE returns raw rows.

@ralphschindler Collaborator

Right, I discussed with @EvanDotPro - I see whats going on. Basically, we shouldn't be iterating $this, if we want raw values. We should be iterating the datasource. When iterating $this, current() is called, thus the hydrator is used. I don't think this is the desired behavior, or, if it is, it needs to have a special flag.

We need to update this PR such that it will actually return unadulterated raw values from the datasource instead of passing through the hydrator.

@EvanDotPro Collaborator

Will look into this later today or tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $return[] = $row;
+ } else {
+ $return[] = $this->getHydrator()->extract($row);
+ }
}
return $return;
}
-
}
View
100 tests/Zend/Db/ResultSet/HydratingResultSetTest.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Db
+ */
+
+namespace ZendTest\Db\ResultSet;
+
+use PHPUnit_Framework_TestCase as TestCase;
+use Zend\Db\ResultSet\HydratingResultSet;
+use Zend\Stdlib\Hydrator\ObjectProperty;
+use Zend\Stdlib\Hydrator\ArraySerializable;
+use ArrayObject;
+use StdClass;
+
+/**
+ * @category Zend
+ * @package Zend_Db
+ * @subpackage UnitTest
+ */
+class HydratingResultSetTest extends TestCase
+{
+ /**
+ * @var ResultSet
+ */
+ protected $resultSet;
+
+ /**
+ * Sets up the fixture, for example, opens a network connection.
+ * This method is called before a test is executed.
+ */
+ protected function setUp()
+ {
+ $this->resultSet = new HydratingResultSet;
+ }
+
+ public function testRowObjectPrototypeIsArrayObjectAndHydratorIsArraySerializableByDefault()
+ {
+ $row = $this->resultSet->getObjectPrototype();
+ $this->assertInstanceOf('ArrayObject', $row);
+
+ $hydrator = $this->resultSet->getHydrator();
+ $this->assertInstanceOf('Zend\Stdlib\Hydrator\ArraySerializable', $hydrator);
+ }
+
+ public function testRowObjectPrototypeIsMutable()
+ {
+ $row = new StdClass();
+ $this->resultSet->setObjectPrototype($row);
+ $this->assertSame($row, $this->resultSet->getObjectPrototype());
+ }
+
+ public function testHydratorAndRowObjectPrototypeMayBePassedToConstructor()
+ {
+ $row = new StdClass();
+ $hydrator = new ObjectProperty;
+ $resultSet = new HydratingResultSet($hydrator, $row);
+ $this->assertSame($row, $resultSet->getObjectPrototype());
+ $this->assertSame($hydrator, $resultSet->getHydrator());
+ }
+
+ public function getData()
+ {
+ return array(
+ array(
+ 'id' => 1,
+ 'title' => 'hello',
+ )
+ );
+ }
+
+ public function testObjectPrototypeIsHydratedByHydrator()
+ {
+ $resultSet = new HydratingResultSet(new ObjectProperty, new StdClass);
+ $resultSet->initialize($this->getData());
+ $row = $resultSet->current();
+ $this->assertEquals(1, $row->id);
+ $this->assertEquals('hello', $row->title);
+ }
+
+ public function testToArrayReturnsArrayOfArraysByDefault()
+ {
+ $resultSet = new HydratingResultSet(new ObjectProperty, new StdClass);
+ $resultSet->initialize($this->getData());
+ $array = $resultSet->toArray();
+ $this->assertEquals($this->getData(), $array);
+ }
+
+ public function testToArrayReturnsArrayOfHydratedObjects()
+ {
+ $resultSet = new HydratingResultSet(new ObjectProperty, new StdClass);
+ $resultSet->initialize($this->getData());
+ $array = $resultSet->toArray(HydratingResultSet::ARRAY_RAW);
+ $this->assertInstanceOf('StdClass', $array[0]);
+ }
+}
Something went wrong with that request. Please try again.