Skip to content

Commit

Permalink
fix failure when setting fetch mode before execute
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemo64 committed Mar 22, 2020
1 parent 5e724f4 commit 3de10b3
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 51 deletions.
17 changes: 16 additions & 1 deletion src/RdsDataStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Aws\RDSDataService\Exception\RDSDataServiceException;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType;

/**
Expand Down Expand Up @@ -42,6 +43,13 @@ class RdsDataStatement implements \IteratorAggregate, Statement
*/
private $sql;

/**
* Retain the fetch mode across results
*
* @var array
*/
private $fetchMode = [FetchMode::MIXED];

/**
* @var RdsDataResult
*/
Expand Down Expand Up @@ -78,7 +86,13 @@ public function columnCount(): int
*/
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null): bool
{
return $this->result->setFetchMode($fetchMode, $arg2, $arg3);
$this->fetchMode = func_get_args();

if ($this->result !== null) {
$this->result->setFetchMode(...$this->fetchMode);
}

return true;
}

/**
Expand Down Expand Up @@ -196,6 +210,7 @@ public function execute($params = null): bool
}

$this->result = new RdsDataResult($result, $this->dataConverter);
$this->result->setFetchMode(...$this->fetchMode);
return true;
} catch (RDSDataServiceException $exception) {
if ($exception->getAwsErrorCode() === 'BadRequestException') {
Expand Down
87 changes: 37 additions & 50 deletions tests/RdsDataConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,25 @@
namespace Nemo64\DbalRdsData\Tests;


use Aws\RDSDataService\RDSDataServiceClient;
use Aws\Result;
use Doctrine\DBAL\FetchMode;
use Nemo64\DbalRdsData\RdsDataConnection;
use PHPUnit\Framework\TestCase;

class RdsDataConnectionTest extends TestCase
{
private const DEFAULT_OPTIONS = [
'resourceArn' => 'resource_arm',
'secretArn' => 'secret_arm',
];

/**
* @var \PHPUnit\Framework\MockObject\MockObject|RDSDataServiceClient
*/
private $client;

private $expectedCalls = [
// ['executeStatement', ['options' => 'value'], 'returnValue']
];

/**
* @var RdsDataConnection
*/
private $connection;
use RdsDataServiceClientTrait;

protected function setUp()
{
$this->client = $this->createMock(RDSDataServiceClient::class);
$this->client->method('__call')->willReturnCallback(function ($methodName, $arguments) {
$nextCall = array_shift($this->expectedCalls);
$this->assertIsArray($nextCall, "there must be another call planned");
$this->assertEquals($nextCall[0], $methodName, "method call");
$this->assertEquals($nextCall[1], $arguments[0], "options of $methodName");
return $nextCall[2];
});

$this->connection = new RdsDataConnection(
$this->client,
self::DEFAULT_OPTIONS['resourceArn'],
self::DEFAULT_OPTIONS['secretArn'],
'db'
);
}

private function addClientCall(string $method, array $options, array $result)
{
$this->expectedCalls[] = [$method, $options, new Result($result)];
$this->createRdsDataServiceClient();
}

