Skip to content

Commit 1a43d11

Browse files
authored
Added a way to retrieve the first column of the first row from a query. (#41858)
* Added a way to retrieve the first column of the first row from a query result. * styleci fixes
1 parent 76a158e commit 1a43d11

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

src/Illuminate/Database/Connection.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,33 @@ public function selectOne($query, $bindings = [], $useReadPdo = true)
334334
return array_shift($records);
335335
}
336336

337+
/**
338+
* Run a select statement and return the first column of the first row.
339+
*
340+
* @param string $query
341+
* @param array $bindings
342+
* @param bool $useReadPdo
343+
* @return mixed
344+
*
345+
* @throws MultipleColumnsSelectedException
346+
*/
347+
public function scalar($query, $bindings = [], $useReadPdo = true)
348+
{
349+
$record = $this->selectOne($query, $bindings, $useReadPdo);
350+
351+
if (is_null($record)) {
352+
return null;
353+
}
354+
355+
$record = (array) $record;
356+
357+
if (count($record) > 1) {
358+
throw new MultipleColumnsSelectedException;
359+
}
360+
361+
return reset($record);
362+
}
363+
337364
/**
338365
* Run a select statement against the database.
339366
*
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Illuminate\Database;
4+
5+
use RuntimeException;
6+
7+
class MultipleColumnsSelectedException extends RuntimeException
8+
{
9+
//
10+
}

tests/Database/DatabaseConnectionTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Illuminate\Database\Events\TransactionBeginning;
1212
use Illuminate\Database\Events\TransactionCommitted;
1313
use Illuminate\Database\Events\TransactionRolledBack;
14+
use Illuminate\Database\MultipleColumnsSelectedException;
1415
use Illuminate\Database\Query\Builder as BaseBuilder;
1516
use Illuminate\Database\Query\Grammars\Grammar;
1617
use Illuminate\Database\Query\Processors\Processor;
@@ -56,6 +57,28 @@ public function testSelectOneCallsSelectAndReturnsSingleResult()
5657
$this->assertSame('foo', $connection->selectOne('foo', ['bar' => 'baz']));
5758
}
5859

60+
public function testScalarCallsSelectOneAndReturnsSingleResult()
61+
{
62+
$connection = $this->getMockConnection(['selectOne']);
63+
$connection->expects($this->once())->method('selectOne')->with('select count(*) from tbl')->willReturn((object) ['count(*)' => 5]);
64+
$this->assertSame(5, $connection->scalar('select count(*) from tbl'));
65+
}
66+
67+
public function testScalarThrowsExceptionIfMultipleColumnsAreSelected()
68+
{
69+
$connection = $this->getMockConnection(['selectOne']);
70+
$connection->expects($this->once())->method('selectOne')->with('select a, b from tbl')->willReturn((object) ['a' => 'a', 'b' => 'b']);
71+
$this->expectException(MultipleColumnsSelectedException::class);
72+
$connection->scalar('select a, b from tbl');
73+
}
74+
75+
public function testScalarReturnsNullIfUnderlyingSelectReturnsNoRows()
76+
{
77+
$connection = $this->getMockConnection(['selectOne']);
78+
$connection->expects($this->once())->method('selectOne')->with('select foo from tbl where 0=1')->willReturn(null);
79+
$this->assertNull($connection->scalar('select foo from tbl where 0=1'));
80+
}
81+
5982
public function testSelectProperlyCallsPDO()
6083
{
6184
$pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock();

0 commit comments

Comments
 (0)