Skip to content

Commit 0b0a274

Browse files
authored
[12.x] Add pipe method query builders (#55171)
* Update tap description * Add pipe method to query builder * Add eloquent query builder tests * Fix builder return type in type tests * Add eloquent builder type tests * Reorganise type tests * Fix broken return syntax * Improve types
1 parent 16ad066 commit 0b0a274

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

src/Illuminate/Database/Concerns/BuildsQueries.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ protected function cursorPaginator($items, $perPage, $cursor, $options)
587587
}
588588

589589
/**
590-
* Pass the query to a given callback.
590+
* Pass the query to a given callback and then return it.
591591
*
592592
* @param callable($this): mixed $callback
593593
* @return $this
@@ -598,4 +598,17 @@ public function tap($callback)
598598

599599
return $this;
600600
}
601+
602+
/**
603+
* Pass the query to a given callback and return the result.
604+
*
605+
* @template TReturn
606+
*
607+
* @param (callable($this): TReturn) $callback
608+
* @return (TReturn is null|void ? $this : TReturn)
609+
*/
610+
public function pipe($callback)
611+
{
612+
return $callback($this) ?? $this;
613+
}
601614
}

tests/Database/DatabaseEloquentBuilderTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Illuminate\Support\Carbon;
2222
use Illuminate\Support\Collection as BaseCollection;
2323
use Mockery as m;
24+
use PDO;
2425
use PHPUnit\Framework\TestCase;
2526
use stdClass;
2627

@@ -2615,6 +2616,31 @@ public function getPassthru(): array
26152616
}
26162617
}
26172618

2619+
public function testPipeCallback()
2620+
{
2621+
$query = new Builder(new BaseBuilder(
2622+
$connection = new Connection(new PDO('sqlite::memory:')),
2623+
new Grammar($connection),
2624+
new Processor,
2625+
));
2626+
2627+
$result = $query->pipe(fn (Builder $query) => 5);
2628+
$this->assertSame(5, $result);
2629+
2630+
$result = $query->pipe(fn (Builder $query) => null);
2631+
$this->assertSame($query, $result);
2632+
2633+
$result = $query->pipe(function (Builder $query) {
2634+
//
2635+
});
2636+
$this->assertSame($query, $result);
2637+
2638+
$this->assertCount(0, $query->getQuery()->wheres);
2639+
$result = $query->pipe(fn (Builder $query) => $query->where('foo', 'bar'));
2640+
$this->assertSame($query, $result);
2641+
$this->assertCount(1, $query->getQuery()->wheres);
2642+
}
2643+
26182644
protected function mockConnectionForModel($model, $database)
26192645
{
26202646
$grammarClass = 'Illuminate\Database\Query\Grammars\\'.$database.'Grammar';

tests/Database/DatabaseQueryBuilderTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,27 @@ public function testTapCallback()
301301
$this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
302302
}
303303

304+
public function testPipeCallback()
305+
{
306+
$query = $this->getBuilder();
307+
308+
$result = $query->pipe(fn (Builder $query) => 5);
309+
$this->assertSame(5, $result);
310+
311+
$result = $query->pipe(fn (Builder $query) => null);
312+
$this->assertSame($query, $result);
313+
314+
$result = $query->pipe(function (Builder $query) {
315+
//
316+
});
317+
$this->assertSame($query, $result);
318+
319+
$this->assertCount(0, $query->wheres);
320+
$result = $query->pipe(fn (Builder $query) => $query->where('foo', 'bar'));
321+
$this->assertSame($query, $result);
322+
$this->assertCount(1, $query->wheres);
323+
}
324+
304325
public function testBasicWheres()
305326
{
306327
$builder = $this->getBuilder();

types/Database/Eloquent/Builder.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ function test(
223223
assertType('Illuminate\Types\Builder\CommentBuilder', $comment->newQuery()->where('foo', 'bar'));
224224
assertType('Illuminate\Types\Builder\CommentBuilder', $comment->newQuery()->foo());
225225
assertType('Illuminate\Types\Builder\Comment', $comment->newQuery()->create(['name' => 'John']));
226+
assertType('Illuminate\Database\Eloquent\Builder<Illuminate\Types\Builder\User>', $query->pipe(function () {
227+
//
228+
}));
229+
assertType('Illuminate\Database\Eloquent\Builder<Illuminate\Types\Builder\User>', $query->pipe(fn () => null));
230+
assertType('Illuminate\Database\Eloquent\Builder<Illuminate\Types\Builder\User>', $query->pipe(fn ($query) => $query));
231+
assertType('5', $query->pipe(fn ($query) => 5));
226232
}
227233

228234
class User extends Model

types/Database/Query/Builder.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,10 @@ function test(Builder $query, EloquentBuilder $userQuery): void
6060
assertType('object', $users);
6161
assertType('int', $page);
6262
});
63+
assertType('Illuminate\Database\Query\Builder', $query->pipe(function () {
64+
//
65+
}));
66+
assertType('Illuminate\Database\Query\Builder', $query->pipe(fn () => null));
67+
assertType('Illuminate\Database\Query\Builder', $query->pipe(fn ($query) => $query));
68+
assertType('5', $query->pipe(fn ($query) => 5));
6369
}

0 commit comments

Comments
 (0)