Skip to content

Commit b2b44dc

Browse files
committed
perf: optimize limitZeroAsAll config retrieval in builders and models
1 parent b08160c commit b2b44dc

5 files changed

Lines changed: 70 additions & 26 deletions

File tree

system/BaseModel.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,13 @@ abstract class BaseModel
370370
*/
371371
protected $afterDelete = [];
372372

373+
/**
374+
* Limit 0 as all
375+
*
376+
* @var bool
377+
*/
378+
protected $limitZeroAsAll;
379+
373380
public function __construct(?ValidationInterface $validation = null)
374381
{
375382
$this->tempReturnType = $this->returnType;
@@ -378,6 +385,8 @@ public function __construct(?ValidationInterface $validation = null)
378385

379386
$this->validation = $validation;
380387

388+
$this->limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
389+
381390
$this->initialize();
382391
$this->createDataConverter();
383392
}
@@ -653,8 +662,7 @@ public function findColumn(string $columnName)
653662
*/
654663
public function findAll(?int $limit = null, int $offset = 0)
655664
{
656-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
657-
if ($limitZeroAsAll) {
665+
if ($this->limitZeroAsAll) {
658666
$limit ??= 0;
659667
}
660668

system/Database/BaseBuilder.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,13 @@ class BaseBuilder
295295
*/
296296
protected $pregOperators = [];
297297

298+
/**
299+
* Limit 0 as all
300+
*
301+
* @var bool
302+
*/
303+
protected $limitZeroAsAll;
304+
298305
/**
299306
* Constructor
300307
*
@@ -334,6 +341,8 @@ public function __construct($tableName, ConnectionInterface $db, ?array $options
334341
}
335342
}
336343
}
344+
345+
$this->limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
337346
}
338347

339348
/**
@@ -1511,8 +1520,7 @@ public function orderBy(string $orderBy, string $direction = '', ?bool $escape =
15111520
*/
15121521
public function limit(?int $value = null, ?int $offset = 0)
15131522
{
1514-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
1515-
if ($limitZeroAsAll && $value === 0) {
1523+
if ($this->limitZeroAsAll && $value === 0) {
15161524
$value = null;
15171525
}
15181526

@@ -1633,8 +1641,7 @@ protected function compileFinalQuery(string $sql): string
16331641
*/
16341642
public function get(?int $limit = null, int $offset = 0, bool $reset = true)
16351643
{
1636-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
1637-
if ($limitZeroAsAll && $limit === 0) {
1644+
if ($this->limitZeroAsAll && $limit === 0) {
16381645
$limit = null;
16391646
}
16401647

@@ -1771,8 +1778,7 @@ public function getWhere($where = null, ?int $limit = null, ?int $offset = 0, bo
17711778
$this->where($where);
17721779
}
17731780

1774-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
1775-
if ($limitZeroAsAll && $limit === 0) {
1781+
if ($this->limitZeroAsAll && $limit === 0) {
17761782
$limit = null;
17771783
}
17781784

@@ -2498,8 +2504,7 @@ public function update($set = null, $where = null, ?int $limit = null): bool
24982504
$this->where($where);
24992505
}
25002506

2501-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
2502-
if ($limitZeroAsAll && $limit === 0) {
2507+
if ($this->limitZeroAsAll && $limit === 0) {
25032508
$limit = null;
25042509
}
25052510

@@ -2545,8 +2550,7 @@ protected function _update(string $table, array $values): string
25452550
$valStr[] = $key . ' = ' . $val;
25462551
}
25472552

2548-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
2549-
if ($limitZeroAsAll) {
2553+
if ($this->limitZeroAsAll) {
25502554
return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr)
25512555
. $this->compileWhereHaving('QBWhere')
25522556
. $this->compileOrderBy()
@@ -2829,8 +2833,7 @@ public function delete($where = '', ?int $limit = null, bool $resetData = true)
28292833

28302834
$sql = $this->_delete($this->removeAlias($table));
28312835

2832-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
2833-
if ($limitZeroAsAll && $limit === 0) {
2836+
if ($this->limitZeroAsAll && $limit === 0) {
28342837
$limit = null;
28352838
}
28362839

@@ -3104,8 +3107,7 @@ protected function compileSelect($selectOverride = false): string
31043107
. $this->compileWhereHaving('QBHaving')
31053108
. $this->compileOrderBy();
31063109

3107-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
3108-
if ($limitZeroAsAll) {
3110+
if ($this->limitZeroAsAll) {
31093111
if ($this->QBLimit) {
31103112
$sql = $this->_limit($sql . "\n");
31113113
}

system/Database/SQLSRV/Builder.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use CodeIgniter\Database\Query;
2121
use CodeIgniter\Database\RawSql;
2222
use CodeIgniter\Database\ResultInterface;
23-
use Config\Feature;
2423

2524
/**
2625
* Builder for SQLSRV
@@ -339,8 +338,7 @@ protected function _limit(string $sql, bool $offsetIgnore = false): string
339338
// DatabaseException:
340339
// [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The number of
341340
// rows provided for a FETCH clause must be greater then zero.
342-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
343-
if (! $limitZeroAsAll && $this->QBLimit === 0) {
341+
if (! $this->limitZeroAsAll && $this->QBLimit === 0) {
344342
return "SELECT * \nFROM " . $this->_fromTables() . ' WHERE 1=0 ';
345343
}
346344

@@ -626,8 +624,7 @@ protected function compileSelect($selectOverride = false): string
626624
. $this->compileOrderBy(); // ORDER BY
627625

628626
// LIMIT
629-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
630-
if ($limitZeroAsAll) {
627+
if ($this->limitZeroAsAll) {
631628
if ($this->QBLimit) {
632629
$sql = $this->_limit($sql . "\n");
633630
}
@@ -646,8 +643,7 @@ protected function compileSelect($selectOverride = false): string
646643
*/
647644
public function get(?int $limit = null, int $offset = 0, bool $reset = true)
648645
{
649-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
650-
if ($limitZeroAsAll && $limit === 0) {
646+
if ($this->limitZeroAsAll && $limit === 0) {
651647
$limit = null;
652648
}
653649

system/Model.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
use CodeIgniter\Exceptions\ModelException;
2626
use CodeIgniter\Validation\ValidationInterface;
2727
use Config\Database;
28-
use Config\Feature;
2928
use stdClass;
3029

3130
/**
@@ -234,8 +233,7 @@ protected function doFindColumn(string $columnName)
234233
*/
235234
protected function doFindAll(?int $limit = null, int $offset = 0)
236235
{
237-
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
238-
if ($limitZeroAsAll) {
236+
if ($this->limitZeroAsAll) {
239237
$limit ??= 0;
240238
}
241239

tests/system/Database/Builder/LimitTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313

1414
namespace CodeIgniter\Database\Builder;
1515

16+
use CodeIgniter\Config\Factories;
1617
use CodeIgniter\Database\BaseBuilder;
1718
use CodeIgniter\Test\CIUnitTestCase;
1819
use CodeIgniter\Test\Mock\MockConnection;
20+
use Config\Feature;
1921
use PHPUnit\Framework\Attributes\Group;
2022

2123
/**
@@ -65,4 +67,42 @@ public function testLimitAndOffsetMethod(): void
6567

6668
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
6769
}
70+
71+
public function testLimitZeroAsAllOptimization(): void
72+
{
73+
$feature = new class () extends Feature {
74+
public int $accessCount = 0;
75+
76+
public function __construct()
77+
{
78+
parent::__construct();
79+
unset($this->limitZeroAsAll);
80+
}
81+
82+
public function __get($name)
83+
{
84+
if ($name === 'limitZeroAsAll') {
85+
$this->accessCount++;
86+
87+
return true;
88+
}
89+
90+
return null;
91+
}
92+
};
93+
94+
Factories::injectMock('config', 'Feature', $feature);
95+
96+
// Constructor accesses it once
97+
$builder = new BaseBuilder('user', $this->db);
98+
$this->assertSame(1, $feature->accessCount);
99+
100+
// Should not access config again during typical query building
101+
$builder->limit(0);
102+
$builder->getCompiledSelect();
103+
104+
$this->assertSame(1, $feature->accessCount);
105+
106+
Factories::reset('config');
107+
}
68108
}

0 commit comments

Comments
 (0)