Skip to content

Commit 195ded5

Browse files
committed
Moving method closer to chunk
1 parent 2e21da9 commit 195ded5

1 file changed

Lines changed: 93 additions & 93 deletions

File tree

src/Illuminate/Database/Query/Builder.php

Lines changed: 93 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,99 @@ public function chunk($count, callable $callback)
15221522
}
15231523
}
15241524

1525+
/**
1526+
* Chunk the results of a query by comparing IDs.
1527+
*
1528+
* @param int $count
1529+
* @param callable $callback
1530+
* @param string|null $column
1531+
* @param string|null $alias
1532+
* @return bool
1533+
*/
1534+
public function chunkById(int $count, callable $callback, string|null $column = null, string|null $alias = null): bool
1535+
{
1536+
$column ??= $this->defaultKeyName();
1537+
1538+
$alias ??= $column;
1539+
1540+
$lastId = null;
1541+
1542+
$page = 1;
1543+
1544+
do {
1545+
$clone = clone $this;
1546+
1547+
// We'll execute the query for the given page and get the results. If there are
1548+
// no results we can just break and return from here. When there are results
1549+
// we will call the callback with the current chunk of these results here.
1550+
$results = $clone->forPageAfterId($count, $lastId, $column)->get();
1551+
1552+
$countResults = count($results);
1553+
1554+
if ($countResults === 0) {
1555+
break;
1556+
}
1557+
1558+
// On each chunk result set, we will pass them to the callback and then let the
1559+
// developer take care of everything within the callback, which allows us to
1560+
// keep the memory low for spinning through large result sets for working.
1561+
if ($callback($results, $page) === false) {
1562+
return false;
1563+
}
1564+
1565+
$lastId = data_get(end($results), $alias);
1566+
1567+
if ($lastId === null) {
1568+
throw new RuntimeException("The chunkById operation was aborted because the [{$alias}] column is not present in the query result.");
1569+
}
1570+
1571+
unset($results);
1572+
1573+
$page++;
1574+
} while ($countResults === $count);
1575+
1576+
return true;
1577+
}
1578+
1579+
/**
1580+
* Constrain the query to the next "page" of results after a given ID.
1581+
*
1582+
* @param int $perPage
1583+
* @param int|null $lastId
1584+
* @param string $column
1585+
* @return $this
1586+
*/
1587+
public function forPageAfterId(int $perPage = 15, int|null $lastId = 0, string $column = 'id'): Builder
1588+
{
1589+
$this->orders = $this->removeExistingOrdersFor($column);
1590+
1591+
if (! is_null($lastId)) {
1592+
$this->where($column, '>', $lastId);
1593+
}
1594+
1595+
return $this->orderBy($column, 'asc')
1596+
->limit($perPage);
1597+
}
1598+
1599+
/**
1600+
* Get an array with all orders with a given column removed.
1601+
*
1602+
* @param string $column
1603+
* @return array
1604+
*/
1605+
protected function removeExistingOrdersFor(string $column): array
1606+
{
1607+
return Collection::make($this->orders)
1608+
->reject(function ($order) use ($column) {
1609+
return isset($order['column']) && $order['column'] === $column;
1610+
})->values()->all();
1611+
}
1612+
1613+
private function defaultKeyName(): string
1614+
{
1615+
return 'id';
1616+
}
1617+
15251618
/**
15261619
* Get an array with the values of a given column.
15271620
*
@@ -2185,97 +2278,4 @@ public function __call($method, $parameters)
21852278
throw new \BadMethodCallException("Call to undefined method {$className}::{$method}()");
21862279
}
21872280

2188-
/**
2189-
* Chunk the results of a query by comparing IDs.
2190-
*
2191-
* @param int $count
2192-
* @param callable $callback
2193-
* @param string|null $column
2194-
* @param string|null $alias
2195-
* @return bool
2196-
*/
2197-
public function chunkById(int $count, callable $callback, string|null $column = null, string|null $alias = null): bool
2198-
{
2199-
$column ??= $this->defaultKeyName();
2200-
2201-
$alias ??= $column;
2202-
2203-
$lastId = null;
2204-
2205-
$page = 1;
2206-
2207-
do {
2208-
$clone = clone $this;
2209-
2210-
// We'll execute the query for the given page and get the results. If there are
2211-
// no results we can just break and return from here. When there are results
2212-
// we will call the callback with the current chunk of these results here.
2213-
$results = $clone->forPageAfterId($count, $lastId, $column)->get();
2214-
2215-
$countResults = count($results);
2216-
2217-
if ($countResults === 0) {
2218-
break;
2219-
}
2220-
2221-
// On each chunk result set, we will pass them to the callback and then let the
2222-
// developer take care of everything within the callback, which allows us to
2223-
// keep the memory low for spinning through large result sets for working.
2224-
if ($callback($results, $page) === false) {
2225-
return false;
2226-
}
2227-
2228-
$lastId = data_get(end($results), $alias);
2229-
2230-
if ($lastId === null) {
2231-
throw new RuntimeException("The chunkById operation was aborted because the [{$alias}] column is not present in the query result.");
2232-
}
2233-
2234-
unset($results);
2235-
2236-
$page++;
2237-
} while ($countResults === $count);
2238-
2239-
return true;
2240-
}
2241-
2242-
/**
2243-
* Constrain the query to the next "page" of results after a given ID.
2244-
*
2245-
* @param int $perPage
2246-
* @param int|null $lastId
2247-
* @param string $column
2248-
* @return $this
2249-
*/
2250-
public function forPageAfterId(int $perPage = 15, int|null $lastId = 0, string $column = 'id'): Builder
2251-
{
2252-
$this->orders = $this->removeExistingOrdersFor($column);
2253-
2254-
if (! is_null($lastId)) {
2255-
$this->where($column, '>', $lastId);
2256-
}
2257-
2258-
return $this->orderBy($column, 'asc')
2259-
->limit($perPage);
2260-
}
2261-
2262-
/**
2263-
* Get an array with all orders with a given column removed.
2264-
*
2265-
* @param string $column
2266-
* @return array
2267-
*/
2268-
protected function removeExistingOrdersFor(string $column): array
2269-
{
2270-
return Collection::make($this->orders)
2271-
->reject(function ($order) use ($column) {
2272-
return isset($order['column']) && $order['column'] === $column;
2273-
})->values()->all();
2274-
}
2275-
2276-
private function defaultKeyName(): string
2277-
{
2278-
return 'id';
2279-
}
2280-
22812281
}

0 commit comments

Comments
 (0)