Skip to content

Commit bbf075c

Browse files
committed
Merge upstream/0.6.x into test/adapter-coverage-100
Resolve conflicts and reconcile with upstream API changes (PR php-db#144 phpstan-type Profiler, PR php-db#145 provide-driver-defaults): - Profiler.php: take upstream's phpstan-typed version (supersedes PR's dead-code pass) - AdapterInterfaceDelegatorTest: union of both test sets; keep PR's #[Group]/ #[CoversMethod] plus upstream's testDelegatorWithPluginManager - ConnectionTest: keep upstream's testResource and the PR's real testConstructorWithPdoResourceSetsConnected (drop skipped placeholder) - Remove getDatabasePlatformName from test assets (API method removed upstream) - Rewrite TestPdoWithFeatures constructor to set properties directly (AbstractPdo constructor removed upstream) - Drop obsolete testCloneWithNullParameterContainerDoesNotClone (Statement parameter container is now non-nullable) - Remove invalid #[CoversMethod(...'__construct')] attributes in ConnectionTest and PdoTest that were marking tests risky and discarding coverage Suite: 1444 tests pass, PHPStan clean, PHPCS clean, 99.94% line coverage.
2 parents e6f69c2 + 81844a5 commit bbf075c

17 files changed

Lines changed: 147 additions & 154 deletions

phpstan-baseline.neon

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ parameters:
66
count: 1
77
path: src/Sql/AbstractSql.php
88

9-
-
10-
message: '#^Cannot call method getAttribute\(\) on resource\.$#'
11-
identifier: method.nonObject
12-
count: 1
13-
path: test/unit/Adapter/Driver/Pdo/TestAsset/TestPdo.php
14-
159
-
1610
message: '#^Parameter \#1 \$attribute \(string\) of method PhpDbTest\\Adapter\\Driver\\TestAsset\\PdoMock\:\:getAttribute\(\) should be compatible with parameter \$attribute \(int\) of method PDO\:\:getAttribute\(\)$#'
1711
identifier: method.childParameterType

src/Adapter/Driver/DriverInterface.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ interface DriverInterface
1010
{
1111
public const PARAMETERIZATION_POSITIONAL = 'positional';
1212
public const PARAMETERIZATION_NAMED = 'named';
13-
public const NAME_FORMAT_CAMELCASE = 'camelCase';
14-
public const NAME_FORMAT_NATURAL = 'natural';
15-
16-
/** Get database platform name */
17-
public function getDatabasePlatformName(string $nameFormat = DriverInterface::NAME_FORMAT_CAMELCASE): string;
1813

1914
/**
2015
* Check environment

src/Adapter/Driver/Pdo/AbstractPdo.php

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use Override;
88
use PDO;
99
use PDOStatement;
10-
use PhpDb\Adapter\Driver\ConnectionInterface;
11-
use PhpDb\Adapter\Driver\Feature\DriverFeatureProviderInterface;
10+
use PhpDb\Adapter\Driver\AbstractConnection;
11+
use PhpDb\Adapter\Driver\PdoConnectionInterface;
1212
use PhpDb\Adapter\Driver\PdoDriverAwareInterface;
1313
use PhpDb\Adapter\Driver\PdoDriverInterface;
1414
use PhpDb\Adapter\Driver\ResultInterface;
@@ -27,26 +27,14 @@
2727

2828
abstract class AbstractPdo implements PdoDriverInterface, ProfilerAwareInterface
2929
{
30-
/** @internal */
31-
protected ?ProfilerInterface $profiler;
30+
protected (PdoConnectionInterface&AbstractConnection&PdoDriverAwareInterface)|PDO $connection;
3231

33-
public function __construct(
34-
protected AbstractPdoConnection|PDO $connection,
35-
protected StatementInterface&PdoDriverAwareInterface $statementPrototype,
36-
protected ResultInterface $resultPrototype,
37-
array $features = [],
38-
) {
39-
if ($this->connection instanceof PdoDriverAwareInterface) {
40-
$this->connection->setDriver($this);
41-
}
32+
protected StatementInterface&PdoDriverAwareInterface $statementPrototype;
4233

43-
$this->statementPrototype->setDriver($this);
34+
protected ResultInterface $resultPrototype;
4435

45-
// $features is not constructor promoted because $this->features is defined in the trait
46-
if ($features !== [] && $this instanceof DriverFeatureProviderInterface) {
47-
$this->addFeatures($features);
48-
}
49-
}
36+
/** @internal */
37+
protected ?ProfilerInterface $profiler;
5038

5139
#[Override]
5240
public function setProfiler(ProfilerInterface $profiler): ProfilerAwareInterface
@@ -83,7 +71,7 @@ public function checkEnvironment(): bool
8371
}
8472

8573
#[Override]
86-
public function getConnection(): ConnectionInterface
74+
public function getConnection(): PdoConnectionInterface
8775
{
8876
return $this->connection;
8977
}

src/Adapter/Driver/Pdo/AbstractPdoConnection.php

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use PhpDb\Adapter\Exception;
1717
use PhpDb\Adapter\Exception\RuntimeException;
1818

19-
use function is_array;
2019
use function strtolower;
2120

2221
abstract class AbstractPdoConnection extends AbstractConnection implements
@@ -30,21 +29,6 @@ abstract class AbstractPdoConnection extends AbstractConnection implements
3029
/** @var ?PDO $resource */
3130
protected $resource;
3231

33-
/**
34-
* Constructor
35-
*
36-
* @throws Exception\InvalidArgumentException
37-
*/
38-
public function __construct(
39-
PDO|array $connectionParameters
40-
) {
41-
if (is_array($connectionParameters)) {
42-
$this->setConnectionParameters($connectionParameters);
43-
} elseif ($connectionParameters instanceof PDO) {
44-
$this->setResource($connectionParameters);
45-
}
46-
}
47-
4832
#[Override]
4933
public function setDriver(PdoDriverInterface $driver): PdoDriverAwareInterface
5034
{

src/Adapter/Driver/Pdo/Statement.php

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class Statement implements StatementInterface, PdoDriverAwareInterface, Profiler
4444
protected bool $isPrepared = false;
4545

4646
public function __construct(
47-
protected ?ParameterContainer $parameterContainer = null,
47+
protected ParameterContainer $parameterContainer = new ParameterContainer(),
4848
protected array $options = [],
4949
) {
5050
}
@@ -114,7 +114,7 @@ public function setParameterContainer(ParameterContainer $parameterContainer): S
114114
#[Override]
115115
public function getParameterContainer(): ParameterContainer
116116
{
117-
return $this->parameterContainer ??= new ParameterContainer();
117+
return $this->parameterContainer;
118118
}
119119

120120
/** @throws Exception\RuntimeException */
@@ -156,13 +156,9 @@ public function execute(null|array|ParameterContainer $parameters = null): ?Resu
156156
}
157157

158158
/** START Standard ParameterContainer Merging Block */
159-
if (! $this->parameterContainer instanceof ParameterContainer) {
160-
if ($parameters instanceof ParameterContainer) {
161-
$this->parameterContainer = $parameters;
162-
$parameters = null;
163-
} else {
164-
$this->parameterContainer = new ParameterContainer();
165-
}
159+
if ($parameters instanceof ParameterContainer) {
160+
$this->parameterContainer = $parameters;
161+
$parameters = null;
166162
}
167163

168164
if (is_array($parameters)) {
@@ -247,11 +243,9 @@ protected function bindParametersFromContainer(): void
247243
/** Perform a deep clone */
248244
public function __clone(): void
249245
{
250-
$this->isPrepared = false;
251-
$this->parametersBound = false;
252-
$this->resource = null;
253-
if ($this->parameterContainer) {
254-
$this->parameterContainer = clone $this->parameterContainer;
255-
}
246+
$this->isPrepared = false;
247+
$this->parametersBound = false;
248+
$this->resource = null;
249+
$this->parameterContainer = clone $this->parameterContainer;
256250
}
257251
}

src/Adapter/Driver/PdoConnectionInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace PhpDb\Adapter\Driver;
66

7-
interface PdoConnectionInterface
7+
interface PdoConnectionInterface extends ConnectionInterface
88
{
99
public function getDsn(): string;
1010
}

src/Adapter/Profiler/Profiler.php

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,36 @@
55
namespace PhpDb\Adapter\Profiler;
66

77
use PhpDb\Adapter\Exception;
8+
use PhpDb\Adapter\Exception\InvalidArgumentException;
9+
use PhpDb\Adapter\ParameterContainer;
810
use PhpDb\Adapter\StatementContainerInterface;
911

1012
use function end;
13+
use function is_string;
1114
use function microtime;
1215

16+
/**
17+
* @phpstan-type ProfileShape array{
18+
* sql: string,
19+
* parameters: ParameterContainer|null,
20+
* start: float,
21+
* end: float|null,
22+
* elapse: float|null,
23+
* }
24+
* @phpstan-type ProfilesShape ProfileShape[]
25+
*/
1326
class Profiler implements ProfilerInterface
1427
{
15-
/** @var array */
28+
/** @var ProfilesShape */
1629
protected $profiles = [];
1730

1831
/** @var int */
1932
protected $currentIndex = 0;
2033

21-
/** @return $this Provides a fluent interface */
34+
/**
35+
* @throws InvalidArgumentException
36+
* @return $this Provides a fluent interface
37+
*/
2238
public function profilerStart(string|StatementContainerInterface $target): ProfilerInterface
2339
{
2440
$profileInformation = [
@@ -28,14 +44,15 @@ public function profilerStart(string|StatementContainerInterface $target): Profi
2844
'end' => null,
2945
'elapse' => null,
3046
];
31-
if ($target instanceof StatementContainerInterface) {
47+
48+
if (is_string($target)) {
49+
$profileInformation['sql'] = $target;
50+
} else {
3251
$profileInformation['sql'] = $target->getSql();
3352
$container = $target->getParameterContainer();
3453
if ($container !== null) {
3554
$profileInformation['parameters'] = clone $container;
3655
}
37-
} else {
38-
$profileInformation['sql'] = $target;
3956
}
4057

4158
$this->profiles[$this->currentIndex] = $profileInformation;
@@ -61,13 +78,16 @@ public function profilerFinish(): ProfilerInterface
6178
}
6279

6380
/**
64-
* @return array|null
81+
* @return ProfileShape|null
6582
*/
6683
public function getLastProfile(): ?array
6784
{
6885
return end($this->profiles);
6986
}
7087

88+
/**
89+
* @return ProfilesShape
90+
*/
7191
public function getProfiles(): array
7292
{
7393
return $this->profiles;

test/unit/Adapter/Container/AdapterInterfaceDelegatorTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace PhpDbTest\Adapter\Container;
66

7+
use Laminas\ServiceManager\AbstractPluginManager;
78
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
89
use Laminas\ServiceManager\ServiceManager;
910
use PhpDb\Adapter\Adapter;
@@ -216,6 +217,55 @@ public function testDelegatorWithServiceManagerAndCustomAdapterName(): void
216217
);
217218
}
218219

220+
public function testDelegatorWithPluginManager(): void
221+
{
222+
$databaseAdapter = new Adapter(
223+
$this->createMock(DriverInterface::class),
224+
$this->createMock(PlatformInterface::class),
225+
$this->createMock(ResultSetInterface::class)
226+
);
227+
228+
$container = new ServiceManager([
229+
'factories' => [
230+
AdapterInterface::class => static fn() => $databaseAdapter,
231+
],
232+
]);
233+
234+
$pluginManagerConfig = [
235+
'invokables' => [
236+
ConcreteAdapterAwareObject::class => ConcreteAdapterAwareObject::class,
237+
],
238+
'delegators' => [
239+
ConcreteAdapterAwareObject::class => [
240+
AdapterInterfaceDelegator::class,
241+
],
242+
],
243+
];
244+
245+
$pluginManager = new class ($container, $pluginManagerConfig) extends AbstractPluginManager {
246+
public function validate(mixed $instance): void
247+
{
248+
}
249+
};
250+
251+
$options = [
252+
'table' => 'foo',
253+
'field' => 'bar',
254+
];
255+
256+
/** @var ConcreteAdapterAwareObject $result */
257+
$result = $pluginManager->build(
258+
ConcreteAdapterAwareObject::class,
259+
$options
260+
);
261+
262+
$this->assertInstanceOf(
263+
AdapterInterface::class,
264+
$result->getAdapter()
265+
);
266+
$this->assertSame($options, $result->getOptions());
267+
}
268+
219269
public function testSetStateWithDefaultAdapterName(): void
220270
{
221271
$delegator = AdapterInterfaceDelegator::__set_state([]);

test/unit/Adapter/Driver/Pdo/ConnectionTest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
#[CoversMethod(AbstractPdoConnection::class, 'getResource')]
2525
#[CoversMethod(AbstractPdoConnection::class, 'getDsn')]
26-
#[CoversMethod(AbstractPdoConnection::class, '__construct')]
2726
#[CoversMethod(AbstractPdoConnection::class, 'setDriver')]
2827
#[CoversMethod(AbstractPdoConnection::class, 'setConnectionParameters')]
2928
#[CoversMethod(AbstractPdoConnection::class, 'isConnected')]
@@ -53,6 +52,15 @@ protected function setUp(): void
5352
);
5453
}
5554

55+
/**
56+
* Test getResource method tries to connect to the database, it should never return null
57+
*/
58+
public function testResource(): void
59+
{
60+
$resource = $this->connection->getResource();
61+
self::assertNotNull($resource);
62+
}
63+
5664
/**
5765
* Test getConnectedDsn returns a DSN string if it has been set
5866
*/

test/unit/Adapter/Driver/Pdo/PdoTest.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
use PHPUnit\Framework\Attributes\Group;
2424
use PHPUnit\Framework\TestCase;
2525

26-
#[CoversMethod(AbstractPdo::class, 'getDatabasePlatformName')]
2726
#[CoversMethod(AbstractPdo::class, 'getResultPrototype')]
28-
#[CoversMethod(AbstractPdo::class, '__construct')]
2927
#[CoversMethod(AbstractPdo::class, 'checkEnvironment')]
3028
#[CoversMethod(AbstractPdo::class, 'getConnection')]
3129
#[CoversMethod(AbstractPdo::class, 'createStatement')]
@@ -49,14 +47,6 @@ protected function setUp(): void
4947
$this->pdo = new TestPdo([]);
5048
}
5149

52-
public function testGetDatabasePlatformName(): void
53-
{
54-
// Test platform name for SqlServer
55-
$this->pdo->getConnection()->setConnectionParameters(['pdodriver' => 'sqlsrv']);
56-
self::assertEquals('SqlServer', $this->pdo->getDatabasePlatformName());
57-
self::assertEquals('SQLServer', $this->pdo->getDatabasePlatformName(DriverInterface::NAME_FORMAT_NATURAL));
58-
}
59-
6050
/** @psalm-return array<array-key, array{0: int|string, 1: null|string, 2: string}> */
6151
public static function getParamsAndType(): array
6252
{

0 commit comments

Comments
 (0)