From b01a51807d4db3f39d748375cb52ca4a84364e52 Mon Sep 17 00:00:00 2001 From: Erik Araujo Date: Thu, 24 Apr 2025 10:51:38 -0300 Subject: [PATCH 1/6] Add `Count` Query Builder and Statement --- .../QueryBuilders/CountQueryBuilder.php | 107 ++++++++++++++++++ .../Builder/QueryBuilders/QueryBuilder.php | 8 ++ .../src/QueryStatements/CountStatement.php | 41 +++++++ .../QueryStatements/CountStatementTest.php | 58 ++++++++++ .../Builder/CountQueryBuilderTest.php | 104 +++++++++++++++++ 5 files changed, 318 insertions(+) create mode 100644 src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php create mode 100644 src/Tempest/Database/src/QueryStatements/CountStatement.php create mode 100644 src/Tempest/Database/tests/QueryStatements/CountStatementTest.php create mode 100644 tests/Integration/Database/Builder/CountQueryBuilderTest.php diff --git a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php new file mode 100644 index 000000000..01a923780 --- /dev/null +++ b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php @@ -0,0 +1,107 @@ + $modelClass */ + private readonly string $modelClass; + + private ?ModelDefinition $modelDefinition; + + private CountStatement $count; + + private array $bindings = []; + + public function __construct(string|object $model, ?string $column = null) + { + $this->modelDefinition = ModelDefinition::tryFrom($model); + $this->modelClass = is_object($model) ? $model::class : $model; + + $this->count = new CountStatement( + table: $this->resolveTable($model), + column: $column, + ); + } + + public function execute(mixed ...$bindings): int + { + $key = "COUNT({$this->count->countArgument})"; + + return $this->build()->fetchFirst(...$bindings)[$key]; + } + + /** @return self */ + public function where(string $where, mixed ...$bindings): self + { + $this->count->where[] = new WhereStatement($where); + + $this->bind(...$bindings); + + return $this; + } + + public function andWhere(string $where, mixed ...$bindings): self + { + return $this->where("AND {$where}", ...$bindings); + } + + public function orWhere(string $where, mixed ...$bindings): self + { + return $this->where("OR {$where}", ...$bindings); + } + + /** @return self */ + public function whereField(string $field, mixed $value): self + { + $field = $this->modelDefinition->getFieldDefinition($field); + + return $this->where("{$field} = :{$field->name}", ...[$field->name => $value]); + } + + /** @return self */ + public function bind(mixed ...$bindings): self + { + $this->bindings = [...$this->bindings, ...$bindings]; + + return $this; + } + + public function toSql(): string + { + return $this->build()->getSql(); + } + + public function build(array $bindings = []): Query + { + return new Query($this->count, [...$this->bindings, ...$bindings]); + } + + private function clone(): self + { + return clone $this; + } + + private function resolveTable(string|object $model): TableDefinition + { + if ($this->modelDefinition === null) { + return new TableDefinition($model); + } + + return $this->modelDefinition->getTableDefinition(); + } +} diff --git a/src/Tempest/Database/src/Builder/QueryBuilders/QueryBuilder.php b/src/Tempest/Database/src/Builder/QueryBuilders/QueryBuilder.php index e9fc0622e..750888951 100644 --- a/src/Tempest/Database/src/Builder/QueryBuilders/QueryBuilder.php +++ b/src/Tempest/Database/src/Builder/QueryBuilders/QueryBuilder.php @@ -47,4 +47,12 @@ public function delete(): DeleteQueryBuilder { return new DeleteQueryBuilder($this->model); } + + public function count(?string $column = null): CountQueryBuilder + { + return new CountQueryBuilder( + model: $this->model, + column: $column, + ); + } } diff --git a/src/Tempest/Database/src/QueryStatements/CountStatement.php b/src/Tempest/Database/src/QueryStatements/CountStatement.php new file mode 100644 index 000000000..72360f4dd --- /dev/null +++ b/src/Tempest/Database/src/QueryStatements/CountStatement.php @@ -0,0 +1,41 @@ +countArgument = $this->column === null + ? '*' + : "`{$this->column}`"; + } + + public function compile(DatabaseDialect $dialect): string + { + $query = arr([ + sprintf('SELECT COUNT(%s)', $this->countArgument), + sprintf('FROM `%s`', $this->table->name), + ]); + + if ($this->where->isNotEmpty()) { + $query[] = 'WHERE ' . $this->where + ->map(fn (WhereStatement $where) => $where->compile($dialect)) + ->implode(PHP_EOL); + } + + return $query->implode(PHP_EOL); + } +} diff --git a/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php b/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php new file mode 100644 index 000000000..5ffbae576 --- /dev/null +++ b/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php @@ -0,0 +1,58 @@ +assertSame($expected, $statement->compile(DatabaseDialect::MYSQL)); + $this->assertSame($expected, $statement->compile(DatabaseDialect::POSTGRESQL)); + $this->assertSame($expected, $statement->compile(DatabaseDialect::SQLITE)); + } + + public function test_count_statement_with_specified_column(): void + { + $tableDefinition = new TableDefinition('foo', 'bar'); + + $statement = new CountStatement( + table: $tableDefinition, + column: 'foobar', + ); + + $expected = <<assertSame($expected, $statement->compile(DatabaseDialect::MYSQL)); + $this->assertSame($expected, $statement->compile(DatabaseDialect::POSTGRESQL)); + $this->assertSame($expected, $statement->compile(DatabaseDialect::SQLITE)); + } +} diff --git a/tests/Integration/Database/Builder/CountQueryBuilderTest.php b/tests/Integration/Database/Builder/CountQueryBuilderTest.php new file mode 100644 index 000000000..efbe5e3c7 --- /dev/null +++ b/tests/Integration/Database/Builder/CountQueryBuilderTest.php @@ -0,0 +1,104 @@ +count() + ->where('`title` = ?', 'Timeline Taxi') + ->andWhere('`index` <> ?', '1') + ->orWhere('`createdAt` > ?', '2025-01-01') + ->build(); + + $expected = << ? + OR `createdAt` > ? + SQL; + + $sql = $query->getSql(); + $bindings = $query->bindings; + + $this->assertSame($expected, $sql); + $this->assertSame(['Timeline Taxi', '1', '2025-01-01'], $bindings); + } + + public function test_count_query_with_specified_field(): void + { + $query = query('chapters')->count('title')->build(); + + $sql = $query->getSql(); + + $expected = <<assertSame($expected, $sql); + } + + public function test_count_from_model(): void + { + $query = query(Author::class)->count()->build(); + + $sql = $query->getSql(); + + $expected = <<assertSame($expected, $sql); + } + + public function test_count_query_with_conditions(): void + { + $query = query('chapters') + ->count() + ->when( + true, + fn (CountQueryBuilder $query) => $query + ->where('`title` = ?', 'Timeline Taxi') + ->andWhere('`index` <> ?', '1') + ->orWhere('`createdAt` > ?', '2025-01-01'), + ) + ->when( + false, + fn (CountQueryBuilder $query) => $query + ->where('`title` = ?', 'Timeline Uber') + ->andWhere('`index` <> ?', '2') + ->orWhere('`createdAt` > ?', '2025-01-02'), + ) + ->build(); + + $expected = << ? + OR `createdAt` > ? + SQL; + + $sql = $query->getSql(); + $bindings = $query->bindings; + + $this->assertSame($expected, $sql); + $this->assertSame(['Timeline Taxi', '1', '2025-01-01'], $bindings); + } +} From cea03e180913a5c75bd56ce80683374f80c5e0ba Mon Sep 17 00:00:00 2001 From: Erik Araujo Date: Thu, 24 Apr 2025 11:03:30 -0300 Subject: [PATCH 2/6] Cleans up unused code --- .../src/Builder/QueryBuilders/CountQueryBuilder.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php index 01a923780..872ee4618 100644 --- a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php +++ b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php @@ -18,9 +18,6 @@ final class CountQueryBuilder { use HasConditions; - /** @var class-string $modelClass */ - private readonly string $modelClass; - private ?ModelDefinition $modelDefinition; private CountStatement $count; @@ -30,7 +27,6 @@ final class CountQueryBuilder public function __construct(string|object $model, ?string $column = null) { $this->modelDefinition = ModelDefinition::tryFrom($model); - $this->modelClass = is_object($model) ? $model::class : $model; $this->count = new CountStatement( table: $this->resolveTable($model), @@ -91,11 +87,6 @@ public function build(array $bindings = []): Query return new Query($this->count, [...$this->bindings, ...$bindings]); } - private function clone(): self - { - return clone $this; - } - private function resolveTable(string|object $model): TableDefinition { if ($this->modelDefinition === null) { From 32bf6b4f84ffdd14615b3de32b4d76301a285597 Mon Sep 17 00:00:00 2001 From: Erik Araujo Date: Fri, 25 Apr 2025 07:15:07 -0300 Subject: [PATCH 3/6] Add alias --- .../QueryBuilders/CountQueryBuilder.php | 10 +++++-- .../src/QueryStatements/CountStatement.php | 17 +++++++++++- .../QueryStatements/CountStatementTest.php | 21 +++++++++++++++ .../Builder/CountQueryBuilderTest.php | 27 ++++++++++++++++++- 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php index 872ee4618..07ae1402e 100644 --- a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php +++ b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php @@ -36,9 +36,15 @@ public function __construct(string|object $model, ?string $column = null) public function execute(mixed ...$bindings): int { - $key = "COUNT({$this->count->countArgument})"; + return $this->build()->fetchFirst(...$bindings)[$this->count->getKey()]; + } - return $this->build()->fetchFirst(...$bindings)[$key]; + /** @return self */ + public function as(string $alias): self + { + $this->count->alias = $alias; + + return $this; } /** @return self */ diff --git a/src/Tempest/Database/src/QueryStatements/CountStatement.php b/src/Tempest/Database/src/QueryStatements/CountStatement.php index 72360f4dd..5c3eaa4f0 100644 --- a/src/Tempest/Database/src/QueryStatements/CountStatement.php +++ b/src/Tempest/Database/src/QueryStatements/CountStatement.php @@ -13,6 +13,8 @@ final class CountStatement implements QueryStatement { public readonly string $countArgument; + public ?string $alias = null; + public function __construct( public readonly TableDefinition $table, public ?string $column = null, @@ -26,7 +28,11 @@ public function __construct( public function compile(DatabaseDialect $dialect): string { $query = arr([ - sprintf('SELECT COUNT(%s)', $this->countArgument), + sprintf( + 'SELECT COUNT(%s)%s', + $this->countArgument, + $this->alias ? " AS `{$this->alias}`" : '', + ), sprintf('FROM `%s`', $this->table->name), ]); @@ -38,4 +44,13 @@ public function compile(DatabaseDialect $dialect): string return $query->implode(PHP_EOL); } + + public function getKey(): string + { + if ($this->alias !== null) { + return $this->alias; + } + + return "COUNT({$this->countArgument})"; + } } diff --git a/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php b/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php index 5ffbae576..0a63e848a 100644 --- a/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php +++ b/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php @@ -37,6 +37,27 @@ public function test_count_statement(): void $this->assertSame($expected, $statement->compile(DatabaseDialect::SQLITE)); } + public function test_count_statement_with_alias(): void + { + $tableDefinition = new TableDefinition('foo', 'bar'); + + $statement = new CountStatement( + table: $tableDefinition, + column: null, + ); + + $statement->alias = 'foobar'; + + $expected = <<assertSame($expected, $statement->compile(DatabaseDialect::MYSQL)); + $this->assertSame($expected, $statement->compile(DatabaseDialect::POSTGRESQL)); + $this->assertSame($expected, $statement->compile(DatabaseDialect::SQLITE)); + } + public function test_count_statement_with_specified_column(): void { $tableDefinition = new TableDefinition('foo', 'bar'); diff --git a/tests/Integration/Database/Builder/CountQueryBuilderTest.php b/tests/Integration/Database/Builder/CountQueryBuilderTest.php index efbe5e3c7..80d23f935 100644 --- a/tests/Integration/Database/Builder/CountQueryBuilderTest.php +++ b/tests/Integration/Database/Builder/CountQueryBuilderTest.php @@ -15,7 +15,7 @@ */ final class CountQueryBuilderTest extends FrameworkIntegrationTestCase { - public function test_count_query(): void + public function test_simple_count_query(): void { $query = query('chapters') ->count() @@ -39,6 +39,31 @@ public function test_count_query(): void $this->assertSame(['Timeline Taxi', '1', '2025-01-01'], $bindings); } + public function test_count_query_with_alias(): void + { + $query = query('chapters') + ->count() + ->as('total') + ->where('`title` = ?', 'Timeline Taxi') + ->andWhere('`index` <> ?', '1') + ->orWhere('`createdAt` > ?', '2025-01-01') + ->build(); + + $expected = << ? + OR `createdAt` > ? + SQL; + + $sql = $query->getSql(); + $bindings = $query->bindings; + + $this->assertSame($expected, $sql); + $this->assertSame(['Timeline Taxi', '1', '2025-01-01'], $bindings); + } + public function test_count_query_with_specified_field(): void { $query = query('chapters')->count('title')->build(); From 1300c0e2352652488e32029555eb9365dc40b2f5 Mon Sep 17 00:00:00 2001 From: Erik Araujo Date: Fri, 25 Apr 2025 07:52:45 -0300 Subject: [PATCH 4/6] Adds support for counting `DISTINCT` --- .../QueryBuilders/CountQueryBuilder.php | 13 +++ ...tCountDistinctWithoutSpecifyingAColumn.php | 13 +++ .../src/QueryStatements/CountStatement.php | 25 ++++-- .../Builder/CountQueryBuilderTest.php | 89 +++++++++++++++++++ 4 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 src/Tempest/Database/src/Exceptions/CannotCountDistinctWithoutSpecifyingAColumn.php diff --git a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php index 07ae1402e..19835516c 100644 --- a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php +++ b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php @@ -6,6 +6,7 @@ use Tempest\Database\Builder\ModelDefinition; use Tempest\Database\Builder\TableDefinition; +use Tempest\Database\Exceptions\CannotCountDistinctWithoutSpecifyingAColumn; use Tempest\Database\Query; use Tempest\Database\QueryStatements\CountStatement; use Tempest\Database\QueryStatements\WhereStatement; @@ -47,6 +48,18 @@ public function as(string $alias): self return $this; } + /** @return self */ + public function distinct(): self + { + if ($this->count->column === null || $this->count->column === '*') { + throw new CannotCountDistinctWithoutSpecifyingAColumn(); + } + + $this->count->distinct = true; + + return $this; + } + /** @return self */ public function where(string $where, mixed ...$bindings): self { diff --git a/src/Tempest/Database/src/Exceptions/CannotCountDistinctWithoutSpecifyingAColumn.php b/src/Tempest/Database/src/Exceptions/CannotCountDistinctWithoutSpecifyingAColumn.php new file mode 100644 index 000000000..ea2e9594e --- /dev/null +++ b/src/Tempest/Database/src/Exceptions/CannotCountDistinctWithoutSpecifyingAColumn.php @@ -0,0 +1,13 @@ +countArgument = $this->column === null - ? '*' - : "`{$this->column}`"; - } + ) {} public function compile(DatabaseDialect $dialect): string { $query = arr([ sprintf( 'SELECT COUNT(%s)%s', - $this->countArgument, + $this->getCountArgument(), $this->alias ? " AS `{$this->alias}`" : '', ), sprintf('FROM `%s`', $this->table->name), @@ -45,12 +41,23 @@ public function compile(DatabaseDialect $dialect): string return $query->implode(PHP_EOL); } + public function getCountArgument(): string + { + return $this->column === null || $this->column === '*' + ? '*' + : sprintf( + '%s`%s`', + $this->distinct ? 'DISTINCT ' : '', + $this->column, + ); + } + public function getKey(): string { if ($this->alias !== null) { return $this->alias; } - return "COUNT({$this->countArgument})"; + return "COUNT({$this->getCountArgument()})"; } } diff --git a/tests/Integration/Database/Builder/CountQueryBuilderTest.php b/tests/Integration/Database/Builder/CountQueryBuilderTest.php index 80d23f935..36d0edcd9 100644 --- a/tests/Integration/Database/Builder/CountQueryBuilderTest.php +++ b/tests/Integration/Database/Builder/CountQueryBuilderTest.php @@ -5,6 +5,7 @@ namespace Tests\Tempest\Integration\Database\Builder; use Tempest\Database\Builder\QueryBuilders\CountQueryBuilder; +use Tempest\Database\Exceptions\CannotCountDistinctWithoutSpecifyingAColumn; use Tests\Tempest\Fixtures\Modules\Books\Models\Author; use Tests\Tempest\Integration\FrameworkIntegrationTestCase; @@ -64,6 +65,22 @@ public function test_count_query_with_alias(): void $this->assertSame(['Timeline Taxi', '1', '2025-01-01'], $bindings); } + public function test_count_query_with_specified_asterisk(): void + { + $query = query('chapters') + ->count('*') + ->build(); + + $sql = $query->getSql(); + + $expected = <<assertSame($expected, $sql); + } + public function test_count_query_with_specified_field(): void { $query = query('chapters')->count('title')->build(); @@ -78,6 +95,78 @@ public function test_count_query_with_specified_field(): void $this->assertSame($expected, $sql); } + public function test_count_query_with_specified_field_and_alias(): void + { + $query = query('chapters') + ->count('title') + ->as('total') + ->build(); + + $sql = $query->getSql(); + + $expected = <<assertSame($expected, $sql); + } + + public function test_count_query_without_specifying_column_cannot_be_distinct(): void + { + $this->expectException(CannotCountDistinctWithoutSpecifyingAColumn::class); + + query('chapters') + ->count() + ->distinct() + ->build(); + } + + public function test_count_query_with_specified_asterisk_cannot_be_distinct(): void + { + $this->expectException(CannotCountDistinctWithoutSpecifyingAColumn::class); + + query('chapters') + ->count('*') + ->distinct() + ->build(); + } + + public function test_count_query_with_distinct_specified_field(): void + { + $query = query('chapters') + ->count('title') + ->distinct() + ->build(); + + $sql = $query->getSql(); + + $expected = <<assertSame($expected, $sql); + } + + public function test_count_query_with_distinct_specified_field_and_alias(): void + { + $query = query('chapters') + ->count('title') + ->as('total') + ->distinct() + ->build(); + + $sql = $query->getSql(); + + $expected = <<assertSame($expected, $sql); + } + public function test_count_from_model(): void { $query = query(Author::class)->count()->build(); From 8e5ff7bbff0c00a5e6871ad4eb726dcdc9139a81 Mon Sep 17 00:00:00 2001 From: Erik Araujo Date: Fri, 25 Apr 2025 08:07:02 -0300 Subject: [PATCH 5/6] Removes useless alias --- composer.json | 2 +- .../QueryBuilders/CountQueryBuilder.php | 8 --- .../src/QueryStatements/CountStatement.php | 9 +-- .../QueryStatements/CountStatementTest.php | 23 +++---- .../Builder/CountQueryBuilderTest.php | 60 ------------------- 5 files changed, 9 insertions(+), 93 deletions(-) diff --git a/composer.json b/composer.json index 82c11a8a5..8c5d87dfa 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "symfony/uid": "^7.1", "symfony/var-dumper": "^7.1", "symfony/var-exporter": "^7.1", - "tempest/highlight": "^2.11.2", + "tempest/highlight": "^2.11.4", "vlucas/phpdotenv": "^5.6", "voku/portable-ascii": "^2.0.3" }, diff --git a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php index 19835516c..f70e1ec0a 100644 --- a/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php +++ b/src/Tempest/Database/src/Builder/QueryBuilders/CountQueryBuilder.php @@ -40,14 +40,6 @@ public function execute(mixed ...$bindings): int return $this->build()->fetchFirst(...$bindings)[$this->count->getKey()]; } - /** @return self */ - public function as(string $alias): self - { - $this->count->alias = $alias; - - return $this; - } - /** @return self */ public function distinct(): self { diff --git a/src/Tempest/Database/src/QueryStatements/CountStatement.php b/src/Tempest/Database/src/QueryStatements/CountStatement.php index 4c43c58b1..182cecb10 100644 --- a/src/Tempest/Database/src/QueryStatements/CountStatement.php +++ b/src/Tempest/Database/src/QueryStatements/CountStatement.php @@ -11,8 +11,6 @@ final class CountStatement implements QueryStatement { - public ?string $alias = null; - public bool $distinct = false; public function __construct( @@ -25,9 +23,8 @@ public function compile(DatabaseDialect $dialect): string { $query = arr([ sprintf( - 'SELECT COUNT(%s)%s', + 'SELECT COUNT(%s)', $this->getCountArgument(), - $this->alias ? " AS `{$this->alias}`" : '', ), sprintf('FROM `%s`', $this->table->name), ]); @@ -54,10 +51,6 @@ public function getCountArgument(): string public function getKey(): string { - if ($this->alias !== null) { - return $this->alias; - } - return "COUNT({$this->getCountArgument()})"; } } diff --git a/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php b/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php index 0a63e848a..2e6682afa 100644 --- a/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php +++ b/src/Tempest/Database/tests/QueryStatements/CountStatementTest.php @@ -3,18 +3,9 @@ namespace Tempest\Database\Tests\QueryStatements; use PHPUnit\Framework\TestCase; -use Tempest\Database\Builder\FieldDefinition; use Tempest\Database\Builder\TableDefinition; use Tempest\Database\Config\DatabaseDialect; use Tempest\Database\QueryStatements\CountStatement; -use Tempest\Database\QueryStatements\GroupByStatement; -use Tempest\Database\QueryStatements\HavingStatement; -use Tempest\Database\QueryStatements\JoinStatement; -use Tempest\Database\QueryStatements\OrderByStatement; -use Tempest\Database\QueryStatements\SelectStatement; -use Tempest\Database\QueryStatements\WhereStatement; - -use function Tempest\Support\arr; final class CountStatementTest extends TestCase { @@ -37,19 +28,17 @@ public function test_count_statement(): void $this->assertSame($expected, $statement->compile(DatabaseDialect::SQLITE)); } - public function test_count_statement_with_alias(): void + public function test_count_statement_with_specified_column(): void { $tableDefinition = new TableDefinition('foo', 'bar'); $statement = new CountStatement( table: $tableDefinition, - column: null, + column: 'foobar', ); - $statement->alias = 'foobar'; - $expected = <<assertSame($expected, $statement->compile(DatabaseDialect::SQLITE)); } - public function test_count_statement_with_specified_column(): void + public function test_count_statement_with_distinct_specified_column(): void { $tableDefinition = new TableDefinition('foo', 'bar'); @@ -67,8 +56,10 @@ public function test_count_statement_with_specified_column(): void column: 'foobar', ); + $statement->distinct = true; + $expected = <<assertSame(['Timeline Taxi', '1', '2025-01-01'], $bindings); } - public function test_count_query_with_alias(): void - { - $query = query('chapters') - ->count() - ->as('total') - ->where('`title` = ?', 'Timeline Taxi') - ->andWhere('`index` <> ?', '1') - ->orWhere('`createdAt` > ?', '2025-01-01') - ->build(); - - $expected = << ? - OR `createdAt` > ? - SQL; - - $sql = $query->getSql(); - $bindings = $query->bindings; - - $this->assertSame($expected, $sql); - $this->assertSame(['Timeline Taxi', '1', '2025-01-01'], $bindings); - } - public function test_count_query_with_specified_asterisk(): void { $query = query('chapters') @@ -95,23 +70,6 @@ public function test_count_query_with_specified_field(): void $this->assertSame($expected, $sql); } - public function test_count_query_with_specified_field_and_alias(): void - { - $query = query('chapters') - ->count('title') - ->as('total') - ->build(); - - $sql = $query->getSql(); - - $expected = <<assertSame($expected, $sql); - } - public function test_count_query_without_specifying_column_cannot_be_distinct(): void { $this->expectException(CannotCountDistinctWithoutSpecifyingAColumn::class); @@ -149,24 +107,6 @@ public function test_count_query_with_distinct_specified_field(): void $this->assertSame($expected, $sql); } - public function test_count_query_with_distinct_specified_field_and_alias(): void - { - $query = query('chapters') - ->count('title') - ->as('total') - ->distinct() - ->build(); - - $sql = $query->getSql(); - - $expected = <<assertSame($expected, $sql); - } - public function test_count_from_model(): void { $query = query(Author::class)->count()->build(); From 038a801b0a13eaad50477c4d4739703e5f7e501c Mon Sep 17 00:00:00 2001 From: Erik Araujo Date: Fri, 25 Apr 2025 08:08:21 -0300 Subject: [PATCH 6/6] Undo composer changes that were made by the `qa` script --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8c5d87dfa..82c11a8a5 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "symfony/uid": "^7.1", "symfony/var-dumper": "^7.1", "symfony/var-exporter": "^7.1", - "tempest/highlight": "^2.11.4", + "tempest/highlight": "^2.11.2", "vlucas/phpdotenv": "^5.6", "voku/portable-ascii": "^2.0.3" },