diff --git a/inc/constants.php b/inc/constants.php index faa33a9..0ff770d 100644 --- a/inc/constants.php +++ b/inc/constants.php @@ -3,7 +3,7 @@ namespace RebelCode\Atlas; // For use in select queries, for readability purposes. -const ALL = ['*']; +const ALL = '*'; // Aliases for order constants const ASC = Order::ASC; diff --git a/src/Expression/Term.php b/src/Expression/Term.php index a083159..d92805d 100644 --- a/src/Expression/Term.php +++ b/src/Expression/Term.php @@ -3,7 +3,6 @@ namespace RebelCode\Atlas\Expression; use InvalidArgumentException; -use Iterator; use Traversable; /** @psalm-immutable */ @@ -14,6 +13,7 @@ class Term extends BaseExpr public const BOOLEAN = 2; public const LIST = 3; public const NULL = 4; + public const SPECIAL = 5; /** @var mixed */ protected $value; @@ -67,6 +67,8 @@ protected function toBaseString(): string }, $elements); return '(' . implode(', ', $elementsStr) . ')'; + case self::SPECIAL: + return $this->value; default: throw new InvalidArgumentException("Term has unknown type: \"$this->type\""); } diff --git a/src/F.php b/src/F.php index 973081f..6115cf8 100644 --- a/src/F.php +++ b/src/F.php @@ -178,8 +178,12 @@ abstract class F * @param list $arguments The call arguments. * @return FnExpr The created function expression. */ - public static function __callStatic(string $operator, array $arguments): FnExpr + public static function __callStatic(string $fnName, array $args): FnExpr { - return new FnExpr($operator, array_map([Term::class, 'create'], $arguments)); + if ($fnName === 'COUNT' && (count($args) === 0 || $args[0] === '*')) { + $args = [new Term(Term::SPECIAL, '*')]; + } + + return new FnExpr($fnName, array_map([Term::class, 'create'], $args)); } } diff --git a/tests/FTest.php b/tests/FTest.php index d59974e..0f7f233 100644 --- a/tests/FTest.php +++ b/tests/FTest.php @@ -22,4 +22,22 @@ public function testMagicStaticCall() $this->assertEquals('foo', $this->expose($expr)->name); $this->assertSame([$term1, $term2], $this->expose($expr)->args); } + + public function testCountNoArgs() + { + $count = F::COUNT(); + $star = new Term(Term::SPECIAL, '*'); + + $this->assertEquals('COUNT', $this->expose($count)->name); + $this->assertEquals([$star], $this->expose($count)->args); + } + + public function testCountWithStar() + { + $count = F::COUNT('*'); + $star = new Term(Term::SPECIAL, '*'); + + $this->assertEquals('COUNT', $this->expose($count)->name); + $this->assertEquals([$star], $this->expose($count)->args); + } }