Skip to content

Commit

Permalink
Fix getColumnName() with negative index
Browse files Browse the repository at this point in the history
  • Loading branch information
derrabus committed Aug 19, 2024
1 parent a41d81d commit d9ef290
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 107 deletions.
7 changes: 2 additions & 5 deletions src/Cache/ArrayResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,8 @@ public function columnCount(): int

public function getColumnName(int $index): string
{
if ($this->data === [] || $index > count($this->data[0])) {
throw InvalidColumnIndex::new($index);
}

return array_keys($this->data[0])[$index];
return array_keys($this->data[0] ?? [])[$index]
?? throw InvalidColumnIndex::new($index);
}

public function free(): void
Expand Down
15 changes: 9 additions & 6 deletions src/Driver/PDO/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use PDO;
use PDOException;
use PDOStatement;
use ValueError;

final class Result implements ResultInterface
{
Expand Down Expand Up @@ -78,15 +79,17 @@ public function getColumnName(int $index): string
{
try {
$meta = $this->statement->getColumnMeta($index);

if ($meta === false) {
throw InvalidColumnIndex::new($index);
}

return $meta['name'];
} catch (ValueError $exception) {
throw InvalidColumnIndex::new($index, $exception);
} catch (PDOException $exception) {
throw Exception::new($exception);
}

if ($meta === false) {
throw InvalidColumnIndex::new($index);
}

return $meta['name'];
}

public function free(): void
Expand Down
5 changes: 3 additions & 2 deletions src/Exception/InvalidColumnIndex.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

use Doctrine\DBAL\Exception;
use LogicException;
use Throwable;

use function sprintf;

/** @psalm-immutable */
final class InvalidColumnIndex extends LogicException implements Exception
{
public static function new(int $index): self
public static function new(int $index, ?Throwable $previous = null): self
{
return new self(sprintf('Invalid column index "%s".', $index));
return new self(sprintf('Invalid column index "%s".', $index), previous: $previous);
}
}
104 changes: 104 additions & 0 deletions tests/Cache/ArrayResultTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Tests\Cache;

use Doctrine\DBAL\Cache\ArrayResult;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;

use function array_values;

class ArrayResultTest extends TestCase
{
/** @var list<array<string, mixed>> */
private array $users = [
[
'username' => 'jwage',
'active' => true,
],
[
'username' => 'romanb',
'active' => false,
],
];

public function testCloseCursor(): void
{
$result = $this->createTestArrayResult();

self::assertSame(2, $result->rowCount());

$result->free();

self::assertSame(0, $result->rowCount());
}

public function testColumnCount(): void
{
$result = $this->createTestArrayResult();

self::assertSame(2, $result->columnCount());
}

public function testColumnNames(): void
{
$result = $this->createTestArrayResult();

self::assertSame('username', $result->getColumnName(0));
self::assertSame('active', $result->getColumnName(1));
}

#[TestWith([2])]
#[TestWith([-1])]
public function testInvalidColumnIndex(int $index): void
{
$result = $this->createTestArrayResult();
$this->expectException(InvalidColumnIndex::class);

$result->getColumnName($index);
}

public function testRowCount(): void
{
$statement = $this->createTestArrayResult();

self::assertSame(2, $statement->rowCount());
}

public function testFetchAssociative(): void
{
$result = $this->createTestArrayResult();

self::assertSame($this->users[0], $result->fetchAssociative());
}

public function testFetchNumeric(): void
{
$result = $this->createTestArrayResult();

self::assertSame(array_values($this->users[0]), $result->fetchNumeric());
}

public function testFetchOne(): void
{
$result = $this->createTestArrayResult();

self::assertSame('jwage', $result->fetchOne());
self::assertSame('romanb', $result->fetchOne());
}

public function testFetchAll(): void
{
$statement = $this->createTestArrayResult();

self::assertSame($this->users, $statement->fetchAllAssociative());
}

private function createTestArrayResult(): ArrayResult
{
return new ArrayResult($this->users);
}
}
92 changes: 0 additions & 92 deletions tests/Cache/ArrayStatementTest.php

This file was deleted.

7 changes: 5 additions & 2 deletions tests/Functional/ResultMetadataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use PHPUnit\Framework\Attributes\TestWith;

use function strtolower;

Expand Down Expand Up @@ -36,7 +37,9 @@ public function testColumnNameWithResults(): void
self::assertEquals('alternate_name', strtolower($result->getColumnName(1)));
}

public function testColumnNameWithInvalidIndex(): void
#[TestWith([2])]
#[TestWith([-1])]
public function testColumnNameWithInvalidIndex(int $index): void
{
$sql = 'SELECT test_int, test_int AS alternate_name FROM result_metadata_table';

Expand All @@ -47,7 +50,7 @@ public function testColumnNameWithInvalidIndex(): void

$this->expectException(InvalidColumnIndex::class);

$result->getColumnName(2);
$result->getColumnName($index);
}

public function testColumnNameWithoutResults(): void
Expand Down

0 comments on commit d9ef290

Please sign in to comment.