Skip to content

Commit df6fd49

Browse files
committed
Applying necessary changes
1 parent 02a3ff1 commit df6fd49

File tree

5 files changed

+51
-55
lines changed

5 files changed

+51
-55
lines changed

system/BaseModel.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,9 @@ abstract public function chunk(int $size, Closure $userFunc);
598598
* @return void
599599
*
600600
* @throws DataException
601+
* @throws InvalidArgumentException if $size is not a positive integer
601602
*/
602-
abstract public function chunkArray(int $size, Closure $userFunc);
603+
abstract public function chunkRows(int $size, Closure $userFunc);
603604

604605
/**
605606
* Fetches the row of database.

system/Model.php

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use CodeIgniter\Validation\ValidationInterface;
2727
use Config\Database;
2828
use Config\Feature;
29+
use Generator;
2930
use stdClass;
3031

3132
/**
@@ -525,17 +526,10 @@ public function countAllResults(bool $reset = true, bool $test = false)
525526
return $this->builder()->testMode($test)->countAllResults($reset);
526527
}
527528

528-
/**
529-
* {@inheritDoc}
530-
*
531-
* Works with `$this->builder` to get the Compiled select to
532-
* determine the rows to operate on.
533-
* This method works only with dbCalls.
534-
*/
535-
public function chunk(int $size, Closure $userFunc)
529+
private function iterateChunks(int $size): Generator
536530
{
537531
if ($size <= 0) {
538-
throw new InvalidArgumentException('chunk() requires a positive integer for the $size argument.');
532+
throw new InvalidArgumentException('$size must be a positive integer.');
539533
}
540534

541535
$total = $this->builder()->countAllResults(false);
@@ -557,6 +551,20 @@ public function chunk(int $size, Closure $userFunc)
557551
continue;
558552
}
559553

