Skip to content

Commit

Permalink
Add Distinct query modifier and CountDistinct operand (#209)
Browse files Browse the repository at this point in the history
* create Distinct query modifier

* create CountDistinct operand

* remove not used classes
  • Loading branch information
peter-gribanov authored Oct 7, 2019
1 parent 162ff2a commit 83d928e
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/Operand/CountDistinct.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Happyr\DoctrineSpecification\Operand;

use Doctrine\ORM\QueryBuilder;

class CountDistinct implements Operand
{
/**
* @var Operand|string
*/
private $field;

/**
* @param Operand|string $field
*/
public function __construct($field)
{
$this->field = $field;
}

/**
* @param QueryBuilder $qb
* @param string $dqlAlias
*
* @return string
*/
public function transform(QueryBuilder $qb, $dqlAlias)
{
$field = ArgumentToOperandConverter::toField($this->field);
$field = $field->transform($qb, $dqlAlias);

return sprintf('COUNT(DISTINCT %s)', $field);
}
}
17 changes: 17 additions & 0 deletions src/Query/Distinct.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Happyr\DoctrineSpecification\Query;

use Doctrine\ORM\QueryBuilder;

class Distinct implements QueryModifier
{
/**
* @param QueryBuilder $qb
* @param string $dqlAlias
*/
public function modify(QueryBuilder $qb, $dqlAlias)
{
$qb->distinct();
}
}
20 changes: 20 additions & 0 deletions src/Spec.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Happyr\DoctrineSpecification\Operand\BitOr;
use Happyr\DoctrineSpecification\Operand\BitRightShift;
use Happyr\DoctrineSpecification\Operand\BitXor;
use Happyr\DoctrineSpecification\Operand\CountDistinct;
use Happyr\DoctrineSpecification\Operand\Division;
use Happyr\DoctrineSpecification\Operand\Field;
use Happyr\DoctrineSpecification\Operand\LikePattern;
Expand All @@ -32,6 +33,7 @@
use Happyr\DoctrineSpecification\Operand\Value;
use Happyr\DoctrineSpecification\Operand\Values;
use Happyr\DoctrineSpecification\Query\AddSelect;
use Happyr\DoctrineSpecification\Query\Distinct;
use Happyr\DoctrineSpecification\Query\GroupBy;
use Happyr\DoctrineSpecification\Query\IndexBy;
use Happyr\DoctrineSpecification\Query\InnerJoin;
Expand Down Expand Up @@ -245,6 +247,14 @@ public static function groupBy($field, $dqlAlias = null)
return new GroupBy($field, $dqlAlias);
}

/**
* @return Distinct
*/
public static function distinct()
{
return new Distinct();
}

/*
* Selection
*/
Expand Down Expand Up @@ -581,6 +591,16 @@ public static function likePattern($value, $format = LikePattern::CONTAINS)
return new LikePattern($value, $format);
}

/**
* @param Operand|string $field
*
* @return CountDistinct
*/
public static function countDistinct($field)
{
return new CountDistinct($field);
}

/*
* Arithmetic operands
*/
Expand Down
36 changes: 36 additions & 0 deletions tests/Operand/CountDistinctSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace tests\Happyr\DoctrineSpecification\Operand;

use Doctrine\ORM\QueryBuilder;
use Happyr\DoctrineSpecification\Operand\CountDistinct;
use Happyr\DoctrineSpecification\Operand\Operand;
use PhpSpec\ObjectBehavior;

/**
* @mixin CountDistinct
*/
class CountDistinctSpec extends ObjectBehavior
{
private $field = 'foo';

public function let()
{
$this->beConstructedWith($this->field);
}

public function it_is_a_count_distinct()
{
$this->shouldBeAnInstanceOf(CountDistinct::class);
}

public function it_is_a_operand()
{
$this->shouldBeAnInstanceOf(Operand::class);
}

public function it_is_transformable(QueryBuilder $qb)
{
$this->transform($qb, 'a')->shouldReturn('COUNT(DISTINCT a.foo)');
}
}
30 changes: 30 additions & 0 deletions tests/Query/DistinctSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace tests\Happyr\DoctrineSpecification\Query;

use Doctrine\ORM\QueryBuilder;
use Happyr\DoctrineSpecification\Query\Distinct;
use Happyr\DoctrineSpecification\Query\QueryModifier;
use PhpSpec\ObjectBehavior;

/**
* @mixin Distinct
*/
class DistinctSpec extends ObjectBehavior
{
public function it_is_a_distinct()
{
$this->shouldBeAnInstanceOf(Distinct::class);
}

public function it_is_a_query_modifier()
{
$this->shouldHaveType(QueryModifier::class);
}

public function it_add_having(QueryBuilder $qb)
{
$qb->distinct()->shouldBeCalled();
$this->modify($qb, 'a');
}
}
12 changes: 12 additions & 0 deletions tests/SpecSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
use Happyr\DoctrineSpecification\Operand\Alias;
use Happyr\DoctrineSpecification\Operand\BitAnd;
use Happyr\DoctrineSpecification\Operand\BitOr;
use Happyr\DoctrineSpecification\Operand\CountDistinct;
use Happyr\DoctrineSpecification\Operand\Division;
use Happyr\DoctrineSpecification\Operand\Modulo;
use Happyr\DoctrineSpecification\Operand\Multiplication;
use Happyr\DoctrineSpecification\Operand\PlatformFunction;
use Happyr\DoctrineSpecification\Operand\Subtraction;
use Happyr\DoctrineSpecification\Query\AddSelect;
use Happyr\DoctrineSpecification\Query\Distinct;
use Happyr\DoctrineSpecification\Query\Select;
use Happyr\DoctrineSpecification\Query\Selection\SelectAs;
use Happyr\DoctrineSpecification\Query\Selection\SelectEntity;
Expand All @@ -31,6 +33,16 @@ public function it_creates_an_x_specification()
$this->andX()->shouldReturnAnInstanceOf(LogicX::class);
}

public function it_creates_distinct()
{
$this->distinct()->shouldReturnAnInstanceOf(Distinct::class);
}

public function it_creates_count_distinct()
{
$this->countDistinct('foo')->shouldReturnAnInstanceOf(CountDistinct::class);
}

public function it_creates_add_operand()
{
$this->add('foo', 'bar')->shouldReturnAnInstanceOf(Addition::class);
Expand Down

1 comment on commit 83d928e

@yaffol
Copy link

@yaffol yaffol commented on 83d928e Oct 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was literally just writing a query to count distinct - so I am very grateful for this update 👍

Please sign in to comment.