public function testSimpleQuery()
{
$this->addClientCall(
'executeStatement',
self::DEFAULT_OPTIONS + [
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'database' => 'db',
'continueAfterTimeout' => false,
'includeResultMetadata' => true,
Expand Down Expand Up @@ -88,15 +51,21 @@ public function testTransaction()
{
$this->addClientCall(
'beginTransaction',
self::DEFAULT_OPTIONS + ['database' => 'db'],
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'database' => 'db',
],
['transactionId' => '~~transaction id~~']
);
$this->assertTrue($this->connection->beginTransaction());
$this->assertEquals('~~transaction id~~', $this->connection->getTransactionId());

$this->addClientCall(
'executeStatement',
self::DEFAULT_OPTIONS + [
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'database' => 'db',
'continueAfterTimeout' => false,
'includeResultMetadata' => true,
Expand Down Expand Up @@ -125,7 +94,11 @@ public function testTransaction()

$this->addClientCall(
'commitTransaction',
self::DEFAULT_OPTIONS + ['transactionId' => '~~transaction id~~'],
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'transactionId' => '~~transaction id~~',
],
['transactionStatus' => 'cleaning up']
);
$this->assertTrue($this->connection->commit());
Expand All @@ -137,7 +110,11 @@ public function testRollBack()
{
$this->addClientCall(
'beginTransaction',
self::DEFAULT_OPTIONS + ['database' => 'db'],
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'database' => 'db',
],
['transactionId' => '~~transaction id~~']
);
$this->assertTrue($this->connection->beginTransaction());
Expand All @@ -146,7 +123,11 @@ public function testRollBack()

$this->addClientCall(
'rollbackTransaction',
self::DEFAULT_OPTIONS + ['transactionId' => '~~transaction id~~'],
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'transactionId' => '~~transaction id~~',
],
['transactionStatus' => 'cleaning up']
);
$this->assertTrue($this->connection->rollBack());
Expand All @@ -158,7 +139,9 @@ public function testUpdate()
{
$this->addClientCall(
'executeStatement',
self::DEFAULT_OPTIONS + [
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'database' => 'db',
'continueAfterTimeout' => false,
'includeResultMetadata' => true,
Expand All @@ -179,7 +162,9 @@ public function testParameters()
{
$this->addClientCall(
'executeStatement',
self::DEFAULT_OPTIONS + [
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'database' => 'db',
'continueAfterTimeout' => false,
'includeResultMetadata' => true,
Expand Down Expand Up @@ -222,7 +207,9 @@ public function testInsert()

$this->addClientCall(
'executeStatement',
self::DEFAULT_OPTIONS + [
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'database' => 'db',
'continueAfterTimeout' => false,
'includeResultMetadata' => true,
Expand Down
44 changes: 44 additions & 0 deletions tests/RdsDataServiceClientTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Nemo64\DbalRdsData\Tests;


use Aws\RDSDataService\RDSDataServiceClient;
use Aws\Result;
use Nemo64\DbalRdsData\RdsDataConnection;

trait RdsDataServiceClientTrait
{
/**
* @var \PHPUnit\Framework\MockObject\MockObject|RDSDataServiceClient
*/
private $client;

private $expectedCalls = [
// ['executeStatement', ['options' => 'value'], 'returnValue']
];

/**
* @var RdsDataConnection
*/
private $connection;

protected function createRdsDataServiceClient()
{
$this->client = $this->createMock(RDSDataServiceClient::class);
$this->client->method('__call')->willReturnCallback(function ($methodName, $arguments) {
$nextCall = array_shift($this->expectedCalls);
$this->assertIsArray($nextCall, "there must be another call planned");
$this->assertEquals($nextCall[0], $methodName, "method call");
$this->assertEquals($nextCall[1], $arguments[0], "options of $methodName");
return $nextCall[2];
});

$this->connection = new RdsDataConnection($this->client, 'arn:resource', 'arn:secret', 'db');
}

private function addClientCall(string $method, array $options, array $result)
{
$this->expectedCalls[] = [$method, $options, new Result($result)];
}
}
56 changes: 56 additions & 0 deletions tests/RdsDataStatementTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Nemo64\DbalRdsData\Tests;


use Doctrine\DBAL\FetchMode;
use Nemo64\DbalRdsData\RdsDataStatement;
use PHPUnit\Framework\TestCase;

class RdsDataStatementTest extends TestCase
{
use RdsDataServiceClientTrait;

public function setUp()
{
$this->createRdsDataServiceClient();
}

public function testRetainFetchMode()
{
foreach (range(1, 2) as $item) {
$this->addClientCall(
'executeStatement',
[
'resourceArn' => 'arn:resource',
'secretArn' => 'arn:secret',
'database' => 'db',
'continueAfterTimeout' => false,
'includeResultMetadata' => true,
'parameters' => [],
'resultSetOptions' => ['decimalReturnType' => 'STRING'],
'sql' => 'SELECT 1 AS id',
],
[
"columnMetadata" => [
["label" => "id"],
],
"numberOfRecordsUpdated" => 0,
"records" => [
[
["longValue" => 1],
],
],
]
);
}

$statement = new RdsDataStatement($this->connection, 'SELECT 1 AS id');

$statement->setFetchMode(FetchMode::NUMERIC);
$statement->execute();
$this->assertEquals([[1]], $statement->fetchAll());
$statement->execute();
$this->assertEquals([[1]], $statement->fetchAll());
}
}

0 comments on commit 3de10b3

Please sign in to comment.