EloquentCursorPaginateTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. namespace Illuminate\Tests\Integration\Database;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Database\Schema\Blueprint;
  5. use Illuminate\Pagination\Cursor;
  6. use Illuminate\Support\Facades\DB;
  7. use Illuminate\Support\Facades\Schema;
  8. class EloquentCursorPaginateTest extends DatabaseTestCase
  9. {
  10. protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
  11. {
  12. Schema::create('test_posts', function (Blueprint $table) {
  13. $table->increments('id');
  14. $table->string('title')->nullable();
  15. $table->unsignedInteger('user_id')->nullable();
  16. $table->timestamps();
  17. });
  18. Schema::create('test_users', function ($table) {
  19. $table->increments('id');
  20. $table->timestamps();
  21. });
  22. }
  23. public function testCursorPaginationOnTopOfColumns()
  24. {
  25. for ($i = 1; $i <= 50; $i++) {
  26. TestPost::create([
  27. 'title' => 'Title '.$i,
  28. ]);
  29. }
  30. $this->assertCount(15, TestPost::cursorPaginate(15, ['id', 'title']));
  31. }
  32. public function testPaginationWithUnion()
  33. {
  34. TestPost::create(['title' => 'Hello world', 'user_id' => 1]);
  35. TestPost::create(['title' => 'Goodbye world', 'user_id' => 2]);
  36. TestPost::create(['title' => 'Howdy', 'user_id' => 3]);
  37. TestPost::create(['title' => '4th', 'user_id' => 4]);
  38. $table1 = TestPost::query()->whereIn('user_id', [1, 2]);
  39. $table2 = TestPost::query()->whereIn('user_id', [3, 4]);
  40. $result = $table1->unionAll($table2)
  41. ->orderBy('user_id', 'desc')
  42. ->cursorPaginate(1);
  43. self::assertSame(['user_id'], $result->getOptions()['parameters']);
  44. }
  45. public function testPaginationWithDistinct()
  46. {
  47. for ($i = 1; $i <= 3; $i++) {
  48. TestPost::create(['title' => 'Hello world']);
  49. TestPost::create(['title' => 'Goodbye world']);
  50. }
  51. $query = TestPost::query()->distinct();
  52. $this->assertEquals(6, $query->get()->count());
  53. $this->assertEquals(6, $query->count());
  54. $this->assertCount(6, $query->cursorPaginate()->items());
  55. }
  56. public function testPaginationWithWhereClause()
  57. {
  58. for ($i = 1; $i <= 3; $i++) {
  59. TestPost::create(['title' => 'Hello world', 'user_id' => null]);
  60. TestPost::create(['title' => 'Goodbye world', 'user_id' => 2]);
  61. }
  62. $query = TestPost::query()->whereNull('user_id');
  63. $this->assertEquals(3, $query->get()->count());
  64. $this->assertEquals(3, $query->count());
  65. $this->assertCount(3, $query->cursorPaginate()->items());
  66. }
  67. /** @group SkipMSSQL */
  68. public function testPaginationWithHasClause()
  69. {
  70. for ($i = 1; $i <= 3; $i++) {
  71. TestUser::create(['id' => $i]);
  72. TestPost::create(['title' => 'Hello world', 'user_id' => null]);
  73. TestPost::create(['title' => 'Goodbye world', 'user_id' => 2]);
  74. TestPost::create(['title' => 'Howdy', 'user_id' => 3]);
  75. }
  76. $query = TestUser::query()->has('posts');
  77. $this->assertEquals(2, $query->get()->count());
  78. $this->assertEquals(2, $query->count());
  79. $this->assertCount(2, $query->cursorPaginate()->items());
  80. }
  81. /** @group SkipMSSQL */
  82. public function testPaginationWithWhereHasClause()
  83. {
  84. for ($i = 1; $i <= 3; $i++) {
  85. TestUser::create(['id' => $i]);
  86. TestPost::create(['title' => 'Hello world', 'user_id' => null]);
  87. TestPost::create(['title' => 'Goodbye world', 'user_id' => 2]);
  88. TestPost::create(['title' => 'Howdy', 'user_id' => 3]);
  89. }
  90. $query = TestUser::query()->whereHas('posts', function ($query) {
  91. $query->where('title', 'Howdy');
  92. });
  93. $this->assertEquals(1, $query->get()->count());
  94. $this->assertEquals(1, $query->count());
  95. $this->assertCount(1, $query->cursorPaginate()->items());
  96. }
  97. /** @group SkipMSSQL */
  98. public function testPaginationWithWhereExistsClause()
  99. {
  100. for ($i = 1; $i <= 3; $i++) {
  101. TestUser::create(['id' => $i]);
  102. TestPost::create(['title' => 'Hello world', 'user_id' => null]);
  103. TestPost::create(['title' => 'Goodbye world', 'user_id' => 2]);
  104. TestPost::create(['title' => 'Howdy', 'user_id' => 3]);
  105. }
  106. $query = TestUser::query()->whereExists(function ($query) {
  107. $query->select(DB::raw(1))
  108. ->from('test_posts')
  109. ->whereColumn('test_posts.user_id', 'test_users.id');
  110. });
  111. $this->assertEquals(2, $query->get()->count());
  112. $this->assertEquals(2, $query->count());
  113. $this->assertCount(2, $query->cursorPaginate()->items());
  114. }
  115. /** @group SkipMSSQL */
  116. public function testPaginationWithMultipleWhereClauses()
  117. {
  118. for ($i = 1; $i <= 4; $i++) {
  119. TestUser::create(['id' => $i]);
  120. TestPost::create(['title' => 'Hello world', 'user_id' => null]);
  121. TestPost::create(['title' => 'Goodbye world', 'user_id' => 2]);
  122. TestPost::create(['title' => 'Howdy', 'user_id' => 3]);
  123. TestPost::create(['title' => 'Howdy', 'user_id' => 4]);
  124. }
  125. $query = TestUser::query()->whereExists(function ($query) {
  126. $query->select(DB::raw(1))
  127. ->from('test_posts')
  128. ->whereColumn('test_posts.user_id', 'test_users.id');
  129. })->whereHas('posts', function ($query) {
  130. $query->where('title', 'Howdy');
  131. })->where('id', '<', 5)->orderBy('id');
  132. $clonedQuery = $query->clone();
  133. $anotherQuery = $query->clone();
  134. $this->assertEquals(2, $query->get()->count());
  135. $this->assertEquals(2, $query->count());
  136. $this->assertCount(2, $query->cursorPaginate()->items());
  137. $this->assertCount(1, $clonedQuery->cursorPaginate(1)->items());
  138. $this->assertCount(
  139. 1,
  140. $anotherQuery->cursorPaginate(5, ['*'], 'cursor', new Cursor(['id' => 3]))
  141. ->items()
  142. );
  143. }
  144. /** @group SkipMSSQL */
  145. public function testPaginationWithAliasedOrderBy()
  146. {
  147. for ($i = 1; $i <= 6; $i++) {
  148. TestUser::create(['id' => $i]);
  149. }
  150. $query = TestUser::query()->select('id as user_id')->orderBy('user_id');
  151. $clonedQuery = $query->clone();
  152. $anotherQuery = $query->clone();
  153. $this->assertEquals(6, $query->get()->count());
  154. $this->assertEquals(6, $query->count());
  155. $this->assertCount(6, $query->cursorPaginate()->items());
  156. $this->assertCount(3, $clonedQuery->cursorPaginate(3)->items());
  157. $this->assertCount(
  158. 4,
  159. $anotherQuery->cursorPaginate(10, ['*'], 'cursor', new Cursor(['user_id' => 2]))
  160. ->items()
  161. );
  162. }
  163. public function testPaginationWithDistinctColumnsAndSelect()
  164. {
  165. for ($i = 1; $i <= 3; $i++) {
  166. TestPost::create(['title' => 'Hello world']);
  167. TestPost::create(['title' => 'Goodbye world']);
  168. }
  169. $query = TestPost::query()->orderBy('title')->distinct('title')->select('title');
  170. $this->assertEquals(2, $query->get()->count());
  171. $this->assertEquals(2, $query->count());
  172. $this->assertCount(2, $query->cursorPaginate()->items());
  173. }
  174. public function testPaginationWithDistinctColumnsAndSelectAndJoin()
  175. {
  176. for ($i = 1; $i <= 5; $i++) {
  177. $user = TestUser::create();
  178. for ($j = 1; $j <= 10; $j++) {
  179. TestPost::create([
  180. 'title' => 'Title '.$i,
  181. 'user_id' => $user->id,
  182. ]);
  183. }
  184. }
  185. $query = TestUser::query()->join('test_posts', 'test_posts.user_id', '=', 'test_users.id')
  186. ->distinct('test_users.id')->select('test_users.*');
  187. $this->assertEquals(5, $query->get()->count());
  188. $this->assertEquals(5, $query->count());
  189. $this->assertCount(5, $query->cursorPaginate()->items());
  190. }
  191. }
  192. class TestPost extends Model
  193. {
  194. protected $guarded = [];
  195. }
  196. class TestUser extends Model
  197. {
  198. protected $guarded = [];
  199. public function posts()
  200. {
  201. return $this->hasMany(TestPost::class, 'user_id');
  202. }
  203. }