Unverified Commit 9282211f authored by Alex Pott's avatar Alex Pott
Browse files

fix: #3552669 Error when fetching all query results as class instances

By: pjotr.savitski
By: quietone
By: godotislate
By: smustgrave
By: rhezios
By: alexpott
By: dpi
By: mondrake
(cherry picked from commit eeb5c183)
parent c8c3972c
Loading
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -80,7 +80,14 @@ public function fetch(FetchAs $mode, array $fetchOptions): array|object|int|floa
   * {@inheritdoc}
   */
  public function fetchAll(FetchAs $mode, array $fetchOptions): array {
    return $this->clientFetchAll($mode, $fetchOptions['column'] ?? $fetchOptions['class'] ?? NULL, $fetchOptions['constructor_args'] ?? NULL);
    return $this->clientFetchAll($mode, ...match ($mode) {
      FetchAs::Column => [$fetchOptions['column'] ?? NULL],
      FetchAs::ClassObject => [
        $fetchOptions['class'] ?? NULL,
        $fetchOptions['constructor_args'] ?? NULL,
      ],
      default => [],
    });
  }

}
+32 −0
Original line number Diff line number Diff line
@@ -173,6 +173,38 @@ public function testQueryFetchAllColumn(): void {
    $this->assertEquals($expected_result, $query_result, 'Returned the correct result.');
  }

  /**
   * Confirms that we can fetch all records as class instances explicitly.
   */
  public function testQueryFetchAllAsClassInstances(): void {
    $query = $this->connection->select(table: 'test', options: ['fetch' => FakeRecord::class]);
    $query->addField('test', 'name');
    $query->orderBy('name');
    $query_result = $query->execute()->fetchAll();

    $this->assertContainsOnlyInstancesOf(FakeRecord::class, $query_result);
    $names = array_map(fn(FakeRecord $record) => $record->name, $query_result);
    $expected_names = ['George', 'John', 'Paul', 'Ringo'];
    $this->assertEquals($expected_names, $names);
  }

  /**
   * Confirms that we can fetch class instances by setting fetch mode.
   */
  public function testQueryFetchAllAsFetchModeClassInstances(): void {
    $query = $this->connection->query('SELECT [name] FROM {test} ORDER BY [name]');
    $query->setFetchMode(FetchAs::ClassObject, FakeRecord::class, [
      // Test custom constructor arguments.
      'fakeArg' => 10,
    ]);

    $query_result = $query->fetchAll();

    $arrayed = array_map(fn (FakeRecord $record) => \get_object_vars($record), $query_result);
    $this->assertEquals(['George', 'John', 'Paul', 'Ringo'], array_column($arrayed, 'name'));
    $this->assertEquals([10, 10, 10, 10], array_column($arrayed, 'fakeArg'));
  }

  /**
   * Confirms that we can fetch an entire column of a result set at once.
   */