Introduce Statement::fetchFirstColumn()

parent 5e8192df
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
1. The `FetchMode` class and the `setFetchMode()` method of the `Connection` and `Statement` interfaces are deprecated. 1. The `FetchMode` class and the `setFetchMode()` method of the `Connection` and `Statement` interfaces are deprecated.
2. The `Statement::fetch()` method is deprecated in favor of `fetchNumeric()`, `fetchAssociative()` and `fetchOne()`. 2. The `Statement::fetch()` method is deprecated in favor of `fetchNumeric()`, `fetchAssociative()` and `fetchOne()`.
3. The `Statement::fetchAll()` method is deprecated in favor of `fetchAllNumeric()` and `fetchAllAssociative()`. There is no currently replacement for `Statement::fetchAll(FETCH_MODE::COLUMN)`. In a future major version, `fetchColumn()` will be used as a replacement. 3. The `Statement::fetchAll()` method is deprecated in favor of `fetchAllNumeric()`, `fetchAllAssociative()` and `fetchFirstColumn()`.
4. The `Statement::fetchColumn()` method is deprecated in favor of `fetchOne()`. 4. The `Statement::fetchColumn()` method is deprecated in favor of `fetchOne()`.
5. The `Connection::fetchArray()` and `fetchAssoc()` method are deprecated in favor of `fetchNumeric()` and `fetchAssociative()` respectively. 5. The `Connection::fetchArray()` and `fetchAssoc()` method are deprecated in favor of `fetchNumeric()` and `fetchAssociative()` respectively.
6. The `StatementIterator` class and the usage of a `Statement` object as `Traversable` is deprecated in favor of `iterateNumeric()`, `iterateAssociative()` and `iterateColumn()`. 6. The `StatementIterator` class and the usage of a `Statement` object as `Traversable` is deprecated in favor of `iterateNumeric()`, `iterateAssociative()` and `iterateColumn()`.
......
...@@ -201,6 +201,14 @@ class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompa ...@@ -201,6 +201,14 @@ class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompa
return FetchUtils::fetchAllAssociative($this); return FetchUtils::fetchAllAssociative($this);
} }
/**
* {@inheritdoc}
*/
public function fetchFirstColumn() : array
{
return FetchUtils::fetchFirstColumn($this);
}
/** /**
* @return mixed|false * @return mixed|false
*/ */
......
...@@ -277,6 +277,14 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -277,6 +277,14 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
return $this->data; return $this->data;
} }
/**
* {@inheritdoc}
*/
public function fetchFirstColumn() : array
{
return FetchUtils::fetchFirstColumn($this);
}
/** /**
* Returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement * Returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
* executed by the corresponding object. * executed by the corresponding object.
......
...@@ -991,6 +991,32 @@ class Connection implements DriverConnection ...@@ -991,6 +991,32 @@ class Connection implements DriverConnection
} }
} }
/**
* Prepares and executes an SQL query and returns the result as an array of the first column values.
*
* @param string $query The SQL query.
* @param array<int, mixed>|array<string, mixed> $params The query parameters.
* @param array<int, int|string>|array<string, int|string> $types The query parameter types.
*
* @return array<int,mixed>
*
* @throws DBALException
*/
public function fetchFirstColumn(string $query, array $params = [], array $types = []) : array
{
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
return $stmt->fetchFirstColumn();
}
return $stmt->fetchAll(FetchMode::COLUMN);
} catch (Throwable $e) {
throw DBALException::driverExceptionDuringQuery($this->_driver, $e, $query);
}
}
/** /**
* Prepares and executes an SQL query and returns the result as an iterator over rows represented as numeric arrays. * Prepares and executes an SQL query and returns the result as an iterator over rows represented as numeric arrays.
* *
......
...@@ -58,4 +58,20 @@ final class FetchUtils ...@@ -58,4 +58,20 @@ final class FetchUtils
return $rows; return $rows;
} }
/**
* @return array<int,mixed>
*
* @throws DriverException
*/
public static function fetchFirstColumn(ResultStatement $stmt) : array
{
$rows = [];
while (($row = $stmt->fetchOne()) !== false) {
$rows[] = $row;
}
return $rows;
}
} }
...@@ -408,6 +408,14 @@ class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleRes ...@@ -408,6 +408,14 @@ class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleRes
return FetchUtils::fetchAllAssociative($this); return FetchUtils::fetchAllAssociative($this);
} }
/**
* {@inheritdoc}
*/
public function fetchFirstColumn() : array
{
return FetchUtils::fetchFirstColumn($this);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -467,6 +467,14 @@ class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatible ...@@ -467,6 +467,14 @@ class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatible
return FetchUtils::fetchAllAssociative($this); return FetchUtils::fetchAllAssociative($this);
} }
/**
* {@inheritdoc}
*/
public function fetchFirstColumn() : array
{
return FetchUtils::fetchFirstColumn($this);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -591,6 +591,14 @@ class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleRe ...@@ -591,6 +591,14 @@ class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleRe
return $this->doFetchAll(OCI_ASSOC, OCI_FETCHSTATEMENT_BY_ROW); return $this->doFetchAll(OCI_ASSOC, OCI_FETCHSTATEMENT_BY_ROW);
} }
/**
* {@inheritdoc}
*/
public function fetchFirstColumn() : array
{
return $this->doFetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_COLUMN)[0];
}
/** /**
* @return mixed|false * @return mixed|false
*/ */
......
...@@ -240,6 +240,14 @@ class PDOStatement extends \PDOStatement implements Statement, ForwardCompatible ...@@ -240,6 +240,14 @@ class PDOStatement extends \PDOStatement implements Statement, ForwardCompatible
return $this->fetchAll(PDO::FETCH_ASSOC); return $this->fetchAll(PDO::FETCH_ASSOC);
} }
/**
* {@inheritdoc}
*/
public function fetchFirstColumn() : array
{
return $this->fetchAll(PDO::FETCH_COLUMN);
}
/** /**
* Converts DBAL parameter type to PDO parameter type * Converts DBAL parameter type to PDO parameter type
* *
......
...@@ -368,6 +368,16 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompa ...@@ -368,6 +368,16 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompa
return FetchUtils::fetchAllAssociative($this); return FetchUtils::fetchAllAssociative($this);
} }
/**
* @return array<int,mixed>
*
* @throws DriverException
*/
public function fetchFirstColumn() : array
{
return FetchUtils::fetchFirstColumn($this);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -476,6 +476,14 @@ class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatible ...@@ -476,6 +476,14 @@ class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatible
return FetchUtils::fetchAllAssociative($this); return FetchUtils::fetchAllAssociative($this);
} }
/**
* {@inheritdoc}
*/
public function fetchFirstColumn() : array
{
return FetchUtils::fetchFirstColumn($this);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -56,4 +56,13 @@ interface ResultStatement extends BaseResultStatement ...@@ -56,4 +56,13 @@ interface ResultStatement extends BaseResultStatement
* @throws DriverException * @throws DriverException
*/ */
public function fetchAllAssociative() : array; public function fetchAllAssociative() : array;
/**
* Returns an array containing the values of the first column of the result set.
*
* @return array<int,mixed>
*
* @throws DriverException
*/
public function fetchFirstColumn() : array;
} }
...@@ -255,6 +255,20 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -255,6 +255,20 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
return $this->fixResultSet($data, true, true); return $this->fixResultSet($data, true, true);
} }
/**
* {@inheritdoc}
*/
public function fetchFirstColumn() : array
{
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
$data = $this->stmt->fetchFirstColumn();
} else {
$data = $this->stmt->fetchAll(FetchMode::COLUMN);
}
return $this->fixResultSet($data, true, false);
}
/** /**
* @param mixed $result * @param mixed $result
* *
......
...@@ -370,6 +370,24 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -370,6 +370,24 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
} }
} }
/**
* {@inheritdoc}
*
* @throws DBALException
*/
public function fetchFirstColumn() : array
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
return $this->stmt->fetchFirstColumn();
}
return $this->stmt->fetchAll(FetchMode::COLUMN);
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
}
/** /**
* {@inheritDoc} * {@inheritDoc}
* *
......
...@@ -76,6 +76,15 @@ class FetchTest extends DbalFunctionalTestCase ...@@ -76,6 +76,15 @@ class FetchTest extends DbalFunctionalTestCase
], $this->connection->fetchAllAssociative($this->query)); ], $this->connection->fetchAllAssociative($this->query));
} }
public function testFetchFirstColumn() : void
{
self::assertEquals([
'foo',
'bar',
'baz',
], $this->connection->fetchFirstColumn($this->query));
}
public function testIterateNumeric() : void public function testIterateNumeric() : void
{ {
self::assertEquals([ self::assertEquals([
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment