diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 5a093e0..c025226 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -17,7 +17,12 @@ use PhpDb\Adapter\Platform\PlatformInterface; use PhpDb\Adapter\Profiler\Profiler; use PhpDb\Adapter\Profiler\ProfilerInterface; +use PhpDb\Container\AdapterAbstractServiceFactory; use PhpDb\Container\AdapterManager; +use PhpDb\Container\ConnectionInterfaceFactoryFactoryInterface; +use PhpDb\Container\DriverInterfaceFactoryFactoryInterface; +use PhpDb\Container\MetadataFactory; +use PhpDb\Container\PlatformInterfaceFactoryFactoryInterface; use PhpDb\Metadata\MetadataInterface; use PhpDb\ResultSet; @@ -34,6 +39,9 @@ public function __invoke(): array public function getDependencies(): array { return [ + 'abstract_factories' => [ + AdapterAbstractServiceFactory::class, + ], 'aliases' => [ MetadataInterface::class => Metadata\Source\SqliteMetadata::class, ], @@ -68,6 +76,9 @@ public function getAdapterManagerConfig(): array ResultInterface::class => Result::class, ResultSet\ResultSetInterface::class => ResultSet\ResultSet::class, StatementInterface::class => Statement::class, + ConnectionInterfaceFactoryFactoryInterface::class => Container\ConnectionInterfaceFactoryFactory::class, + DriverInterfaceFactoryFactoryInterface::class => Container\DriverInterfaceFactoryFactory::class, + PlatformInterfaceFactoryFactoryInterface::class => Container\PlatformInterfaceFactoryFactory::class, ], 'factories' => [ AdapterInterface::class => Container\AdapterFactory::class, @@ -79,6 +90,14 @@ public function getAdapterManagerConfig(): array Profiler::class => InvokableFactory::class, ResultSet\ResultSet::class => InvokableFactory::class, ], + 'invokables' => [ + Container\ConnectionInterfaceFactoryFactory::class + => Container\ConnectionInterfaceFactoryFactory::class, + Container\DriverInterfaceFactoryFactory::class + => Container\DriverInterfaceFactoryFactory::class, + Container\PlatformInterfaceFactoryFactory::class + => Container\PlatformInterfaceFactoryFactory::class, + ], ]; } } diff --git a/src/Container/ConnectionInterfaceFactoryFactory.php b/src/Container/ConnectionInterfaceFactoryFactory.php new file mode 100644 index 0000000..25907e4 --- /dev/null +++ b/src/Container/ConnectionInterfaceFactoryFactory.php @@ -0,0 +1,44 @@ +get('config')['db']['adapters'] ?? []; + if (! isset($adapterConfig[$requestedName]['driver'])) { + throw new RuntimeException(sprintf( + 'Named adapter "%s" is not configured with a driver', + $requestedName + )); + } + $adapterServices = $container->get('config')[AdapterManager::class]; + $configuredDriver = $adapterConfig[$requestedName]['driver']; + if (array_key_exists($configuredDriver, $adapterServices['aliases'])) { + $aliasTo = $adapterServices['aliases'][$configuredDriver]; + } else { + $aliasTo = $configuredDriver; + } + return match ($aliasTo) { + Pdo::class => new PdoConnectionFactory(), + default => throw new RuntimeException(sprintf( + 'No connection factory found for driver "%s"', + $configuredDriver + )), + }; + } +} diff --git a/src/Container/DriverInterfaceFactoryFactory.php b/src/Container/DriverInterfaceFactoryFactory.php new file mode 100644 index 0000000..aa33088 --- /dev/null +++ b/src/Container/DriverInterfaceFactoryFactory.php @@ -0,0 +1,34 @@ +get('config')['db']['adapters'] ?? []; + if (! isset($adapterConfig[$requestedName]['driver'])) { + throw new RuntimeException(sprintf( + 'Named adapter "%s" is not configured with a driver', + $requestedName + )); + } + $adapterServices = $container->get('config')[AdapterManager::class]; + + $configuredDriver = $adapterConfig[$requestedName]['driver']; + $aliasTo ??= $adapterServices['aliases'][$configuredDriver] ?? $configuredDriver; + $driverFactory = $adapterServices['factories'][$aliasTo]; + return new $driverFactory(); + } +} diff --git a/src/Container/PdoConnectionFactory.php b/src/Container/PdoConnectionFactory.php index 7499c1e..346e9f4 100644 --- a/src/Container/PdoConnectionFactory.php +++ b/src/Container/PdoConnectionFactory.php @@ -23,4 +23,12 @@ public function __invoke(ContainerInterface $container): ConnectionInterface&Con return new Connection($connectionConfig); } + + public static function createFromConfig( + ContainerInterface $container, + string $requestedName + ): ConnectionInterface&Connection { + $adapterConfig = $container->get('config')['db']['adapters'][$requestedName] ?? []; + return new Connection($adapterConfig['connection'] ?? []); + } } diff --git a/src/Container/PdoDriverFactory.php b/src/Container/PdoDriverFactory.php index 33cd20b..f51e23e 100644 --- a/src/Container/PdoDriverFactory.php +++ b/src/Container/PdoDriverFactory.php @@ -39,4 +39,31 @@ public function __invoke(ContainerInterface $container): PdoDriverInterface&PdoD [new SqliteRowCounter()], ); } + + public static function createFromConfig( + ContainerInterface $container, + string $requestedName, + ): PdoDriverInterface&PdoDriver { + /** @var AdapterManager $adapterManager */ + $adapterManager = $container->get(AdapterManager::class); + $connectionFactory = ( + $adapterManager->get(ConnectionInterfaceFactoryFactory::class) + )($container, $requestedName); + + /** @var ConnectionInterface&Connection $connectionInstance */ + $connectionInstance = $connectionFactory::createFromConfig($container, $requestedName); + + /** @var StatementInterface&Statement $statementInstance */ + $statementInstance = $adapterManager->get(Statement::class); + + /** @var ResultInterface&Result $resultInstance */ + $resultInstance = $adapterManager->get(Result::class); + + return new PdoDriver( + $connectionInstance, + $statementInstance, + $resultInstance, + [new SqliteRowCounter()], + ); + } } diff --git a/src/Container/PlatformInterfaceFactory.php b/src/Container/PlatformInterfaceFactory.php index 32b8ebf..c42b83c 100644 --- a/src/Container/PlatformInterfaceFactory.php +++ b/src/Container/PlatformInterfaceFactory.php @@ -32,4 +32,9 @@ public function __invoke(ContainerInterface $container): PlatformInterface&Sqlit return new Sqlite($driverInstance); } + + public static function fromDriver(PdoDriverInterface $driverInstance): PlatformInterface&Sqlite + { + return new Sqlite($driverInstance); + } } diff --git a/src/Container/PlatformInterfaceFactoryFactory.php b/src/Container/PlatformInterfaceFactoryFactory.php new file mode 100644 index 0000000..15c4574 --- /dev/null +++ b/src/Container/PlatformInterfaceFactoryFactory.php @@ -0,0 +1,16 @@ +