@@ -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