How would one go about changing the statement mode for the laminas adapter driver pdo result? I see there is two class constants that define the statement mode, but there is no setter to allow modifying which mode the Result is to use. I’m having a hard time understanding why two modes are considered if there is no way to utilize:
I see it similarly to how you have already described it. There is actually no method to change Result::$statementMode. Since it is declared as protected, one can 't change this class member publicly. The only possibility I can think of off the top of my head is extending the result class.
<?php
declare(strict_types=1);
namespace Marcel\Db\Adapter\Driver\Pdo;
use Laminas\Db\Adapter\Driver\Pdo\Result;
class MyOwnSimpleResult extends Result
{
public function setStatementMode(string $statementMode): void
{
$this->statementMode = $statementMode;
}
}
$result = new Result();
$result->setStatementMode(Result::STATEMENT_MODE_SCROLLABLE);
$result->init(...);
The other way around would be changing the protected class member via reflection. However, both options look too complicated for me. It would actually be easier if there was a simple setter method. At the moment, I don’t see anything that could speak against it. Or am I missing something here? The Iterator interface does not implement any functionality, which is associated with a forward only functionality.
Yea, have been thinking the same. I suppose the cleanest way to test it will be via the event feature and just attach a listener and modify it via reflection.
So here is how I tackled it initially. The following is just the initial test code.
I created a new feature with a preInitialize method:
<?php
declare(strict_types=1);
namespace Axleus\Db\Feature;
use Axleus\Db\Feature\ScrollablePdoResult\Result;
use Laminas\Db\Adapter\Driver\Pdo\Pdo;
use Laminas\Db\TableGateway\Feature\AbstractFeature;
final class ScrollablePdoResultFeature extends AbstractFeature
{
public function preInitialize()
{
/** @var Pdo */
$driver = $this->tableGateway->getAdapter()->getDriver();
if (! $driver instanceof Pdo) {
return;
}
$resultPrototype = new Result();
$resultPrototype->setStatementMode(Result::STATEMENT_MODE_SCROLLABLE);
$driver->registerResultPrototype($resultPrototype);
}
}
And a subclassed Result class as mentioned by @ezkimo
<?php
declare(strict_types=1);
namespace Axleus\Db\Feature\ScrollablePdoResult;
use Axleus\Db\Exception\InvalidArgumentException;
use Laminas\Db\Adapter\Driver\Pdo;
use function get_class;
use function in_array;
final class Result extends Pdo\Result
{
private const ALLOWED_MODES = [
self::STATEMENT_MODE_SCROLLABLE,
self::STATEMENT_MODE_FORWARD
];
public function setStatementMode(string $mode): void
{
if (! in_array($mode, self::ALLOWED_MODES)) {
throw new InvalidArgumentException(
'$mode must be one of ' . get_class($this) . '::ALLOWED_MODES received: ' . $mode
);
}
$this->statementMode = $mode;
}
}
Usage is the same as any other laminas-db TableGateway feature.
@froschdesign is there any reason you can think of that this should not be done?