Skip to content

Commit 2d40b1b

Browse files
authored
Support qualified cursor (#3)
1 parent 51c3d6b commit 2d40b1b

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

src/Processor.php

+25
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ class Processor extends ArrayProcessor
2222
{
2323
use HasSnakeAliases;
2424

25+
/**
26+
* Return comparable value from a row.
27+
*
28+
* @param mixed $row
29+
* @param string $column
30+
* @return int|string
31+
*/
32+
protected function field($row, $column)
33+
{
34+
return parent::field($row, static::dropTablePrefix($column));
35+
}
36+
2537
/**
2638
* Slice rows, like PHP function array_slice().
2739
*
@@ -62,4 +74,17 @@ protected function defaultFormat($rows, array $meta, Query $query)
6274
{
6375
return new PaginationResult($rows, $meta);
6476
}
77+
78+
/**
79+
* Drop table prefix on column name.
80+
*
81+
* @param string $column
82+
* @return string
83+
*/
84+
protected static function dropTablePrefix($column)
85+
{
86+
$segments = explode('.', $column);
87+
88+
return end($segments);
89+
}
6590
}

tests/MySQLGrammarTest.php

+38
Original file line numberDiff line numberDiff line change
@@ -416,4 +416,42 @@ public function testDescendingBackwardExclusive()
416416
) `temporary_table`
417417
', $this->toSql($builder));
418418
}
419+
420+
/**
421+
* @test
422+
*/
423+
public function testQualifiedColumnOrder()
424+
{
425+
$cursor = ['posts.updated_at' => '', 'posts.created_at' => '', 'posts.id' => ''];
426+
$builder = lampager(ORM::forTable('posts')->where_equal('posts.user_id', 2))
427+
->forward()->limit(3)
428+
->order_by_asc('posts.updated_at')
429+
->order_by_asc('posts.created_at')
430+
->order_by_asc('posts.id')
431+
->seekable()
432+
->build($cursor);
433+
$this->assertSqlEquals('
434+
SELECT * FROM (
435+
SELECT * FROM `posts`
436+
WHERE `posts`.`user_id` = ? AND (
437+
`posts`.`updated_at` = ? AND `posts`.`created_at` = ? AND `posts`.`id` < ? OR
438+
`posts`.`updated_at` = ? AND `posts`.`created_at` < ? OR
439+
`posts`.`updated_at` < ?
440+
)
441+
ORDER BY `posts`.`updated_at` DESC, `posts`.`created_at` DESC, `posts`.`id` DESC
442+
LIMIT 1
443+
) `temporary_table`
444+
UNION ALL
445+
SELECT * FROM (
446+
SELECT * FROM `posts`
447+
WHERE `posts`.`user_id` = ? AND (
448+
`posts`.`updated_at` = ? AND `posts`.`created_at` = ? AND `posts`.`id` >= ? OR
449+
`posts`.`updated_at` = ? AND `posts`.`created_at` > ? OR
450+
`posts`.`updated_at` > ?
451+
)
452+
ORDER BY `posts`.`updated_at` ASC, `posts`.`created_at` ASC, `posts`.`id` ASC
453+
LIMIT 4
454+
) `temporary_table`
455+
', $this->toSql($builder));
456+
}
419457
}

tests/ProcessorTest.php

+26
Original file line numberDiff line numberDiff line change
@@ -435,4 +435,30 @@ public function testDescendingBackwardExclusive()
435435
->paginate(['id' => '3', 'updated_at' => '2017-01-01 10:00:00'])
436436
);
437437
}
438+
439+
/**
440+
* @test
441+
*/
442+
public function testQualifiedColumnOrder()
443+
{
444+
$this->assertResultSame(
445+
[
446+
'records' => [
447+
['id' => '3', 'updated_at' => '2017-01-01 10:00:00'],
448+
['id' => '5', 'updated_at' => '2017-01-01 10:00:00'],
449+
['id' => '2', 'updated_at' => '2017-01-01 11:00:00'],
450+
],
451+
'has_previous' => true,
452+
'previous_cursor' => ['posts.updated_at' => '2017-01-01 10:00:00', 'posts.id' => '1'],
453+
'has_next' => true,
454+
'next_cursor' => ['posts.updated_at' => '2017-01-01 11:00:00', 'posts.id' => '4'],
455+
],
456+
lampager(ORM::for_table('posts'))
457+
->forward()->limit(3)
458+
->order_by_asc('posts.updated_at')
459+
->order_by_asc('posts.id')
460+
->seekable()
461+
->paginate(['posts.id' => '3', 'posts.updated_at' => '2017-01-01 10:00:00'])
462+
);
463+
}
438464
}

0 commit comments

Comments
 (0)