Skip to content

Commit abf7549

Browse files
authored
Merge pull request #108 from tyrsson:reintroduce-adapterinterface-factory
Delegates adapter creation back to php-db/phpdb
2 parents 48e2233 + 0eceb26 commit abf7549

File tree

6 files changed

+118
-40
lines changed

6 files changed

+118
-40
lines changed

src/ConfigProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public function getDependencies(): array
3838
'aliases' => [
3939
Adapter\AdapterInterface::class => Adapter\Adapter::class,
4040
],
41+
'factories' => [
42+
Adapter\Adapter::class => Container\AdapterInterfaceFactory::class,
43+
],
4144
];
4245
}
4346
}

src/Container/AbstractAdapterInterfaceFactory.php

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PhpDb\Adapter\Profiler\ProfilerInterface;
1515
use PhpDb\ConfigProvider;
1616
use PhpDb\Exception\ContainerException;
17+
use PhpDb\ResultSet\ResultSet;
1718
use PhpDb\ResultSet\ResultSetInterface;
1819
use Psr\Container\ContainerInterface;
1920

@@ -26,7 +27,7 @@
2627
*
2728
* @internal
2829
*/
29-
class AbstractAdapterInterfaceFactory implements AbstractFactoryInterface
30+
final class AbstractAdapterInterfaceFactory implements AbstractFactoryInterface
3031
{
3132
protected ?array $config = null;
3233

@@ -49,7 +50,7 @@ public function canCreate(ContainerInterface $container, $requestedName): bool
4950
}
5051

5152
/**
52-
* Create a DB adapter
53+
* Create a "Named" DB adapter
5354
*
5455
* @phpstan-param ContainerInterface&ServiceManager $container
5556
* @param string $requestedName
@@ -59,7 +60,7 @@ public function __invoke(
5960
$requestedName,
6061
?array $options = null
6162
): AdapterInterface&Adapter {
62-
/** @var string|null $driverClass */
63+
/** @var class-string<DriverInterface>|class-string<PdoDriverInterface>|null $driverClass */
6364
$driverClass = $this->config[$requestedName]['driver'] ?? null;
6465

