Skip to content

Commit a1ed340

Browse files
committed
feat: add feature flag for limit(0)
1 parent 6e10d52 commit a1ed340

File tree

7 files changed

+70
-3
lines changed

7 files changed

+70
-3
lines changed

app/Config/Feature.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,12 @@ class Feature extends BaseConfig
1818
* Use filter execution order in 4.4 or before.
1919
*/
2020
public bool $oldFilterOrder = false;
21+
22+
/**
23+
* Keep the behavior of `limit(0)` in Query Builder in 4.4 or before.
24+
*
25+
* If true, `limit(0)` returns all records. (the behavior in 4.4 or before)
26+
* If false, `limit(0)` returns no records.
27+
*/
28+
public bool $limitZeroAsAll = false;
2129
}

system/BaseModel.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use CodeIgniter\I18n\Time;
2222
use CodeIgniter\Pager\Pager;
2323
use CodeIgniter\Validation\ValidationInterface;
24+
use Config\Feature;
2425
use Config\Services;
2526
use InvalidArgumentException;
2627
use ReflectionClass;
@@ -596,6 +597,10 @@ public function findColumn(string $columnName)
596597
*/
597598
public function findAll(?int $limit = null, int $offset = 0)
598599
{
600+
if (config(Feature::class)->limitZeroAsAll) {
601+
$limit ??= 0;
602+
}
603+
599604
if ($this->tempAllowCallbacks) {
600605
// Call the before event and check for a return
601606
$eventData = $this->trigger('beforeFind', [

system/Database/BaseBuilder.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use CodeIgniter\Database\Exceptions\DatabaseException;
1616
use CodeIgniter\Database\Exceptions\DataException;
1717
use CodeIgniter\Traits\ConditionalTrait;
18+
use Config\Feature;
1819
use InvalidArgumentException;
1920

2021
/**
@@ -1603,6 +1604,10 @@ protected function compileFinalQuery(string $sql): string
16031604
*/
16041605
public function get(?int $limit = null, int $offset = 0, bool $reset = true)
16051606
{
1607+
if (config(Feature::class)->limitZeroAsAll) {
1608+
$limit ??= 0;
1609+
}
1610+
16061611
if ($limit !== null) {
16071612
$this->limit($limit, $offset);
16081613
}
@@ -2493,6 +2498,13 @@ protected function _update(string $table, array $values): string
24932498
$valStr[] = $key . ' = ' . $val;
24942499
}
24952500

2501+
if (config(Feature::class)->limitZeroAsAll) {
2502+
return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr)
2503+
. $this->compileWhereHaving('QBWhere')
2504+
. $this->compileOrderBy()
2505+
. ($this->QBLimit ? $this->_limit(' ', true) : '');
2506+
}
2507+
24962508
return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr)
24972509
. $this->compileWhereHaving('QBWhere')
24982510
. $this->compileOrderBy()
@@ -3028,7 +3040,11 @@ protected function compileSelect($selectOverride = false): string
30283040
. $this->compileWhereHaving('QBHaving')
30293041
. $this->compileOrderBy();
30303042

3031-
if ($this->QBLimit !== false || $this->QBOffset) {
3043+
if (config(Feature::class)->limitZeroAsAll) {
3044+
if ($this->QBLimit) {
3045+
$sql = $this->_limit($sql . "\n");
3046+
}
3047+
} elseif ($this->QBLimit !== false || $this->QBOffset) {
30323048
$sql = $this->_limit($sql . "\n");
30333049
}
30343050

system/Database/SQLSRV/Builder.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use CodeIgniter\Database\Exceptions\DataException;
1717
use CodeIgniter\Database\RawSql;
1818
use CodeIgniter\Database\ResultInterface;
19+
use Config\Feature;
1920

2021
/**
2122
* Builder for SQLSRV
@@ -310,7 +311,7 @@ protected function _limit(string $sql, bool $offsetIgnore = false): string
310311
// DatabaseException:
311312
// [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The number of
312313
// rows provided for a FETCH clause must be greater then zero.
313-
if ($this->QBLimit === 0) {
314+
if (! config(Feature::class)->limitZeroAsAll && $this->QBLimit === 0) {
314315
return $sql . ' WHERE 1=0 ';
315316
}
316317

@@ -596,7 +597,11 @@ protected function compileSelect($selectOverride = false): string
596597
. $this->compileOrderBy(); // ORDER BY
597598

598599
// LIMIT
599-
if ($this->QBLimit !== false || $this->QBOffset) {
600+
if (config(Feature::class)->limitZeroAsAll) {
601+
if ($this->QBLimit) {
602+
$sql = $this->_limit($sql . "\n");
603+
}
604+
} elseif ($this->QBLimit !== false || $this->QBOffset) {
600605
$sql = $this->_limit($sql . "\n");
601606
}
602607

system/Model.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use CodeIgniter\Exceptions\ModelException;
2525
use CodeIgniter\Validation\ValidationInterface;
2626
use Config\Database;
27+
use Config\Feature;
2728
use ReflectionException;
2829

2930
/**
@@ -228,6 +229,10 @@ protected function doFindColumn(string $columnName)
228229
*/
229230
protected function doFindAll(?int $limit = null, int $offset = 0)
230231
{
232+
if (config(Feature::class)->limitZeroAsAll) {
233+
$limit ??= 0;
234+
}
235+
231236
$builder = $this->builder();
232237

233238
if ($this->tempUseSoftDeletes) {

tests/system/Database/Builder/GetTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use CodeIgniter\Test\CIUnitTestCase;
1515
use CodeIgniter\Test\Mock\MockConnection;
16+
use Config\Feature;
1617

1718
/**
1819
* @internal
@@ -55,6 +56,22 @@ public function testGetWithReset(): void
5556
$this->assertSame($expectedSQLafterreset, str_replace("\n", ' ', $builder->get(0, 50, true)));
5657
}
5758

59+
public function testGetWithResetWithLimitZeroAsAll(): void
60+
{
61+
$config = config(Feature::class);
62+
$config->limitZeroAsAll = true;
63+
64+
$builder = $this->db->table('users');
65+
$builder->testMode()->where('username', 'bogus');
66+
67+
$expectedSQL = 'SELECT * FROM "users" WHERE "username" = \'bogus\'';
68+
$expectedSQLafterreset = 'SELECT * FROM "users"';
69+
70+
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->get(0, 50, false)));
71+
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->get(0, 50, true)));
72+
$this->assertSame($expectedSQLafterreset, str_replace("\n", ' ', $builder->get(0, 50, true)));
73+
}
74+
5875
/**
5976
* @see https://github.com/codeigniter4/CodeIgniter4/issues/2143
6077
*/

tests/system/Database/Live/GetTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use CodeIgniter\Database\Exceptions\DatabaseException;
1515
use CodeIgniter\Test\CIUnitTestCase;
1616
use CodeIgniter\Test\DatabaseTestTrait;
17+
use Config\Feature;
1718
use Tests\Support\Database\Seeds\CITestSeeder;
1819

1920
/**
@@ -55,6 +56,16 @@ public function testGetWithLimitZero(): void
5556
$this->assertCount(0, $jobs);
5657
}
5758

59+
public function testGetWithLimitZeroAsAll(): void
60+
{
61+
$config = config(Feature::class);
62+
$config->limitZeroAsAll = true;
63+
64+
$jobs = $this->db->table('job')->limit(0)->get()->getResult();
65+
66+
$this->assertCount(4, $jobs);
67+
}
68+
5869
public function testGetWhereArray(): void
5970
{
6071
$jobs = $this->db->table('job')

0 commit comments

Comments
 (0)