BuildsQueries.php 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <?php
  2. namespace Illuminate\Database\Concerns;
  3. use Illuminate\Container\Container;
  4. use Illuminate\Pagination\Paginator;
  5. use Illuminate\Pagination\LengthAwarePaginator;
  6. trait BuildsQueries
  7. {
  8. /**
  9. * Chunk the results of the query.
  10. *
  11. * @param int $count
  12. * @param callable $callback
  13. * @return bool
  14. */
  15. public function chunk($count, callable $callback)
  16. {
  17. $this->enforceOrderBy();
  18. $page = 1;
  19. do {
  20. // We'll execute the query for the given page and get the results. If there are
  21. // no results we can just break and return from here. When there are results
  22. // we will call the callback with the current chunk of these results here.
  23. $results = $this->forPage($page, $count)->get();
  24. $countResults = $results->count();
  25. if ($countResults == 0) {
  26. break;
  27. }
  28. // On each chunk result set, we will pass them to the callback and then let the
  29. // developer take care of everything within the callback, which allows us to
  30. // keep the memory low for spinning through large result sets for working.
  31. if ($callback($results, $page) === false) {
  32. return false;
  33. }
  34. unset($results);
  35. $page++;
  36. } while ($countResults == $count);
  37. return true;
  38. }
  39. /**
  40. * Execute a callback over each item while chunking.
  41. *
  42. * @param callable $callback
  43. * @param int $count
  44. * @return bool
  45. */
  46. public function each(callable $callback, $count = 1000)
  47. {
  48. return $this->chunk($count, function ($results) use ($callback) {
  49. foreach ($results as $key => $value) {
  50. if ($callback($value, $key) === false) {
  51. return false;
  52. }
  53. }
  54. });
  55. }
  56. /**
  57. * Execute the query and get the first result.
  58. *
  59. * @param array $columns
  60. * @return \Illuminate\Database\Eloquent\Model|object|static|null
  61. */
  62. public function first($columns = ['*'])
  63. {
  64. return $this->take(1)->get($columns)->first();
  65. }
  66. /**
  67. * Apply the callback's query changes if the given "value" is true.
  68. *
  69. * @param mixed $value
  70. * @param callable $callback
  71. * @param callable $default
  72. * @return mixed
  73. */
  74. public function when($value, $callback, $default = null)
  75. {
  76. if ($value) {
  77. return $callback($this, $value) ?: $this;
  78. } elseif ($default) {
  79. return $default($this, $value) ?: $this;
  80. }
  81. return $this;
  82. }
  83. /**
  84. * Pass the query to a given callback.
  85. *
  86. * @param \Closure $callback
  87. * @return \Illuminate\Database\Query\Builder
  88. */
  89. public function tap($callback)
  90. {
  91. return $this->when(true, $callback);
  92. }
  93. /**
  94. * Apply the callback's query changes if the given "value" is false.
  95. *
  96. * @param mixed $value
  97. * @param callable $callback
  98. * @param callable $default
  99. * @return mixed
  100. */
  101. public function unless($value, $callback, $default = null)
  102. {
  103. if (! $value) {
  104. return $callback($this, $value) ?: $this;
  105. } elseif ($default) {
  106. return $default($this, $value) ?: $this;
  107. }
  108. return $this;
  109. }
  110. /**
  111. * Create a new length-aware paginator instance.
  112. *
  113. * @param \Illuminate\Support\Collection $items
  114. * @param int $total
  115. * @param int $perPage
  116. * @param int $currentPage
  117. * @param array $options
  118. * @return \Illuminate\Pagination\LengthAwarePaginator
  119. */
  120. protected function paginator($items, $total, $perPage, $currentPage, $options)
  121. {
  122. return Container::getInstance()->makeWith(LengthAwarePaginator::class, compact(
  123. 'items', 'total', 'perPage', 'currentPage', 'options'
  124. ));
  125. }
  126. /**
  127. * Create a new simple paginator instance.
  128. *
  129. * @param \Illuminate\Support\Collection $items
  130. * @param int $perPage
  131. * @param int $currentPage
  132. * @param array $options
  133. * @return \Illuminate\Pagination\Paginator
  134. */
  135. protected function simplePaginator($items, $perPage, $currentPage, $options)
  136. {
  137. return Container::getInstance()->makeWith(Paginator::class, compact(
  138. 'items', 'perPage', 'currentPage', 'options'
  139. ));
  140. }
  141. }