Skip to content

Commit

Permalink
fix(orm): handle delete with EntityResult
Browse files Browse the repository at this point in the history
  • Loading branch information
kbond committed Feb 28, 2024
1 parent 0e73aff commit 4f0924c
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 3 deletions.
23 changes: 20 additions & 3 deletions src/Collection/Doctrine/ORM/EntityResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,20 @@ public function readonly(): self

public function first(mixed $default = null): mixed
{
$query = $this->query();
$sql = $query->getSQL();

if (\is_array($sql)) {
$sql = \implode(' ', $sql);
}

if (\str_starts_with(\mb_strtolower($sql), 'delete')) {
return $this->normalizeResult($query->execute());
}

try {
return $this->normalizeResult($this->query()->setMaxResults(1)->getSingleResult()) ?? $default;
} catch (NoResultException) {
return $this->normalizeResult($query->setMaxResults(1)->getSingleResult()) ?? $default;
} catch (NoResultException $e) {
return $default;
}
}
Expand Down Expand Up @@ -211,12 +222,18 @@ public function getIterator(): \Traversable
}

throw $e;
} catch (\TypeError $e) {
throw new \LogicException('Result is not a collection.', previous: $e);
}
}

public function eager(): ArrayCollection
{
return new ArrayCollection(\array_map([$this, 'normalizeResult'], $this->query()->execute()));
if (!\is_array($result = $this->query()->execute())) {
throw new \LogicException('Result is not a collection.');
}

return new ArrayCollection(\array_map([$this, 'normalizeResult'], $result));
}

public function count(): int
Expand Down
116 changes: 116 additions & 0 deletions tests/Doctrine/ORM/Result/SingleScalarTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

/*
* This file is part of the zenstruck/collection package.
*
* (c) Kevin Bond <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Doctrine\ORM\Result;

use PHPUnit\Framework\TestCase;
use Zenstruck\Collection\Doctrine\ORM\EntityResultQueryBuilder;
use Zenstruck\Collection\Tests\Doctrine\Fixture\Entity;
use Zenstruck\Collection\Tests\Doctrine\HasDatabase;

/**
* @author Kevin Bond <[email protected]>
*/
final class SingleScalarTest extends TestCase
{
use HasDatabase;

/**
* @test
*/
public function can_get_single_scalar_value_on_filter(): void
{
$this->persistEntities(4);

$result = EntityResultQueryBuilder::forEntity($this->em, Entity::class, 'e')
->select('SUM(e.id)')
->result()
;

$this->assertSame(10, $result->asScalar()->first());
$this->assertSame(10, $result->asInt()->first());
$this->assertSame(10.0, $result->asFloat()->first());
$this->assertSame('10', $result->asString()->first());
}

/**
* @test
*/
public function can_get_single_scalar_value_on_delete(): void
{
$this->persistEntities(4);

$result = EntityResultQueryBuilder::forEntity($this->em, Entity::class, 'e')
->delete()
->where('e.id > 1')
->result()
;

$this->assertSame(3, $result->asScalar()->first());
$this->assertSame(0, $result->asInt()->first());
$this->assertSame(0.0, $result->asFloat()->first());
$this->assertSame('0', $result->asString()->first());
}

/**
* @test
*/
public function can_get_single_scalar_value_on_update(): void
{
$this->persistEntities(4);

$result = EntityResultQueryBuilder::forEntity($this->em, Entity::class, 'e')
->update()
->set('e.value', ':value')
->setParameter('value', 'foo')
->where('e.id > 1')
->result()
;

$this->assertSame(3, $result->asScalar()->first());
$this->assertSame(3, $result->asInt()->first());
$this->assertSame(3.0, $result->asFloat()->first());
$this->assertSame('3', $result->asString()->first());
}

/**
* @test
*/
public function not_a_collection_eager(): void
{
$result = EntityResultQueryBuilder::forEntity($this->em, Entity::class, 'e')
->delete()
->where('e.id > 1')
->result()
;

$this->expectException(\LogicException::class);

$result->eager()->all();
}

/**
* @test
*/
public function not_a_collection_iterate(): void
{
$result = EntityResultQueryBuilder::forEntity($this->em, Entity::class, 'e')
->delete()
->where('e.id > 1')
->result()
;

$this->expectException(\LogicException::class);

foreach ($result as $item) {
}
}
}

0 comments on commit 4f0924c

Please sign in to comment.