diff --git a/src/DataSource/NetteDatabaseTableDataSource.php b/src/DataSource/NetteDatabaseTableDataSource.php index 4a87cf96..d46394b8 100755 --- a/src/DataSource/NetteDatabaseTableDataSource.php +++ b/src/DataSource/NetteDatabaseTableDataSource.php @@ -11,10 +11,10 @@ use Contributte\Datagrid\Filter\FilterSelect; use Contributte\Datagrid\Filter\FilterText; use Contributte\Datagrid\Utils\DateTimeHelper; +use Contributte\Datagrid\Utils\NetteDatabaseSelectionHelper; use Contributte\Datagrid\Utils\Sorting; use LogicException; use Nette\Database\Table\Selection; -use Nette\Utils\Strings; class NetteDatabaseTableDataSource extends FilterableDataSource implements IDataSource { @@ -29,25 +29,23 @@ public function getCount(): int { $dataSourceSqlBuilder = $this->dataSource->getSqlBuilder(); + if ($dataSourceSqlBuilder->getGroup() !== '') { + $query = sprintf('SELECT COUNT(*) FROM (%s) AS datagrid_count', $this->dataSource->getSql()); + $explorer = NetteDatabaseSelectionHelper::getContext($this->dataSource); + + /** @phpstan-ignore argument.type */ + $result = $explorer->query($query, ...$dataSourceSqlBuilder->getParameters()); + + return (int) $result->fetchField(); + } + try { $primary = $this->dataSource->getPrimary(); } catch (LogicException) { - if ($dataSourceSqlBuilder->getGroup() !== '') { - return $this->dataSource->count( - 'DISTINCT ' . Strings::replace($dataSourceSqlBuilder->getGroup(), '~ (DESC|ASC)~') - ); - } - return $this->dataSource->count('*'); } - if ($dataSourceSqlBuilder->getGroup() !== '') { - return $this->dataSource->count( - 'DISTINCT ' . Strings::replace($dataSourceSqlBuilder->getGroup(), '~ (DESC|ASC)~') - ); - } - return $this->dataSource->count( $this->dataSource->getName() . '.' . (is_array($primary) ? reset($primary) : $primary) ); diff --git a/tests/Cases/DataSources/NetteDatabaseTableDataSourceTest.phpt b/tests/Cases/DataSources/NetteDatabaseTableDataSourceTest.phpt index c7d62f82..52312908 100644 --- a/tests/Cases/DataSources/NetteDatabaseTableDataSourceTest.phpt +++ b/tests/Cases/DataSources/NetteDatabaseTableDataSourceTest.phpt @@ -10,6 +10,7 @@ use Nette\Database\Conventions\DiscoveredConventions; use Nette\Database\Explorer; use Nette\Database\Structure; use Nette\Database\Table\Selection; +use Tester\Assert; require __DIR__ . '/BaseDataSourceTest.phpt'; @@ -27,6 +28,38 @@ final class NetteDatabaseTableDataSourceTest extends BaseDataSourceTest $this->grid = $factory->createTestingDatagrid(); } + public function testGetCountWithGroupByMultipleColumns(): void + { + $this->db->query('CREATE TABLE orders_products ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title VARCHAR (50), + variant VARCHAR (50), + course_city VARCHAR (50), + course_date VARCHAR (50) + ); + '); + $this->db->getStructure()->rebuild(); + + $rows = [ + ['title' => 'A', 'variant' => 'x', 'course_city' => null, 'course_date' => null], + ['title' => 'A', 'variant' => 'x', 'course_city' => null, 'course_date' => null], + ['title' => 'B', 'variant' => 'y', 'course_city' => null, 'course_date' => null], + ['title' => 'C', 'variant' => 'z', 'course_city' => 'Prague', 'course_date' => '2021-01-01'], + ]; + + foreach ($rows as $row) { + $this->db->query('INSERT INTO orders_products', $row); + } + + $selection = $this->db->table('orders_products') + ->group('title, variant, course_city, course_date'); + + $ds = new NetteDatabaseTableDataSource($selection, 'id'); + + Assert::same(3, $ds->getCount()); + Assert::same(3, count($ds->getData())); + } + protected function setUpDatabase(): void { $connection = new Connection('sqlite::memory:');