Skip to content

Commit 935058c

Browse files
authored
Merge pull request #2616 from nuernbergerA/enhance-count
[9.x] Improve count performance for simple queries.
2 parents 6d8b2fb + 5e61221 commit 935058c

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

src/QueryDataTable.php

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -210,30 +210,29 @@ protected function filteredCount()
210210
*/
211211
public function count()
212212
{
213-
$builder = $this->prepareCountQuery();
214-
215-
$table = $this->connection->raw('('.$builder->toSql().') count_row_table');
216-
217-
return $this->connection->table($table)
218-
->setBindings($builder->getBindings())
219-
->count();
213+
return $this->prepareCountQuery()->count();
220214
}
221215

222216
/**
223217
* Prepare count query builder.
224218
*
225219
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
226220
*/
227-
protected function prepareCountQuery()
221+
public function prepareCountQuery()
228222
{
229223
$builder = clone $this->query;
230224

231-
if (! $this->isComplexQuery($builder)) {
232-
$row_count = $this->wrap('row_count');
233-
$builder->select($this->connection->raw("'1' as {$row_count}"));
234-
if (! $this->keepSelectBindings) {
235-
$builder->setBindings([], 'select');
236-
}
225+
if ($this->isComplexQuery($builder)) {
226+
$table = $this->connection->raw('('.$builder->toSql().') count_row_table');
227+
228+
return $this->connection->table($table)
229+
->setBindings($builder->getBindings());
230+
}
231+
232+
$row_count = $this->wrap('row_count');
233+
$builder->select($this->connection->raw("'1' as {$row_count}"));
234+
if (! $this->keepSelectBindings) {
235+
$builder->setBindings([], 'select');
237236
}
238237

239238
return $builder;

tests/Unit/QueryDataTableTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Yajra\DataTables\Tests\Unit;
4+
5+
use Illuminate\Support\Facades\DB;
6+
use Illuminate\Support\Str;
7+
use Yajra\DataTables\Tests\Models\User;
8+
use Yajra\DataTables\Tests\TestCase;
9+
10+
class QueryDataTableTest extends TestCase
11+
{
12+
public function test_complex_query_are_wrapped_and_countable()
13+
{
14+
/** @var \Yajra\DataTables\QueryDataTable $dataTable */
15+
$dataTable = app('datatables')->of(
16+
DB::table('module_telers')
17+
->selectRaw('module_telers.id, module_telers.publiceren, module_telers.archief, module_telers.uitgelicht, module_telers.image_header, module_telers.bedrijfsnaam, module_telers.titel, module_telers.plaats, group_concat(DISTINCT productenAlias.titel SEPARATOR \', \') as producten')
18+
->leftJoin('relation_producten_telers', 'module_telers.id', '=', 'relation_producten_telers.telers_id')
19+
->leftJoin('module_producten as productenAlias', 'productenAlias.id', '=', 'relation_producten_telers.producten_id')
20+
->groupBy('module_telers.id')
21+
);
22+
23+
$this->assertQueryWrapped(true, $dataTable->prepareCountQuery());
24+
25+
/** @var \Yajra\DataTables\QueryDataTable $dataTable */
26+
$dataTable = app('datatables')->of(
27+
DB::table('posts')->selectRaw('title AS state')->groupBy('state')->having('state', '!=', 'deleted')
28+
);
29+
30+
$this->assertQueryWrapped(true, $dataTable->prepareCountQuery());
31+
$this->assertEquals(60, $dataTable->count());
32+
}
33+
34+
public function test_simple_queries_are_not_wrapped_and_countable()
35+
{
36+
/** @var \Yajra\DataTables\QueryDataTable $dataTable */
37+
$dataTable = app('datatables')->of(
38+
User::with('posts')->select('users.*')
39+
);
40+
41+
$this->assertQueryWrapped(false, $dataTable->prepareCountQuery());
42+
$this->assertEquals(20, $dataTable->count());
43+
}
44+
45+
/**
46+
* @param $expected bool
47+
* @param $query \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
48+
* @return void
49+
*/
50+
protected function assertQueryWrapped($expected, $query)
51+
{
52+
$sql = $query->toSql();
53+
54+
$this->assertSame($expected, Str::endsWith($sql, 'count_row_table'), "'{$sql}' is not wrapped");
55+
}
56+
}

0 commit comments

Comments
 (0)