Skip to content

Commit 7ad36e1

Browse files
committed
Adds final public const ConfigProvider::NAMED_ADAPTER_KEY for targeting the configuration key used by the AbstractAdapterInterfaceFactory
Signed-off-by: Joey Smith <[email protected]> Signed-off-by: Joey Smith <[email protected]>
1 parent dbd0839 commit 7ad36e1

File tree

4 files changed

+173
-128
lines changed

4 files changed

+173
-128
lines changed

src/ConfigProvider.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,26 @@
66

77
final class ConfigProvider
88
{
9+
public final const NAMED_ADAPTER_KEY = 'adapters';
910
public function __invoke(): array
1011
{
1112
return [
12-
'dependencies' => $this->getDependencies(),
13+
'dependencies' => $this->getDependencies(),
14+
Adapter\AdapterInterface::class => $this->getConfig(),
15+
];
16+
}
17+
18+
public function getConfig(): array
19+
{
20+
// supported configuration structure
21+
return [
22+
// Adapter\Adapter::class => [],
23+
// Adapter\AdapterInterface::class => [],
24+
// self::NAMED_ADAPTER_KEY => [
25+
// Adapter\Adapter::class => [],
26+
// Adapter\AdapterInterface::class => [],
27+
// 'Custom\Name' => [],
28+
// ],
1329
];
1430
}
1531

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpDb\Container;
6+
7+
use Laminas\ServiceManager\Factory\AbstractFactoryInterface;
8+
use Laminas\ServiceManager\ServiceManager;
9+
use PhpDb\Adapter\Adapter;
10+
use PhpDb\Adapter\AdapterInterface;
11+
use PhpDb\Adapter\Driver\DriverInterface;
12+
use PhpDb\Adapter\Driver\PdoDriverInterface;
13+
use PhpDb\Adapter\Platform\PlatformInterface;
14+
use PhpDb\Adapter\Profiler\ProfilerInterface;
15+
use PhpDb\ConfigProvider;
16+
use PhpDb\Exception\ContainerException;
17+
use PhpDb\ResultSet\ResultSetInterface;
18+
use PSpell\Config;
19+
use Psr\Container\ContainerInterface;
20+
21+
use function is_array;
22+
23+
/**
24+
* Database adapter abstract service factory.
25+
*
26+
* Allows configuring several database instances (such as writer and reader).
27+
*
28+
* @internal
29+
*/
30+
class AbstractAdapterInterfaceFactory implements AbstractFactoryInterface
31+
{
32+
protected ?array $config = null;
33+
34+
/**
35+
* Can we create an adapter by the requested name?
36+
*
37+
* @param string $requestedName
38+
*/
39+
public function canCreate(ContainerInterface $container, $requestedName): bool
40+
{
41+
$config = $this->getConfig($container);
42+
43+
if ($config === []) {
44+
return false;
45+
}
46+
47+
return isset($config[$requestedName])
48+
&& is_array($config[$requestedName])
49+
&& ! empty($config[$requestedName]);
50+
}
51+
52+
/**
53+
* Create a DB adapter
54+
*
55+
* @param string $requestedName
56+
*/
57+
public function __invoke(
58+
ContainerInterface&ServiceManager $container,
59+
$requestedName,
60+
?array $options = null
61+
): AdapterInterface&Adapter {
62+
/** @var string|null $driverClass */
63+
$driverClass = $this->config[$requestedName]['driver'] ?? null;
64+
65+
if ($driverClass === null) {
66+
throw ContainerException::forService(
67+
$requestedName,
68+
self::class,
69+
'no driver configured'
70+
);
71+
}
72+
73+
/** @var DriverInterface|PdoDriverInterface $driver */
74+
$driver = $container->build($driverClass, $this->config[$requestedName]);
75+
/** @var PlatformInterface&Pgsql\AdapterPlatform $platform */
76+
$platform = $container->build(PlatformInterface::class, ['driver' => $driver]);
77+
/** @var ResultSetInterface|null $resultSet */
78+
$resultSet = $container->has(ResultSetInterface::class)
79+
? $container->build(ResultSetInterface::class)
80+
: null;
81+
/** @var ProfilerInterface|null $profiler */
82+
$profiler = $container->has(ProfilerInterface::class)
83+
? $container->build(ProfilerInterface::class)
84+
: null;
85+
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+
};
108+
}
109+
110+
/**
111+
* Get db configuration, if any
112+
* todo: refactor to use PhpDb\ConfigProvider::NAMED_ADAPTER_KEY instead of hardcoding 'adapters'
113+
*/
114+
protected function getConfig(ContainerInterface $container): array
115+
{
116+
if ($this->config !== null) {
117+
return $this->config;
118+
}
119+
120+
if (! $container->has('config')) {
121+
$this->config = [];
122+
return $this->config;
123+
}
124+
125+
$config = $container->get('config');
126+
$this->config = $config[AdapterInterface::class][ConfigProvider::NAMED_ADAPTER_KEY] ?? [];
127+
return $this->config;
128+
}
129+
}

src/Container/AdapterAbstractServiceFactory.php

Lines changed: 0 additions & 127 deletions
This file was deleted.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpDb\Exception;
6+
7+
use Psr\Container\ContainerExceptionInterface;
8+
use RuntimeException as SplRuntimeException;
9+
10+
final class ContainerException extends SplRuntimeException implements ContainerExceptionInterface
11+
{
12+
public static function forService(
13+
string $serviceName,
14+
string $factoryClass,
15+
string $reason
16+
): self {
17+
return new self(
18+
sprintf(
19+
'Failed to create service "%s" in factory %s Reason: %s',
20+
$serviceName,
21+
$factoryClass,
22+
$reason
23+
),
24+
0,
25+
);
26+
}
27+
}

0 commit comments

Comments
 (0)