Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions analyzer-baseline.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,12 @@ code = "missing-constant-type"
message = "Class constant `DEFAULT_SCHEMA` is missing a type hint."
count = 1

[[issues]]
file = "src/Metadata/Source/AbstractSource.php"
code = "unfulfilled-expect"
message = "This pragma was not used and may be removed."
count = 3

[[issues]]
file = "src/ResultSet/AbstractResultSet.php"
code = "imprecise-type"
Expand Down
19 changes: 15 additions & 4 deletions docs/book/table-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,30 @@ PhpDb\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter(
$table = new MyTableGateway(); // adapter is statically loaded
```

### MasterSlaveFeature
### PrimaryReplicaFeature

Use a master adapter for `insert()`, `update()`, and `delete()`, but switch
to a slave adapter for all `select()` operations:
Use a primary adapter for `insert()`, `update()`, and `delete()`, but switch
to a replica adapter for all `select()` operations:

```php
$table = new TableGateway(
'artist',
$adapter,
new Feature\MasterSlaveFeature($slaveAdapter)
new Feature\PrimaryReplicaFeature($replicaAdapter)
);
```

### MasterSlaveFeature

> ### Deprecated
>
> `MasterSlaveFeature` is deprecated as of 0.6.0 and will be removed in the next
> major release. Use [PrimaryReplicaFeature](#primaryreplicafeature) instead.

`MasterSlaveFeature` extends `PrimaryReplicaFeature` and retains the original
API; `getSlaveAdapter()` and `getSlaveSql()` proxy to `getReplicaAdapter()` and
`getReplicaSql()` respectively.

### MetadataFeature

Populate `TableGateway` with column information from a `Metadata` object. It
Expand Down
48 changes: 24 additions & 24 deletions lint-baseline.toml
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,12 @@ code = "yoda-conditions"
message = "Use Yoda condition style for safer comparisons"
count = 6

[[issues]]
file = "src/RowGateway/Feature/FeatureSet.php"
code = "too-many-methods"
message = "Class has too many methods."
count = 1

[[issues]]
file = "src/RowGateway/RowGateway.php"
code = "no-else-clause"
Expand Down Expand Up @@ -966,6 +972,24 @@ code = "too-many-methods"
message = "Class has too many methods."
count = 1

[[issues]]
file = "src/TableGateway/Feature/EventFeature.php"
code = "too-many-methods"
message = "Class has too many methods."
count = 1

[[issues]]
file = "src/TableGateway/Feature/FeatureSet.php"
code = "kan-defect"
message = "Class has a high kan defect score."
count = 1

[[issues]]
file = "src/TableGateway/Feature/FeatureSet.php"
code = "too-many-methods"
message = "Class has too many methods."
count = 1

[[issues]]
file = "src/TableGateway/TableGateway.php"
code = "no-shorthand-ternary"
Expand Down Expand Up @@ -8465,27 +8489,3 @@ file = "test/unit/TableGateway/TableGatewayTest.php"
code = "strict-assertions"
message = "Use strict assertions in PHPUnit tests."
count = 2

[[issues]]
file = "src/RowGateway/Feature/FeatureSet.php"
code = "too-many-methods"
message = 'Class has too many methods.'
count = 1

[[issues]]
file = "src/TableGateway/Feature/FeatureSet.php"
code = "kan-defect"
message = 'Class has a high kan defect score.'
count = 1

[[issues]]
file = "src/TableGateway/Feature/FeatureSet.php"
code = "too-many-methods"
message = 'Class has too many methods.'
count = 1

[[issues]]
file = "src/TableGateway/Feature/EventFeature.php"
code = "too-many-methods"
message = 'Class has too many methods.'
count = 1
72 changes: 11 additions & 61 deletions src/TableGateway/Feature/MasterSlaveFeature.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,80 +6,30 @@

use PhpDb\Adapter\AdapterInterface;
use PhpDb\Sql\Sql;
use PhpDb\TableGateway\Exception;

final class MasterSlaveFeature extends AbstractFeature
/**
* @deprecated Use PrimaryReplicaFeature instead. This class will be removed in the next major release.
*/
final class MasterSlaveFeature extends PrimaryReplicaFeature
{
protected AdapterInterface $slaveAdapter;

protected ?Sql $masterSql = null;

protected ?Sql $slaveSql = null;

public function __construct(AdapterInterface $slaveAdapter, ?Sql $slaveSql = null)
{
$this->slaveAdapter = $slaveAdapter;
if ($slaveSql instanceof Sql) {
$this->slaveSql = $slaveSql;
}
}

public function getSlaveAdapter(): AdapterInterface
{
return $this->slaveAdapter;
}

public function getSlaveSql(): ?Sql
{
return $this->slaveSql;
}

/**
* after initialization, retrieve the original adapter as "master"
*
* @throws Exception\RuntimeException
*/
public function postInitialize(): void
{
$masterSql = $this->tableGateway->sql;
if (! $masterSql instanceof Sql) {
throw new Exception\RuntimeException(
'The table gateway must be initialized with a Sql instance before this feature is applied.',
);
}

$this->masterSql = $masterSql;
if (null === $this->slaveSql) {
$this->slaveSql = new Sql(
$this->slaveAdapter,
$masterSql->getTable(),
);
}
parent::__construct($slaveAdapter, $slaveSql);
}

/**
* postSelect()
* Ensure to return to the master adapter
*
* @throws Exception\RuntimeException
* @deprecated Use PrimaryReplicaFeature::getReplicaAdapter() instead.
*/
public function postSelect(): void
public function getSlaveAdapter(): AdapterInterface
{
if (! $this->masterSql instanceof Sql) {
throw new Exception\RuntimeException(
'The master Sql instance is not available; postInitialize() has not been run.',
);
}

$this->tableGateway->sql = $this->masterSql;
return $this->getReplicaAdapter();
}

/**
* preSelect()
* Replace adapter with slave temporarily
* @deprecated Use PrimaryReplicaFeature::getReplicaSql() instead.
*/
public function preSelect(): void
public function getSlaveSql(): ?Sql
{
$this->tableGateway->sql = $this->slaveSql;
return $this->getReplicaSql();
}
}
85 changes: 85 additions & 0 deletions src/TableGateway/Feature/PrimaryReplicaFeature.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace PhpDb\TableGateway\Feature;

use PhpDb\Adapter\AdapterInterface;
use PhpDb\Sql\Sql;
use PhpDb\TableGateway\Exception;

class PrimaryReplicaFeature extends AbstractFeature
{
protected AdapterInterface $replicaAdapter;

protected ?Sql $primarySql = null;

protected ?Sql $replicaSql = null;

public function __construct(AdapterInterface $replicaAdapter, ?Sql $replicaSql = null)
{
$this->replicaAdapter = $replicaAdapter;
if ($replicaSql instanceof Sql) {
$this->replicaSql = $replicaSql;
}
}

public function getReplicaAdapter(): AdapterInterface
{
return $this->replicaAdapter;
}

public function getReplicaSql(): ?Sql
{
return $this->replicaSql;
}

/**
* after initialization, retrieve the original adapter as "primary"
*
* @throws Exception\RuntimeException
*/
public function postInitialize(): void
{
$primarySql = $this->tableGateway->sql;
if (! $primarySql instanceof Sql) {
throw new Exception\RuntimeException(
'The table gateway must be initialized with a Sql instance before this feature is applied.',
);
}

$this->primarySql = $primarySql;
if (null === $this->replicaSql) {
$this->replicaSql = new Sql(
$this->replicaAdapter,
$primarySql->getTable(),
);
}
}

/**
* postSelect()
* Ensure to return to the primary adapter
*
* @throws Exception\RuntimeException
*/
public function postSelect(): void
{
if (! $this->primarySql instanceof Sql) {
throw new Exception\RuntimeException(
'The primary Sql instance is not available; postInitialize() has not been run.',
);
}

$this->tableGateway->sql = $this->primarySql;
}

/**
* preSelect()
* Replace adapter with replica temporarily
*/
public function preSelect(): void
{
$this->tableGateway->sql = $this->replicaSql;
}
}
12 changes: 6 additions & 6 deletions test/unit/TableGateway/Feature/FeatureSetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
use PhpDb\Metadata\Object\ConstraintObject;
use PhpDb\TableGateway\AbstractTableGateway;
use PhpDb\TableGateway\Feature\FeatureSet;
use PhpDb\TableGateway\Feature\MasterSlaveFeature;
use PhpDb\TableGateway\Feature\MetadataFeature;
use PhpDb\TableGateway\Feature\PrimaryReplicaFeature;
use PhpDb\TableGateway\Feature\SequenceFeature;
use PhpDbTest\TableGateway\Feature\TestAsset\TestTableGatewayFeature;
use PHPUnit\Framework\Attributes\CoversMethod;
Expand Down Expand Up @@ -68,17 +68,17 @@ public function addFeatureThatFeatureDoesNotHaveTableGatewayButFeatureSetHas():
$mockMasterAdapter->expects($this->any())->method('getDriver')->willReturn($mockDriver);
$mockMasterAdapter->expects($this->any())->method('getPlatform')->willReturn(new Sql92());

$mockSlaveAdapter = $this->getMockBuilder(AdapterInterface::class)->getMock();
$mockReplicaAdapter = $this->getMockBuilder(AdapterInterface::class)->getMock();

$mockStatement = $this->getMockBuilder(StatementInterface::class)->getMock();
$mockDriver = $this->getMockBuilder(DriverInterface::class)->getMock();
$mockDriver->expects($this->any())->method('createStatement')->willReturn($mockStatement);
$mockSlaveAdapter->expects($this->any())->method('getDriver')->willReturn($mockDriver);
$mockSlaveAdapter->expects($this->any())->method('getPlatform')->willReturn(new Sql92());
$mockReplicaAdapter->expects($this->any())->method('getDriver')->willReturn($mockDriver);
$mockReplicaAdapter->expects($this->any())->method('getPlatform')->willReturn(new Sql92());

$tableGatewayMock = $this->getMockBuilder(AbstractTableGateway::class)->onlyMethods([])->getMock();

$feature = new MasterSlaveFeature($mockSlaveAdapter);
$feature = new PrimaryReplicaFeature($mockReplicaAdapter);

$featureSet = new FeatureSet();
$featureSet->setTableGateway($tableGatewayMock);
Expand Down Expand Up @@ -132,7 +132,7 @@ public function applyCallsMethodOnFeatures(): void
->disableOriginalConstructor()
->getMock();

$feature = new MasterSlaveFeature(
$feature = new PrimaryReplicaFeature(
$this->getMockBuilder(AdapterInterface::class)->getMock(),
);

Expand Down
Loading
Loading