diff --git a/src/Group.php b/src/Group.php index 84ba446..0407db2 100644 --- a/src/Group.php +++ b/src/Group.php @@ -2,4 +2,70 @@ namespace RebelCode\Atlas; -class Group extends Order {} +use RebelCode\Atlas\Expression\ColumnTerm; + +class Group +{ + public const ASC = 'ASC'; + public const DESC = 'DESC'; + + protected ColumnTerm $column; + protected ?string $sort; + + /** + * Constructor. + * + * @param string|ColumnTerm $column The column to sort by. + * @param string|null $sort The sort order. + */ + public function __construct($column, ?string $sort = null) + { + $this->column = $column instanceof ColumnTerm ? $column : new ColumnTerm(null, $column); + $this->sort = $sort; + } + + public function getColumn(): ColumnTerm + { + return $this->column; + } + + public function getSort(): ?string + { + return $this->sort; + } + + public function asc(): Group + { + return ($this->sort !== self::ASC) + ? new self($this->column, self::ASC) + : $this; + } + + public function desc(): Group + { + return ($this->sort !== self::DESC) + ? new self($this->column, self::DESC) + : $this; + } + + public function noSort(): Group + { + return ($this->sort !== null) + ? new self($this->column, null) + : $this; + } + + public function dir(?string $order, string $default = self::ASC): Group + { + if ($order !== null) { + $order = strtoupper($order); + $order = ($order === self::ASC || $order === self::DESC) ? $order : $default; + } + return new self($this->column, $order); + } + + public static function by(string $column): Group + { + return new self($column); + } +} diff --git a/src/Query/Traits/HasGroupByTrait.php b/src/Query/Traits/HasGroupByTrait.php index 9444a78..514d498 100644 --- a/src/Query/Traits/HasGroupByTrait.php +++ b/src/Query/Traits/HasGroupByTrait.php @@ -2,7 +2,6 @@ namespace RebelCode\Atlas\Query\Traits; -use InvalidArgumentException; use RebelCode\Atlas\Group; trait HasGroupByTrait @@ -36,7 +35,13 @@ protected function compileGroupBy(): string $groupParts = []; foreach ($this->groups as $group) { - $groupParts[] = $group->getColumn() . ' ' . $group->getSort(); + $col = $group->getColumn(); + $sort = $group->getSort(); + if ($sort === null) { + $groupParts[] = $col; + } else { + $groupParts[] = "$col $sort"; + } } return 'GROUP BY ' . implode(', ', $groupParts); diff --git a/tests/Query/SelectQueryTest.php b/tests/Query/SelectQueryTest.php index 721c8b6..6798bce 100644 --- a/tests/Query/SelectQueryTest.php +++ b/tests/Query/SelectQueryTest.php @@ -314,7 +314,7 @@ public function testCompileSelectGroupBy() new Group('baz', Group::DESC), ]); - $expected = 'SELECT * FROM table GROUP BY `foo` ASC, `bar` ASC, `baz` DESC'; + $expected = 'SELECT * FROM table GROUP BY `foo`, `bar` ASC, `baz` DESC'; $actual = $query->toSql(); $this->assertEquals($expected, $actual); diff --git a/tests/Query/Traits/HasGroupByTraitTest.php b/tests/Query/Traits/HasGroupByTraitTest.php index 5fa7830..485fd4c 100644 --- a/tests/Query/Traits/HasGroupByTraitTest.php +++ b/tests/Query/Traits/HasGroupByTraitTest.php @@ -29,11 +29,12 @@ public function testSetGroups() public function testCompile() { $mock = $this->getMockForTrait(HasGroupByTrait::class)->groupBy([ - Group::by('foo')->asc(), - Group::by('bar')->desc(), + Group::by('foo'), + Group::by('bar')->asc(), + Group::by('baz')->desc(), ]); - $this->assertEquals('GROUP BY `foo` ASC, `bar` DESC', $this->expose($mock)->compileGroupBy()); + $this->assertEquals('GROUP BY `foo`, `bar` ASC, `baz` DESC', $this->expose($mock)->compileGroupBy()); } public function testCompileNoGroups()