554+
yield $rows;
555+
}
556+
}
557+
558+
/**
559+
* {@inheritDoc}
560+
*
561+
* Works with `$this->builder` to get the Compiled select to
562+
* determine the rows to operate on.
563+
* This method works only with dbCalls.
564+
*/
565+
public function chunk(int $size, Closure $userFunc)
566+
{
567+
foreach ($this->iterateChunks($size) as $rows) {
560568
foreach ($rows as $row) {
561569
if ($userFunc($row) === false) {
562570
return;
@@ -572,31 +580,9 @@ public function chunk(int $size, Closure $userFunc)
572580
* determine the rows to operate on.
573581
* This method works only with dbCalls.
574582
*/
575-
public function chunkArray(int $size, Closure $userFunc)
583+
public function chunkRows(int $size, Closure $userFunc)
576584
{
577-
if ($size <= 0) {
578-
throw new InvalidArgumentException('chunkArray() requires a positive integer for the $size argument.');
579-
}
580-
581-
$total = $this->builder()->countAllResults(false);
582-
$offset = 0;
583-
584-
while ($offset < $total) {
585-
$builder = clone $this->builder();
586-
$rows = $builder->get($size, $offset);
587-
588-
if (! $rows) {
589-
throw DataException::forEmptyDataset('chunk');
590-
}
591-
592-
$rows = $rows->getResult($this->tempReturnType);
593-
594-
$offset += $size;
595-
596-
if ($rows === []) {
597-
continue;
598-
}
599-
585+
foreach ($this->iterateChunks($size) as $rows) {
600586
if ($userFunc($rows) === false) {
601587
return;
602588
}

tests/system/Models/MiscellaneousModelTest.php

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ public function testChunk(): void
4444
public function testChunkThrowsOnZeroSize(): void
4545
{
4646
$this->expectException(InvalidArgumentException::class);
47-
$this->expectExceptionMessage('chunk() requires a positive integer for the $size argument.');
47+
$this->expectExceptionMessage('$size must be a positive integer.');
4848

4949
$this->createModel(UserModel::class)->chunk(0, static function ($row): void {});
5050
}
5151

5252
public function testChunkThrowsOnNegativeSize(): void
5353
{
5454
$this->expectException(InvalidArgumentException::class);
55-
$this->expectExceptionMessage('chunk() requires a positive integer for the $size argument.');
55+
$this->expectExceptionMessage('$size must be a positive integer.');
5656

5757
$this->createModel(UserModel::class)->chunk(-1, static function ($row): void {});
5858
}
@@ -97,12 +97,12 @@ public function testChunkEmptyTable(): void
9797
$this->assertSame(0, $rowCount);
9898
}
9999

100-
public function testChunkArray(): void
100+
public function testChunkRows(): void
101101
{
102102
$chunkCount = 0;
103103
$numRowsInChunk = [];
104104

105-
$this->createModel(UserModel::class)->chunkArray(2, static function ($rows) use (&$chunkCount, &$numRowsInChunk): void {
105+
$this->createModel(UserModel::class)->chunkRows(2, static function ($rows) use (&$chunkCount, &$numRowsInChunk): void {
106106
$chunkCount++;
107107
$numRowsInChunk[] = count($rows);
108108
});
@@ -111,27 +111,27 @@ public function testChunkArray(): void
111111
$this->assertSame([2, 2], $numRowsInChunk);
112112
}
113113

114-
public function testChunkArrayThrowsOnZeroSize(): void
114+
public function testChunkRowsThrowsOnZeroSize(): void
115115
{
116116
$this->expectException(InvalidArgumentException::class);
117-
$this->expectExceptionMessage('chunkArray() requires a positive integer for the $size argument.');
117+
$this->expectExceptionMessage('$size must be a positive integer.');
118118

119-
$this->createModel(UserModel::class)->chunkArray(0, static function ($row): void {});
119+
$this->createModel(UserModel::class)->chunkRows(0, static function ($row): void {});;
120120
}
121121

122-
public function testChunkArrayThrowsOnNegativeSize(): void
122+
public function testChunkRowsThrowsOnNegativeSize(): void
123123
{
124124
$this->expectException(InvalidArgumentException::class);
125-
$this->expectExceptionMessage('chunkArray() requires a positive integer for the $size argument.');
125+
$this->expectExceptionMessage('$size must be a positive integer.');
126126

127-
$this->createModel(UserModel::class)->chunkArray(-1, static function ($row): void {});
127+
$this->createModel(UserModel::class)->chunkRows(-1, static function ($row): void {});
128128
}
129129

130-
public function testChunkArrayEarlyExit(): void
130+
public function testChunkRowsEarlyExit(): void
131131
{
132132
$rowCount = 0;
133133

134-
$this->createModel(UserModel::class)->chunkArray(2, static function ($rows) use (&$rowCount): bool {
134+
$this->createModel(UserModel::class)->chunkRows(2, static function ($rows) use (&$rowCount): bool {
135135
$rowCount++;
136136

137137
return false;
@@ -140,27 +140,27 @@ public function testChunkArrayEarlyExit(): void
140140
$this->assertSame(1, $rowCount);
141141
}
142142

143-
public function testChunkArrayDoesNotRunExtraQuery(): void
143+
public function testChunkRowsDoesNotRunExtraQuery(): void
144144
{
145145
$queryCount = 0;
146146
$listener = static function () use (&$queryCount): void {
147147
$queryCount++;
148148
};
149149

150150
Events::on('DBQuery', $listener);
151-
$this->createModel(UserModel::class)->chunkArray(4, static function ($rows): void {});
151+
$this->createModel(UserModel::class)->chunkRows(4, static function ($rows): void {});
152152
Events::removeListener('DBQuery', $listener);
153153

154154
$this->assertSame(2, $queryCount);
155155
}
156156

157-
public function testChunkArrayEmptyTable(): void
157+
public function testChunkRowsEmptyTable(): void
158158
{
159159
$this->db->table('user')->truncate();
160160

161161
$rowCount = 0;
162162

163-
$this->createModel(UserModel::class)->chunkArray(2, static function ($row) use (&$rowCount): void {
163+
$this->createModel(UserModel::class)->chunkRows(2, static function ($row) use (&$rowCount): void {
164164
$rowCount++;
165165
});
166166

user_guide_src/source/changelogs/v4.8.0.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Others
7171
Model
7272
=====
7373

74-
- Added new ``chunkArray()`` method to ``CodeIgniter\Model`` for processing large datasets in smaller chunks. See :ref:`model-chunk-array` for usage.
74+
- Added new ``chunkArray()`` method to ``CodeIgniter\Model`` for processing large datasets in smaller chunks.
7575

7676
Libraries
7777
=========

user_guide_src/source/models/model.rst

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -900,15 +900,24 @@ Processing Large Amounts of Data
900900
================================
901901

902902
Sometimes, you need to process large amounts of data and would run the risk of running out of memory.
903-
To make this simpler, you may use the chunk() method to get smaller chunks of data that you can then
903+
This is best used during cronjobs, data exports, or other large tasks. To make this simpler, you can
904+
process the data in smaller, manageable pieces using the methods below.
905+
906+
chunk()
907+
-------
908+
909+
You may use the ``chunk()`` method to get smaller chunks of data that you can then
904910
do your work on. The first parameter is the number of rows to retrieve in a single chunk. The second
905911
parameter is a Closure that will be called for each row of data.
906912

907-
This is best used during cronjobs, data exports, or other large tasks.
908-
909913
.. literalinclude:: model/049.php
910914

911-
On the other hand, if you want entire chunk to be passed to the Closure, you can use the chunkArray() method.
915+
chunkRows()
916+
-----------
917+
918+
.. versionadded:: 4.8.0
919+
920+
On the other hand, if you want the entire chunk to be passed to the Closure at once, you can use the ``chunkRows()`` method.
912921

913922
.. literalinclude:: model/064.php
914923

0 commit comments

Comments
 (0)