Skip to content

Commit 3de10b3

Browse files
committed
fix failure when setting fetch mode before execute
1 parent 5e724f4 commit 3de10b3

File tree

4 files changed

+153
-51
lines changed

4 files changed

+153
-51
lines changed

src/RdsDataStatement.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use Aws\RDSDataService\Exception\RDSDataServiceException;
77
use Doctrine\DBAL\Driver\Statement;
8+
use Doctrine\DBAL\FetchMode;
89
use Doctrine\DBAL\ParameterType;
910

1011
/**
@@ -42,6 +43,13 @@ class RdsDataStatement implements \IteratorAggregate, Statement
4243
*/
4344
private $sql;
4445

46+
/**
47+
* Retain the fetch mode across results
48+
*
49+
* @var array
50+
*/
51+
private $fetchMode = [FetchMode::MIXED];
52+
4553
/**
4654
* @var RdsDataResult
4755
*/
@@ -78,7 +86,13 @@ public function columnCount(): int
7886
*/
7987
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null): bool
8088
{
81-
return $this->result->setFetchMode($fetchMode, $arg2, $arg3);
89+
$this->fetchMode = func_get_args();
90+
91+
if ($this->result !== null) {
92+
$this->result->setFetchMode(...$this->fetchMode);
93+
}
94+
95+
return true;
8296
}
8397

8498
/**
@@ -196,6 +210,7 @@ public function execute($params = null): bool
196210
}
197211

198212
$this->result = new RdsDataResult($result, $this->dataConverter);
213+
$this->result->setFetchMode(...$this->fetchMode);
199214
return true;
200215
} catch (RDSDataServiceException $exception) {
201216
if ($exception->getAwsErrorCode() === 'BadRequestException') {

tests/RdsDataConnectionTest.php

Lines changed: 37 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,62 +3,25 @@
33
namespace Nemo64\DbalRdsData\Tests;
44

55

6-
use Aws\RDSDataService\RDSDataServiceClient;
7-
use Aws\Result;
86
use Doctrine\DBAL\FetchMode;
9-
use Nemo64\DbalRdsData\RdsDataConnection;
107
use PHPUnit\Framework\TestCase;
118

129
class RdsDataConnectionTest extends TestCase
1310
{
14-
private const DEFAULT_OPTIONS = [
15-
'resourceArn' => 'resource_arm',
16-
'secretArn' => 'secret_arm',
17-
];
18-
19-
/**
20-
* @var \PHPUnit\Framework\MockObject\MockObject|RDSDataServiceClient
21-
*/
22-
private $client;
23-
24-
private $expectedCalls = [
25-
// ['executeStatement', ['options' => 'value'], 'returnValue']
26-
];
27-
28-
/**
29-
* @var RdsDataConnection
30-
*/
31-
private $connection;
11+
use RdsDataServiceClientTrait;
3212

3313
protected function setUp()
3414
{
35-
$this->client = $this->createMock(RDSDataServiceClient::class);
36-
$this->client->method('__call')->willReturnCallback(function ($methodName, $arguments) {
37-
$nextCall = array_shift($this->expectedCalls);
38-
$this->assertIsArray($nextCall, "there must be another call planned");
39-
$this->assertEquals($nextCall[0], $methodName, "method call");
40-
$this->assertEquals($nextCall[1], $arguments[0], "options of $methodName");
41-
return $nextCall[2];
42-
});
43-
44-
$this->connection = new RdsDataConnection(
45-
$this->client,
46-
self::DEFAULT_OPTIONS['resourceArn'],
47-
self::DEFAULT_OPTIONS['secretArn'],
48-
'db'
49-
);
50-
}
51-
52-
private function addClientCall(string $method, array $options, array $result)
53-
{
54-
$this->expectedCalls[] = [$method, $options, new Result($result)];
15+
$this->createRdsDataServiceClient();
5516
}
5617

