Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* BC deleted Metadata setter & getter
* BC deleted deprecated methods on Mysqli and Pgsql drivers
* BC deleted CCMBenchmark\Ting\Query\Generator::getByCriteriaWithOrderAndLimit, use CCMBenchmark\Ting\Query\Generator::getByCriteria
* New feature: HydratorValueObject allows hydrating simple objects without metadata using native fetch_object() methods

3.12.0 (2025-04-17):
* add __debuginfo() in NotifyInterface to reduce context when dumping an entity
Expand Down
13 changes: 13 additions & 0 deletions src/Ting/Driver/CacheResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ class CacheResult implements ResultInterface

protected ?Iterator $result = null;

/**
* @var class-string|null
*/
protected ?string $objectToFetch = null;

/**
* @param string $connectionName
Expand Down Expand Up @@ -66,6 +70,15 @@ public function setResult($result): static
return $this;
}

/**
* @param class-string $objectToFetch
*/
public function setObjectToFetch(string $objectToFetch): static
{
$this->objectToFetch = $objectToFetch;
return $this;
}

public function getConnectionName(): ?string
{
return $this->connectionName;
Expand Down
20 changes: 18 additions & 2 deletions src/Ting/Driver/Mysqli/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ class Result implements ResultInterface
/** @var array<int, object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: string, max_length: int, length: int, charsetnr: string, flags: int, type: int, decimals: int}> $fields */
protected array $fields = [];
protected int $iteratorOffset = 0;
protected ?array $iteratorCurrent = null;
/** @var array|false|object|null */
protected $iteratorCurrent = null;
/** @var class-string|null */
protected ?string $objectToFetch = null;

public function setConnectionName(string $connectionName): static
{
Expand All @@ -61,6 +64,15 @@ public function setResult($result): static
return $this;
}

/**
* @param class-string $objectToFetch
*/
public function setObjectToFetch(string $objectToFetch): static
{
$this->objectToFetch = $objectToFetch;
return $this;
}

public function getConnectionName(): ?string
{
return $this->connectionName;
Expand Down Expand Up @@ -193,7 +205,11 @@ public function key(): mixed
public function next(): void
{
if ($this->result !== null) {
$this->iteratorCurrent = $this->format($this->result->fetch_array(MYSQLI_NUM));
if ($this->objectToFetch !== null) {
$this->iteratorCurrent = $this->result->fetch_object($this->objectToFetch);
} else {
$this->iteratorCurrent = $this->format($this->result->fetch_array(MYSQLI_NUM));
}

$this->iteratorOffset++;
}
Expand Down
21 changes: 19 additions & 2 deletions src/Ting/Driver/Pgsql/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ class Result implements ResultInterface
protected $result = null;
protected array $fields = [];
protected int $iteratorOffset = 0;
protected ?array $iteratorCurrent = null;
/** @var array|object|false|null */
protected $iteratorCurrent = null;
/** @var class-string|null */
protected ?string $objectToFetch = null;

/**
* @param string $connectionName
Expand Down Expand Up @@ -73,6 +76,15 @@ public function setResult($result): static
return $this;
}

/**
* @param class-string $objectToFetch
*/
public function setObjectToFetch(string $objectToFetch): static
{
$this->objectToFetch = $objectToFetch;
return $this;
}

public function getConnectionName(): ?string
{
return $this->connectionName;
Expand Down Expand Up @@ -335,7 +347,12 @@ public function key(): mixed

public function next(): void
{
$this->iteratorCurrent = $this->format(pg_fetch_array($this->result, null, \PGSQL_NUM));
if ($this->objectToFetch !== null) {
$this->iteratorCurrent = pg_fetch_object($this->result, null, $this->objectToFetch);
} else {
$this->iteratorCurrent = $this->format(pg_fetch_array($this->result, null, \PGSQL_NUM));
}

$this->iteratorOffset++;
}

Expand Down
5 changes: 5 additions & 0 deletions src/Ting/Driver/ResultInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public function setDatabase(string $database): static;
*/
public function setResult($result): static;

/**
* @param class-string<T> $objectToFetch
*/
public function setObjectToFetch(string $objectToFetch): static;

public function getConnectionName(): ?string;

public function getDatabase(): ?string;
Expand Down
97 changes: 97 additions & 0 deletions src/Ting/Repository/HydratorValueObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

/***********************************************************************
*
* Ting - PHP Datamapper
* ==========================================
*
* Copyright (C) 2014 CCM Benchmark Group. (http://www.ccmbenchmark.com)
*
***********************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
**********************************************************************/

namespace CCMBenchmark\Ting\Repository;

use CCMBenchmark\Ting\Driver\ResultInterface;
use CCMBenchmark\Ting\Exception;
use CCMBenchmark\Ting\MetadataRepository;
use CCMBenchmark\Ting\UnitOfWork;

/**
* @template T
*
* @template-implements HydratorInterface<T>
*/
class HydratorValueObject implements HydratorInterface
{
/**
* @var class-string<T>
*/
protected $objectToHydrate;
/**
* @var ResultInterface<T>
*/
protected $result = null;


/**
* @param class-string<T> $objectToHydrate
*/
public function __construct(string $objectToHydrate)
{
$this->objectToHydrate = $objectToHydrate;
}

/**
* @return \Generator<int, T>
*/
public function getIterator(): \Generator
{
$this->result->setObjectToFetch($this->objectToHydrate);

foreach ($this->result as $key => $row) {
yield $key => $row;
}
}

/**
* @return int
*/
public function count(): int
{
if ($this->result === null) {
return 0;
}

return $this->result->getNumRows();
}

public function setMetadataRepository(MetadataRepository $metadataRepository): void
{
// Useless for this hydrator
}

public function setUnitOfWork(UnitOfWork $unitOfWork): void
{
// Useless for this hydrator
}

public function setResult(ResultInterface $result): static
{
$this->result = $result;
return $this;
}
}
7 changes: 7 additions & 0 deletions tests/fixtures/FakeDriver/MysqliResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ public function getConnectionName(): ?string

public function getDatabase(): ?string
{
}

public function setObjectToFetch(string $objectToFetch): static
{
}

public function fetch_object($class_name = null)
{
}
}
32 changes: 32 additions & 0 deletions tests/fixtures/ValueObject/Bouh.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace tests\fixtures\ValueObject;

class Bouh
{
private $firstname;

private $name;

public function __construct($firstname, $name)
{
$this->firstname = $firstname;
$this->name = $name;
}

/**
* @return mixed
*/
public function getFirstname()
{
return $this->firstname;
}

/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
}
99 changes: 99 additions & 0 deletions tests/units/Ting/Repository/HydratorValueObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

/***********************************************************************
*
* Ting - PHP Datamapper
* ==========================================
*
* Copyright (C) 2014 CCM Benchmark Group. (http://www.ccmbenchmark.com)
*
***********************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
**********************************************************************/

namespace tests\units\CCMBenchmark\Ting\Repository;

use CCMBenchmark\Ting\Driver\Mysqli\Result;
use atoum;
use CCMBenchmark\Ting\Exception;
use ReflectionException;
use tests\fixtures\ValueObject\Bouh;
use tests\fixtures\ValueObject\BouhWithConstruct;
use tests\fixtures\ValueObject\BouhWithNativeType;
use tests\fixtures\ValueObject\WrongObject;

class HydratorValueObject extends atoum
{
public function testHydrateShouldReturnBouhObject()
{
$data = ['Sylvain', 'Robez-Masson'];
$mockMysqliResult = new \mock\tests\fixtures\FakeDriver\MysqliResult([$data]);
$this->calling($mockMysqliResult)->fetch_fields = function () {
$fields = [];
$stdClass = new \stdClass();
$stdClass->name = 'firstname';
$stdClass->orgname = 'boo_firstname';
$stdClass->table = 'bouh';
$stdClass->orgtable = 'T_BOUH_BOO';
$stdClass->type = MYSQLI_TYPE_VAR_STRING;
$fields[] = $stdClass;

$stdClass = new \stdClass();
$stdClass->name = 'name';
$stdClass->orgname = 'boo_name';
$stdClass->table = 'bouh';
$stdClass->orgtable = 'T_BOUH_BOO';
$stdClass->type = MYSQLI_TYPE_VAR_STRING;
$fields[] = $stdClass;
return $fields;
};

$this->calling($mockMysqliResult)->fetch_object = function () use ($data) {
return new Bouh(...$data);
};

$result = new Result();
$result->setResult($mockMysqliResult);
$result->setConnectionName('connectionName');
$result->setDatabase('database');

$this
->if($hydrator = new \CCMBenchmark\Ting\Repository\HydratorValueObject(Bouh::class))
->then($iterator = $hydrator->setResult($result)->getIterator())
->then($bouh = $iterator->current())
->mock($mockMysqliResult)
->call('fetch_object')
->once()
->object($bouh)
->isInstanceOf('tests\fixtures\ValueObject\Bouh')
->string($bouh->getName())
->isIdenticalTo('Robez-Masson')
->string($bouh->getFirstname())
->isIdenticalTo('Sylvain');
}

public function testCountShouldReturn2()
{
$result = new \mock\CCMBenchmark\Ting\Driver\Mysqli\Result();

$this->calling($result)->getNumRows = 2;

$this
->if($hydrator = new \CCMBenchmark\Ting\Repository\HydratorValueObject(Bouh::class))
->then($hydrator->setResult($result))
->integer($hydrator->count())
->isIdenticalTo(2);
}
}