From b760e6180015eae01f584f0c82e789cfb7aadd16 Mon Sep 17 00:00:00 2001 From: Istvan Palinkas Date: Wed, 29 Mar 2023 15:12:05 +0200 Subject: [PATCH] [10.x] Add `selectResultsets` to database Connection (#46592) * add `selectResultsets` to database Connection * formatting --------- Co-authored-by: Taylor Otwell --- src/Illuminate/Database/Connection.php | 33 +++++++++++++++++++++++ tests/Database/DatabaseConnectionTest.php | 29 ++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php index a45c563458ad..b9c8e16710be 100755 --- a/src/Illuminate/Database/Connection.php +++ b/src/Illuminate/Database/Connection.php @@ -422,6 +422,39 @@ public function select($query, $bindings = [], $useReadPdo = true) }); } + /** + * Run a select statement against the database and returns all of the result sets. + * + * @param string $query + * @param array $bindings + * @param bool $useReadPdo + * @return array + */ + public function selectResultSets($query, $bindings = [], $useReadPdo = true) + { + return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { + if ($this->pretending()) { + return []; + } + + $statement = $this->prepared( + $this->getPdoForSelect($useReadPdo)->prepare($query) + ); + + $this->bindValues($statement, $this->prepareBindings($bindings)); + + $statement->execute(); + + $sets = []; + + do { + $sets[] = $statement->fetchAll(); + } while ($statement->nextRowset()); + + return $sets; + }); + } + /** * Run a select statement against the database and returns a generator. * diff --git a/tests/Database/DatabaseConnectionTest.php b/tests/Database/DatabaseConnectionTest.php index 5b21b36fe416..776e17ed78d7 100755 --- a/tests/Database/DatabaseConnectionTest.php +++ b/tests/Database/DatabaseConnectionTest.php @@ -104,6 +104,35 @@ public function testSelectProperlyCallsPDO() $this->assertIsNumeric($log[0]['time']); } + public function testSelectResultsetsReturnsMultipleRowset() + { + $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock(); + $writePdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock(); + $writePdo->expects($this->never())->method('prepare'); + $statement = $this->getMockBuilder('PDOStatement') + ->onlyMethods(['setFetchMode', 'execute', 'fetchAll', 'bindValue', 'nextRowset']) + ->getMock(); + $statement->expects($this->once())->method('setFetchMode'); + $statement->expects($this->once())->method('bindValue')->with(1, 'foo', 2); + $statement->expects($this->once())->method('execute'); + $statement->expects($this->atLeastOnce())->method('fetchAll')->willReturn(['boom']); + $statement->expects($this->atLeastOnce())->method('nextRowset')->will($this->returnCallback(function () { + static $i = 1; + + return ++$i <= 2; + })); + $pdo->expects($this->once())->method('prepare')->with('CALL a_procedure(?)')->willReturn($statement); + $mock = $this->getMockConnection(['prepareBindings'], $writePdo); + $mock->setReadPdo($pdo); + $mock->expects($this->once())->method('prepareBindings')->with($this->equalTo(['foo']))->willReturn(['foo']); + $results = $mock->selectResultsets('CALL a_procedure(?)', ['foo']); + $this->assertEquals([['boom'], ['boom']], $results); + $log = $mock->getQueryLog(); + $this->assertSame('CALL a_procedure(?)', $log[0]['query']); + $this->assertEquals(['foo'], $log[0]['bindings']); + $this->assertIsNumeric($log[0]['time']); + } + public function testInsertCallsTheStatementMethod() { $connection = $this->getMockConnection(['statement']);