Skip to content

Commit 16e8f91

Browse files
committed
Add support for cursor pagination
This commit adds support for Laravel cursor pagination. Fixes #2314
1 parent 6cdd309 commit 16e8f91

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/Eloquent/Builder.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,35 @@ public function getConnection()
216216
{
217217
return $this->query->getConnection();
218218
}
219+
220+
/**
221+
* @inheritdoc
222+
*/
223+
protected function ensureOrderForCursorPagination($shouldReverse = false)
224+
{
225+
if (empty($this->query->orders)) {
226+
$this->enforceOrderBy();
227+
}
228+
229+
if ($shouldReverse) {
230+
$this->query->orders = collect($this->query->orders)->map(function ($direction) {
231+
return $direction === 1 ? -1 : 1;
232+
})->toArray();
233+
}
234+
235+
return $this->mapMongodbOrdersToEloquentOrders($this->query->orders);
236+
}
237+
238+
private function mapMongodbOrdersToEloquentOrders($orders) {
239+
$eloquentOrders = [];
240+
241+
foreach($orders as $column => $direction) {
242+
$eloquentOrders[] = [
243+
'column' => $column,
244+
'direction' => $direction === 1 ? 'asc' : 'desc',
245+
];
246+
}
247+
248+
return collect($eloquentOrders);
249+
}
219250
}

tests/QueryTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,29 @@ public function testPaginate(): void
383383
$this->assertEquals(1, $results->currentPage());
384384
}
385385

386+
public function testCursorPaginate(): void
387+
{
388+
$results = User::cursorPaginate(2);
389+
$this->assertEquals(2, $results->count());
390+
$this->assertNotNull($results->first()->title);
391+
$this->assertNotNull($results->nextCursor());
392+
$this->assertTrue($results->onFirstPage());
393+
394+
$results = User::cursorPaginate(2, ['name', 'age']);
395+
$this->assertEquals(2, $results->count());
396+
$this->assertNull($results->first()->title);
397+
398+
$results = User::orderBy('age', 'desc')->cursorPaginate(2, ['name', 'age']);
399+
$this->assertEquals(2, $results->count());
400+
$this->assertEquals(37, $results->first()->age);
401+
$this->assertNull($results->first()->title);
402+
403+
$results = User::whereNotNull('age')->orderBy('age', 'asc')->cursorPaginate(2, ['name', 'age']);
404+
$this->assertEquals(2, $results->count());
405+
$this->assertEquals(13, $results->first()->age);
406+
$this->assertNull($results->first()->title);
407+
}
408+
386409
public function testUpdate(): void
387410
{
388411
$this->assertEquals(1, User::where(['name' => 'John Doe'])->update(['name' => 'Jim Morrison']));

0 commit comments

Comments
 (0)