From 6f0c2d066b2af3cb486b247406e3dc535d24af5f Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 19 Feb 2025 14:15:17 +0800 Subject: [PATCH 01/27] update `bin/split.sh` Signed-off-by: Mior Muhammad Zaki --- bin/split.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/split.sh b/bin/split.sh index ae4cdf01f8f3..9536ec7a4f31 100755 --- a/bin/split.sh +++ b/bin/split.sh @@ -3,7 +3,7 @@ set -e set -x -CURRENT_BRANCH="12.x" +CURRENT_BRANCH="master" function split() { From ad719b5793e6b83eaa6a516a0a644fdd949c6569 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 19 Feb 2025 10:00:17 -0600 Subject: [PATCH 02/27] Revert "[12.x] Query builder PDO fetch modes (#54443)" (#54709) This reverts commit ca7ca2cddeff32427ca67c8bfd1e0f8a778a074c. --- src/Illuminate/Database/Connection.php | 19 ++--- .../Database/ConnectionInterface.php | 6 +- src/Illuminate/Database/Query/Builder.php | 75 +++++++++--------- ...EloquentBelongsToManyCreateOrFirstTest.php | 10 +-- ...tabaseEloquentBuilderCreateOrFirstTest.php | 28 +++---- ...tabaseEloquentHasManyCreateOrFirstTest.php | 18 ++--- ...loquentHasManyThroughCreateOrFirstTest.php | 9 --- tests/Database/DatabaseQueryBuilderTest.php | 76 +++++++++---------- .../Integration/Database/QueryBuilderTest.php | 48 ------------ 9 files changed, 110 insertions(+), 179 deletions(-) diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php index 5d5be92e936f..69780f78a2b4 100755 --- a/src/Illuminate/Database/Connection.php +++ b/src/Illuminate/Database/Connection.php @@ -389,12 +389,11 @@ public function selectFromWriteConnection($query, $bindings = []) * @param string $query * @param array $bindings * @param bool $useReadPdo - * @param array $fetchUsing * @return array */ - public function select($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) + public function select($query, $bindings = [], $useReadPdo = true) { - return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo, $fetchUsing) { + return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { if ($this->pretending()) { return []; } @@ -410,7 +409,7 @@ public function select($query, $bindings = [], $useReadPdo = true, array $fetchU $statement->execute(); - return $statement->fetchAll(...$fetchUsing); + return $statement->fetchAll(); }); } @@ -420,12 +419,11 @@ public function select($query, $bindings = [], $useReadPdo = true, array $fetchU * @param string $query * @param array $bindings * @param bool $useReadPdo - * @param array $fetchUsing * @return array */ - public function selectResultSets($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) + public function selectResultSets($query, $bindings = [], $useReadPdo = true) { - return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo, $fetchUsing) { + return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { if ($this->pretending()) { return []; } @@ -441,7 +439,7 @@ public function selectResultSets($query, $bindings = [], $useReadPdo = true, arr $sets = []; do { - $sets[] = $statement->fetchAll(...$fetchUsing); + $sets[] = $statement->fetchAll(); } while ($statement->nextRowset()); return $sets; @@ -454,10 +452,9 @@ public function selectResultSets($query, $bindings = [], $useReadPdo = true, arr * @param string $query * @param array $bindings * @param bool $useReadPdo - * @param array $fetchUsing * @return \Generator */ - public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) + public function cursor($query, $bindings = [], $useReadPdo = true) { $statement = $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { if ($this->pretending()) { @@ -482,7 +479,7 @@ public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchU return $statement; }); - while ($record = $statement->fetch(...$fetchUsing)) { + while ($record = $statement->fetch()) { yield $record; } } diff --git a/src/Illuminate/Database/ConnectionInterface.php b/src/Illuminate/Database/ConnectionInterface.php index 22f866b43763..288adb4206e3 100755 --- a/src/Illuminate/Database/ConnectionInterface.php +++ b/src/Illuminate/Database/ConnectionInterface.php @@ -51,10 +51,9 @@ public function scalar($query, $bindings = [], $useReadPdo = true); * @param string $query * @param array $bindings * @param bool $useReadPdo - * @param array $fetchUsing * @return array */ - public function select($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []); + public function select($query, $bindings = [], $useReadPdo = true); /** * Run a select statement against the database and returns a generator. @@ -62,10 +61,9 @@ public function select($query, $bindings = [], $useReadPdo = true, array $fetchU * @param string $query * @param array $bindings * @param bool $useReadPdo - * @param array $fetchUsing * @return \Generator */ - public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []); + public function cursor($query, $bindings = [], $useReadPdo = true); /** * Run an insert statement against the database. diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 0266f24cfe69..c5db6b31060e 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -249,13 +249,6 @@ class Builder implements BuilderContract */ public $useWritePdo = false; - /** - * The custom arguments for the PDOStatement::fetchAll / fetch functions. - * - * @var array - */ - public array $fetchUsing = []; - /** * Create a new query builder instance. * @@ -3094,13 +3087,9 @@ public function soleValue($column) */ public function get($columns = ['*']) { - $original = $this->columns; - - $this->columns ??= Arr::wrap($columns); - - $items = new Collection($this->processor->processSelect($this, $this->runSelect())); - - $this->columns = $original; + $items = new Collection($this->onceWithColumns(Arr::wrap($columns), function () { + return $this->processor->processSelect($this, $this->runSelect()); + })); return $this->applyAfterQueryCallbacks( isset($this->groupLimit) ? $this->withoutGroupLimitKeys($items) : $items @@ -3115,7 +3104,7 @@ public function get($columns = ['*']) protected function runSelect() { return $this->connection->select( - $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing + $this->toSql(), $this->getBindings(), ! $this->useWritePdo ); } @@ -3333,7 +3322,7 @@ public function cursor() return (new LazyCollection(function () { yield from $this->connection->cursor( - $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing + $this->toSql(), $this->getBindings(), ! $this->useWritePdo ); }))->map(function ($item) { return $this->applyAfterQueryCallbacks(new Collection([$item]))->first(); @@ -3363,18 +3352,17 @@ protected function enforceOrderBy() */ public function pluck($column, $key = null) { - $original = $this->columns; - // First, we will need to select the results of the query accounting for the // given columns / key. Once we have the results, we will be able to take // the results and get the exact data that was requested for the query. - $this->columns = is_null($key) || $key === $column - ? [$column] - : [$column, $key]; - - $queryResult = $this->processor->processSelect($this, $this->runSelect()); - - $this->columns = $original; + $queryResult = $this->onceWithColumns( + is_null($key) || $key === $column ? [$column] : [$column, $key], + function () { + return $this->processor->processSelect( + $this, $this->runSelect() + ); + } + ); if (empty($queryResult)) { return new Collection; @@ -3668,6 +3656,30 @@ protected function setAggregate($function, $columns) return $this; } + /** + * Execute the given callback while selecting the given columns. + * + * After running the callback, the columns are reset to the original value. + * + * @param array $columns + * @param callable $callback + * @return mixed + */ + protected function onceWithColumns($columns, $callback) + { + $original = $this->columns; + + if (is_null($original)) { + $this->columns = $columns; + } + + $result = $callback(); + + $this->columns = $original; + + return $result; + } + /** * Insert new records into the database. * @@ -4281,19 +4293,6 @@ public function useWritePdo() return $this; } - /** - * Specify arguments for the PDOStatement::fetchAll / fetch functions. - * - * @param mixed ...$fetchUsing - * @return $this - */ - public function fetchUsing(...$fetchUsing) - { - $this->fetchUsing = $fetchUsing; - - return $this; - } - /** * Determine if the value is a query builder instance or a Closure. * diff --git a/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php b/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php index 886bc47ef6c4..8fb7dab36607 100644 --- a/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php @@ -84,7 +84,7 @@ public function testCreateOrFirstMethodAssociatesExistingRelated(): void $source->getConnection() ->expects('select') - ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([[ 'id' => 456, 'attr' => 'foo', @@ -128,7 +128,6 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAlreadyAssociated 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([[ 'id' => 456, @@ -177,7 +176,7 @@ public function testCreateOrFirstMethodRetrievesExistingRelatedAssociatedJustNow $source->getConnection() ->expects('select') - ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([[ 'id' => 456, 'attr' => 'foo', @@ -200,7 +199,6 @@ public function testCreateOrFirstMethodRetrievesExistingRelatedAssociatedJustNow 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], false, - [], ) ->andReturn([[ 'id' => 456, @@ -245,7 +243,6 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAndAssociatesIt() 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([]); @@ -255,7 +252,6 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAndAssociatesIt() 'select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, - [], ) ->andReturn([[ 'id' => 456, @@ -330,7 +326,6 @@ protected function newBelongsToMany(Builder $query, Model $parent, $table, $fore 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([]); @@ -340,7 +335,6 @@ protected function newBelongsToMany(Builder $query, Model $parent, $table, $fore 'select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, - [], ) ->andReturn([]); diff --git a/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php b/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php index dcf9d912fe79..63cffe311f53 100755 --- a/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php @@ -66,7 +66,7 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -95,7 +95,7 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -124,7 +124,7 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -152,7 +152,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([]); $sql = 'insert into "table" ("attr", "val", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -165,7 +165,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -194,7 +194,7 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -231,7 +231,7 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -259,7 +259,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([]); $sql = 'insert into "table" ("attr", "val", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -272,7 +272,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -309,7 +309,7 @@ public function testIncrementOrCreateMethodIncrementsExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -351,7 +351,7 @@ public function testIncrementOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -379,7 +379,7 @@ public function testIncrementOrCreateMethodIncrementParametersArePassed(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -423,7 +423,7 @@ public function testIncrementOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) ->andReturn([]); $sql = 'insert into "table" ("attr", "count", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -436,7 +436,7 @@ public function testIncrementOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) ->andReturn([[ 'id' => 123, 'attr' => 'foo', diff --git a/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php b/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php index 38802b80f335..5a3b9e5c1c06 100755 --- a/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php @@ -70,7 +70,7 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -102,7 +102,7 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -132,7 +132,7 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -164,7 +164,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) ->andReturn([]); $sql = 'insert into "child_table" ("attr", "val", "parent_id", "updated_at", "created_at") values (?, ?, ?, ?, ?)'; @@ -177,7 +177,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -209,7 +209,7 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -239,7 +239,7 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -276,7 +276,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) ->andReturn([]); $sql = 'insert into "child_table" ("attr", "val", "parent_id", "updated_at", "created_at") values (?, ?, ?, ?, ?)'; @@ -289,7 +289,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) ->andReturn([[ 'id' => 456, 'parent_id' => 123, diff --git a/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php b/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php index 62acbbfe9e87..b499100ef406 100644 --- a/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php @@ -75,7 +75,6 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([[ 'id' => 789, @@ -115,7 +114,6 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([]); @@ -150,7 +148,6 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([[ 'id' => 789, @@ -190,7 +187,6 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([]); @@ -208,7 +204,6 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ? and "val" = ?) limit 1', [123, 'foo', 'bar'], true, - [], ) ->andReturn([[ 'id' => 789, @@ -248,7 +243,6 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([]); @@ -286,7 +280,6 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([[ 'id' => 789, @@ -334,7 +327,6 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, - [], ) ->andReturn([]); @@ -352,7 +344,6 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ? and "val" = ?) limit 1', [123, 'foo', 'bar'], true, - [], ) ->andReturn([[ 'id' => 789, diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 3671b47e90aa..1773aff32783 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -82,12 +82,12 @@ public function testBasicSelectUseWritePdo() { $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with('select * from `users`', [], false, []); + ->with('select * from `users`', [], false); $builder->useWritePdo()->select('*')->from('users')->get(); $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with('select * from `users`', [], true, []); + ->with('select * from `users`', [], true); $builder->select('*')->from('users')->get(); } @@ -1747,31 +1747,31 @@ public function testUnionAggregate() { $expected = 'select count(*) as aggregate from ((select * from `posts`) union (select * from `videos`)) as `temp_table`'; $builder = $this->getMySqlBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getMySqlBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from ((select `id` from `posts`) union (select `id` from `videos`)) as `temp_table`'; $builder = $this->getMySqlBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->select('id')->union($this->getMySqlBuilder()->from('videos')->select('id'))->count(); $expected = 'select count(*) as aggregate from ((select * from "posts") union (select * from "videos")) as "temp_table"'; $builder = $this->getPostgresBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getPostgresBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from (select * from (select * from "posts") union select * from (select * from "videos")) as "temp_table"'; $builder = $this->getSQLiteBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getSQLiteBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from (select * from (select * from [posts]) as [temp_table] union select * from (select * from [videos]) as [temp_table]) as [temp_table]'; $builder = $this->getSqlServerBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getSqlServerBuilder()->from('videos'))->count(); } @@ -1781,7 +1781,7 @@ public function testHavingAggregate() $expected = 'select count(*) as aggregate from (select (select `count(*)` from `videos` where `posts`.`id` = `videos`.`post_id`) as `videos_count` from `posts` having `videos_count` > ?) as `temp_table`'; $builder = $this->getMySqlBuilder(); $builder->getConnection()->shouldReceive('getDatabaseName'); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2263,7 +2263,7 @@ public function testHavingFollowedBySelectGet() { $builder = $this->getBuilder(); $query = 'select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > ?'; - $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular', 3], true, [])->andReturn([['category' => 'rock', 'total' => 5]]); + $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular', 3], true)->andReturn([['category' => 'rock', 'total' => 5]]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2274,7 +2274,7 @@ public function testHavingFollowedBySelectGet() // Using \Raw value $builder = $this->getBuilder(); $query = 'select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > 3'; - $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular'], true, [])->andReturn([['category' => 'rock', 'total' => 5]]); + $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular'], true)->andReturn([['category' => 'rock', 'total' => 5]]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2367,7 +2367,7 @@ public function testGetCountForPaginationWithBindings() $q->select('body')->from('posts')->where('id', 4); }, 'post'); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2383,7 +2383,7 @@ public function testGetCountForPaginationWithColumnAliases() $columns = ['body as post_body', 'teaser', 'posts.created as published']; $builder->from('posts')->select($columns); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("body", "teaser", "posts"."created") as aggregate from "posts"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("body", "teaser", "posts"."created") as aggregate from "posts"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2397,7 +2397,7 @@ public function testGetCountForPaginationWithUnion() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id')); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2411,7 +2411,7 @@ public function testGetCountForPaginationWithUnionOrders() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'))->latest(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2425,7 +2425,7 @@ public function testGetCountForPaginationWithUnionLimitAndOffset() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'))->take(15)->skip(1); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3412,7 +3412,7 @@ public function testRawExpressionsInSelect() public function testFindReturnsFirstResultByID() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3436,7 +3436,7 @@ public function testFindOrReturnsFirstResultByID() public function testFirstMethodReturnsFirstResult() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3447,7 +3447,7 @@ public function testFirstMethodReturnsFirstResult() public function testFirstOrFailMethodReturnsFirstResult() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3458,7 +3458,7 @@ public function testFirstOrFailMethodReturnsFirstResult() public function testFirstOrFailMethodThrowsRecordNotFoundException() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [])->andReturn([]); @@ -3490,7 +3490,7 @@ public function testPluckMethodGetsCollectionOfColumnValues() public function testPluckAvoidsDuplicateColumnSelection() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ?', [1], true, [])->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ?', [1], true)->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3522,7 +3522,7 @@ public function testImplode() public function testValueMethodReturnsSingleColumn() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturn([['foo' => 'bar']]); $results = $builder->from('users')->where('id', '=', 1)->value('foo'); $this->assertSame('bar', $results); @@ -3531,7 +3531,7 @@ public function testValueMethodReturnsSingleColumn() public function testRawValueMethodReturnsSingleColumn() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select UPPER("foo") from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['UPPER("foo")' => 'BAR']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select UPPER("foo") from "users" where "id" = ? limit 1', [1], true)->andReturn([['UPPER("foo")' => 'BAR']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['UPPER("foo")' => 'BAR']])->andReturn([['UPPER("foo")' => 'BAR']]); $results = $builder->from('users')->where('id', '=', 1)->rawValue('UPPER("foo")'); $this->assertSame('BAR', $results); @@ -3540,7 +3540,7 @@ public function testRawValueMethodReturnsSingleColumn() public function testAggregateFunctions() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3558,7 +3558,7 @@ public function testAggregateFunctions() $this->assertTrue($results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select max("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select max("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3566,7 +3566,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select min("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select min("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3574,7 +3574,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3582,7 +3582,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3590,7 +3590,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3641,9 +3641,9 @@ public function testDoesntExistsOr() public function testAggregateResetFollowedByGet() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 2]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column1", "column2" from "users"', [], true, [])->andReturn([['column1' => 'foo', 'column2' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 2]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column1", "column2" from "users"', [], true)->andReturn([['column1' => 'foo', 'column2' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3659,8 +3659,8 @@ public function testAggregateResetFollowedByGet() public function testAggregateResetFollowedBySelectGet() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true, [])->andReturn([['column2' => 'foo', 'column3' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true)->andReturn([['column2' => 'foo', 'column3' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3674,8 +3674,8 @@ public function testAggregateResetFollowedBySelectGet() public function testAggregateResetFollowedByGetWithColumns() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true, [])->andReturn([['column2' => 'foo', 'column3' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true)->andReturn([['column2' => 'foo', 'column3' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3689,7 +3689,7 @@ public function testAggregateResetFollowedByGetWithColumns() public function testAggregateWithSubSelect() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -5171,12 +5171,12 @@ public function testSelectWithLockUsesWritePdo() { $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with(m::any(), m::any(), false, []); + ->with(m::any(), m::any(), false); $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock()->get(); $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with(m::any(), m::any(), false, []); + ->with(m::any(), m::any(), false); $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false)->get(); } diff --git a/tests/Integration/Database/QueryBuilderTest.php b/tests/Integration/Database/QueryBuilderTest.php index 4e964149659a..c323ff0e1513 100644 --- a/tests/Integration/Database/QueryBuilderTest.php +++ b/tests/Integration/Database/QueryBuilderTest.php @@ -11,7 +11,6 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Testing\Assert as PHPUnit; use Orchestra\Testbench\Attributes\DefineEnvironment; -use PDO; use PDOException; class QueryBuilderTest extends DatabaseTestCase @@ -601,12 +600,6 @@ public function testChunkMap() public function testPluck() { - // Test empty result set. - $this->assertSame( - [], - DB::table('posts')->whereRaw('0=1')->pluck('title')->toArray() - ); - // Test SELECT override, since pluck will take the first column. $this->assertSame([ 'Foo Post', @@ -643,47 +636,6 @@ public function testPluck() ], DB::table('posts')->pluck('title', 'content')->toArray()); } - public function testFetchUsing() - { - // Fetch column as a list. - $this->assertSame([ - 'Foo Post', - 'Bar Post', - ], DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_COLUMN)->get()->toArray()); - - // Fetch the second column as a list (zero-indexed). - $this->assertSame([ - 'Lorem Ipsum.', - 'Lorem Ipsum.', - ], DB::table('posts')->select(['title', 'content'])->fetchUsing(PDO::FETCH_COLUMN, 1)->get()->toArray()); - - // Fetch two columns as key value pairs. - $this->assertSame([ - 1 => 'Foo Post', - 2 => 'Bar Post', - ], DB::table('posts')->select(['id', 'title'])->fetchUsing(PDO::FETCH_KEY_PAIR)->get()->toArray()); - - // Fetch data as associative array with custom key. - $result = DB::table('posts')->select(['id', 'title'])->fetchUsing(PDO::FETCH_UNIQUE)->get()->toArray(); - // Note: results are keyed by their post id here. - $this->assertSame('Foo Post', $result[1]->title); - $this->assertSame('Bar Post', $result[2]->title); - - // Use a cursor. - $this->assertSame([ - 'Foo Post', - 'Bar Post', - ], DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_COLUMN)->cursor()->collect()->toArray()); - - // Test the default 'object' fetch mode. - $result = DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_OBJ)->get()->toArray(); - $result2 = DB::table('posts')->select(['title'])->fetchUsing()->get()->toArray(); - $this->assertSame('Foo Post', $result[0]->title); - $this->assertSame('Bar Post', $result[1]->title); - $this->assertSame('Foo Post', $result2[0]->title); - $this->assertSame('Bar Post', $result2[1]->title); - } - protected function defineEnvironmentWouldThrowsPDOException($app) { $this->afterApplicationCreated(function () { From c5de81cf7e9aa80e3a4061858d43de39338d5cdc Mon Sep 17 00:00:00 2001 From: taylorotwell <463230+taylorotwell@users.noreply.github.com> Date: Wed, 19 Feb 2025 16:01:04 +0000 Subject: [PATCH 03/27] Update facade docblocks --- src/Illuminate/Support/Facades/DB.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Support/Facades/DB.php b/src/Illuminate/Support/Facades/DB.php index 233816bf5767..3ddeae76298a 100644 --- a/src/Illuminate/Support/Facades/DB.php +++ b/src/Illuminate/Support/Facades/DB.php @@ -40,9 +40,9 @@ * @method static mixed selectOne(string $query, array $bindings = [], bool $useReadPdo = true) * @method static mixed scalar(string $query, array $bindings = [], bool $useReadPdo = true) * @method static array selectFromWriteConnection(string $query, array $bindings = []) - * @method static array select(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) - * @method static array selectResultSets(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) - * @method static \Generator cursor(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) + * @method static array select(string $query, array $bindings = [], bool $useReadPdo = true) + * @method static array selectResultSets(string $query, array $bindings = [], bool $useReadPdo = true) + * @method static \Generator cursor(string $query, array $bindings = [], bool $useReadPdo = true) * @method static bool insert(string $query, array $bindings = []) * @method static int update(string $query, array $bindings = []) * @method static int delete(string $query, array $bindings = []) From e2dea9575b3eac886eb9f1d31119c7462bda5468 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Thu, 20 Feb 2025 03:08:13 +0800 Subject: [PATCH 04/27] [13.x] Prepare branch alias for Laravel 13 (#54701) Signed-off-by: Mior Muhammad Zaki --- composer.json | 2 +- src/Illuminate/Auth/composer.json | 20 ++++++++++---------- src/Illuminate/Broadcasting/composer.json | 14 +++++++------- src/Illuminate/Bus/composer.json | 12 ++++++------ src/Illuminate/Cache/composer.json | 16 ++++++++-------- src/Illuminate/Collections/composer.json | 8 ++++---- src/Illuminate/Concurrency/composer.json | 10 +++++----- src/Illuminate/Conditionable/composer.json | 4 ++-- src/Illuminate/Config/composer.json | 6 +++--- src/Illuminate/Console/composer.json | 20 ++++++++++---------- src/Illuminate/Container/composer.json | 4 ++-- src/Illuminate/Contracts/composer.json | 2 +- src/Illuminate/Cookie/composer.json | 10 +++++----- src/Illuminate/Database/composer.json | 20 ++++++++++---------- src/Illuminate/Encryption/composer.json | 6 +++--- src/Illuminate/Events/composer.json | 14 +++++++------- src/Illuminate/Filesystem/composer.json | 12 ++++++------ src/Illuminate/Foundation/Application.php | 2 +- src/Illuminate/Hashing/composer.json | 6 +++--- src/Illuminate/Http/composer.json | 10 +++++----- src/Illuminate/Log/composer.json | 6 +++--- src/Illuminate/Macroable/composer.json | 2 +- src/Illuminate/Mail/composer.json | 12 ++++++------ src/Illuminate/Notifications/composer.json | 22 +++++++++++----------- src/Illuminate/Pagination/composer.json | 8 ++++---- src/Illuminate/Pipeline/composer.json | 6 +++--- src/Illuminate/Process/composer.json | 10 +++++----- src/Illuminate/Queue/composer.json | 20 ++++++++++---------- src/Illuminate/Redis/composer.json | 10 +++++----- src/Illuminate/Routing/composer.json | 20 ++++++++++---------- src/Illuminate/Session/composer.json | 12 ++++++------ src/Illuminate/Support/composer.json | 12 ++++++------ src/Illuminate/Testing/composer.json | 16 ++++++++-------- src/Illuminate/Translation/composer.json | 12 ++++++------ src/Illuminate/Validation/composer.json | 16 ++++++++-------- src/Illuminate/View/composer.json | 16 ++++++++-------- 36 files changed, 199 insertions(+), 199 deletions(-) diff --git a/composer.json b/composer.json index af09d946e602..b2940ef887b1 100644 --- a/composer.json +++ b/composer.json @@ -161,7 +161,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { diff --git a/src/Illuminate/Auth/composer.json b/src/Illuminate/Auth/composer.json index 7073f8b060cc..3147a19878e6 100644 --- a/src/Illuminate/Auth/composer.json +++ b/src/Illuminate/Auth/composer.json @@ -16,12 +16,12 @@ "require": { "php": "^8.2", "ext-hash": "*", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/http": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/queue": "^12.0", - "illuminate/support": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/http": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/queue": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -30,13 +30,13 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { - "illuminate/console": "Required to use the auth:clear-resets command (^12.0).", - "illuminate/queue": "Required to fire login / logout events (^12.0).", - "illuminate/session": "Required to use the session based guard (^12.0)." + "illuminate/console": "Required to use the auth:clear-resets command (^13.0).", + "illuminate/queue": "Required to fire login / logout events (^13.0).", + "illuminate/session": "Required to use the session based guard (^13.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Broadcasting/composer.json b/src/Illuminate/Broadcasting/composer.json index 103b02ac2733..dc93d07dbcee 100644 --- a/src/Illuminate/Broadcasting/composer.json +++ b/src/Illuminate/Broadcasting/composer.json @@ -16,12 +16,12 @@ "require": { "php": "^8.2", "psr/log": "^1.0|^2.0|^3.0", - "illuminate/bus": "^12.0", - "illuminate/collections": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/queue": "^12.0", - "illuminate/support": "^12.0" + "illuminate/bus": "^13.0", + "illuminate/collections": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/queue": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -30,7 +30,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { diff --git a/src/Illuminate/Bus/composer.json b/src/Illuminate/Bus/composer.json index 4f255d33abfa..aff8e8f6a9ac 100644 --- a/src/Illuminate/Bus/composer.json +++ b/src/Illuminate/Bus/composer.json @@ -15,10 +15,10 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/pipeline": "^12.0", - "illuminate/support": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/pipeline": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -27,11 +27,11 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { - "illuminate/queue": "Required to use closures when chaining jobs (^7.0)." + "illuminate/queue": "Required to use closures when chaining jobs (^13.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Cache/composer.json b/src/Illuminate/Cache/composer.json index b1a44ef6d451..9f8febd74667 100755 --- a/src/Illuminate/Cache/composer.json +++ b/src/Illuminate/Cache/composer.json @@ -15,10 +15,10 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0" }, "provide": { "psr/simple-cache-implementation": "1.0|2.0|3.0" @@ -30,16 +30,16 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { "ext-apcu": "Required to use the APC cache driver.", "ext-filter": "Required to use the DynamoDb cache driver.", "ext-memcached": "Required to use the memcache cache driver.", - "illuminate/database": "Required to use the database cache driver (^12.0).", - "illuminate/filesystem": "Required to use the file cache driver (^12.0).", - "illuminate/redis": "Required to use the redis cache driver (^12.0).", + "illuminate/database": "Required to use the database cache driver (^13.0).", + "illuminate/filesystem": "Required to use the file cache driver (^13.0).", + "illuminate/redis": "Required to use the redis cache driver (^13.0).", "symfony/cache": "Required to use PSR-6 cache bridge (^7.2)." }, "config": { diff --git a/src/Illuminate/Collections/composer.json b/src/Illuminate/Collections/composer.json index ab98b8ee456a..b5ac24aeb240 100644 --- a/src/Illuminate/Collections/composer.json +++ b/src/Illuminate/Collections/composer.json @@ -15,9 +15,9 @@ ], "require": { "php": "^8.2", - "illuminate/conditionable": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0" + "illuminate/conditionable": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0" }, "autoload": { "psr-4": { @@ -30,7 +30,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { diff --git a/src/Illuminate/Concurrency/composer.json b/src/Illuminate/Concurrency/composer.json index 8d542d699155..d9718543c92f 100644 --- a/src/Illuminate/Concurrency/composer.json +++ b/src/Illuminate/Concurrency/composer.json @@ -15,10 +15,10 @@ ], "require": { "php": "^8.2", - "illuminate/console": "^11.0", - "illuminate/contracts": "^11.0", - "illuminate/process": "^11.0", - "illuminate/support": "^11.0", + "illuminate/console": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/process": "^13.0", + "illuminate/support": "^13.0", "laravel/serializable-closure": "^1.3|^2.0" }, "autoload": { @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "11.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Conditionable/composer.json b/src/Illuminate/Conditionable/composer.json index 919f09ef4611..be75be9adf18 100644 --- a/src/Illuminate/Conditionable/composer.json +++ b/src/Illuminate/Conditionable/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.0.2" + "php": "^8.2" }, "autoload": { "psr-4": { @@ -23,7 +23,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Config/composer.json b/src/Illuminate/Config/composer.json index 48db6c1db52a..c60554a66f39 100755 --- a/src/Illuminate/Config/composer.json +++ b/src/Illuminate/Config/composer.json @@ -15,8 +15,8 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Console/composer.json b/src/Illuminate/Console/composer.json index 82fe11336e8a..051e359cb2a8 100755 --- a/src/Illuminate/Console/composer.json +++ b/src/Illuminate/Console/composer.json @@ -16,11 +16,11 @@ "require": { "php": "^8.2", "ext-mbstring": "*", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0", - "illuminate/view": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0", + "illuminate/view": "^13.0", "laravel/prompts": "^0.3.0", "nunomaduro/termwind": "^2.0", "symfony/console": "^7.2.0", @@ -34,17 +34,17 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { "ext-pcntl": "Required to use signal trapping.", "dragonmantank/cron-expression": "Required to use scheduler (^3.3.2).", "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^7.8).", - "illuminate/bus": "Required to use the scheduled job dispatcher (^12.0).", - "illuminate/container": "Required to use the scheduler (^12.0).", - "illuminate/filesystem": "Required to use the generator command (^12.0).", - "illuminate/queue": "Required to use closures for scheduled jobs (^12.0)." + "illuminate/bus": "Required to use the scheduled job dispatcher (^13.0).", + "illuminate/container": "Required to use the scheduler (^13.0).", + "illuminate/filesystem": "Required to use the generator command (^13.0).", + "illuminate/queue": "Required to use closures for scheduled jobs (^13.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Container/composer.json b/src/Illuminate/Container/composer.json index 16d737f2a216..d5b9715a2fe0 100755 --- a/src/Illuminate/Container/composer.json +++ b/src/Illuminate/Container/composer.json @@ -15,7 +15,7 @@ ], "require": { "php": "^8.2", - "illuminate/contracts": "^12.0", + "illuminate/contracts": "^13.0", "psr/container": "^1.1.1|^2.0.1" }, "provide": { @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Contracts/composer.json b/src/Illuminate/Contracts/composer.json index 01e8f8495602..4406f866ec8f 100644 --- a/src/Illuminate/Contracts/composer.json +++ b/src/Illuminate/Contracts/composer.json @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Cookie/composer.json b/src/Illuminate/Cookie/composer.json index 7184c3d2e351..ed828af1ba9e 100755 --- a/src/Illuminate/Cookie/composer.json +++ b/src/Illuminate/Cookie/composer.json @@ -16,10 +16,10 @@ "require": { "php": "^8.2", "ext-hash": "*", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0", "symfony/http-foundation": "^7.2.0", "symfony/http-kernel": "^7.2.0" }, @@ -30,7 +30,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Database/composer.json b/src/Illuminate/Database/composer.json index 65829cdf56f3..7426dbc7fe35 100644 --- a/src/Illuminate/Database/composer.json +++ b/src/Illuminate/Database/composer.json @@ -18,11 +18,11 @@ "php": "^8.2", "ext-pdo": "*", "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", - "illuminate/collections": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0", "laravel/serializable-closure": "^1.3|^2.0" }, "autoload": { @@ -32,16 +32,16 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { "ext-filter": "Required to use the Postgres database driver.", "fakerphp/faker": "Required to use the eloquent factory builder (^1.24).", - "illuminate/console": "Required to use the database commands (^12.0).", - "illuminate/events": "Required to use the observers with Eloquent (^12.0).", - "illuminate/filesystem": "Required to use the migrations (^12.0).", - "illuminate/pagination": "Required to paginate the result set (^12.0).", + "illuminate/console": "Required to use the database commands (^13.0).", + "illuminate/events": "Required to use the observers with Eloquent (^13.0).", + "illuminate/filesystem": "Required to use the migrations (^13.0).", + "illuminate/pagination": "Required to paginate the result set (^13.0).", "symfony/finder": "Required to use Eloquent model factories (^7.2)." }, "config": { diff --git a/src/Illuminate/Encryption/composer.json b/src/Illuminate/Encryption/composer.json index 1c430e9c3e34..a9c760401e6b 100644 --- a/src/Illuminate/Encryption/composer.json +++ b/src/Illuminate/Encryption/composer.json @@ -18,8 +18,8 @@ "ext-hash": "*", "ext-mbstring": "*", "ext-openssl": "*", - "illuminate/contracts": "^12.0", - "illuminate/support": "^12.0" + "illuminate/contracts": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Events/composer.json b/src/Illuminate/Events/composer.json index 801895fd899f..399dc24f9d44 100755 --- a/src/Illuminate/Events/composer.json +++ b/src/Illuminate/Events/composer.json @@ -15,12 +15,12 @@ ], "require": { "php": "^8.2", - "illuminate/bus": "^12.0", - "illuminate/collections": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0" + "illuminate/bus": "^13.0", + "illuminate/collections": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -32,7 +32,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Filesystem/composer.json b/src/Illuminate/Filesystem/composer.json index 8e4352665cb4..09ab165da301 100644 --- a/src/Illuminate/Filesystem/composer.json +++ b/src/Illuminate/Filesystem/composer.json @@ -15,10 +15,10 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0", "symfony/finder": "^7.2.0" }, "autoload": { @@ -31,14 +31,14 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { "ext-fileinfo": "Required to use the Filesystem class.", "ext-ftp": "Required to use the Flysystem FTP driver.", "ext-hash": "Required to use the Filesystem class.", - "illuminate/http": "Required for handling uploaded files (^7.2).", + "illuminate/http": "Required for handling uploaded files (^13.0).", "league/flysystem": "Required to use the Flysystem local driver (^3.25.1).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index 8595ec4cfbbe..78d8c7ed9570 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -45,7 +45,7 @@ class Application extends Container implements ApplicationContract, CachesConfig * * @var string */ - const VERSION = '12.x-dev'; + const VERSION = '13.x-dev'; /** * The base path for the Laravel installation. diff --git a/src/Illuminate/Hashing/composer.json b/src/Illuminate/Hashing/composer.json index 623485f95dfc..4885435581b5 100755 --- a/src/Illuminate/Hashing/composer.json +++ b/src/Illuminate/Hashing/composer.json @@ -15,8 +15,8 @@ ], "require": { "php": "^8.2", - "illuminate/contracts": "^12.0", - "illuminate/support": "^12.0" + "illuminate/contracts": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Http/composer.json b/src/Illuminate/Http/composer.json index 0ab2371d7c50..47ddb384b9e0 100755 --- a/src/Illuminate/Http/composer.json +++ b/src/Illuminate/Http/composer.json @@ -19,10 +19,10 @@ "fruitcake/php-cors": "^1.3", "guzzlehttp/guzzle": "^7.8.2", "guzzlehttp/uri-template": "^1.0", - "illuminate/collections": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/session": "^12.0", - "illuminate/support": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/session": "^13.0", + "illuminate/support": "^13.0", "symfony/http-foundation": "^7.2.0", "symfony/http-kernel": "^7.2.0", "symfony/polyfill-php83": "^1.31", @@ -38,7 +38,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Log/composer.json b/src/Illuminate/Log/composer.json index 201883d80002..329ca9fb0c0c 100755 --- a/src/Illuminate/Log/composer.json +++ b/src/Illuminate/Log/composer.json @@ -15,8 +15,8 @@ ], "require": { "php": "^8.2", - "illuminate/contracts": "^12.0", - "illuminate/support": "^12.0", + "illuminate/contracts": "^13.0", + "illuminate/support": "^13.0", "monolog/monolog": "^3.0", "psr/log": "^1.0|^2.0|^3.0" }, @@ -30,7 +30,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Macroable/composer.json b/src/Illuminate/Macroable/composer.json index 38dc6f161a42..6c2d4901c89a 100644 --- a/src/Illuminate/Macroable/composer.json +++ b/src/Illuminate/Macroable/composer.json @@ -23,7 +23,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index cf28958fdcad..bd25c35e43f2 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -15,11 +15,11 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0", "league/commonmark": "^2.6", "psr/log": "^1.0|^2.0|^3.0", "symfony/mailer": "^7.2.0", @@ -32,7 +32,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { diff --git a/src/Illuminate/Notifications/composer.json b/src/Illuminate/Notifications/composer.json index 4041897464c5..cb25e57a9891 100644 --- a/src/Illuminate/Notifications/composer.json +++ b/src/Illuminate/Notifications/composer.json @@ -15,15 +15,15 @@ ], "require": { "php": "^8.2", - "illuminate/broadcasting": "^12.0", - "illuminate/bus": "^12.0", - "illuminate/collections": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/filesystem": "^12.0", - "illuminate/mail": "^12.0", - "illuminate/queue": "^12.0", - "illuminate/support": "^12.0" + "illuminate/broadcasting": "^13.0", + "illuminate/bus": "^13.0", + "illuminate/collections": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/filesystem": "^13.0", + "illuminate/mail": "^13.0", + "illuminate/queue": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -32,11 +32,11 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { - "illuminate/database": "Required to use the database transport (^12.0)." + "illuminate/database": "Required to use the database transport (^13.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Pagination/composer.json b/src/Illuminate/Pagination/composer.json index b848b4a3b08d..4a0b8df405dd 100755 --- a/src/Illuminate/Pagination/composer.json +++ b/src/Illuminate/Pagination/composer.json @@ -16,9 +16,9 @@ "require": { "php": "^8.2", "ext-filter": "*", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/support": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -27,7 +27,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Pipeline/composer.json b/src/Illuminate/Pipeline/composer.json index fbc26da597d0..f6b8e9bca4c0 100644 --- a/src/Illuminate/Pipeline/composer.json +++ b/src/Illuminate/Pipeline/composer.json @@ -15,8 +15,8 @@ ], "require": { "php": "^8.2", - "illuminate/contracts": "^12.0", - "illuminate/support": "^12.0" + "illuminate/contracts": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Process/composer.json b/src/Illuminate/Process/composer.json index 0f2a57773644..b3ee9cb8e916 100644 --- a/src/Illuminate/Process/composer.json +++ b/src/Illuminate/Process/composer.json @@ -15,10 +15,10 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^11.0", - "illuminate/contracts": "^11.0", - "illuminate/macroable": "^11.0", - "illuminate/support": "^11.0", + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0", "symfony/process": "^7.2.0" }, "autoload": { @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Queue/composer.json b/src/Illuminate/Queue/composer.json index ee32be673acb..bbfa42961f46 100644 --- a/src/Illuminate/Queue/composer.json +++ b/src/Illuminate/Queue/composer.json @@ -15,14 +15,14 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^12.0", - "illuminate/console": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/database": "^12.0", - "illuminate/filesystem": "^12.0", - "illuminate/pipeline": "^12.0", - "illuminate/support": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/console": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/database": "^13.0", + "illuminate/filesystem": "^13.0", + "illuminate/pipeline": "^13.0", + "illuminate/support": "^13.0", "laravel/serializable-closure": "^1.3|^2.0", "ramsey/uuid": "^4.7", "symfony/process": "^7.2.0" @@ -34,7 +34,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { @@ -44,7 +44,7 @@ "ext-pcntl": "Required to use all features of the queue worker.", "ext-posix": "Required to use all features of the queue worker.", "aws/aws-sdk-php": "Required to use the SQS queue driver and DynamoDb failed job storage (^3.322.9).", - "illuminate/redis": "Required to use the Redis queue driver (^12.0).", + "illuminate/redis": "Required to use the Redis queue driver (^13.0).", "pda/pheanstalk": "Required to use the Beanstalk queue driver (^5.0)." }, "config": { diff --git a/src/Illuminate/Redis/composer.json b/src/Illuminate/Redis/composer.json index 3addbb07ff68..a516164bcf45 100755 --- a/src/Illuminate/Redis/composer.json +++ b/src/Illuminate/Redis/composer.json @@ -15,10 +15,10 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -31,7 +31,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Routing/composer.json b/src/Illuminate/Routing/composer.json index 1f7e2281463f..24d878a926d7 100644 --- a/src/Illuminate/Routing/composer.json +++ b/src/Illuminate/Routing/composer.json @@ -17,14 +17,14 @@ "php": "^8.2", "ext-filter": "*", "ext-hash": "*", - "illuminate/collections": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/http": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/pipeline": "^12.0", - "illuminate/session": "^12.0", - "illuminate/support": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/http": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/pipeline": "^13.0", + "illuminate/session": "^13.0", + "illuminate/support": "^13.0", "symfony/http-foundation": "^7.2.0", "symfony/http-kernel": "^7.2.0", "symfony/routing": "^7.2.0" @@ -36,11 +36,11 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { - "illuminate/console": "Required to use the make commands (^12.0).", + "illuminate/console": "Required to use the make commands (^13.0).", "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.2)." }, diff --git a/src/Illuminate/Session/composer.json b/src/Illuminate/Session/composer.json index c19e6cbe5081..1c20572600cc 100755 --- a/src/Illuminate/Session/composer.json +++ b/src/Illuminate/Session/composer.json @@ -17,10 +17,10 @@ "php": "^8.2", "ext-ctype": "*", "ext-session": "*", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/filesystem": "^12.0", - "illuminate/support": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/filesystem": "^13.0", + "illuminate/support": "^13.0", "symfony/finder": "^7.2.0", "symfony/http-foundation": "^7.2.0" }, @@ -31,11 +31,11 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { - "illuminate/console": "Required to use the session:table command (^12.0)." + "illuminate/console": "Required to use the session:table command (^13.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Support/composer.json b/src/Illuminate/Support/composer.json index 4b53abef7e57..0a2e77fb45a9 100644 --- a/src/Illuminate/Support/composer.json +++ b/src/Illuminate/Support/composer.json @@ -19,10 +19,10 @@ "ext-filter": "*", "ext-mbstring": "*", "doctrine/inflector": "^2.0", - "illuminate/collections": "^12.0", - "illuminate/conditionable": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/conditionable": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", "nesbot/carbon": "^3.8.4", "voku/portable-ascii": "^2.0.2" }, @@ -43,11 +43,11 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { - "illuminate/filesystem": "Required to use the Composer class (^12.0).", + "illuminate/filesystem": "Required to use the Composer class (^13.0).", "laravel/serializable-closure": "Required to use the once function (^1.3|^2.0).", "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.6).", "league/uri": "Required to use the Uri class (^7.5.1).", diff --git a/src/Illuminate/Testing/composer.json b/src/Illuminate/Testing/composer.json index 0f4286aba64c..5d76b2493858 100644 --- a/src/Illuminate/Testing/composer.json +++ b/src/Illuminate/Testing/composer.json @@ -16,10 +16,10 @@ "require": { "php": "^8.2", "ext-mbstring": "*", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -28,14 +28,14 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", - "illuminate/console": "Required to assert console commands (^12.0).", - "illuminate/database": "Required to assert databases (^12.0).", - "illuminate/http": "Required to assert responses (^12.0).", + "illuminate/console": "Required to assert console commands (^13.0).", + "illuminate/database": "Required to assert databases (^13.0).", + "illuminate/http": "Required to assert responses (^13.0).", "mockery/mockery": "Required to use mocking (^1.6).", "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.5.3|^12.0.1)." }, diff --git a/src/Illuminate/Translation/composer.json b/src/Illuminate/Translation/composer.json index 1b0dfa7a5d4b..8db8134d7a0f 100755 --- a/src/Illuminate/Translation/composer.json +++ b/src/Illuminate/Translation/composer.json @@ -15,11 +15,11 @@ ], "require": { "php": "^8.2", - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/filesystem": "^12.0", - "illuminate/support": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/filesystem": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { diff --git a/src/Illuminate/Validation/composer.json b/src/Illuminate/Validation/composer.json index 93a4c2e071dc..8533f0ae58a1 100755 --- a/src/Illuminate/Validation/composer.json +++ b/src/Illuminate/Validation/composer.json @@ -19,12 +19,12 @@ "ext-mbstring": "*", "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", "egulias/email-validator": "^3.2.5|^4.0", - "illuminate/collections": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0", - "illuminate/translation": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0", + "illuminate/translation": "^13.0", "symfony/http-foundation": "^7.2", "symfony/mime": "^7.2" }, @@ -35,11 +35,11 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "suggest": { - "illuminate/database": "Required to use the database presence verifier (^12.0).", + "illuminate/database": "Required to use the database presence verifier (^13.0).", "ramsey/uuid": "Required to use Validator::validateUuid() (^4.7)." }, "config": { diff --git a/src/Illuminate/View/composer.json b/src/Illuminate/View/composer.json index fd32f9538711..d7a7a4548f82 100644 --- a/src/Illuminate/View/composer.json +++ b/src/Illuminate/View/composer.json @@ -16,13 +16,13 @@ "require": { "php": "^8.2", "ext-tokenizer": "*", - "illuminate/collections": "^12.0", - "illuminate/container": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/events": "^12.0", - "illuminate/filesystem": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/support": "^12.0" + "illuminate/collections": "^13.0", + "illuminate/container": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/events": "^13.0", + "illuminate/filesystem": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/support": "^13.0" }, "autoload": { "psr-4": { @@ -31,7 +31,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "config": { From fba73b5e9efe7fda2feee6124571a241248cb287 Mon Sep 17 00:00:00 2001 From: Bert Date: Fri, 21 Feb 2025 14:10:46 +0100 Subject: [PATCH 05/27] [12.x] Query builder PDO fetch modes + columns fix (#54734) * fetchargs * add fetchArgs() function * fetchargs * add fetchArgs() function * add afterquery callbacks * fix typo * flip afterquerycallback * fix expectations * add expectations * add expectations * add expectations * add raw expression test * rename to fetchUsing * style * Remove test from PR #54396 * Revert most Query\Builder changes * remove DB::raw test * Revert QueryBuilder pluck tests * Add base tests for $query->fetchUsing() * style * formatting * Update Builder.php * Fix filled columns before calling pluck * query db compatibility --------- Co-authored-by: Taylor Otwell --- src/Illuminate/Database/Connection.php | 19 +++-- .../Database/ConnectionInterface.php | 6 +- src/Illuminate/Database/Query/Builder.php | 75 +++++++++--------- ...EloquentBelongsToManyCreateOrFirstTest.php | 10 ++- ...tabaseEloquentBuilderCreateOrFirstTest.php | 28 +++---- ...tabaseEloquentHasManyCreateOrFirstTest.php | 18 ++--- ...loquentHasManyThroughCreateOrFirstTest.php | 9 +++ tests/Database/DatabaseQueryBuilderTest.php | 76 +++++++++---------- .../Integration/Database/QueryBuilderTest.php | 57 ++++++++++++++ 9 files changed, 188 insertions(+), 110 deletions(-) diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php index 69780f78a2b4..5d5be92e936f 100755 --- a/src/Illuminate/Database/Connection.php +++ b/src/Illuminate/Database/Connection.php @@ -389,11 +389,12 @@ public function selectFromWriteConnection($query, $bindings = []) * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return array */ - public function select($query, $bindings = [], $useReadPdo = true) + public function select($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) { - return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { + return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo, $fetchUsing) { if ($this->pretending()) { return []; } @@ -409,7 +410,7 @@ public function select($query, $bindings = [], $useReadPdo = true) $statement->execute(); - return $statement->fetchAll(); + return $statement->fetchAll(...$fetchUsing); }); } @@ -419,11 +420,12 @@ public function select($query, $bindings = [], $useReadPdo = true) * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return array */ - public function selectResultSets($query, $bindings = [], $useReadPdo = true) + public function selectResultSets($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) { - return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { + return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo, $fetchUsing) { if ($this->pretending()) { return []; } @@ -439,7 +441,7 @@ public function selectResultSets($query, $bindings = [], $useReadPdo = true) $sets = []; do { - $sets[] = $statement->fetchAll(); + $sets[] = $statement->fetchAll(...$fetchUsing); } while ($statement->nextRowset()); return $sets; @@ -452,9 +454,10 @@ public function selectResultSets($query, $bindings = [], $useReadPdo = true) * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return \Generator */ - public function cursor($query, $bindings = [], $useReadPdo = true) + public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) { $statement = $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { if ($this->pretending()) { @@ -479,7 +482,7 @@ public function cursor($query, $bindings = [], $useReadPdo = true) return $statement; }); - while ($record = $statement->fetch()) { + while ($record = $statement->fetch(...$fetchUsing)) { yield $record; } } diff --git a/src/Illuminate/Database/ConnectionInterface.php b/src/Illuminate/Database/ConnectionInterface.php index 288adb4206e3..22f866b43763 100755 --- a/src/Illuminate/Database/ConnectionInterface.php +++ b/src/Illuminate/Database/ConnectionInterface.php @@ -51,9 +51,10 @@ public function scalar($query, $bindings = [], $useReadPdo = true); * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return array */ - public function select($query, $bindings = [], $useReadPdo = true); + public function select($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []); /** * Run a select statement against the database and returns a generator. @@ -61,9 +62,10 @@ public function select($query, $bindings = [], $useReadPdo = true); * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return \Generator */ - public function cursor($query, $bindings = [], $useReadPdo = true); + public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []); /** * Run an insert statement against the database. diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index c5db6b31060e..dd7076c12dce 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -249,6 +249,13 @@ class Builder implements BuilderContract */ public $useWritePdo = false; + /** + * The custom arguments for the PDOStatement::fetchAll / fetch functions. + * + * @var array + */ + public array $fetchUsing = []; + /** * Create a new query builder instance. * @@ -3087,9 +3094,13 @@ public function soleValue($column) */ public function get($columns = ['*']) { - $items = new Collection($this->onceWithColumns(Arr::wrap($columns), function () { - return $this->processor->processSelect($this, $this->runSelect()); - })); + $original = $this->columns; + + $this->columns ??= Arr::wrap($columns); + + $items = new Collection($this->processor->processSelect($this, $this->runSelect())); + + $this->columns = $original; return $this->applyAfterQueryCallbacks( isset($this->groupLimit) ? $this->withoutGroupLimitKeys($items) : $items @@ -3104,7 +3115,7 @@ public function get($columns = ['*']) protected function runSelect() { return $this->connection->select( - $this->toSql(), $this->getBindings(), ! $this->useWritePdo + $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing ); } @@ -3322,7 +3333,7 @@ public function cursor() return (new LazyCollection(function () { yield from $this->connection->cursor( - $this->toSql(), $this->getBindings(), ! $this->useWritePdo + $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing ); }))->map(function ($item) { return $this->applyAfterQueryCallbacks(new Collection([$item]))->first(); @@ -3352,17 +3363,18 @@ protected function enforceOrderBy() */ public function pluck($column, $key = null) { + $original = $this->columns; + // First, we will need to select the results of the query accounting for the // given columns / key. Once we have the results, we will be able to take // the results and get the exact data that was requested for the query. - $queryResult = $this->onceWithColumns( - is_null($key) || $key === $column ? [$column] : [$column, $key], - function () { - return $this->processor->processSelect( - $this, $this->runSelect() - ); - } - ); + $this->columns ??= is_null($key) || $key === $column + ? [$column] + : [$column, $key]; + + $queryResult = $this->processor->processSelect($this, $this->runSelect()); + + $this->columns = $original; if (empty($queryResult)) { return new Collection; @@ -3656,30 +3668,6 @@ protected function setAggregate($function, $columns) return $this; } - /** - * Execute the given callback while selecting the given columns. - * - * After running the callback, the columns are reset to the original value. - * - * @param array $columns - * @param callable $callback - * @return mixed - */ - protected function onceWithColumns($columns, $callback) - { - $original = $this->columns; - - if (is_null($original)) { - $this->columns = $columns; - } - - $result = $callback(); - - $this->columns = $original; - - return $result; - } - /** * Insert new records into the database. * @@ -4293,6 +4281,19 @@ public function useWritePdo() return $this; } + /** + * Specify arguments for the PDOStatement::fetchAll / fetch functions. + * + * @param mixed ...$fetchUsing + * @return $this + */ + public function fetchUsing(...$fetchUsing) + { + $this->fetchUsing = $fetchUsing; + + return $this; + } + /** * Determine if the value is a query builder instance or a Closure. * diff --git a/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php b/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php index 8fb7dab36607..886bc47ef6c4 100644 --- a/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php @@ -84,7 +84,7 @@ public function testCreateOrFirstMethodAssociatesExistingRelated(): void $source->getConnection() ->expects('select') - ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 456, 'attr' => 'foo', @@ -128,6 +128,7 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAlreadyAssociated 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([[ 'id' => 456, @@ -176,7 +177,7 @@ public function testCreateOrFirstMethodRetrievesExistingRelatedAssociatedJustNow $source->getConnection() ->expects('select') - ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 456, 'attr' => 'foo', @@ -199,6 +200,7 @@ public function testCreateOrFirstMethodRetrievesExistingRelatedAssociatedJustNow 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], false, + [], ) ->andReturn([[ 'id' => 456, @@ -243,6 +245,7 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAndAssociatesIt() 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -252,6 +255,7 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAndAssociatesIt() 'select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, + [], ) ->andReturn([[ 'id' => 456, @@ -326,6 +330,7 @@ protected function newBelongsToMany(Builder $query, Model $parent, $table, $fore 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -335,6 +340,7 @@ protected function newBelongsToMany(Builder $query, Model $parent, $table, $fore 'select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, + [], ) ->andReturn([]); diff --git a/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php b/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php index 63cffe311f53..dcf9d912fe79 100755 --- a/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php @@ -66,7 +66,7 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -95,7 +95,7 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -124,7 +124,7 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -152,7 +152,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $sql = 'insert into "table" ("attr", "val", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -165,7 +165,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -194,7 +194,7 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -231,7 +231,7 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -259,7 +259,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $sql = 'insert into "table" ("attr", "val", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -272,7 +272,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -309,7 +309,7 @@ public function testIncrementOrCreateMethodIncrementsExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -351,7 +351,7 @@ public function testIncrementOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -379,7 +379,7 @@ public function testIncrementOrCreateMethodIncrementParametersArePassed(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -423,7 +423,7 @@ public function testIncrementOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $sql = 'insert into "table" ("attr", "count", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -436,7 +436,7 @@ public function testIncrementOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', diff --git a/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php b/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php index 5a3b9e5c1c06..38802b80f335 100755 --- a/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php @@ -70,7 +70,7 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -102,7 +102,7 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -132,7 +132,7 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -164,7 +164,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([]); $sql = 'insert into "child_table" ("attr", "val", "parent_id", "updated_at", "created_at") values (?, ?, ?, ?, ?)'; @@ -177,7 +177,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -209,7 +209,7 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -239,7 +239,7 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -276,7 +276,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([]); $sql = 'insert into "child_table" ("attr", "val", "parent_id", "updated_at", "created_at") values (?, ?, ?, ?, ?)'; @@ -289,7 +289,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, diff --git a/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php b/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php index b499100ef406..62acbbfe9e87 100644 --- a/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php @@ -75,6 +75,7 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([[ 'id' => 789, @@ -114,6 +115,7 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -148,6 +150,7 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([[ 'id' => 789, @@ -187,6 +190,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -204,6 +208,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ? and "val" = ?) limit 1', [123, 'foo', 'bar'], true, + [], ) ->andReturn([[ 'id' => 789, @@ -243,6 +248,7 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -280,6 +286,7 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([[ 'id' => 789, @@ -327,6 +334,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -344,6 +352,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ? and "val" = ?) limit 1', [123, 'foo', 'bar'], true, + [], ) ->andReturn([[ 'id' => 789, diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 1773aff32783..3671b47e90aa 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -82,12 +82,12 @@ public function testBasicSelectUseWritePdo() { $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with('select * from `users`', [], false); + ->with('select * from `users`', [], false, []); $builder->useWritePdo()->select('*')->from('users')->get(); $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with('select * from `users`', [], true); + ->with('select * from `users`', [], true, []); $builder->select('*')->from('users')->get(); } @@ -1747,31 +1747,31 @@ public function testUnionAggregate() { $expected = 'select count(*) as aggregate from ((select * from `posts`) union (select * from `videos`)) as `temp_table`'; $builder = $this->getMySqlBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getMySqlBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from ((select `id` from `posts`) union (select `id` from `videos`)) as `temp_table`'; $builder = $this->getMySqlBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->select('id')->union($this->getMySqlBuilder()->from('videos')->select('id'))->count(); $expected = 'select count(*) as aggregate from ((select * from "posts") union (select * from "videos")) as "temp_table"'; $builder = $this->getPostgresBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getPostgresBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from (select * from (select * from "posts") union select * from (select * from "videos")) as "temp_table"'; $builder = $this->getSQLiteBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getSQLiteBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from (select * from (select * from [posts]) as [temp_table] union select * from (select * from [videos]) as [temp_table]) as [temp_table]'; $builder = $this->getSqlServerBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getSqlServerBuilder()->from('videos'))->count(); } @@ -1781,7 +1781,7 @@ public function testHavingAggregate() $expected = 'select count(*) as aggregate from (select (select `count(*)` from `videos` where `posts`.`id` = `videos`.`post_id`) as `videos_count` from `posts` having `videos_count` > ?) as `temp_table`'; $builder = $this->getMySqlBuilder(); $builder->getConnection()->shouldReceive('getDatabaseName'); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2263,7 +2263,7 @@ public function testHavingFollowedBySelectGet() { $builder = $this->getBuilder(); $query = 'select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > ?'; - $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular', 3], true)->andReturn([['category' => 'rock', 'total' => 5]]); + $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular', 3], true, [])->andReturn([['category' => 'rock', 'total' => 5]]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2274,7 +2274,7 @@ public function testHavingFollowedBySelectGet() // Using \Raw value $builder = $this->getBuilder(); $query = 'select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > 3'; - $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular'], true)->andReturn([['category' => 'rock', 'total' => 5]]); + $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular'], true, [])->andReturn([['category' => 'rock', 'total' => 5]]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2367,7 +2367,7 @@ public function testGetCountForPaginationWithBindings() $q->select('body')->from('posts')->where('id', 4); }, 'post'); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2383,7 +2383,7 @@ public function testGetCountForPaginationWithColumnAliases() $columns = ['body as post_body', 'teaser', 'posts.created as published']; $builder->from('posts')->select($columns); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("body", "teaser", "posts"."created") as aggregate from "posts"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("body", "teaser", "posts"."created") as aggregate from "posts"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2397,7 +2397,7 @@ public function testGetCountForPaginationWithUnion() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id')); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2411,7 +2411,7 @@ public function testGetCountForPaginationWithUnionOrders() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'))->latest(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2425,7 +2425,7 @@ public function testGetCountForPaginationWithUnionLimitAndOffset() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'))->take(15)->skip(1); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3412,7 +3412,7 @@ public function testRawExpressionsInSelect() public function testFindReturnsFirstResultByID() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3436,7 +3436,7 @@ public function testFindOrReturnsFirstResultByID() public function testFirstMethodReturnsFirstResult() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3447,7 +3447,7 @@ public function testFirstMethodReturnsFirstResult() public function testFirstOrFailMethodReturnsFirstResult() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3458,7 +3458,7 @@ public function testFirstOrFailMethodReturnsFirstResult() public function testFirstOrFailMethodThrowsRecordNotFoundException() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [])->andReturn([]); @@ -3490,7 +3490,7 @@ public function testPluckMethodGetsCollectionOfColumnValues() public function testPluckAvoidsDuplicateColumnSelection() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ?', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ?', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3522,7 +3522,7 @@ public function testImplode() public function testValueMethodReturnsSingleColumn() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturn([['foo' => 'bar']]); $results = $builder->from('users')->where('id', '=', 1)->value('foo'); $this->assertSame('bar', $results); @@ -3531,7 +3531,7 @@ public function testValueMethodReturnsSingleColumn() public function testRawValueMethodReturnsSingleColumn() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select UPPER("foo") from "users" where "id" = ? limit 1', [1], true)->andReturn([['UPPER("foo")' => 'BAR']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select UPPER("foo") from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['UPPER("foo")' => 'BAR']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['UPPER("foo")' => 'BAR']])->andReturn([['UPPER("foo")' => 'BAR']]); $results = $builder->from('users')->where('id', '=', 1)->rawValue('UPPER("foo")'); $this->assertSame('BAR', $results); @@ -3540,7 +3540,7 @@ public function testRawValueMethodReturnsSingleColumn() public function testAggregateFunctions() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3558,7 +3558,7 @@ public function testAggregateFunctions() $this->assertTrue($results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select max("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select max("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3566,7 +3566,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select min("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select min("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3574,7 +3574,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3582,7 +3582,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3590,7 +3590,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3641,9 +3641,9 @@ public function testDoesntExistsOr() public function testAggregateResetFollowedByGet() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 2]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column1", "column2" from "users"', [], true)->andReturn([['column1' => 'foo', 'column2' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 2]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column1", "column2" from "users"', [], true, [])->andReturn([['column1' => 'foo', 'column2' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3659,8 +3659,8 @@ public function testAggregateResetFollowedByGet() public function testAggregateResetFollowedBySelectGet() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true)->andReturn([['column2' => 'foo', 'column3' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true, [])->andReturn([['column2' => 'foo', 'column3' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3674,8 +3674,8 @@ public function testAggregateResetFollowedBySelectGet() public function testAggregateResetFollowedByGetWithColumns() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true)->andReturn([['column2' => 'foo', 'column3' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true, [])->andReturn([['column2' => 'foo', 'column3' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3689,7 +3689,7 @@ public function testAggregateResetFollowedByGetWithColumns() public function testAggregateWithSubSelect() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -5171,12 +5171,12 @@ public function testSelectWithLockUsesWritePdo() { $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with(m::any(), m::any(), false); + ->with(m::any(), m::any(), false, []); $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock()->get(); $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with(m::any(), m::any(), false); + ->with(m::any(), m::any(), false, []); $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false)->get(); } diff --git a/tests/Integration/Database/QueryBuilderTest.php b/tests/Integration/Database/QueryBuilderTest.php index c323ff0e1513..ac274d971060 100644 --- a/tests/Integration/Database/QueryBuilderTest.php +++ b/tests/Integration/Database/QueryBuilderTest.php @@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Testing\Assert as PHPUnit; use Orchestra\Testbench\Attributes\DefineEnvironment; +use PDO; use PDOException; class QueryBuilderTest extends DatabaseTestCase @@ -600,6 +601,12 @@ public function testChunkMap() public function testPluck() { + // Test empty result set. + $this->assertSame( + [], + DB::table('posts')->whereRaw('0=1')->pluck('title')->toArray() + ); + // Test SELECT override, since pluck will take the first column. $this->assertSame([ 'Foo Post', @@ -634,6 +641,56 @@ public function testPluck() $this->assertSame([ 'Lorem Ipsum.' => 'Bar Post', ], DB::table('posts')->pluck('title', 'content')->toArray()); + + // Test custom select query before calling pluck. + $result = DB::table('posts') + ->selectSub(DB::table('posts')->selectRaw('COUNT(*)'), 'total_posts_count') + ->pluck('total_posts_count') + ->toArray(); + // Cast for database compatibility. + $this->assertSame(2, (int) $result[0]); + $this->assertSame(2, (int) $result[1]); + } + + public function testFetchUsing() + { + // Fetch column as a list. + $this->assertSame([ + 'Foo Post', + 'Bar Post', + ], DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_COLUMN)->get()->toArray()); + + // Fetch the second column as a list (zero-indexed). + $this->assertSame([ + 'Lorem Ipsum.', + 'Lorem Ipsum.', + ], DB::table('posts')->select(['title', 'content'])->fetchUsing(PDO::FETCH_COLUMN, 1)->get()->toArray()); + + // Fetch two columns as key value pairs. + $this->assertSame([ + 1 => 'Foo Post', + 2 => 'Bar Post', + ], DB::table('posts')->select(['id', 'title'])->fetchUsing(PDO::FETCH_KEY_PAIR)->get()->toArray()); + + // Fetch data as associative array with custom key. + $result = DB::table('posts')->select(['id', 'title'])->fetchUsing(PDO::FETCH_UNIQUE)->get()->toArray(); + // Note: results are keyed by their post id here. + $this->assertSame('Foo Post', $result[1]->title); + $this->assertSame('Bar Post', $result[2]->title); + + // Use a cursor. + $this->assertSame([ + 'Foo Post', + 'Bar Post', + ], DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_COLUMN)->cursor()->collect()->toArray()); + + // Test the default 'object' fetch mode. + $result = DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_OBJ)->get()->toArray(); + $result2 = DB::table('posts')->select(['title'])->fetchUsing()->get()->toArray(); + $this->assertSame('Foo Post', $result[0]->title); + $this->assertSame('Bar Post', $result[1]->title); + $this->assertSame('Foo Post', $result2[0]->title); + $this->assertSame('Bar Post', $result2[1]->title); } protected function defineEnvironmentWouldThrowsPDOException($app) From 50f431920daea2abbab3fb3619bee99c715fdf9b Mon Sep 17 00:00:00 2001 From: taylorotwell <463230+taylorotwell@users.noreply.github.com> Date: Fri, 21 Feb 2025 13:11:35 +0000 Subject: [PATCH 06/27] Update facade docblocks --- src/Illuminate/Support/Facades/DB.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Support/Facades/DB.php b/src/Illuminate/Support/Facades/DB.php index 3ddeae76298a..233816bf5767 100644 --- a/src/Illuminate/Support/Facades/DB.php +++ b/src/Illuminate/Support/Facades/DB.php @@ -40,9 +40,9 @@ * @method static mixed selectOne(string $query, array $bindings = [], bool $useReadPdo = true) * @method static mixed scalar(string $query, array $bindings = [], bool $useReadPdo = true) * @method static array selectFromWriteConnection(string $query, array $bindings = []) - * @method static array select(string $query, array $bindings = [], bool $useReadPdo = true) - * @method static array selectResultSets(string $query, array $bindings = [], bool $useReadPdo = true) - * @method static \Generator cursor(string $query, array $bindings = [], bool $useReadPdo = true) + * @method static array select(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) + * @method static array selectResultSets(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) + * @method static \Generator cursor(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) * @method static bool insert(string $query, array $bindings = []) * @method static int update(string $query, array $bindings = []) * @method static int delete(string $query, array $bindings = []) From 09d9af245334b911c9223c7673e7511ecd6dc168 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 24 Feb 2025 18:00:06 +0800 Subject: [PATCH 07/27] [13.x] Fix Tests/CI environments (#54760) Signed-off-by: Mior Muhammad Zaki --- .github/workflows/databases-nightly.yml | 4 ++-- .github/workflows/databases.yml | 16 ++++++++-------- .github/workflows/facades.yml | 2 +- .github/workflows/queues.yml | 10 +++++----- .github/workflows/static-analysis.yml | 2 +- .github/workflows/tests.yml | 4 ++-- composer.json | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/databases-nightly.yml b/.github/workflows/databases-nightly.yml index 059c35ce1321..9003fab41ec5 100644 --- a/.github/workflows/databases-nightly.yml +++ b/.github/workflows/databases-nightly.yml @@ -36,7 +36,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -82,7 +82,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 diff --git a/.github/workflows/databases.yml b/.github/workflows/databases.yml index 15fcb4c1a463..658bb2f82c2e 100644 --- a/.github/workflows/databases.yml +++ b/.github/workflows/databases.yml @@ -40,7 +40,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -87,7 +87,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -133,7 +133,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -180,7 +180,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -229,7 +229,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -276,7 +276,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -324,7 +324,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -363,7 +363,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 diff --git a/.github/workflows/facades.yml b/.github/workflows/facades.yml index 3a3bf57c2f06..329fe1a5d83a 100644 --- a/.github/workflows/facades.yml +++ b/.github/workflows/facades.yml @@ -32,7 +32,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 diff --git a/.github/workflows/queues.yml b/.github/workflows/queues.yml index 2302892a3d38..e802001724af 100644 --- a/.github/workflows/queues.yml +++ b/.github/workflows/queues.yml @@ -29,7 +29,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -64,7 +64,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -112,7 +112,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -150,7 +150,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 @@ -200,7 +200,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 49d197648f40..559f8243268d 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -30,7 +30,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Install dependencies uses: nick-fields/retry@v3 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 47042d8a82be..3e3c4b42d90e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -65,7 +65,7 @@ jobs: REDIS_LIBS: liblz4-dev, liblzf-dev, libzstd-dev - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Set PHPUnit uses: nick-fields/retry@v3 @@ -132,7 +132,7 @@ jobs: coverage: none - name: Set Framework version - run: composer config version "12.x-dev" + run: composer config version "13.x-dev" - name: Set PHPUnit uses: nick-fields/retry@v3 diff --git a/composer.json b/composer.json index b2940ef887b1..1aed785d13c7 100644 --- a/composer.json +++ b/composer.json @@ -111,7 +111,7 @@ "league/flysystem-read-only": "^3.25.1", "league/flysystem-sftp-v3": "^3.25.1", "mockery/mockery": "^1.6.10", - "orchestra/testbench-core": "^10.0", + "orchestra/testbench-core": "^11.0", "pda/pheanstalk": "^5.0.6", "php-http/discovery": "^1.15", "phpstan/phpstan": "^2.0", From 251f55efc3018fd5300c6d6e72cdb0db4cab4cdd Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 24 Feb 2025 20:53:31 +0800 Subject: [PATCH 08/27] [13.x] Requires PHP 8.3 as minimum version (#54763) Signed-off-by: Mior Muhammad Zaki --- .github/workflows/facades.yml | 2 +- .github/workflows/queues.yml | 10 +++++----- .github/workflows/static-analysis.yml | 2 +- .github/workflows/tests.yml | 7 ++----- composer.json | 3 +-- src/Illuminate/Auth/composer.json | 2 +- src/Illuminate/Broadcasting/composer.json | 2 +- src/Illuminate/Bus/composer.json | 2 +- src/Illuminate/Cache/composer.json | 2 +- src/Illuminate/Collections/composer.json | 2 +- src/Illuminate/Concurrency/composer.json | 2 +- src/Illuminate/Config/composer.json | 2 +- src/Illuminate/Console/composer.json | 3 +-- src/Illuminate/Container/composer.json | 2 +- src/Illuminate/Contracts/composer.json | 2 +- src/Illuminate/Cookie/composer.json | 2 +- src/Illuminate/Database/composer.json | 2 +- src/Illuminate/Encryption/composer.json | 2 +- src/Illuminate/Events/composer.json | 2 +- src/Illuminate/Filesystem/composer.json | 2 +- src/Illuminate/Hashing/composer.json | 2 +- src/Illuminate/Http/composer.json | 3 +-- src/Illuminate/Log/composer.json | 2 +- src/Illuminate/Mail/composer.json | 2 +- src/Illuminate/Notifications/composer.json | 2 +- src/Illuminate/Pagination/composer.json | 2 +- src/Illuminate/Pipeline/composer.json | 2 +- src/Illuminate/Process/composer.json | 2 +- src/Illuminate/Queue/composer.json | 2 +- src/Illuminate/Redis/composer.json | 2 +- src/Illuminate/Routing/composer.json | 2 +- src/Illuminate/Session/composer.json | 2 +- src/Illuminate/Support/composer.json | 2 +- src/Illuminate/Testing/composer.json | 2 +- src/Illuminate/Translation/composer.json | 2 +- src/Illuminate/Validation/composer.json | 2 +- src/Illuminate/View/composer.json | 2 +- 37 files changed, 42 insertions(+), 48 deletions(-) diff --git a/.github/workflows/facades.yml b/.github/workflows/facades.yml index 329fe1a5d83a..7b8671755aae 100644 --- a/.github/workflows/facades.yml +++ b/.github/workflows/facades.yml @@ -26,7 +26,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 extensions: :php-psr tools: composer:v2 coverage: none diff --git a/.github/workflows/queues.yml b/.github/workflows/queues.yml index e802001724af..fa60e403fd59 100644 --- a/.github/workflows/queues.yml +++ b/.github/workflows/queues.yml @@ -23,7 +23,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr tools: composer:v2 coverage: none @@ -58,7 +58,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr tools: composer:v2 coverage: none @@ -106,7 +106,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr tools: composer:v2 coverage: none @@ -144,7 +144,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr tools: composer:v2 coverage: none @@ -194,7 +194,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr tools: composer:v2 coverage: none diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 559f8243268d..d4f24bf1fdc5 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -25,7 +25,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 tools: composer:v2 coverage: none diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3e3c4b42d90e..0d4c72479ddd 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -39,12 +39,9 @@ jobs: strategy: fail-fast: true matrix: - php: [8.2, 8.3, 8.4] + php: [8.3, 8.4] phpunit: ['10.5.35', '11.5.3', '12.0.0'] stability: [prefer-lowest, prefer-stable] - exclude: - - php: 8.2 - phpunit: '12.0.0' name: PHP ${{ matrix.php }} - PHPUnit ${{ matrix.phpunit }} - ${{ matrix.stability }} @@ -105,7 +102,7 @@ jobs: strategy: fail-fast: true matrix: - php: [8.2, 8.3, 8.4] + php: [8.3, 8.4] phpunit: ['11.5.3'] stability: [prefer-lowest, prefer-stable] exclude: diff --git a/composer.json b/composer.json index 1aed785d13c7..63f6541be5e3 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-ctype": "*", "ext-filter": "*", "ext-hash": "*", @@ -51,7 +51,6 @@ "symfony/http-kernel": "^7.2.0", "symfony/mailer": "^7.2.0", "symfony/mime": "^7.2.0", - "symfony/polyfill-php83": "^1.31", "symfony/process": "^7.2.0", "symfony/routing": "^7.2.0", "symfony/uid": "^7.2.0", diff --git a/src/Illuminate/Auth/composer.json b/src/Illuminate/Auth/composer.json index 3147a19878e6..45cbc2f973bc 100644 --- a/src/Illuminate/Auth/composer.json +++ b/src/Illuminate/Auth/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-hash": "*", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", diff --git a/src/Illuminate/Broadcasting/composer.json b/src/Illuminate/Broadcasting/composer.json index dc93d07dbcee..03d45b78ea54 100644 --- a/src/Illuminate/Broadcasting/composer.json +++ b/src/Illuminate/Broadcasting/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "psr/log": "^1.0|^2.0|^3.0", "illuminate/bus": "^13.0", "illuminate/collections": "^13.0", diff --git a/src/Illuminate/Bus/composer.json b/src/Illuminate/Bus/composer.json index aff8e8f6a9ac..57aea7551f3e 100644 --- a/src/Illuminate/Bus/composer.json +++ b/src/Illuminate/Bus/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", "illuminate/pipeline": "^13.0", diff --git a/src/Illuminate/Cache/composer.json b/src/Illuminate/Cache/composer.json index 9f8febd74667..dea22e5a6d83 100755 --- a/src/Illuminate/Cache/composer.json +++ b/src/Illuminate/Cache/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0", diff --git a/src/Illuminate/Collections/composer.json b/src/Illuminate/Collections/composer.json index b5ac24aeb240..ed3af30dd74e 100644 --- a/src/Illuminate/Collections/composer.json +++ b/src/Illuminate/Collections/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/conditionable": "^13.0", "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0" diff --git a/src/Illuminate/Concurrency/composer.json b/src/Illuminate/Concurrency/composer.json index d9718543c92f..0a5d5c39bbe4 100644 --- a/src/Illuminate/Concurrency/composer.json +++ b/src/Illuminate/Concurrency/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/console": "^13.0", "illuminate/contracts": "^13.0", "illuminate/process": "^13.0", diff --git a/src/Illuminate/Config/composer.json b/src/Illuminate/Config/composer.json index c60554a66f39..484c4c58ea47 100755 --- a/src/Illuminate/Config/composer.json +++ b/src/Illuminate/Config/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0" }, diff --git a/src/Illuminate/Console/composer.json b/src/Illuminate/Console/composer.json index 051e359cb2a8..d7ccfaa2ed0f 100755 --- a/src/Illuminate/Console/composer.json +++ b/src/Illuminate/Console/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-mbstring": "*", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", @@ -24,7 +24,6 @@ "laravel/prompts": "^0.3.0", "nunomaduro/termwind": "^2.0", "symfony/console": "^7.2.0", - "symfony/polyfill-php83": "^1.31", "symfony/process": "^7.2.0" }, "autoload": { diff --git a/src/Illuminate/Container/composer.json b/src/Illuminate/Container/composer.json index d5b9715a2fe0..85b4860bf832 100755 --- a/src/Illuminate/Container/composer.json +++ b/src/Illuminate/Container/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/contracts": "^13.0", "psr/container": "^1.1.1|^2.0.1" }, diff --git a/src/Illuminate/Contracts/composer.json b/src/Illuminate/Contracts/composer.json index 4406f866ec8f..dea7426f157e 100644 --- a/src/Illuminate/Contracts/composer.json +++ b/src/Illuminate/Contracts/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "psr/container": "^1.1.1|^2.0.1", "psr/simple-cache": "^1.0|^2.0|^3.0" }, diff --git a/src/Illuminate/Cookie/composer.json b/src/Illuminate/Cookie/composer.json index ed828af1ba9e..75ad9b0bef1c 100755 --- a/src/Illuminate/Cookie/composer.json +++ b/src/Illuminate/Cookie/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-hash": "*", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", diff --git a/src/Illuminate/Database/composer.json b/src/Illuminate/Database/composer.json index 7426dbc7fe35..b7626557a888 100644 --- a/src/Illuminate/Database/composer.json +++ b/src/Illuminate/Database/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-pdo": "*", "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", "illuminate/collections": "^13.0", diff --git a/src/Illuminate/Encryption/composer.json b/src/Illuminate/Encryption/composer.json index a9c760401e6b..1539e86ff687 100644 --- a/src/Illuminate/Encryption/composer.json +++ b/src/Illuminate/Encryption/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-hash": "*", "ext-mbstring": "*", "ext-openssl": "*", diff --git a/src/Illuminate/Events/composer.json b/src/Illuminate/Events/composer.json index 399dc24f9d44..4f3f2b4c62e5 100755 --- a/src/Illuminate/Events/composer.json +++ b/src/Illuminate/Events/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/bus": "^13.0", "illuminate/collections": "^13.0", "illuminate/container": "^13.0", diff --git a/src/Illuminate/Filesystem/composer.json b/src/Illuminate/Filesystem/composer.json index 09ab165da301..2f0edda1a1ef 100644 --- a/src/Illuminate/Filesystem/composer.json +++ b/src/Illuminate/Filesystem/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0", diff --git a/src/Illuminate/Hashing/composer.json b/src/Illuminate/Hashing/composer.json index 4885435581b5..18eec76368bd 100755 --- a/src/Illuminate/Hashing/composer.json +++ b/src/Illuminate/Hashing/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/contracts": "^13.0", "illuminate/support": "^13.0" }, diff --git a/src/Illuminate/Http/composer.json b/src/Illuminate/Http/composer.json index 47ddb384b9e0..0aaf1f34e773 100755 --- a/src/Illuminate/Http/composer.json +++ b/src/Illuminate/Http/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-filter": "*", "fruitcake/php-cors": "^1.3", "guzzlehttp/guzzle": "^7.8.2", @@ -25,7 +25,6 @@ "illuminate/support": "^13.0", "symfony/http-foundation": "^7.2.0", "symfony/http-kernel": "^7.2.0", - "symfony/polyfill-php83": "^1.31", "symfony/mime": "^7.2.0" }, "autoload": { diff --git a/src/Illuminate/Log/composer.json b/src/Illuminate/Log/composer.json index 329ca9fb0c0c..7dfa1dcd0d1d 100755 --- a/src/Illuminate/Log/composer.json +++ b/src/Illuminate/Log/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/contracts": "^13.0", "illuminate/support": "^13.0", "monolog/monolog": "^3.0", diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index bd25c35e43f2..7b4f9e6e6eee 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/container": "^13.0", "illuminate/contracts": "^13.0", diff --git a/src/Illuminate/Notifications/composer.json b/src/Illuminate/Notifications/composer.json index cb25e57a9891..eee1f69ccfa8 100644 --- a/src/Illuminate/Notifications/composer.json +++ b/src/Illuminate/Notifications/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/broadcasting": "^13.0", "illuminate/bus": "^13.0", "illuminate/collections": "^13.0", diff --git a/src/Illuminate/Pagination/composer.json b/src/Illuminate/Pagination/composer.json index 4a0b8df405dd..dcb94402aaf9 100755 --- a/src/Illuminate/Pagination/composer.json +++ b/src/Illuminate/Pagination/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-filter": "*", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", diff --git a/src/Illuminate/Pipeline/composer.json b/src/Illuminate/Pipeline/composer.json index f6b8e9bca4c0..24f627d4db14 100644 --- a/src/Illuminate/Pipeline/composer.json +++ b/src/Illuminate/Pipeline/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/contracts": "^13.0", "illuminate/support": "^13.0" }, diff --git a/src/Illuminate/Process/composer.json b/src/Illuminate/Process/composer.json index b3ee9cb8e916..55bf46f2203d 100644 --- a/src/Illuminate/Process/composer.json +++ b/src/Illuminate/Process/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0", diff --git a/src/Illuminate/Queue/composer.json b/src/Illuminate/Queue/composer.json index bbfa42961f46..b72266558f71 100644 --- a/src/Illuminate/Queue/composer.json +++ b/src/Illuminate/Queue/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/console": "^13.0", "illuminate/container": "^13.0", diff --git a/src/Illuminate/Redis/composer.json b/src/Illuminate/Redis/composer.json index a516164bcf45..b1acad53220e 100755 --- a/src/Illuminate/Redis/composer.json +++ b/src/Illuminate/Redis/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0", diff --git a/src/Illuminate/Routing/composer.json b/src/Illuminate/Routing/composer.json index 24d878a926d7..3a54fba26192 100644 --- a/src/Illuminate/Routing/composer.json +++ b/src/Illuminate/Routing/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-filter": "*", "ext-hash": "*", "illuminate/collections": "^13.0", diff --git a/src/Illuminate/Session/composer.json b/src/Illuminate/Session/composer.json index 1c20572600cc..3b0cbfed6897 100755 --- a/src/Illuminate/Session/composer.json +++ b/src/Illuminate/Session/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-ctype": "*", "ext-session": "*", "illuminate/collections": "^13.0", diff --git a/src/Illuminate/Support/composer.json b/src/Illuminate/Support/composer.json index 0a2e77fb45a9..1da003ed1965 100644 --- a/src/Illuminate/Support/composer.json +++ b/src/Illuminate/Support/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-ctype": "*", "ext-filter": "*", "ext-mbstring": "*", diff --git a/src/Illuminate/Testing/composer.json b/src/Illuminate/Testing/composer.json index 5d76b2493858..3f0fac602180 100644 --- a/src/Illuminate/Testing/composer.json +++ b/src/Illuminate/Testing/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-mbstring": "*", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", diff --git a/src/Illuminate/Translation/composer.json b/src/Illuminate/Translation/composer.json index 8db8134d7a0f..3dfb306e89e1 100755 --- a/src/Illuminate/Translation/composer.json +++ b/src/Illuminate/Translation/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "illuminate/collections": "^13.0", "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0", diff --git a/src/Illuminate/Validation/composer.json b/src/Illuminate/Validation/composer.json index 8533f0ae58a1..97265a8965f9 100755 --- a/src/Illuminate/Validation/composer.json +++ b/src/Illuminate/Validation/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-filter": "*", "ext-mbstring": "*", "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", diff --git a/src/Illuminate/View/composer.json b/src/Illuminate/View/composer.json index d7a7a4548f82..b6dab80ff9da 100644 --- a/src/Illuminate/View/composer.json +++ b/src/Illuminate/View/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-tokenizer": "*", "illuminate/collections": "^13.0", "illuminate/container": "^13.0", From 54c7325987ea096283e372978fe18075d1a405af Mon Sep 17 00:00:00 2001 From: Luke Kuzmish <42181698+cosmastech@users.noreply.github.com> Date: Wed, 26 Feb 2025 08:25:16 -0500 Subject: [PATCH 09/27] add missing params (#54798) --- src/Illuminate/Http/Client/Response.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Http/Client/Response.php b/src/Illuminate/Http/Client/Response.php index ac51d9c7ade8..3a8ccb674cb7 100644 --- a/src/Illuminate/Http/Client/Response.php +++ b/src/Illuminate/Http/Client/Response.php @@ -305,14 +305,13 @@ public function toException() /** * Throw an exception if a server or client error occurred. * + * @param null|(\Closure(\Illuminate\Http\Client\Response, \Illuminate\Http\Client\RequestException): mixed) $callback * @return $this * * @throws \Illuminate\Http\Client\RequestException */ - public function throw() + public function throw($callback = null) { - $callback = func_get_args()[0] ?? null; - if ($this->failed()) { throw tap($this->toException(), function ($exception) use ($callback) { if ($callback && is_callable($callback)) { @@ -328,13 +327,14 @@ public function throw() * Throw an exception if a server or client error occurred and the given condition evaluates to true. * * @param \Closure|bool $condition + * @param null|(\Closure(\Illuminate\Http\Client\Response, \Illuminate\Http\Client\RequestException): mixed) $callback * @return $this * * @throws \Illuminate\Http\Client\RequestException */ - public function throwIf($condition) + public function throwIf($condition, $callback = null) { - return value($condition, $this) ? $this->throw(func_get_args()[1] ?? null) : $this; + return value($condition, $this) ? $this->throw($callback) : $this; } /** From 4ca4a16772b2e89233b3606badefae34003e1538 Mon Sep 17 00:00:00 2001 From: Will Rowe Date: Thu, 27 Feb 2025 13:30:39 -0500 Subject: [PATCH 10/27] [13.x] Fix scope removal in nested where conditions (#54816) * Add tests * Remove any scopes removed in a nested where * Update tests to expect calls to `removedScopes` --- src/Illuminate/Database/Eloquent/Builder.php | 3 ++ .../Database/DatabaseEloquentBuilderTest.php | 3 ++ .../DatabaseEloquentGlobalScopesTest.php | 37 +++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 3948debe27e3..456e9454c44c 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -326,6 +326,9 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' $this->eagerLoad = array_merge($this->eagerLoad, $query->getEagerLoads()); + $this->withoutGlobalScopes( + $query->removedScopes() + ); $this->query->addNestedWhereQuery($query->getQuery(), $boolean); } else { $this->query->where(...func_get_args()); diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index 7bbc69abdbb1..37f35ecb2cb0 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -1042,6 +1042,7 @@ public function testNestedWhere() $nestedRawQuery = $this->getMockQueryBuilder(); $nestedQuery->shouldReceive('getQuery')->once()->andReturn($nestedRawQuery); $nestedQuery->shouldReceive('getEagerLoads')->once()->andReturn([]); + $nestedQuery->shouldReceive('removedScopes')->once()->andReturn([]); $model = $this->getMockModel()->makePartial(); $model->shouldReceive('newQueryWithoutRelationships')->once()->andReturn($nestedQuery); $builder = $this->getBuilder(); @@ -1104,6 +1105,7 @@ public function testWhereNot() $nestedRawQuery = $this->getMockQueryBuilder(); $nestedQuery->shouldReceive('getQuery')->once()->andReturn($nestedRawQuery); $nestedQuery->shouldReceive('getEagerLoads')->once()->andReturn([]); + $nestedQuery->shouldReceive('removedScopes')->once()->andReturn([]); $model = $this->getMockModel()->makePartial(); $model->shouldReceive('newQueryWithoutRelationships')->once()->andReturn($nestedQuery); $builder = $this->getBuilder(); @@ -1133,6 +1135,7 @@ public function testOrWhereNot() $nestedRawQuery = $this->getMockQueryBuilder(); $nestedQuery->shouldReceive('getQuery')->once()->andReturn($nestedRawQuery); $nestedQuery->shouldReceive('getEagerLoads')->once()->andReturn([]); + $nestedQuery->shouldReceive('removedScopes')->once()->andReturn([]); $model = $this->getMockModel()->makePartial(); $model->shouldReceive('newQueryWithoutRelationships')->once()->andReturn($nestedQuery); $builder = $this->getBuilder(); diff --git a/tests/Database/DatabaseEloquentGlobalScopesTest.php b/tests/Database/DatabaseEloquentGlobalScopesTest.php index 3b5a379d4fdb..8e6423797fdd 100644 --- a/tests/Database/DatabaseEloquentGlobalScopesTest.php +++ b/tests/Database/DatabaseEloquentGlobalScopesTest.php @@ -147,6 +147,38 @@ public function testHasQueryWhereBothModelsHaveGlobalScopes() $this->assertEquals($mainQuery, $query->toSql()); $this->assertEquals(['bar', 1, 'baz', 1], $query->getBindings()); } + + public function testRegularScopesThatRemoveGlobalScopes() + { + $query = EloquentClosureGlobalScopesTestModel::where('foo', 'foo')->approved()->notApproved(); + + $this->assertSame('select * from "table" where "foo" = ? and ("approved" = ? or "should_approve" = ?) and ("approved" = ? or "should_approve" = ?) order by "name" asc', $query->toSql()); + $this->assertEquals(['foo', 1, 0, 0, 1], $query->getBindings()); + } + + public function testRegularScopesThatRemoveGlobalScopesCalledInNestedWhereCondition() + { + $query = EloquentClosureGlobalScopesTestModel::where('foo', 'foo')->where(function ($query) { + $query->approved(); + $query->orWhere(function ($query) { + $query->notApproved(); + }); + }); + + $this->assertSame('select * from "table" where "foo" = ? and (("approved" = ? or "should_approve" = ?) or (("approved" = ? or "should_approve" = ?))) order by "name" asc', $query->toSql()); + $this->assertEquals(['foo', 1, 0, 0, 1], $query->getBindings()); + } + + public function testRemovingGlobalScopeInNestedWhereCondition() + { + $query = EloquentClosureGlobalScopesTestModel::where('foo', 'foo')->where(function ($query) { + $query->approved(); + $query->withoutGlobalScope('active_scope'); + }); + + $this->assertSame('select * from "table" where "foo" = ? and (("approved" = ? or "should_approve" = ?)) order by "name" asc', $query->toSql()); + $this->assertEquals(['foo', 1, 0], $query->getBindings()); + } } class EloquentClosureGlobalScopesTestModel extends Model @@ -171,6 +203,11 @@ public function scopeApproved($query) return $query->where('approved', 1)->orWhere('should_approve', 0); } + public function scopeNotApproved($query) + { + return $query->where('approved', 0)->orWhere('should_approve', 1)->withoutGlobalScope('active_scope'); + } + public function scopeOrApproved($query) { return $query->orWhere('approved', 1)->orWhere('should_approve', 0); From 79be62470c8f2e209b4f8c9b50ca5293f4fc72bd Mon Sep 17 00:00:00 2001 From: Volodya Kurshudyan <70023120+xurshudyan@users.noreply.github.com> Date: Tue, 4 Mar 2025 18:59:22 +0400 Subject: [PATCH 11/27] [13.x] Remove function existence checks (#54876) * Remove function existence checks * remove unused JsonException import --------- Co-authored-by: Xurshudyan --- src/Illuminate/Support/Str.php | 41 ++----------------- .../Concerns/ValidatesAttributes.php | 8 +--- 2 files changed, 5 insertions(+), 44 deletions(-) diff --git a/src/Illuminate/Support/Str.php b/src/Illuminate/Support/Str.php index 622fcba0d018..b28da97453df 100644 --- a/src/Illuminate/Support/Str.php +++ b/src/Illuminate/Support/Str.php @@ -4,7 +4,6 @@ use Closure; use Illuminate\Support\Traits\Macroable; -use JsonException; use League\CommonMark\Environment\Environment; use League\CommonMark\Extension\GithubFlavoredMarkdownExtension; use League\CommonMark\Extension\InlinesOnly\InlinesOnlyExtension; @@ -546,17 +545,7 @@ public static function isJson($value) return false; } - if (function_exists('json_validate')) { - return json_validate($value, 512); - } - - try { - json_decode($value, true, 512, JSON_THROW_ON_ERROR); - } catch (JsonException) { - return false; - } - - return true; + return json_validate($value, 512); } /** @@ -906,17 +895,7 @@ public static function numbers($value) */ public static function padBoth($value, $length, $pad = ' ') { - if (function_exists('mb_str_pad')) { - return mb_str_pad($value, $length, $pad, STR_PAD_BOTH); - } - - $short = max(0, $length - mb_strlen($value)); - $shortLeft = floor($short / 2); - $shortRight = ceil($short / 2); - - return mb_substr(str_repeat($pad, $shortLeft), 0, $shortLeft). - $value. - mb_substr(str_repeat($pad, $shortRight), 0, $shortRight); + return mb_str_pad($value, $length, $pad, STR_PAD_BOTH); } /** @@ -929,13 +908,7 @@ public static function padBoth($value, $length, $pad = ' ') */ public static function padLeft($value, $length, $pad = ' ') { - if (function_exists('mb_str_pad')) { - return mb_str_pad($value, $length, $pad, STR_PAD_LEFT); - } - - $short = max(0, $length - mb_strlen($value)); - - return mb_substr(str_repeat($pad, $short), 0, $short).$value; + return mb_str_pad($value, $length, $pad, STR_PAD_LEFT); } /** @@ -948,13 +921,7 @@ public static function padLeft($value, $length, $pad = ' ') */ public static function padRight($value, $length, $pad = ' ') { - if (function_exists('mb_str_pad')) { - return mb_str_pad($value, $length, $pad, STR_PAD_RIGHT); - } - - $short = max(0, $length - mb_strlen($value)); - - return $value.mb_substr(str_repeat($pad, $short), 0, $short); + return mb_str_pad($value, $length, $pad, STR_PAD_RIGHT); } /** diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index a98aa59c57ef..27c95ecec435 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -1526,13 +1526,7 @@ public function validateJson($attribute, $value) return false; } - if (function_exists('json_validate')) { - return json_validate($value); - } - - json_decode($value); - - return json_last_error() === JSON_ERROR_NONE; + return json_validate($value); } /** From adf340d9042ced3f25d5270feab054a05b4d6470 Mon Sep 17 00:00:00 2001 From: Andrew Mast Date: Wed, 5 Mar 2025 09:44:11 -0600 Subject: [PATCH 12/27] Removed unneeded argument from json_validate (#54900) --- src/Illuminate/Support/Str.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Support/Str.php b/src/Illuminate/Support/Str.php index b28da97453df..c42bfee08018 100644 --- a/src/Illuminate/Support/Str.php +++ b/src/Illuminate/Support/Str.php @@ -545,7 +545,7 @@ public static function isJson($value) return false; } - return json_validate($value, 512); + return json_validate($value); } /** From 780533bf3e8ee8aefa4438cc13744c42ce685a39 Mon Sep 17 00:00:00 2001 From: Jesper Noordsij <45041769+jnoordsij@users.noreply.github.com> Date: Tue, 1 Apr 2025 17:02:26 +0200 Subject: [PATCH 13/27] Fix unresolved merge conflict in Concurrency composer.json (#55233) --- src/Illuminate/Concurrency/composer.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Illuminate/Concurrency/composer.json b/src/Illuminate/Concurrency/composer.json index 2f8d1e6c7ae2..0a5d5c39bbe4 100644 --- a/src/Illuminate/Concurrency/composer.json +++ b/src/Illuminate/Concurrency/composer.json @@ -14,19 +14,11 @@ } ], "require": { -<<<<<<< HEAD "php": "^8.3", "illuminate/console": "^13.0", "illuminate/contracts": "^13.0", "illuminate/process": "^13.0", "illuminate/support": "^13.0", -======= - "php": "^8.2", - "illuminate/console": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/process": "^12.0", - "illuminate/support": "^12.0", ->>>>>>> 12.x "laravel/serializable-closure": "^1.3|^2.0" }, "autoload": { From cb3f391f498961610615f609729ad2ff78817f2e Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 7 Apr 2025 22:51:22 +0800 Subject: [PATCH 14/27] [13.x] Fixes merge conflict (#55294) Signed-off-by: Mior Muhammad Zaki --- src/Illuminate/Database/Query/Builder.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index c32a3255a584..048d6912e028 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -3354,6 +3354,8 @@ protected function enforceOrderBy() */ public function pluck($column, $key = null) { + $original = $this->columns; + // First, we will need to select the results of the query accounting for the // given columns / key. Once we have the results, we will be able to take // the results and get the exact data that was requested for the query. From f18288f30c3c0007df6d20474c72ea2bed1af4d8 Mon Sep 17 00:00:00 2001 From: Michel Bardelmeijer Date: Thu, 10 Apr 2025 16:47:02 +0200 Subject: [PATCH 15/27] Error exit code for clear command (13.x) (#55355) --- src/Illuminate/Cache/Console/ClearCommand.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Cache/Console/ClearCommand.php b/src/Illuminate/Cache/Console/ClearCommand.php index e84cefae8d6c..965a39cf0248 100755 --- a/src/Illuminate/Cache/Console/ClearCommand.php +++ b/src/Illuminate/Cache/Console/ClearCommand.php @@ -57,7 +57,7 @@ public function __construct(CacheManager $cache, Filesystem $files) /** * Execute the console command. * - * @return void + * @return int|null */ public function handle() { @@ -70,7 +70,9 @@ public function handle() $this->flushFacades(); if (! $successful) { - return $this->components->error('Failed to clear cache. Make sure you have the appropriate permissions.'); + $this->components->error('Failed to clear cache. Make sure you have the appropriate permissions.'); + + return 1; } $this->laravel['events']->dispatch( From 1c873609c717153e2e5c2916584ee8dea5076145 Mon Sep 17 00:00:00 2001 From: Iman Date: Fri, 11 Apr 2025 17:27:19 +0330 Subject: [PATCH 16/27] Add #[\Override] to the BatchFake class methods (#55358) --- src/Illuminate/Support/Testing/Fakes/BatchFake.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Illuminate/Support/Testing/Fakes/BatchFake.php b/src/Illuminate/Support/Testing/Fakes/BatchFake.php index 0d1176c2b3ec..8698e00e71fc 100644 --- a/src/Illuminate/Support/Testing/Fakes/BatchFake.php +++ b/src/Illuminate/Support/Testing/Fakes/BatchFake.php @@ -67,6 +67,7 @@ public function __construct( * * @return self */ + #[\Override] public function fresh() { return $this; @@ -78,6 +79,7 @@ public function fresh() * @param \Illuminate\Support\Enumerable|object|array $jobs * @return self */ + #[\Override] public function add($jobs) { $jobs = Collection::wrap($jobs); @@ -97,6 +99,7 @@ public function add($jobs) * @param string $jobId * @return void */ + #[\Override] public function recordSuccessfulJob(string $jobId) { // @@ -108,6 +111,7 @@ public function recordSuccessfulJob(string $jobId) * @param string $jobId * @return void */ + #[\Override] public function decrementPendingJobs(string $jobId) { // @@ -120,6 +124,7 @@ public function decrementPendingJobs(string $jobId) * @param \Throwable $e * @return void */ + #[\Override] public function recordFailedJob(string $jobId, $e) { // @@ -131,6 +136,7 @@ public function recordFailedJob(string $jobId, $e) * @param string $jobId * @return \Illuminate\Bus\UpdatedBatchJobCounts */ + #[\Override] public function incrementFailedJobs(string $jobId) { return new UpdatedBatchJobCounts; @@ -141,6 +147,7 @@ public function incrementFailedJobs(string $jobId) * * @return void */ + #[\Override] public function cancel() { $this->cancelledAt = Carbon::now(); @@ -151,6 +158,7 @@ public function cancel() * * @return void */ + #[\Override] public function delete() { $this->deleted = true; From 29cc04b9f265e8f6b8353858d0216b5ccd2425ce Mon Sep 17 00:00:00 2001 From: Bert Date: Fri, 18 Apr 2025 17:51:19 +0200 Subject: [PATCH 17/27] [13.x] PDO Fetch modes (#55394) * fetchargs * add fetchArgs() function * fetchargs * add fetchArgs() function * add afterquery callbacks * fix typo * flip afterquerycallback * fix expectations * add expectations * add expectations * add expectations * add raw expression test * rename to fetchUsing * style * Remove test from PR #54396 * Revert most Query\Builder changes * remove DB::raw test * Revert QueryBuilder pluck tests * Add base tests for $query->fetchUsing() * style * formatting * Update Builder.php * Fix filled columns before calling pluck * query db compatibility * remove unrelated test --------- Co-authored-by: Taylor Otwell --- src/Illuminate/Database/Connection.php | 19 +++-- .../Database/ConnectionInterface.php | 6 +- src/Illuminate/Database/Query/Builder.php | 58 +++++++------- ...EloquentBelongsToManyCreateOrFirstTest.php | 10 ++- ...tabaseEloquentBuilderCreateOrFirstTest.php | 28 +++---- ...tabaseEloquentHasManyCreateOrFirstTest.php | 18 ++--- ...loquentHasManyThroughCreateOrFirstTest.php | 9 +++ tests/Database/DatabaseQueryBuilderTest.php | 76 +++++++++---------- .../Integration/Database/QueryBuilderTest.php | 42 ++++++++++ 9 files changed, 164 insertions(+), 102 deletions(-) diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php index a883e3edb22e..f0474f0fd7de 100755 --- a/src/Illuminate/Database/Connection.php +++ b/src/Illuminate/Database/Connection.php @@ -388,11 +388,12 @@ public function selectFromWriteConnection($query, $bindings = []) * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return array */ - public function select($query, $bindings = [], $useReadPdo = true) + public function select($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) { - return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { + return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo, $fetchUsing) { if ($this->pretending()) { return []; } @@ -408,7 +409,7 @@ public function select($query, $bindings = [], $useReadPdo = true) $statement->execute(); - return $statement->fetchAll(); + return $statement->fetchAll(...$fetchUsing); }); } @@ -418,11 +419,12 @@ public function select($query, $bindings = [], $useReadPdo = true) * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return array */ - public function selectResultSets($query, $bindings = [], $useReadPdo = true) + public function selectResultSets($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) { - return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { + return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo, $fetchUsing) { if ($this->pretending()) { return []; } @@ -438,7 +440,7 @@ public function selectResultSets($query, $bindings = [], $useReadPdo = true) $sets = []; do { - $sets[] = $statement->fetchAll(); + $sets[] = $statement->fetchAll(...$fetchUsing); } while ($statement->nextRowset()); return $sets; @@ -451,9 +453,10 @@ public function selectResultSets($query, $bindings = [], $useReadPdo = true) * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return \Generator */ - public function cursor($query, $bindings = [], $useReadPdo = true) + public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []) { $statement = $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { if ($this->pretending()) { @@ -478,7 +481,7 @@ public function cursor($query, $bindings = [], $useReadPdo = true) return $statement; }); - while ($record = $statement->fetch()) { + while ($record = $statement->fetch(...$fetchUsing)) { yield $record; } } diff --git a/src/Illuminate/Database/ConnectionInterface.php b/src/Illuminate/Database/ConnectionInterface.php index 288adb4206e3..22f866b43763 100755 --- a/src/Illuminate/Database/ConnectionInterface.php +++ b/src/Illuminate/Database/ConnectionInterface.php @@ -51,9 +51,10 @@ public function scalar($query, $bindings = [], $useReadPdo = true); * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return array */ - public function select($query, $bindings = [], $useReadPdo = true); + public function select($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []); /** * Run a select statement against the database and returns a generator. @@ -61,9 +62,10 @@ public function select($query, $bindings = [], $useReadPdo = true); * @param string $query * @param array $bindings * @param bool $useReadPdo + * @param array $fetchUsing * @return \Generator */ - public function cursor($query, $bindings = [], $useReadPdo = true); + public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []); /** * Run an insert statement against the database. diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 048d6912e028..e08f133a99b1 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -249,6 +249,13 @@ class Builder implements BuilderContract */ public $useWritePdo = false; + /** + * The custom arguments for the PDOStatement::fetchAll / fetch functions. + * + * @var array + */ + public array $fetchUsing = []; + /** * Create a new query builder instance. */ @@ -3088,9 +3095,13 @@ public function soleValue($column) */ public function get($columns = ['*']) { - $items = new Collection($this->onceWithColumns(Arr::wrap($columns), function () { - return $this->processor->processSelect($this, $this->runSelect()); - })); + $original = $this->columns; + + $this->columns ??= Arr::wrap($columns); + + $items = new Collection($this->processor->processSelect($this, $this->runSelect())); + + $this->columns = $original; return $this->applyAfterQueryCallbacks( isset($this->groupLimit) ? $this->withoutGroupLimitKeys($items) : $items @@ -3105,7 +3116,7 @@ public function get($columns = ['*']) protected function runSelect() { return $this->connection->select( - $this->toSql(), $this->getBindings(), ! $this->useWritePdo + $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing ); } @@ -3324,7 +3335,7 @@ public function cursor() return (new LazyCollection(function () { yield from $this->connection->cursor( - $this->toSql(), $this->getBindings(), ! $this->useWritePdo + $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing ); }))->map(function ($item) { return $this->applyAfterQueryCallbacks(new Collection([$item]))->first(); @@ -3660,30 +3671,6 @@ protected function setAggregate($function, $columns) return $this; } - /** - * Execute the given callback while selecting the given columns. - * - * After running the callback, the columns are reset to the original value. - * - * @param array $columns - * @param callable $callback - * @return mixed - */ - protected function onceWithColumns($columns, $callback) - { - $original = $this->columns; - - if (is_null($original)) { - $this->columns = $columns; - } - - $result = $callback(); - - $this->columns = $original; - - return $result; - } - /** * Insert new records into the database. * @@ -4297,6 +4284,19 @@ public function useWritePdo() return $this; } + /** + * Specify arguments for the PDOStatement::fetchAll / fetch functions. + * + * @param mixed ...$fetchUsing + * @return $this + */ + public function fetchUsing(...$fetchUsing) + { + $this->fetchUsing = $fetchUsing; + + return $this; + } + /** * Determine if the value is a query builder instance or a Closure. * diff --git a/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php b/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php index fc9597378357..254d925cd2c0 100644 --- a/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php @@ -84,7 +84,7 @@ public function testCreateOrFirstMethodAssociatesExistingRelated(): void $source->getConnection() ->expects('select') - ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 456, 'attr' => 'foo', @@ -128,6 +128,7 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAlreadyAssociated 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([[ 'id' => 456, @@ -176,7 +177,7 @@ public function testCreateOrFirstMethodRetrievesExistingRelatedAssociatedJustNow $source->getConnection() ->expects('select') - ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 456, 'attr' => 'foo', @@ -199,6 +200,7 @@ public function testCreateOrFirstMethodRetrievesExistingRelatedAssociatedJustNow 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], false, + [], ) ->andReturn([[ 'id' => 456, @@ -243,6 +245,7 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAndAssociatesIt() 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -252,6 +255,7 @@ public function testFirstOrCreateMethodRetrievesExistingRelatedAndAssociatesIt() 'select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, + [], ) ->andReturn([[ 'id' => 456, @@ -326,6 +330,7 @@ protected function newBelongsToMany(Builder $query, Model $parent, $table, $fore 'select "related_table".*, "pivot_table"."source_id" as "pivot_source_id", "pivot_table"."related_id" as "pivot_related_id" from "related_table" inner join "pivot_table" on "related_table"."id" = "pivot_table"."related_id" where "pivot_table"."source_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -335,6 +340,7 @@ protected function newBelongsToMany(Builder $query, Model $parent, $table, $fore 'select * from "related_table" where ("attr" = ?) limit 1', ['foo'], true, + [], ) ->andReturn([]); diff --git a/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php b/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php index 87fc0c43e24f..e957362691f7 100755 --- a/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php @@ -66,7 +66,7 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -95,7 +95,7 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -124,7 +124,7 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -152,7 +152,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $sql = 'insert into "table" ("attr", "val", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -165,7 +165,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -194,7 +194,7 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -231,7 +231,7 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -259,7 +259,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $sql = 'insert into "table" ("attr", "val", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -272,7 +272,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -309,7 +309,7 @@ public function testIncrementOrCreateMethodIncrementsExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -351,7 +351,7 @@ public function testIncrementOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -379,7 +379,7 @@ public function testIncrementOrCreateMethodIncrementParametersArePassed(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', @@ -423,7 +423,7 @@ public function testIncrementOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], true, []) ->andReturn([]); $sql = 'insert into "table" ("attr", "count", "updated_at", "created_at") values (?, ?, ?, ?)'; @@ -436,7 +436,7 @@ public function testIncrementOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false) + ->with('select * from "table" where ("attr" = ?) limit 1', ['foo'], false, []) ->andReturn([[ 'id' => 123, 'attr' => 'foo', diff --git a/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php b/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php index b7a055a66958..855ac0665fa3 100755 --- a/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php @@ -70,7 +70,7 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -102,7 +102,7 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -132,7 +132,7 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -164,7 +164,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([]); $sql = 'insert into "child_table" ("attr", "val", "parent_id", "updated_at", "created_at") values (?, ?, ?, ?, ?)'; @@ -177,7 +177,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -209,7 +209,7 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([]); $model->getConnection()->expects('insert')->with( @@ -239,7 +239,7 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, @@ -276,7 +276,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], true, []) ->andReturn([]); $sql = 'insert into "child_table" ("attr", "val", "parent_id", "updated_at", "created_at") values (?, ?, ?, ?, ?)'; @@ -289,7 +289,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void $model->getConnection() ->expects('select') - ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false) + ->with('select * from "child_table" where "child_table"."parent_id" = ? and "child_table"."parent_id" is not null and ("attr" = ?) limit 1', [123, 'foo'], false, []) ->andReturn([[ 'id' => 456, 'parent_id' => 123, diff --git a/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php b/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php index 63c69a6175bb..9a5dc0e26daf 100644 --- a/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php +++ b/tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php @@ -75,6 +75,7 @@ public function testCreateOrFirstMethodRetrievesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([[ 'id' => 789, @@ -114,6 +115,7 @@ public function testFirstOrCreateMethodCreatesNewRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -148,6 +150,7 @@ public function testFirstOrCreateMethodRetrievesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([[ 'id' => 789, @@ -187,6 +190,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -204,6 +208,7 @@ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ? and "val" = ?) limit 1', [123, 'foo', 'bar'], true, + [], ) ->andReturn([[ 'id' => 789, @@ -243,6 +248,7 @@ public function testUpdateOrCreateMethodCreatesNewRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -280,6 +286,7 @@ public function testUpdateOrCreateMethodUpdatesExistingRecord(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([[ 'id' => 789, @@ -327,6 +334,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ?) limit 1', [123, 'foo'], true, + [], ) ->andReturn([]); @@ -344,6 +352,7 @@ public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void 'select "child".*, "pivot"."parent_id" as "laravel_through_key" from "child" inner join "pivot" on "pivot"."id" = "child"."pivot_id" where "pivot"."parent_id" = ? and ("attr" = ? and "val" = ?) limit 1', [123, 'foo', 'bar'], true, + [], ) ->andReturn([[ 'id' => 789, diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 9c89ef66eac9..700d64a9502c 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -82,12 +82,12 @@ public function testBasicSelectUseWritePdo() { $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with('select * from `users`', [], false); + ->with('select * from `users`', [], false, []); $builder->useWritePdo()->select('*')->from('users')->get(); $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with('select * from `users`', [], true); + ->with('select * from `users`', [], true, []); $builder->select('*')->from('users')->get(); } @@ -1777,31 +1777,31 @@ public function testUnionAggregate() { $expected = 'select count(*) as aggregate from ((select * from `posts`) union (select * from `videos`)) as `temp_table`'; $builder = $this->getMySqlBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getMySqlBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from ((select `id` from `posts`) union (select `id` from `videos`)) as `temp_table`'; $builder = $this->getMySqlBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->select('id')->union($this->getMySqlBuilder()->from('videos')->select('id'))->count(); $expected = 'select count(*) as aggregate from ((select * from "posts") union (select * from "videos")) as "temp_table"'; $builder = $this->getPostgresBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getPostgresBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from (select * from (select * from "posts") union select * from (select * from "videos")) as "temp_table"'; $builder = $this->getSQLiteBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getSQLiteBuilder()->from('videos'))->count(); $expected = 'select count(*) as aggregate from (select * from (select * from [posts]) as [temp_table] union select * from (select * from [videos]) as [temp_table]) as [temp_table]'; $builder = $this->getSqlServerBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []); $builder->getProcessor()->shouldReceive('processSelect')->once(); $builder->from('posts')->union($this->getSqlServerBuilder()->from('videos'))->count(); } @@ -1811,7 +1811,7 @@ public function testHavingAggregate() $expected = 'select count(*) as aggregate from (select (select `count(*)` from `videos` where `posts`.`id` = `videos`.`post_id`) as `videos_count` from `posts` having `videos_count` > ?) as `temp_table`'; $builder = $this->getMySqlBuilder(); $builder->getConnection()->shouldReceive('getDatabaseName'); - $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2293,7 +2293,7 @@ public function testHavingFollowedBySelectGet() { $builder = $this->getBuilder(); $query = 'select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > ?'; - $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular', 3], true)->andReturn([['category' => 'rock', 'total' => 5]]); + $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular', 3], true, [])->andReturn([['category' => 'rock', 'total' => 5]]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2304,7 +2304,7 @@ public function testHavingFollowedBySelectGet() // Using \Raw value $builder = $this->getBuilder(); $query = 'select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > 3'; - $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular'], true)->andReturn([['category' => 'rock', 'total' => 5]]); + $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular'], true, [])->andReturn([['category' => 'rock', 'total' => 5]]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2419,7 +2419,7 @@ public function testGetCountForPaginationWithBindings() $q->select('body')->from('posts')->where('id', 4); }, 'post'); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2435,7 +2435,7 @@ public function testGetCountForPaginationWithColumnAliases() $columns = ['body as post_body', 'teaser', 'posts.created as published']; $builder->from('posts')->select($columns); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("body", "teaser", "posts"."created") as aggregate from "posts"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("body", "teaser", "posts"."created") as aggregate from "posts"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2449,7 +2449,7 @@ public function testGetCountForPaginationWithUnion() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id')); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2463,7 +2463,7 @@ public function testGetCountForPaginationWithUnionOrders() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'))->latest(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -2477,7 +2477,7 @@ public function testGetCountForPaginationWithUnionLimitAndOffset() $builder = $this->getBuilder(); $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'))->take(15)->skip(1); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3428,7 +3428,7 @@ public function testRawExpressionsInSelect() public function testFindReturnsFirstResultByID() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3452,7 +3452,7 @@ public function testFindOrReturnsFirstResultByID() public function testFirstMethodReturnsFirstResult() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3463,7 +3463,7 @@ public function testFirstMethodReturnsFirstResult() public function testFirstOrFailMethodReturnsFirstResult() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3474,7 +3474,7 @@ public function testFirstOrFailMethodReturnsFirstResult() public function testFirstOrFailMethodThrowsRecordNotFoundException() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([]); + $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true, [])->andReturn([]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [])->andReturn([]); @@ -3506,7 +3506,7 @@ public function testPluckMethodGetsCollectionOfColumnValues() public function testPluckAvoidsDuplicateColumnSelection() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ?', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ?', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) { return $results; }); @@ -3538,7 +3538,7 @@ public function testImplode() public function testValueMethodReturnsSingleColumn() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturn([['foo' => 'bar']]); $results = $builder->from('users')->where('id', '=', 1)->value('foo'); $this->assertSame('bar', $results); @@ -3547,7 +3547,7 @@ public function testValueMethodReturnsSingleColumn() public function testRawValueMethodReturnsSingleColumn() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select UPPER("foo") from "users" where "id" = ? limit 1', [1], true)->andReturn([['UPPER("foo")' => 'BAR']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select UPPER("foo") from "users" where "id" = ? limit 1', [1], true, [])->andReturn([['UPPER("foo")' => 'BAR']]); $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['UPPER("foo")' => 'BAR']])->andReturn([['UPPER("foo")' => 'BAR']]); $results = $builder->from('users')->where('id', '=', 1)->rawValue('UPPER("foo")'); $this->assertSame('BAR', $results); @@ -3556,7 +3556,7 @@ public function testRawValueMethodReturnsSingleColumn() public function testAggregateFunctions() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3574,7 +3574,7 @@ public function testAggregateFunctions() $this->assertTrue($results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select max("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select max("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3582,7 +3582,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select min("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select min("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3590,7 +3590,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3598,7 +3598,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3606,7 +3606,7 @@ public function testAggregateFunctions() $this->assertEquals(1, $results); $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select avg("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3657,9 +3657,9 @@ public function testDoesntExistsOr() public function testAggregateResetFollowedByGet() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 2]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column1", "column2" from "users"', [], true)->andReturn([['column1' => 'foo', 'column2' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 2]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column1", "column2" from "users"', [], true, [])->andReturn([['column1' => 'foo', 'column2' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3675,8 +3675,8 @@ public function testAggregateResetFollowedByGet() public function testAggregateResetFollowedBySelectGet() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true)->andReturn([['column2' => 'foo', 'column3' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true, [])->andReturn([['column2' => 'foo', 'column3' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3690,8 +3690,8 @@ public function testAggregateResetFollowedBySelectGet() public function testAggregateResetFollowedByGetWithColumns() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); - $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true)->andReturn([['column2' => 'foo', 'column3' => 'bar']]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true, [])->andReturn([['column2' => 'foo', 'column3' => 'bar']]); $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) { return $results; }); @@ -3705,7 +3705,7 @@ public function testAggregateResetFollowedByGetWithColumns() public function testAggregateWithSubSelect() { $builder = $this->getBuilder(); - $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]); + $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true, [])->andReturn([['aggregate' => 1]]); $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { return $results; }); @@ -5191,12 +5191,12 @@ public function testSelectWithLockUsesWritePdo() { $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with(m::any(), m::any(), false); + ->with(m::any(), m::any(), false, []); $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock()->get(); $builder = $this->getMySqlBuilderWithProcessor(); $builder->getConnection()->shouldReceive('select')->once() - ->with(m::any(), m::any(), false); + ->with(m::any(), m::any(), false, []); $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false)->get(); } diff --git a/tests/Integration/Database/QueryBuilderTest.php b/tests/Integration/Database/QueryBuilderTest.php index 071ee58a3d66..57a1593dac69 100644 --- a/tests/Integration/Database/QueryBuilderTest.php +++ b/tests/Integration/Database/QueryBuilderTest.php @@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Testing\Assert as PHPUnit; use Orchestra\Testbench\Attributes\DefineEnvironment; +use PDO; use PDOException; class QueryBuilderTest extends DatabaseTestCase @@ -645,6 +646,47 @@ public function testPluck() $this->assertSame(2, (int) $result[1]); } + public function testFetchUsing() + { + // Fetch column as a list. + $this->assertSame([ + 'Foo Post', + 'Bar Post', + ], DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_COLUMN)->get()->toArray()); + + // Fetch the second column as a list (zero-indexed). + $this->assertSame([ + 'Lorem Ipsum.', + 'Lorem Ipsum.', + ], DB::table('posts')->select(['title', 'content'])->fetchUsing(PDO::FETCH_COLUMN, 1)->get()->toArray()); + + // Fetch two columns as key value pairs. + $this->assertSame([ + 1 => 'Foo Post', + 2 => 'Bar Post', + ], DB::table('posts')->select(['id', 'title'])->fetchUsing(PDO::FETCH_KEY_PAIR)->get()->toArray()); + + // Fetch data as associative array with custom key. + $result = DB::table('posts')->select(['id', 'title'])->fetchUsing(PDO::FETCH_UNIQUE)->get()->toArray(); + // Note: results are keyed by their post id here. + $this->assertSame('Foo Post', $result[1]->title); + $this->assertSame('Bar Post', $result[2]->title); + + // Use a cursor. + $this->assertSame([ + 'Foo Post', + 'Bar Post', + ], DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_COLUMN)->cursor()->collect()->toArray()); + + // Test the default 'object' fetch mode. + $result = DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_OBJ)->get()->toArray(); + $result2 = DB::table('posts')->select(['title'])->fetchUsing()->get()->toArray(); + $this->assertSame('Foo Post', $result[0]->title); + $this->assertSame('Bar Post', $result[1]->title); + $this->assertSame('Foo Post', $result2[0]->title); + $this->assertSame('Bar Post', $result2[1]->title); + } + protected function defineEnvironmentWouldThrowsPDOException($app) { $this->afterApplicationCreated(function () { From 0df7b013288754cbcab6ae11ade6c27c5ad1a553 Mon Sep 17 00:00:00 2001 From: taylorotwell <463230+taylorotwell@users.noreply.github.com> Date: Fri, 18 Apr 2025 15:51:47 +0000 Subject: [PATCH 18/27] Update facade docblocks --- src/Illuminate/Support/Facades/DB.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Support/Facades/DB.php b/src/Illuminate/Support/Facades/DB.php index f1c41bc0abb4..90990046ed69 100644 --- a/src/Illuminate/Support/Facades/DB.php +++ b/src/Illuminate/Support/Facades/DB.php @@ -40,9 +40,9 @@ * @method static mixed selectOne(string $query, array $bindings = [], bool $useReadPdo = true) * @method static mixed scalar(string $query, array $bindings = [], bool $useReadPdo = true) * @method static array selectFromWriteConnection(string $query, array $bindings = []) - * @method static array select(string $query, array $bindings = [], bool $useReadPdo = true) - * @method static array selectResultSets(string $query, array $bindings = [], bool $useReadPdo = true) - * @method static \Generator cursor(string $query, array $bindings = [], bool $useReadPdo = true) + * @method static array select(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) + * @method static array selectResultSets(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) + * @method static \Generator cursor(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = []) * @method static bool insert(string $query, array $bindings = []) * @method static int update(string $query, array $bindings = []) * @method static int delete(string $query, array $bindings = []) From 4b9458124d5bbd117f48867f851b679b4f7230ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9opold=20Jacquot?= Date: Tue, 22 Apr 2025 15:44:53 +0200 Subject: [PATCH 19/27] Allow Listeners to dynamically specify deleteWhenMissingModels (#55508) * Allow Listeners to dynamically specify deleteWhenMissingModels * Update BroadcastEvent.php * Update CallQueuedListener.php --------- Co-authored-by: Taylor Otwell --- src/Illuminate/Broadcasting/BroadcastEvent.php | 8 ++++++++ src/Illuminate/Events/CallQueuedListener.php | 7 +++++++ src/Illuminate/Events/Dispatcher.php | 1 + 3 files changed, 16 insertions(+) diff --git a/src/Illuminate/Broadcasting/BroadcastEvent.php b/src/Illuminate/Broadcasting/BroadcastEvent.php index c4da0faab220..7c03641ace53 100644 --- a/src/Illuminate/Broadcasting/BroadcastEvent.php +++ b/src/Illuminate/Broadcasting/BroadcastEvent.php @@ -50,6 +50,13 @@ class BroadcastEvent implements ShouldQueue */ public $maxExceptions; + /** + * Indicates if the job should be deleted when models are missing. + * + * @var bool + */ + public $deleteWhenMissingModels; + /** * Create a new job handler instance. * @@ -63,6 +70,7 @@ public function __construct($event) $this->backoff = property_exists($event, 'backoff') ? $event->backoff : null; $this->afterCommit = property_exists($event, 'afterCommit') ? $event->afterCommit : null; $this->maxExceptions = property_exists($event, 'maxExceptions') ? $event->maxExceptions : null; + $this->deleteWhenMissingModels = property_exists($event, 'deleteWhenMissingModels') ? $event->deleteWhenMissingModels : null; } /** diff --git a/src/Illuminate/Events/CallQueuedListener.php b/src/Illuminate/Events/CallQueuedListener.php index e78a4c4e2c5f..13f33e338304 100644 --- a/src/Illuminate/Events/CallQueuedListener.php +++ b/src/Illuminate/Events/CallQueuedListener.php @@ -82,6 +82,13 @@ class CallQueuedListener implements ShouldQueue */ public $shouldBeEncrypted = false; + /** + * Indicates if the job should be deleted when models are missing. + * + * @var bool + */ + public $deleteWhenMissingModels; + /** * Create a new job instance. * diff --git a/src/Illuminate/Events/Dispatcher.php b/src/Illuminate/Events/Dispatcher.php index ee409586efc8..bfea9a47e353 100755 --- a/src/Illuminate/Events/Dispatcher.php +++ b/src/Illuminate/Events/Dispatcher.php @@ -677,6 +677,7 @@ protected function propagateListenerOptions($listener, $job) $job->timeout = $listener->timeout ?? null; $job->failOnTimeout = $listener->failOnTimeout ?? false; $job->tries = $listener->tries ?? null; + $job->deleteWhenMissingModels = $listener->deleteWhenMissingModels ?? false; $job->through(array_merge( method_exists($listener, 'middleware') ? $listener->middleware(...$data) : [], From 7672871912796fe2640f37503c410a71d8b31231 Mon Sep 17 00:00:00 2001 From: Will Rowe Date: Sat, 10 May 2025 14:20:54 -0400 Subject: [PATCH 20/27] [13.x] Do not allow new model instances to be created during boot (#55685) * Add failing test * Only mark a model class as booted after the boot process has been completed * Mark a model class as booting as soon as the boot process starts - A model class is removed from the `booting` array as soon as the boot process has completed. * Throw an exception if `bootIfNotBooted` is called while booting - This infers that something in the boot process expected the boot to already be finished. - If we just ignore the call then the model class would be in an inconsistent state for whichever code called it. * formatting * formatting --------- Co-authored-by: Taylor Otwell --- src/Illuminate/Database/Eloquent/Model.php | 18 +++++++++++++++++- tests/Database/DatabaseEloquentModelTest.php | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Eloquent/Model.php b/src/Illuminate/Database/Eloquent/Model.php index 72d7e3315e36..990b5b526108 100644 --- a/src/Illuminate/Database/Eloquent/Model.php +++ b/src/Illuminate/Database/Eloquent/Model.php @@ -4,6 +4,7 @@ use ArrayAccess; use Closure; +use Exception; use Illuminate\Contracts\Broadcasting\HasBroadcastChannel; use Illuminate\Contracts\Queue\QueueableCollection; use Illuminate\Contracts\Queue\QueueableEntity; @@ -143,6 +144,13 @@ abstract class Model implements Arrayable, ArrayAccess, CanBeEscapedWhenCastToSt */ protected static $dispatcher; + /** + * The models that are currently being booted. + * + * @var array + */ + protected static $booting = []; + /** * The array of booted models. * @@ -286,12 +294,20 @@ public function __construct(array $attributes = []) protected function bootIfNotBooted() { if (! isset(static::$booted[static::class])) { - static::$booted[static::class] = true; + if (isset(static::$booting[static::class])) { + throw new LogicException('The ['.__METHOD__.'] method may not be called on model ['.static::class.'] while it is being booted.'); + } + + static::$booting[static::class] = true; $this->fireModelEvent('booting', false); static::booting(); static::boot(); + + static::$booted[static::class] = true; + unset(static::$booting[static::class]); + static::booted(); static::$bootedCallbacks[static::class] ??= []; diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index d7f6f1538b72..54c2673b3b6f 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -3330,6 +3330,21 @@ public function testUseFactoryAttribute() $this->assertEquals(EloquentModelWithUseFactoryAttribute::class, $factory->modelName()); $this->assertEquals('test name', $instance->name); // Small smoke test to ensure the factory is working } + + public function testNestedModelBootingIsDisallowed() + { + $this->expectExceptionMessageMatches('/The \[(.+)] method may not be called on model \[(.+)\] while it is being booted\./'); + + $model = new class extends Model + { + protected static function boot() + { + parent::boot(); + + $tableName = (new static())->getTable(); + } + }; + } } class EloquentTestObserverStub From d8306c99ec14fb2fe89ecfb6f15bcbf8af90b191 Mon Sep 17 00:00:00 2001 From: TheJoeSchr <8218910+TheJoeSchr@users.noreply.github.com> Date: Mon, 26 May 2025 19:18:11 +0200 Subject: [PATCH 21/27] Fix typo in `Blueprint` `datetime` => `dateTime` (#55859) It still works, because of php case sensitive rules, but it's better correct. --- src/Illuminate/Database/Schema/Blueprint.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Schema/Blueprint.php b/src/Illuminate/Database/Schema/Blueprint.php index b7687e839f34..f864e4f41953 100755 --- a/src/Illuminate/Database/Schema/Blueprint.php +++ b/src/Illuminate/Database/Schema/Blueprint.php @@ -1282,9 +1282,9 @@ public function timestampsTz($precision = null) */ public function datetimes($precision = null) { - $this->datetime('created_at', $precision)->nullable(); + $this->dateTime('created_at', $precision)->nullable(); - $this->datetime('updated_at', $precision)->nullable(); + $this->dateTime('updated_at', $precision)->nullable(); } /** @@ -1320,7 +1320,7 @@ public function softDeletesTz($column = 'deleted_at', $precision = null) */ public function softDeletesDatetime($column = 'deleted_at', $precision = null) { - return $this->datetime($column, $precision)->nullable(); + return $this->dateTime($column, $precision)->nullable(); } /** From 7c9e306c3d61bbf45c8d675d15d23d49b72b3e9b Mon Sep 17 00:00:00 2001 From: Diego Lozano Date: Tue, 27 May 2025 17:16:22 -0500 Subject: [PATCH 22/27] Feature: add support straight join in mysql (#55786) * feat: add support in grammar * feat: add functions in builder * test: add tests * test: adjust syntax mysql * test: adjust syntax mysql * test: remove line noused * test: execute compileJoins * formatting --------- Co-authored-by: Taylor Otwell --- src/Illuminate/Database/Query/Builder.php | 43 +++++++++++++++++ .../Database/Query/Grammars/Grammar.php | 14 +++++- .../Database/Query/Grammars/MySqlGrammar.php | 8 ++++ tests/Database/DatabaseQueryBuilderTest.php | 47 +++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 16afbd436295..c92b7ebb7518 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -776,6 +776,49 @@ public function crossJoinSub($query, $as) return $this; } + /** + * Add a straight join to the query. + * + * @param \Illuminate\Contracts\Database\Query\Expression|string $table + * @param \Closure|string $first + * @param string|null $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second + * @return $this + */ + public function straightJoin($table, $first, $operator = null, $second = null) + { + return $this->join($table, $first, $operator, $second, 'straight_join'); + } + + /** + * Add a "straight join where" clause to the query. + * + * @param \Illuminate\Contracts\Database\Query\Expression|string $table + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first + * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string $second + * @return $this + */ + public function straightJoinWhere($table, $first, $operator, $second) + { + return $this->joinWhere($table, $first, $operator, $second, 'straight_join'); + } + + /** + * Add a subquery straight join to the query. + * + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*>|string $query + * @param string $as + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first + * @param string|null $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second + * @return $this + */ + public function straightJoinSub($query, $as, $first, $operator = null, $second = null) + { + return $this->joinSub($query, $as, $first, $operator, $second, 'straight_join'); + } + /** * Get a new join clause. * diff --git a/src/Illuminate/Database/Query/Grammars/Grammar.php b/src/Illuminate/Database/Query/Grammars/Grammar.php index ea1c44e00866..092380bebc70 100755 --- a/src/Illuminate/Database/Query/Grammars/Grammar.php +++ b/src/Illuminate/Database/Query/Grammars/Grammar.php @@ -199,7 +199,9 @@ protected function compileJoins(Builder $query, $joins) return $this->compileJoinLateral($join, $tableAndNestedJoins); } - return trim("{$join->type} join {$tableAndNestedJoins} {$this->compileWheres($join)}"); + $joinWord = ($join->type === 'straight_join' && $this->supportsStraightJoins()) ? '' : ' join'; + + return trim("{$join->type}{$joinWord} {$tableAndNestedJoins} {$this->compileWheres($join)}"); })->implode(' '); } @@ -217,6 +219,16 @@ public function compileJoinLateral(JoinLateralClause $join, string $expression): throw new RuntimeException('This database engine does not support lateral joins.'); } + /** + * Determine if the grammar supports straight joins. + * + * @return bool + */ + protected function supportsStraightJoins() + { + throw new RuntimeException('This database engine does not support straight joins.'); + } + /** * Compile the "where" portions of the query. * diff --git a/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php b/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php index 4372bae32791..6c4c2c09e212 100755 --- a/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php @@ -387,6 +387,14 @@ public function compileJoinLateral(JoinLateralClause $join, string $expression): return trim("{$join->type} join lateral {$expression} on true"); } + /** + * {@inheritdoc} + */ + protected function supportsStraightJoins() + { + return true; + } + /** * Prepare a JSON column being updated using the JSON_SET function. * diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 700d64a9502c..a22dd68c8f18 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -3299,6 +3299,53 @@ public function testRightJoinSub() $builder->from('users')->rightJoinSub(['foo'], 'sub', 'users.id', '=', 'sub.id'); } + public function testStraightJoin() + { + $builder = $this->getMySqlBuilder(); + $builder->getConnection()->shouldReceive('getDatabaseName'); + $builder->select('*')->from('users')->straightJoin('contacts', 'users.id', 'contacts.id'); + $this->assertSame('select * from `users` straight_join `contacts` on `users`.`id` = `contacts`.`id`', $builder->toSql()); + + $builder = $this->getMySqlBuilder(); + $builder->getConnection()->shouldReceive('getDatabaseName'); + $builder->select('*')->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->straightJoin('photos', 'users.id', '=', 'photos.id'); + $this->assertSame('select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` straight_join `photos` on `users`.`id` = `photos`.`id`', $builder->toSql()); + + $builder = $this->getMySqlBuilder(); + $builder->getConnection()->shouldReceive('getDatabaseName'); + $builder->select('*')->from('users')->straightJoinWhere('photos', 'users.id', '=', 'bar')->joinWhere('photos', 'users.id', '=', 'foo'); + $this->assertSame('select * from `users` straight_join `photos` on `users`.`id` = ? inner join `photos` on `users`.`id` = ?', $builder->toSql()); + $this->assertEquals(['bar', 'foo'], $builder->getBindings()); + } + + public function testStraightJoinNoSupport() + { + $this->expectException(RuntimeException::class); + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->straightJoin('contacts', 'users.id', 'contacts.id'); + $builder->toSql(); + } + + public function testStraightJoinSub() + { + $builder = $this->getMySqlBuilder(); + $builder->getConnection()->shouldReceive('getDatabaseName'); + $builder->from('users')->straightJoinSub($this->getBuilder()->from('contacts'), 'sub', 'users.id', '=', 'sub.id'); + $this->assertSame('select * from `users` straight_join (select * from "contacts") as `sub` on `users`.`id` = `sub`.`id`', $builder->toSql()); + + $this->expectException(InvalidArgumentException::class); + $builder = $this->getBuilder(); + $builder->from('users')->straightJoinSub(['foo'], 'sub', 'users.id', '=', 'sub.id'); + } + + public function testStraightJoinSubNoSupport() + { + $this->expectException(RuntimeException::class); + $builder = $this->getBuilder(); + $builder->from('users')->straightJoinSub($this->getBuilder()->from('contacts'), 'sub', 'users.id', '=', 'sub.id'); + $builder->toSql(); + } + public function testJoinLateral() { $builder = $this->getMySqlBuilder(); From 5ce08d4d8b2a765cddd57a7aa38dd5ac9813383c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Debrauwer?= Date: Thu, 5 Jun 2025 17:01:59 +0200 Subject: [PATCH 23/27] [13.x] Register subdomain routes before routes that are not linked to a domain (#55921) * wip * wip * wip * linting --- src/Illuminate/Routing/RouteCollection.php | 16 ++++- tests/Routing/RouteCollectionTest.php | 60 +++++++++++++++++++ .../Testing/Console/RouteListCommandTest.php | 2 +- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Routing/RouteCollection.php b/src/Illuminate/Routing/RouteCollection.php index 9d6a087204c4..2898f0fa5eb6 100644 --- a/src/Illuminate/Routing/RouteCollection.php +++ b/src/Illuminate/Routing/RouteCollection.php @@ -62,10 +62,22 @@ protected function addToCollections($route) $domainAndUri = $route->getDomain().$route->uri(); foreach ($methods as $method) { - $this->routes[$method][$domainAndUri] = $route; + if ($route->getDomain()) { + $domainRoutes = array_filter($this->routes[$method] ?? [], fn ($route) => $route->getDomain() !== null); + + $this->routes[$method] = $domainRoutes + [$domainAndUri => $route] + ($this->routes[$method] ?? []); + } else { + $this->routes[$method][$domainAndUri] = $route; + } } - $this->allRoutes[implode('|', $methods).$domainAndUri] = $route; + if ($route->getDomain()) { + $domainRoutes = array_filter($this->allRoutes, fn ($route) => $route->getDomain() !== null); + + $this->allRoutes = $domainRoutes + [implode('|', $methods).$domainAndUri => $route] + $this->allRoutes; + } else { + $this->allRoutes[implode('|', $methods).$domainAndUri] = $route; + } } /** diff --git a/tests/Routing/RouteCollectionTest.php b/tests/Routing/RouteCollectionTest.php index 4fb543df1172..e061b9ba777b 100644 --- a/tests/Routing/RouteCollectionTest.php +++ b/tests/Routing/RouteCollectionTest.php @@ -359,4 +359,64 @@ public function testOverlappingRoutesMatchesFirstRoute() $this->assertCount(2, $this->routeCollection->getRoutes()); $this->assertEquals('first', $this->routeCollection->match($request)->getName()); } + + public function testPrependsRoutesWithDomain() + { + $this->routeCollection->add( + $noDomainGet1 = new Route('GET', 'no-domain-get1', ['uses' => 'NoDomainController@index']) + ); + + $this->routeCollection->add( + $fooDomainGet1 = (new Route('GET', 'foo-domain-get1', ['uses' => 'FooDomainController@index']))->domain('foo.test') + ); + + $this->routeCollection->add( + $barDomainGet1 = (new Route('GET', 'bar-domain-get1', ['uses' => 'BarDomainController@index']))->domain('bar.test') + ); + + $this->routeCollection->add( + $noDomainGet2 = new Route('GET', 'no-domain-get2', ['uses' => 'NoDomainController@show']) + ); + + $this->routeCollection->add( + $fooDomainGet2 = (new Route('GET', 'foo-domain-get2', ['uses' => 'FooDomainController@show']))->domain('foo.test') + ); + + $this->routeCollection->add( + $barDomainGet2 = (new Route('GET', 'bar-domain-get2', ['uses' => 'BarDomainController@show']))->domain('bar.test') + ); + + $this->assertSame([ + $fooDomainGet1, + $barDomainGet1, + $fooDomainGet2, + $barDomainGet2, + $noDomainGet1, + $noDomainGet2, + ], $this->routeCollection->getRoutes()); + + $this->assertSame([ + 'GET' => [ + 'foo.testfoo-domain-get1' => $fooDomainGet1, + 'bar.testbar-domain-get1' => $barDomainGet1, + + 'foo.testfoo-domain-get2' => $fooDomainGet2, + 'bar.testbar-domain-get2' => $barDomainGet2, + + 'no-domain-get1' => $noDomainGet1, + 'no-domain-get2' => $noDomainGet2, + ], + + 'HEAD' => [ + 'foo.testfoo-domain-get1' => $fooDomainGet1, + 'bar.testbar-domain-get1' => $barDomainGet1, + + 'foo.testfoo-domain-get2' => $fooDomainGet2, + 'bar.testbar-domain-get2' => $barDomainGet2, + + 'no-domain-get1' => $noDomainGet1, + 'no-domain-get2' => $noDomainGet2, + ], + ], $this->routeCollection->getRoutesByMethod()); + } } diff --git a/tests/Testing/Console/RouteListCommandTest.php b/tests/Testing/Console/RouteListCommandTest.php index c6deeeb8df21..daad2697381b 100644 --- a/tests/Testing/Console/RouteListCommandTest.php +++ b/tests/Testing/Console/RouteListCommandTest.php @@ -63,8 +63,8 @@ public function testDisplayRoutesForCli() $this->artisan(RouteListCommand::class) ->assertSuccessful() ->expectsOutput('') - ->expectsOutput(' GET|HEAD / ..................................................... ') ->expectsOutput(' GET|HEAD {account}.example.com/ ................................ ') + ->expectsOutput(' GET|HEAD / ..................................................... ') ->expectsOutput(' GET|HEAD closure ............................................... ') ->expectsOutput(' POST controller-invokable Illuminate\Tests\Testing\Console\…') ->expectsOutput(' GET|HEAD controller-method/{user} Illuminate\Tests\Testing\Cons…') From 37a74cdcce95e0d3bfe2731df7346f269e505c1d Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 16 Jun 2025 21:36:21 +0800 Subject: [PATCH 24/27] [13.x] Supports Symfony 7.4 & 8.0 (#56029) * [13.x] Supports Symfony 7.4 Signed-off-by: Mior Muhammad Zaki * Update `Application` to use `addCommand` insteads of deprecated `add` Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * Remove `addToParent()` method. Signed-off-by: Mior Muhammad Zaki * Revert "Remove `addToParent()` method." This reverts commit 7cf2aa7d7d6ccdfebad673f26681d1ade1023f43. * wip Signed-off-by: Mior Muhammad Zaki * Update Application.php --------- Signed-off-by: Mior Muhammad Zaki --- composer.json | 42 ++++++++++++------------ src/Illuminate/Cache/composer.json | 2 +- src/Illuminate/Collections/composer.json | 2 +- src/Illuminate/Console/Application.php | 28 ++++------------ src/Illuminate/Console/composer.json | 4 +-- src/Illuminate/Cookie/composer.json | 4 +-- src/Illuminate/Database/composer.json | 2 +- src/Illuminate/Filesystem/composer.json | 6 ++-- src/Illuminate/Http/composer.json | 6 ++-- src/Illuminate/Mail/composer.json | 8 ++--- src/Illuminate/Process/composer.json | 2 +- src/Illuminate/Queue/composer.json | 2 +- src/Illuminate/Routing/composer.json | 8 ++--- src/Illuminate/Session/composer.json | 4 +-- src/Illuminate/Support/composer.json | 6 ++-- src/Illuminate/Validation/composer.json | 4 +-- 16 files changed, 58 insertions(+), 72 deletions(-) diff --git a/composer.json b/composer.json index 82a743fab87e..1053c5cbee78 100644 --- a/composer.json +++ b/composer.json @@ -44,17 +44,17 @@ "psr/log": "^1.0|^2.0|^3.0", "psr/simple-cache": "^1.0|^2.0|^3.0", "ramsey/uuid": "^4.7", - "symfony/console": "^7.2.0", - "symfony/error-handler": "^7.2.0", - "symfony/finder": "^7.2.0", - "symfony/http-foundation": "^7.2.0", - "symfony/http-kernel": "^7.2.0", - "symfony/mailer": "^7.2.0", - "symfony/mime": "^7.2.0", - "symfony/process": "^7.2.0", - "symfony/routing": "^7.2.0", - "symfony/uid": "^7.2.0", - "symfony/var-dumper": "^7.2.0", + "symfony/console": "^7.4.0|^8.0.0", + "symfony/error-handler": "^7.4.0|^8.0.0", + "symfony/finder": "^7.4.0|^8.0.0", + "symfony/http-foundation": "^7.4.0|^8.0.0", + "symfony/http-kernel": "^7.4.0|^8.0.0", + "symfony/mailer": "^7.4.0|^8.0.0", + "symfony/mime": "^7.4.0|^8.0.0", + "symfony/process": "^7.4.0|^8.0.0", + "symfony/routing": "^7.4.0|^8.0.0", + "symfony/uid": "^7.4.0|^8.0.0", + "symfony/var-dumper": "^7.4.0|^8.0.0", "tijsverkoyen/css-to-inline-styles": "^2.2.5", "vlucas/phpdotenv": "^5.6.1", "voku/portable-ascii": "^2.0.2" @@ -117,10 +117,10 @@ "phpunit/phpunit": "^10.5.35|^11.5.3|^12.0.1", "predis/predis": "^2.3|^3.0", "resend/resend-php": "^0.10.0", - "symfony/cache": "^7.2.0", - "symfony/http-client": "^7.2.0", - "symfony/psr-http-message-bridge": "^7.2.0", - "symfony/translation": "^7.2.0" + "symfony/cache": "^7.4.0|^8.0.0", + "symfony/http-client": "^7.4.0|^8.0.0", + "symfony/psr-http-message-bridge": "^7.4.0|^8.0.0", + "symfony/translation": "^7.4.0" }, "conflict": { "tightenco/collect": "<5.5.33" @@ -192,12 +192,12 @@ "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^7.2).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^7.2).", - "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.2).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.2).", - "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.2).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.2)." + "symfony/cache": "Required to PSR-6 cache bridge (^7.4|^8.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.4|^8.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.4|^8.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.4|^8.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.4|^8.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.4|^8.0)." }, "config": { "sort-packages": true, diff --git a/src/Illuminate/Cache/composer.json b/src/Illuminate/Cache/composer.json index dea22e5a6d83..07628f3c6ed9 100755 --- a/src/Illuminate/Cache/composer.json +++ b/src/Illuminate/Cache/composer.json @@ -40,7 +40,7 @@ "illuminate/database": "Required to use the database cache driver (^13.0).", "illuminate/filesystem": "Required to use the file cache driver (^13.0).", "illuminate/redis": "Required to use the redis cache driver (^13.0).", - "symfony/cache": "Required to use PSR-6 cache bridge (^7.2)." + "symfony/cache": "Required to use PSR-6 cache bridge (^7.4|^8.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Collections/composer.json b/src/Illuminate/Collections/composer.json index b7cad15cc091..965a8398cd6e 100644 --- a/src/Illuminate/Collections/composer.json +++ b/src/Illuminate/Collections/composer.json @@ -35,7 +35,7 @@ }, "suggest": { "illuminate/http": "Required to convert collections to API resources (^12.0).", - "symfony/var-dumper": "Required to use the dump method (^7.2)." + "symfony/var-dumper": "Required to use the dump method (^7.4|^8.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Console/Application.php b/src/Illuminate/Console/Application.php index 8a5755231b79..3db2e9bb3bfe 100755 --- a/src/Illuminate/Console/Application.php +++ b/src/Illuminate/Console/Application.php @@ -205,28 +205,14 @@ public function output() : ''; } - /** - * Add an array of commands to the console. - * - * @param array $commands - * @return void - */ - #[\Override] - public function addCommands(array $commands): void - { - foreach ($commands as $command) { - $this->add($command); - } - } - /** * Add a command to the console. * - * @param \Symfony\Component\Console\Command\Command $command + * @param \Symfony\Component\Console\Command\Command|callable $command * @return \Symfony\Component\Console\Command\Command|null */ #[\Override] - public function add(SymfonyCommand $command): ?SymfonyCommand + public function addCommand(SymfonyCommand|callable $command): ?SymfonyCommand { if ($command instanceof Command) { $command->setLaravel($this->laravel); @@ -238,12 +224,12 @@ public function add(SymfonyCommand $command): ?SymfonyCommand /** * Add the command to the parent instance. * - * @param \Symfony\Component\Console\Command\Command $command + * @param \Symfony\Component\Console\Command\Command|callable $command * @return \Symfony\Component\Console\Command\Command */ - protected function addToParent(SymfonyCommand $command) + protected function addToParent(SymfonyCommand|callable $command) { - return parent::add($command); + return parent::addCommand($command); } /** @@ -269,10 +255,10 @@ public function resolve($command) } if ($command instanceof Command) { - return $this->add($command); + return $this->addCommand($command); } - return $this->add($this->laravel->make($command)); + return $this->addCommand($this->laravel->make($command)); } /** diff --git a/src/Illuminate/Console/composer.json b/src/Illuminate/Console/composer.json index d7ccfaa2ed0f..4b8974ad8bdd 100755 --- a/src/Illuminate/Console/composer.json +++ b/src/Illuminate/Console/composer.json @@ -23,8 +23,8 @@ "illuminate/view": "^13.0", "laravel/prompts": "^0.3.0", "nunomaduro/termwind": "^2.0", - "symfony/console": "^7.2.0", - "symfony/process": "^7.2.0" + "symfony/console": "^7.4.0|^8.0.0", + "symfony/process": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { diff --git a/src/Illuminate/Cookie/composer.json b/src/Illuminate/Cookie/composer.json index 75ad9b0bef1c..ca7be9b040c5 100755 --- a/src/Illuminate/Cookie/composer.json +++ b/src/Illuminate/Cookie/composer.json @@ -20,8 +20,8 @@ "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0", "illuminate/support": "^13.0", - "symfony/http-foundation": "^7.2.0", - "symfony/http-kernel": "^7.2.0" + "symfony/http-foundation": "^7.4.0|^8.0.0", + "symfony/http-kernel": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { diff --git a/src/Illuminate/Database/composer.json b/src/Illuminate/Database/composer.json index 0ad4d12d8a05..a5ce5414590d 100644 --- a/src/Illuminate/Database/composer.json +++ b/src/Illuminate/Database/composer.json @@ -43,7 +43,7 @@ "illuminate/filesystem": "Required to use the migrations (^13.0).", "illuminate/http": "Required to convert Eloquent models to API resources (^13.0).", "illuminate/pagination": "Required to paginate the result set (^13.0).", - "symfony/finder": "Required to use Eloquent model factories (^7.2)." + "symfony/finder": "Required to use Eloquent model factories (^7.4|^8.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Filesystem/composer.json b/src/Illuminate/Filesystem/composer.json index 2f0edda1a1ef..13deb8c174fb 100644 --- a/src/Illuminate/Filesystem/composer.json +++ b/src/Illuminate/Filesystem/composer.json @@ -19,7 +19,7 @@ "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0", "illuminate/support": "^13.0", - "symfony/finder": "^7.2.0" + "symfony/finder": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { @@ -44,8 +44,8 @@ "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^7.2).", - "symfony/mime": "Required to enable support for guessing extensions (^7.2)." + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.4|^8.0).", + "symfony/mime": "Required to enable support for guessing extensions (^7.4|^8.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Http/composer.json b/src/Illuminate/Http/composer.json index 0aaf1f34e773..5c12169ddeb6 100755 --- a/src/Illuminate/Http/composer.json +++ b/src/Illuminate/Http/composer.json @@ -23,9 +23,9 @@ "illuminate/macroable": "^13.0", "illuminate/session": "^13.0", "illuminate/support": "^13.0", - "symfony/http-foundation": "^7.2.0", - "symfony/http-kernel": "^7.2.0", - "symfony/mime": "^7.2.0" + "symfony/http-foundation": "^7.4.0|^8.0.0", + "symfony/http-kernel": "^7.4.0|^8.0.0", + "symfony/mime": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index f834704a3600..20b22c2ab390 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -22,7 +22,7 @@ "illuminate/support": "^13.0", "league/commonmark": "^2.7", "psr/log": "^1.0|^2.0|^3.0", - "symfony/mailer": "^7.2.0", + "symfony/mailer": "^7.4.0|^8.0.0", "tijsverkoyen/css-to-inline-styles": "^2.2.5" }, "autoload": { @@ -38,9 +38,9 @@ "suggest": { "aws/aws-sdk-php": "Required to use the SES mail driver (^3.322.9).", "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", - "symfony/http-client": "Required to use the Symfony API mail transports (^7.2).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.2).", - "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.2)." + "symfony/http-client": "Required to use the Symfony API mail transports (^7.4|^8.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.4|^8.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.4|^8.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Process/composer.json b/src/Illuminate/Process/composer.json index 55bf46f2203d..b48f20d70fb5 100644 --- a/src/Illuminate/Process/composer.json +++ b/src/Illuminate/Process/composer.json @@ -19,7 +19,7 @@ "illuminate/contracts": "^13.0", "illuminate/macroable": "^13.0", "illuminate/support": "^13.0", - "symfony/process": "^7.2.0" + "symfony/process": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { diff --git a/src/Illuminate/Queue/composer.json b/src/Illuminate/Queue/composer.json index 12c8a2a0a771..61c652bfe38e 100644 --- a/src/Illuminate/Queue/composer.json +++ b/src/Illuminate/Queue/composer.json @@ -25,7 +25,7 @@ "illuminate/support": "^13.0", "laravel/serializable-closure": "^1.3|^2.0", "ramsey/uuid": "^4.7", - "symfony/process": "^7.2.0" + "symfony/process": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { diff --git a/src/Illuminate/Routing/composer.json b/src/Illuminate/Routing/composer.json index 3a54fba26192..d5f0cd50a1bb 100644 --- a/src/Illuminate/Routing/composer.json +++ b/src/Illuminate/Routing/composer.json @@ -25,9 +25,9 @@ "illuminate/pipeline": "^13.0", "illuminate/session": "^13.0", "illuminate/support": "^13.0", - "symfony/http-foundation": "^7.2.0", - "symfony/http-kernel": "^7.2.0", - "symfony/routing": "^7.2.0" + "symfony/http-foundation": "^7.4.0|^8.0.0", + "symfony/http-kernel": "^7.4.0|^8.0.0", + "symfony/routing": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { @@ -42,7 +42,7 @@ "suggest": { "illuminate/console": "Required to use the make commands (^13.0).", "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.2)." + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.4|^8.0)." }, "config": { "sort-packages": true, diff --git a/src/Illuminate/Session/composer.json b/src/Illuminate/Session/composer.json index 3b0cbfed6897..ac65e2df88ee 100755 --- a/src/Illuminate/Session/composer.json +++ b/src/Illuminate/Session/composer.json @@ -21,8 +21,8 @@ "illuminate/contracts": "^13.0", "illuminate/filesystem": "^13.0", "illuminate/support": "^13.0", - "symfony/finder": "^7.2.0", - "symfony/http-foundation": "^7.2.0" + "symfony/finder": "^7.4.0|^8.0.0", + "symfony/http-foundation": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { diff --git a/src/Illuminate/Support/composer.json b/src/Illuminate/Support/composer.json index 9032e8eda274..e1e435673099 100644 --- a/src/Illuminate/Support/composer.json +++ b/src/Illuminate/Support/composer.json @@ -52,9 +52,9 @@ "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.7).", "league/uri": "Required to use the Uri class (^7.5.1).", "ramsey/uuid": "Required to use Str::uuid() (^4.7).", - "symfony/process": "Required to use the Composer class (^7.2).", - "symfony/uid": "Required to use Str::ulid() (^7.2).", - "symfony/var-dumper": "Required to use the dd function (^7.2).", + "symfony/process": "Required to use the Composer class (^7.4|^8.0).", + "symfony/uid": "Required to use Str::ulid() (^7.4|^8.0).", + "symfony/var-dumper": "Required to use the dd function (^7.4|^8.0).", "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.6.1)." }, "config": { diff --git a/src/Illuminate/Validation/composer.json b/src/Illuminate/Validation/composer.json index fbf8110c008f..9429bfb62a01 100755 --- a/src/Illuminate/Validation/composer.json +++ b/src/Illuminate/Validation/composer.json @@ -25,8 +25,8 @@ "illuminate/macroable": "^13.0", "illuminate/support": "^13.0", "illuminate/translation": "^13.0", - "symfony/http-foundation": "^7.2", - "symfony/mime": "^7.2" + "symfony/http-foundation": "^7.4.0|^8.0.0", + "symfony/mime": "^7.4.0|^8.0.0" }, "autoload": { "psr-4": { From fa6f6e71904b0351b4640b6a266b9ffece7e33aa Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Thu, 19 Jun 2025 00:52:07 +0000 Subject: [PATCH 25/27] Apply fixes from StyleCI --- tests/Database/DatabaseEloquentModelTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index 6c00adc86295..03984ce60086 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -3406,6 +3406,7 @@ protected static function boot() } }; } + public function testUseCustomBuilderWithUseEloquentBuilderAttribute() { $model = new EloquentModelWithUseEloquentBuilderAttributeStub(); From 693bef8b26cf8fe85699e884425c0d9b3e5df67f Mon Sep 17 00:00:00 2001 From: Jonathan Goode Date: Wed, 2 Jul 2025 23:42:19 +0100 Subject: [PATCH 26/27] Change to hyphenate prefixes and cookie names (#56172) * Change to hyphenate prefixes * Use `Str::snake()` as intended --- config/cache.php | 2 +- config/database.php | 2 +- config/session.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/cache.php b/config/cache.php index f529e1e3ec74..c2d927d79978 100644 --- a/config/cache.php +++ b/config/cache.php @@ -103,6 +103,6 @@ | */ - 'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel'), '_').'_cache_'), + 'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-cache-'), ]; diff --git a/config/database.php b/config/database.php index 8a3b731fb52e..2c28fef7d038 100644 --- a/config/database.php +++ b/config/database.php @@ -148,7 +148,7 @@ 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), - 'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel'), '_').'_database_'), + 'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'), 'persistent' => env('REDIS_PERSISTENT', false), ], diff --git a/config/session.php b/config/session.php index 13d86a4ac63d..f348f5f8c2db 100644 --- a/config/session.php +++ b/config/session.php @@ -129,7 +129,7 @@ 'cookie' => env( 'SESSION_COOKIE', - Str::slug((string) env('APP_NAME', 'laravel'), '_').'_session' + Str::snake((string) env('APP_NAME', 'laravel')).'_session' ), /* From 7185379f2409032dcc9c3b7de9b169b0b4eaf67a Mon Sep 17 00:00:00 2001 From: Bert Date: Thu, 3 Jul 2025 01:00:53 +0200 Subject: [PATCH 27/27] pass exception (#56148) --- src/Illuminate/Queue/Events/JobAttempted.php | 6 +++--- src/Illuminate/Queue/Worker.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Queue/Events/JobAttempted.php b/src/Illuminate/Queue/Events/JobAttempted.php index b10c62903e77..a46acb61af98 100644 --- a/src/Illuminate/Queue/Events/JobAttempted.php +++ b/src/Illuminate/Queue/Events/JobAttempted.php @@ -9,12 +9,12 @@ class JobAttempted * * @param string $connectionName The connection name. * @param \Illuminate\Contracts\Queue\Job $job The job instance. - * @param bool $exceptionOccurred Indicates if an exception occurred while processing the job. + * @param \Throwable|null $exception The exception, if one occurred while processing the job. */ public function __construct( public $connectionName, public $job, - public $exceptionOccurred = false, + public $exception = null, ) { } @@ -25,6 +25,6 @@ public function __construct( */ public function successful(): bool { - return ! $this->job->hasFailed() && ! $this->exceptionOccurred; + return ! $this->job->hasFailed() && is_null($this->exception); } } diff --git a/src/Illuminate/Queue/Worker.php b/src/Illuminate/Queue/Worker.php index 83df07eac618..e69004c53dd2 100644 --- a/src/Illuminate/Queue/Worker.php +++ b/src/Illuminate/Queue/Worker.php @@ -445,12 +445,12 @@ public function process($connectionName, $job, WorkerOptions $options) $this->raiseAfterJobEvent($connectionName, $job); } catch (Throwable $e) { - $exceptionOccurred = true; + $exceptionOccurred = $e; $this->handleJobException($connectionName, $job, $options, $e); } finally { $this->events->dispatch(new JobAttempted( - $connectionName, $job, $exceptionOccurred ?? false + $connectionName, $job, $exceptionOccurred ?? null )); } }