5718
public function testSimpleQuery()
5819
{
5920
$this->addClientCall(
6021
'executeStatement',
61-
self::DEFAULT_OPTIONS + [
22+
[
23+
'resourceArn' => 'arn:resource',
24+
'secretArn' => 'arn:secret',
6225
'database' => 'db',
6326
'continueAfterTimeout' => false,
6427
'includeResultMetadata' => true,
@@ -88,15 +51,21 @@ public function testTransaction()
8851
{
8952
$this->addClientCall(
9053
'beginTransaction',
91-
self::DEFAULT_OPTIONS + ['database' => 'db'],
54+
[
55+
'resourceArn' => 'arn:resource',
56+
'secretArn' => 'arn:secret',
57+
'database' => 'db',
58+
],
9259
['transactionId' => '~~transaction id~~']
9360
);
9461
$this->assertTrue($this->connection->beginTransaction());
9562
$this->assertEquals('~~transaction id~~', $this->connection->getTransactionId());
9663

9764
$this->addClientCall(
9865
'executeStatement',
99-
self::DEFAULT_OPTIONS + [
66+
[
67+
'resourceArn' => 'arn:resource',
68+
'secretArn' => 'arn:secret',
10069
'database' => 'db',
10170
'continueAfterTimeout' => false,
10271
'includeResultMetadata' => true,
@@ -125,7 +94,11 @@ public function testTransaction()
12594

12695
$this->addClientCall(
12796
'commitTransaction',
128-
self::DEFAULT_OPTIONS + ['transactionId' => '~~transaction id~~'],
97+
[
98+
'resourceArn' => 'arn:resource',
99+
'secretArn' => 'arn:secret',
100+
'transactionId' => '~~transaction id~~',
101+
],
129102
['transactionStatus' => 'cleaning up']
130103
);
131104
$this->assertTrue($this->connection->commit());
@@ -137,7 +110,11 @@ public function testRollBack()
137110
{
138111
$this->addClientCall(
139112
'beginTransaction',
140-
self::DEFAULT_OPTIONS + ['database' => 'db'],
113+
[
114+
'resourceArn' => 'arn:resource',
115+
'secretArn' => 'arn:secret',
116+
'database' => 'db',
117+
],
141118
['transactionId' => '~~transaction id~~']
142119
);
143120
$this->assertTrue($this->connection->beginTransaction());
@@ -146,7 +123,11 @@ public function testRollBack()
146123

147124
$this->addClientCall(
148125
'rollbackTransaction',
149-
self::DEFAULT_OPTIONS + ['transactionId' => '~~transaction id~~'],
126+
[
127+
'resourceArn' => 'arn:resource',
128+
'secretArn' => 'arn:secret',
129+
'transactionId' => '~~transaction id~~',
130+
],
150131
['transactionStatus' => 'cleaning up']
151132
);
152133
$this->assertTrue($this->connection->rollBack());
@@ -158,7 +139,9 @@ public function testUpdate()
158139
{
159140
$this->addClientCall(
160141
'executeStatement',
161-
self::DEFAULT_OPTIONS + [
142+
[
143+
'resourceArn' => 'arn:resource',
144+
'secretArn' => 'arn:secret',
162145
'database' => 'db',
163146
'continueAfterTimeout' => false,
164147
'includeResultMetadata' => true,
@@ -179,7 +162,9 @@ public function testParameters()
179162
{
180163
$this->addClientCall(
181164
'executeStatement',
182-
self::DEFAULT_OPTIONS + [
165+
[
166+
'resourceArn' => 'arn:resource',
167+
'secretArn' => 'arn:secret',
183168
'database' => 'db',
184169
'continueAfterTimeout' => false,
185170
'includeResultMetadata' => true,
@@ -222,7 +207,9 @@ public function testInsert()
222207

223208
$this->addClientCall(
224209
'executeStatement',
225-
self::DEFAULT_OPTIONS + [
210+
[
211+
'resourceArn' => 'arn:resource',
212+
'secretArn' => 'arn:secret',
226213
'database' => 'db',
227214
'continueAfterTimeout' => false,
228215
'includeResultMetadata' => true,

tests/RdsDataServiceClientTrait.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Nemo64\DbalRdsData\Tests;
4+
5+
6+
use Aws\RDSDataService\RDSDataServiceClient;
7+
use Aws\Result;
8+
use Nemo64\DbalRdsData\RdsDataConnection;
9+
10+
trait RdsDataServiceClientTrait
11+
{
12+
/**
13+
* @var \PHPUnit\Framework\MockObject\MockObject|RDSDataServiceClient
14+
*/
15+
private $client;
16+
17+
private $expectedCalls = [
18+
// ['executeStatement', ['options' => 'value'], 'returnValue']
19+
];
20+
21+
/**
22+
* @var RdsDataConnection
23+
*/
24+
private $connection;
25+
26+
protected function createRdsDataServiceClient()
27+
{
28+
$this->client = $this->createMock(RDSDataServiceClient::class);
29+
$this->client->method('__call')->willReturnCallback(function ($methodName, $arguments) {
30+
$nextCall = array_shift($this->expectedCalls);
31+
$this->assertIsArray($nextCall, "there must be another call planned");
32+
$this->assertEquals($nextCall[0], $methodName, "method call");
33+
$this->assertEquals($nextCall[1], $arguments[0], "options of $methodName");
34+
return $nextCall[2];
35+
});
36+
37+
$this->connection = new RdsDataConnection($this->client, 'arn:resource', 'arn:secret', 'db');
38+
}
39+
40+
private function addClientCall(string $method, array $options, array $result)
41+
{
42+
$this->expectedCalls[] = [$method, $options, new Result($result)];
43+
}
44+
}

tests/RdsDataStatementTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Nemo64\DbalRdsData\Tests;
4+
5+
6+
use Doctrine\DBAL\FetchMode;
7+
use Nemo64\DbalRdsData\RdsDataStatement;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class RdsDataStatementTest extends TestCase
11+
{
12+
use RdsDataServiceClientTrait;
13+
14+
public function setUp()
15+
{
16+
$this->createRdsDataServiceClient();
17+
}
18+
19+
public function testRetainFetchMode()
20+
{
21+
foreach (range(1, 2) as $item) {
22+
$this->addClientCall(
23+
'executeStatement',
24+
[
25+
'resourceArn' => 'arn:resource',
26+
'secretArn' => 'arn:secret',
27+
'database' => 'db',
28+
'continueAfterTimeout' => false,
29+
'includeResultMetadata' => true,
30+
'parameters' => [],
31+
'resultSetOptions' => ['decimalReturnType' => 'STRING'],
32+
'sql' => 'SELECT 1 AS id',
33+
],
34+
[
35+
"columnMetadata" => [
36+
["label" => "id"],
37+
],
38+
"numberOfRecordsUpdated" => 0,
39+
"records" => [
40+
[
41+
["longValue" => 1],
42+
],
43+
],
44+
]
45+
);
46+
}
47+
48+
$statement = new RdsDataStatement($this->connection, 'SELECT 1 AS id');
49+
50+
$statement->setFetchMode(FetchMode::NUMERIC);
51+
$statement->execute();
52+
$this->assertEquals([[1]], $statement->fetchAll());
53+
$statement->execute();
54+
$this->assertEquals([[1]], $statement->fetchAll());
55+
}
56+
}

0 commit comments

Comments
 (0)