Skip to content

Commit

Permalink
feat: add feature flag for limit(0)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenjis committed Dec 3, 2023
1 parent e2092c0 commit 48e0cbd
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 3 deletions.
8 changes: 8 additions & 0 deletions app/Config/Feature.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,12 @@ class Feature extends BaseConfig
* Use filter execution order in 4.4 or before.
*/
public bool $oldFilterOrder = false;

/**
* Keep the behavior of `limit(0)` in Query Builder in 4.4 or before.
*
* If true, `limit(0)` returns all records. (the behavior in 4.4 or before)
* If false, `limit(0)` returns no records.
*/
public bool $limitZeroAsAll = false;
}
5 changes: 5 additions & 0 deletions system/BaseModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use CodeIgniter\I18n\Time;
use CodeIgniter\Pager\Pager;
use CodeIgniter\Validation\ValidationInterface;
use Config\Feature;
use Config\Services;
use InvalidArgumentException;
use ReflectionClass;
Expand Down Expand Up @@ -596,6 +597,10 @@ public function findColumn(string $columnName)
*/
public function findAll(?int $limit = null, int $offset = 0)
{
if (config(Feature::class)->limitZeroAsAll) {
$limit ??= 0;
}

if ($this->tempAllowCallbacks) {
// Call the before event and check for a return
$eventData = $this->trigger('beforeFind', [
Expand Down
18 changes: 17 additions & 1 deletion system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use CodeIgniter\Database\Exceptions\DatabaseException;
use CodeIgniter\Database\Exceptions\DataException;
use CodeIgniter\Traits\ConditionalTrait;
use Config\Feature;
use InvalidArgumentException;

/**
Expand Down Expand Up @@ -1603,6 +1604,10 @@ protected function compileFinalQuery(string $sql): string
*/
public function get(?int $limit = null, int $offset = 0, bool $reset = true)
{
if (config(Feature::class)->limitZeroAsAll) {
$limit ??= 0;
}

if ($limit !== null) {
$this->limit($limit, $offset);
}
Expand Down Expand Up @@ -2493,6 +2498,13 @@ protected function _update(string $table, array $values): string
$valStr[] = $key . ' = ' . $val;
}

if (config(Feature::class)->limitZeroAsAll) {
return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr)
. $this->compileWhereHaving('QBWhere')
. $this->compileOrderBy()
. ($this->QBLimit ? $this->_limit(' ', true) : '');
}

return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr)
. $this->compileWhereHaving('QBWhere')
. $this->compileOrderBy()
Expand Down Expand Up @@ -3028,7 +3040,11 @@ protected function compileSelect($selectOverride = false): string
. $this->compileWhereHaving('QBHaving')
. $this->compileOrderBy();

if ($this->QBLimit !== false || $this->QBOffset) {
if (config(Feature::class)->limitZeroAsAll) {
if ($this->QBLimit) {
$sql = $this->_limit($sql . "\n");
}
} elseif ($this->QBLimit !== false || $this->QBOffset) {
$sql = $this->_limit($sql . "\n");
}

Expand Down
9 changes: 7 additions & 2 deletions system/Database/SQLSRV/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use CodeIgniter\Database\Exceptions\DataException;
use CodeIgniter\Database\RawSql;
use CodeIgniter\Database\ResultInterface;
use Config\Feature;

/**
* Builder for SQLSRV
Expand Down Expand Up @@ -310,7 +311,7 @@ protected function _limit(string $sql, bool $offsetIgnore = false): string
// DatabaseException:
// [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The number of
// rows provided for a FETCH clause must be greater then zero.
if ($this->QBLimit === 0) {
if (! config(Feature::class)->limitZeroAsAll && $this->QBLimit === 0) {
return "SELECT * \nFROM " . $this->_fromTables() . ' WHERE 1=0 ';
}

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

// LIMIT
if ($this->QBLimit !== false || $this->QBOffset) {
if (config(Feature::class)->limitZeroAsAll) {
if ($this->QBLimit) {
$sql = $this->_limit($sql . "\n");
}
} elseif ($this->QBLimit !== false || $this->QBOffset) {
$sql = $this->_limit($sql . "\n");
}

Expand Down
5 changes: 5 additions & 0 deletions system/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use CodeIgniter\Exceptions\ModelException;
use CodeIgniter\Validation\ValidationInterface;
use Config\Database;
use Config\Feature;
use ReflectionException;

/**
Expand Down Expand Up @@ -228,6 +229,10 @@ protected function doFindColumn(string $columnName)
*/
protected function doFindAll(?int $limit = null, int $offset = 0)
{
if (config(Feature::class)->limitZeroAsAll) {
$limit ??= 0;
}

$builder = $this->builder();

if ($this->tempUseSoftDeletes) {
Expand Down
17 changes: 17 additions & 0 deletions tests/system/Database/Builder/GetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\Mock\MockConnection;
use Config\Feature;

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

public function testGetWithResetWithLimitZeroAsAll(): void
{
$config = config(Feature::class);
$config->limitZeroAsAll = true;

$builder = $this->db->table('users');
$builder->testMode()->where('username', 'bogus');

$expectedSQL = 'SELECT * FROM "users" WHERE "username" = \'bogus\'';
$expectedSQLafterreset = 'SELECT * FROM "users"';

$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->get(0, 50, false)));
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->get(0, 50, true)));
$this->assertSame($expectedSQLafterreset, str_replace("\n", ' ', $builder->get(0, 50, true)));
}

/**
* @see https://github.com/codeigniter4/CodeIgniter4/issues/2143
*/
Expand Down
11 changes: 11 additions & 0 deletions tests/system/Database/Live/GetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use CodeIgniter\Database\Exceptions\DatabaseException;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Config\Feature;
use Tests\Support\Database\Seeds\CITestSeeder;

/**
Expand Down Expand Up @@ -55,6 +56,16 @@ public function testGetWithLimitZero(): void
$this->assertCount(0, $jobs);
}

public function testGetWithLimitZeroAsAll(): void
{
$config = config(Feature::class);
$config->limitZeroAsAll = true;

$jobs = $this->db->table('job')->limit(0)->get()->getResult();

$this->assertCount(4, $jobs);
}

public function testGetWhereArray(): void
{
$jobs = $this->db->table('job')
Expand Down

0 comments on commit 48e0cbd

Please sign in to comment.