6566
if ($driverClass === null) {
@@ -72,44 +73,30 @@ public function __invoke(
7273

7374
/** @var DriverInterface|PdoDriverInterface $driver */
7475
$driver = $container->build($driverClass, $this->config[$requestedName]);
76+
7577
/** @var PlatformInterface $platform */
7678
$platform = $container->build(PlatformInterface::class, ['driver' => $driver]);
79+
7780
/** @var ResultSetInterface|null $resultSet */
7881
$resultSet = $container->has(ResultSetInterface::class)
7982
? $container->build(ResultSetInterface::class)
80-
: null;
83+
: new ResultSet();
84+
8185
/** @var ProfilerInterface|null $profiler */
8286
$profiler = $container->has(ProfilerInterface::class)
8387
? $container->build(ProfilerInterface::class)
8488
: null;
8589

86-
return match (true) {
87-
$resultSet !== null && $profiler !== null => new Adapter(
88-
driver: $driver,
89-
platform: $platform,
90-
queryResultSetPrototype: $resultSet,
91-
profiler: $profiler,
92-
),
93-
$resultSet !== null => new Adapter(
94-
driver: $driver,
95-
platform: $platform,
96-
queryResultSetPrototype: $resultSet,
97-
),
98-
$profiler !== null => new Adapter(
99-
driver: $driver,
100-
platform: $platform,
101-
profiler: $profiler,
102-
),
103-
default => new Adapter(
104-
driver: $driver,
105-
platform: $platform,
106-
),
107-
};
90+
return new Adapter(
91+
driver: $driver,
92+
platform: $platform,
93+
queryResultSetPrototype: $resultSet,
94+
profiler: $profiler,
95+
);
10896
}
10997

11098
/**
11199
* Get db configuration, if any
112-
* todo: refactor to use PhpDb\ConfigProvider::NAMED_ADAPTER_KEY instead of hardcoding 'adapters'
113100
*/
114101
protected function getConfig(ContainerInterface $container): array
115102
{

src/Container/AdapterServiceDelegator.php renamed to src/Container/AdapterInterfaceDelegator.php

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

1515
use function sprintf;
1616

17-
class AdapterServiceDelegator
17+
class AdapterInterfaceDelegator
1818
{
1919
public function __construct(
2020
protected readonly string $adapterName = AdapterInterface::class
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpDb\Container;
6+
7+
use Laminas\ServiceManager\ServiceManager;
8+
use PhpDb\Adapter\Adapter;
9+
use PhpDb\Adapter\AdapterInterface;
10+
use PhpDb\Adapter\Driver\DriverInterface;
11+
use PhpDb\Adapter\Driver\PdoDriverInterface;
12+
use PhpDb\Adapter\Platform\PlatformInterface;
13+
use PhpDb\Adapter\Profiler\ProfilerInterface;
14+
use PhpDb\Exception\ContainerException;
15+
use PhpDb\ResultSet\ResultSet;
16+
use PhpDb\ResultSet\ResultSetInterface;
17+
use Psr\Container\ContainerInterface;
18+
19+
final class AdapterInterfaceFactory
20+
{
21+
public function __invoke(
22+
ContainerInterface&ServiceManager $container,
23+
string $requestedName,
24+
): AdapterInterface&Adapter {
25+
if (! $container->has('config')) {
26+
throw ContainerException::forService(
27+
$requestedName,
28+
self::class,
29+
'Container is missing a config service'
30+
);
31+
}
32+
$config = $container->get('config') ?? [];
33+
$adapterConfig = $config[AdapterInterface::class] ?? $config[Adapter::class] ?? [];
34+
35+
if ($adapterConfig === []) {
36+
throw ContainerException::forService(
37+
AdapterInterface::class,
38+
self::class,
39+
'No configuration found for ' . $requestedName
40+
);
41+
}
42+
43+
/** @var class-string<DriverInterface>|class-string<PdoDriverInterface>|null $driverClass */
44+
$driverClass = $adapterConfig['driver'] ?? null;
45+
46+
if ($driverClass === null || ! $container->has($driverClass)) {
47+
throw ContainerException::forService(
48+
AdapterInterface::class,
49+
self::class,
50+
'Invalid or missing driver provided for ' . $requestedName
51+
);
52+
}
53+
54+
/** @var DriverInterface|PdoDriverInterface $driver */
55+
$driver = $container->build($driverClass, $adapterConfig);
56+
57+
/** @var PlatformInterface $adapterPlatform */
58+
$adapterPlatform = $container->build(PlatformInterface::class, ['driver' => $driver]);
59+
60+
/** @var ProfilerInterface|null $profilerInterface */
61+
$profilerInterface = $container->has(ProfilerInterface::class)
62+
? $container->build(ProfilerInterface::class)
63+
: null;
64+
65+
/** @var ResultSetInterface|null $queryResultSetPrototype */
66+
$queryResultSetPrototype = $container->has(ResultSetInterface::class)
67+
? $container->get(ResultSetInterface::class)
68+
: new ResultSet();
69+
70+
return new Adapter(
71+
driver: $driver,
72+
platform: $adapterPlatform,
73+
queryResultSetPrototype: $queryResultSetPrototype,
74+
profiler: $profilerInterface,
75+
);
76+
}
77+
}

test/unit/Adapter/Container/AdapterServiceDelegatorTest.php renamed to test/unit/Adapter/Container/AdapterInterfaceDelegatorTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use PhpDb\Adapter\AdapterInterface;
1212
use PhpDb\Adapter\Driver\DriverInterface;
1313
use PhpDb\Adapter\Platform\PlatformInterface;
14-
use PhpDb\Container\AdapterServiceDelegator;
14+
use PhpDb\Container\AdapterInterfaceDelegator;
1515
use PhpDb\Exception\RuntimeException;
1616
use PhpDb\ResultSet\ResultSetInterface;
1717
use PhpDbTest\Adapter\TestAsset\ConcreteAdapterAwareObject;
@@ -22,7 +22,7 @@
2222
use Psr\Container\NotFoundExceptionInterface;
2323
use stdClass;
2424

25-
final class AdapterServiceDelegatorTest extends TestCase
25+
final class AdapterInterfaceDelegatorTest extends TestCase
2626
{
2727
/**
2828
* @throws Exception
@@ -44,7 +44,7 @@ public function testSetAdapterShouldBeCalledForExistingAdapter(): void
4444
$callback = static fn(): ConcreteAdapterAwareObject => new ConcreteAdapterAwareObject();
4545

4646
/** @var ConcreteAdapterAwareObject $result */
47-
$result = (new AdapterServiceDelegator())(
47+
$result = (new AdapterInterfaceDelegator())(
4848
$container,
4949
ConcreteAdapterAwareObject::class,
5050
$callback
@@ -78,7 +78,7 @@ public function testSetAdapterShouldBeCalledForOnlyConcreteAdapter(): void
7878
$callback = static fn(): ConcreteAdapterAwareObject => new ConcreteAdapterAwareObject();
7979

8080
/** @var ConcreteAdapterAwareObject $result */
81-
$result = (new AdapterServiceDelegator())(
81+
$result = (new AdapterInterfaceDelegator())(
8282
$container,
8383
ConcreteAdapterAwareObject::class,
8484
$callback
@@ -110,7 +110,7 @@ public function testSetAdapterShouldNotBeCalledForMissingAdapter(): void
110110
$this->expectException(ServiceNotFoundException::class);
111111
$this->expectExceptionMessage('Service "PhpDb\Adapter\AdapterInterface" not found in container');
112112

113-
(new AdapterServiceDelegator())(
113+
(new AdapterInterfaceDelegator())(
114114
$container,
115115
ConcreteAdapterAwareObject::class,
116116
$callback
@@ -134,7 +134,7 @@ public function testSetAdapterShouldNotBeCalledForWrongClassInstance(): void
134134
'Delegated service "stdClass" must implement PhpDb\Adapter\AdapterAwareInterface'
135135
);
136136

137-
(new AdapterServiceDelegator())(
137+
(new AdapterInterfaceDelegator())(
138138
$container,
139139
stdClass::class,
140140
$callback
@@ -163,7 +163,7 @@ public function testDelegatorWithServiceManager(): void
163163
],
164164
'delegators' => [
165165
ConcreteAdapterAwareObject::class => [
166-
AdapterServiceDelegator::class,
166+
AdapterInterfaceDelegator::class,
167167
],
168168
],
169169
]);
@@ -198,7 +198,7 @@ public function testDelegatorWithServiceManagerAndCustomAdapterName(): void
198198
],
199199
'delegators' => [
200200
ConcreteAdapterAwareObject::class => [
201-
new AdapterServiceDelegator('alternate-database-adapter'),
201+
new AdapterInterfaceDelegator('alternate-database-adapter'),
202202
],
203203
],
204204
]);
@@ -236,7 +236,7 @@ public function testDelegatorWithPluginManager(): void
236236
],
237237
'delegators' => [
238238
ConcreteAdapterAwareObject::class => [
239-
AdapterServiceDelegator::class,
239+
AdapterInterfaceDelegator::class,
240240
],
241241
],
242242
];

test/unit/ConfigProviderTest.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,32 @@
66

77
use PhpDb\Adapter;
88
use PhpDb\ConfigProvider;
9-
use PhpDb\Container\AbstractAdapterInterfaceFactory;
9+
use PhpDb\Container;
1010
use PHPUnit\Framework\TestCase;
1111

1212
class ConfigProviderTest extends TestCase
1313
{
14-
/** @phpstan-var array{'dependencies': array{abstract_factories: list<class-string>, aliases: array<class-string, class-string>}} */
14+
/**
15+
* @phpstan-var array{
16+
* 'dependencies': array{
17+
* abstract_factories: list<class-string>,
18+
* aliases: array<class-string, class-string>,
19+
* factories: array<class-string, class-string>,
20+
* }
21+
* }
22+
* */
1523
private array $config = [
1624
Adapter\AdapterInterface::class => [],
1725
'dependencies' => [
1826
'abstract_factories' => [
19-
AbstractAdapterInterfaceFactory::class,
27+
Container\AbstractAdapterInterfaceFactory::class,
2028
],
2129
'aliases' => [
2230
Adapter\AdapterInterface::class => Adapter\Adapter::class,
2331
],
32+
'factories' => [
33+
Adapter\Adapter::class => Container\AdapterInterfaceFactory::class,
34+
],
2435
],
2536
];
2637

0 commit comments

Comments
 (0)