Skip to content

Commit 4043700

Browse files
authored
feature: getFieldList (#390)
closes #247
1 parent a885f49 commit 4043700

4 files changed

Lines changed: 96 additions & 1 deletion

File tree

src/Result/ResultSet.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,32 @@ public function asArray():array {
8585
);
8686
}
8787

88+
/** @return array<string> */
89+
public function getFieldList():array {
90+
$fieldCount = $this->statement->columnCount();
91+
$fieldList = [];
92+
for($i = 0; $i < $fieldCount; $i++) {
93+
$meta = $this->statement->getColumnMeta($i);
94+
$name = $meta["name"] ?? null;
95+
if(is_string($name)) {
96+
$fieldList[] = $name;
97+
}
98+
}
99+
100+
if(!empty($fieldList)) {
101+
return $fieldList;
102+
}
103+
104+
// Some drivers may not have the column meta - fetch the first row and reset.
105+
$currentIteratorIndex = $this->iteratorIndex;
106+
$this->rewind();
107+
$row = $this->fetch();
108+
$fieldList = $row?->getFieldList() ?? [];
109+
$this->rewind();
110+
$this->iteratorIndex = $currentIteratorIndex;
111+
return $fieldList;
112+
}
113+
88114
public function rewind():void {
89115
$this->statement->execute();
90116
$this->currentRow = null;

src/Result/Row.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ public function asArray():array {
6767
return $this->data;
6868
}
6969

70+
/** @return array<string> */
71+
public function getFieldList():array {
72+
return array_keys($this->data);
73+
}
74+
7075
public function contains(string $name):bool {
7176
return $this->__isset($name);
7277
}

test/phpunit/Result/ResultSetTest.php

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,44 @@ public function testCountTwice() {
8888
self::assertCount($count, $resultSet);
8989
}
9090

91+
public function testGetFieldList() {
92+
$resultSet = new ResultSet($this->getStatementMock());
93+
self::assertSame(
94+
["id", "name", "timestamp", "date"],
95+
$resultSet->getFieldList()
96+
);
97+
}
98+
99+
public function testGetFieldListFallbackToFirstRow() {
100+
$resultSet = new ResultSet($this->getStatementMock(false));
101+
self::assertSame(
102+
["id", "name", "timestamp", "date"],
103+
$resultSet->getFieldList()
104+
);
105+
}
106+
107+
public function testGetFieldListNoRows() {
108+
$statement = $this->createMock(PDOStatement::class);
109+
$statement->method("fetch")->willReturn(null);
110+
$statement->method("execute")->willReturn(true);
111+
$statement->method("columnCount")->willReturn(0);
112+
$resultSet = new ResultSet($statement);
113+
114+
self::assertSame([], $resultSet->getFieldList());
115+
}
116+
117+
public function testGetFieldListMidIteration() {
118+
$resultSet = new ResultSet($this->getStatementMock());
119+
$resultSet->rewind();
120+
$resultSet->next();
121+
122+
self::assertSame(
123+
["id", "name", "timestamp", "date"],
124+
$resultSet->getFieldList()
125+
);
126+
self::assertEquals(2, $resultSet->current()->id);
127+
}
128+
91129
public function testAccessByRowIndex() {
92130
$resultSet = new ResultSet($this->getStatementMock());
93131

@@ -137,12 +175,25 @@ public function testAsDateTime() {
137175
self::assertEquals("1988-04-05 17:24", $row->getDateTime("timestamp")->format("Y-m-d H:i"));
138176
}
139177

140-
private function getStatementMock():PDOStatement {
178+
private function getStatementMock(bool $withMetadata = true):PDOStatement {
141179
$statement = $this->createMock(PDOStatement::class);
142180
$statement->method("fetch")
143181
->will(self::returnCallback([$this, "getNextFakeData"]));
144182
$statement->method("execute")
145183
->willReturnCallback([$this, "rewindFakeData"]);
184+
if($withMetadata) {
185+
$statement->method("columnCount")
186+
->willReturn(count(self::FAKE_DATA[0]));
187+
$statement->method("getColumnMeta")
188+
->willReturnCallback(function(int $index):array {
189+
$name = array_keys(self::FAKE_DATA[0])[$index] ?? null;
190+
return ["name" => $name];
191+
});
192+
}
193+
else {
194+
$statement->method("columnCount")
195+
->willReturn(0);
196+
}
146197

147198
return $statement;
148199
}

test/phpunit/Result/RowTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@ public function testContains() {
5656
self::assertFalse($row->contains("col2"));
5757
}
5858

59+
public function testGetFieldList() {
60+
$row = new Row([
61+
"id" => 123,
62+
"name" => "Example",
63+
"enabled" => 1,
64+
]);
65+
66+
self::assertSame(
67+
["id", "name", "enabled"],
68+
$row->getFieldList()
69+
);
70+
}
71+
5972
/** @dataProvider data_getTestRow */
6073
public function testIteration(array $data) {
6174
$row = new Row($data);

0 commit comments

Comments
 (0)