From 83d928e5583e4eeb2fadb27084cbc2695b8c8204 Mon Sep 17 00:00:00 2001 From: Peter Gribanov Date: Mon, 7 Oct 2019 12:16:00 +0300 Subject: [PATCH] Add Distinct query modifier and CountDistinct operand (#209) * create Distinct query modifier * create CountDistinct operand * remove not used classes --- src/Operand/CountDistinct.php | 35 ++++++++++++++++++++++++++++ src/Query/Distinct.php | 17 ++++++++++++++ src/Spec.php | 20 ++++++++++++++++ tests/Operand/CountDistinctSpec.php | 36 +++++++++++++++++++++++++++++ tests/Query/DistinctSpec.php | 30 ++++++++++++++++++++++++ tests/SpecSpec.php | 12 ++++++++++ 6 files changed, 150 insertions(+) create mode 100644 src/Operand/CountDistinct.php create mode 100644 src/Query/Distinct.php create mode 100644 tests/Operand/CountDistinctSpec.php create mode 100644 tests/Query/DistinctSpec.php diff --git a/src/Operand/CountDistinct.php b/src/Operand/CountDistinct.php new file mode 100644 index 00000000..a207f17c --- /dev/null +++ b/src/Operand/CountDistinct.php @@ -0,0 +1,35 @@ +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); + } +} diff --git a/src/Query/Distinct.php b/src/Query/Distinct.php new file mode 100644 index 00000000..6fa91f96 --- /dev/null +++ b/src/Query/Distinct.php @@ -0,0 +1,17 @@ +distinct(); + } +} diff --git a/src/Spec.php b/src/Spec.php index 7dab6c17..a29eb9a2 100644 --- a/src/Spec.php +++ b/src/Spec.php @@ -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; @@ -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; @@ -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 */ @@ -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 */ diff --git a/tests/Operand/CountDistinctSpec.php b/tests/Operand/CountDistinctSpec.php new file mode 100644 index 00000000..b752f53d --- /dev/null +++ b/tests/Operand/CountDistinctSpec.php @@ -0,0 +1,36 @@ +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)'); + } +} diff --git a/tests/Query/DistinctSpec.php b/tests/Query/DistinctSpec.php new file mode 100644 index 00000000..6ede8454 --- /dev/null +++ b/tests/Query/DistinctSpec.php @@ -0,0 +1,30 @@ +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'); + } +} diff --git a/tests/SpecSpec.php b/tests/SpecSpec.php index f141608a..ce0dd594 100644 --- a/tests/SpecSpec.php +++ b/tests/SpecSpec.php @@ -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; @@ -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);