From 3bae0854515122ebe58dbd8f6e35b4a577966f7a Mon Sep 17 00:00:00 2001 From: David Grudl Date: Thu, 29 Aug 2024 04:54:35 +0200 Subject: [PATCH] added Factory::createFromParameters() & createFromDsn() [WIP] merging Connection & Explorer classes into one (BC break) [WIP] --- src/Bridges/DatabaseDI/DatabaseExtension.php | 2 +- src/Database/Explorer.php | 5 +- src/Database/Factory.php | 71 ++++++++++++++++---- 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/Bridges/DatabaseDI/DatabaseExtension.php b/src/Bridges/DatabaseDI/DatabaseExtension.php index 35e5e8257..b2de27fa5 100644 --- a/src/Bridges/DatabaseDI/DatabaseExtension.php +++ b/src/Bridges/DatabaseDI/DatabaseExtension.php @@ -99,7 +99,7 @@ private function setupDatabase(\stdClass $config, string $name): void $cache = new Statement(Nette\Caching\Cache::class, [1 => $cacheId]); $explorer = $builder->addDefinition($this->prefix($name)) - ->setFactory(Nette\Database\Explorer::class, [$config->dsn, $config->user, $config->password, $config->options]) + ->setFactory([Nette\Database\Factory::class, 'createFromDsn'], [$config->dsn, $config->user, $config->password, $config->options]) ->addSetup('setCache', [$cache]) ->setAutowired($config->autowired); diff --git a/src/Database/Explorer.php b/src/Database/Explorer.php index da8a76324..d45fec870 100644 --- a/src/Database/Explorer.php +++ b/src/Database/Explorer.php @@ -43,8 +43,9 @@ public function __construct( if (is_string($driver)) { // compatibility with version 3.x [$dsn, $user, $password, $options] = func_get_args() + [null, null, null, []]; unset($options['lazy']); - Factory::configure($this, $options); - $driver = Factory::createDriverFromDsn($dsn, $user, $password, $options); + $explorer = Factory::createFromDsn($dsn, $user, $password, $options); + $driver = $explorer->driver; + $this->typeConverter = $explorer->typeConverter; } $this->driver = $driver; diff --git a/src/Database/Factory.php b/src/Database/Factory.php index 520e60453..4f55dbfde 100644 --- a/src/Database/Factory.php +++ b/src/Database/Factory.php @@ -28,41 +28,88 @@ final class Factory private const TypeConverterOptions = ['convertBoolean', 'convertDateTime', 'convertDecimal', 'newDateTime']; - /** @internal */ - public static function createDriverFromDsn( + public static function createFromParameters( + #[\SensitiveParameter] + ...$params, + ): Explorer + { + $params = count($params) === 1 && is_array($params[0] ?? null) ? $params[0] : $params; + $driver = self::createDriverFromParameters($params); + return self::createExplorer($driver, $params); + } + + + public static function createFromDsn( string $dsn, ?string $username = null, #[\SensitiveParameter] ?string $password = null, array $options = [], + ): Explorer + { + $driver = self::createDriverFromDsn($dsn, $username, $password, $options); + return self::createExplorer($driver, $options); + } + + + private static function createDriverFromParameters( + #[\SensitiveParameter] + array $params, ): Drivers\Driver { if ($class = $params['driverClass'] ?? null) { if (!is_subclass_of($class, Drivers\Driver::class)) { throw new \LogicException("Driver class '$class' is not subclass of " . Drivers\Driver::class); } + unset($params['driverClass']); - } else { - $driver = explode(':', $dsn)[0]; - $class = self::Drivers['pdo-' . $driver] ?? null; + } elseif ($driver = $params['driver'] ?? null) { + $class = self::Drivers[$driver] ?? null; if (!$class) { - throw new \LogicException("Unknown PDO driver '$driver'."); + throw new \LogicException("Unknown driver '$driver'."); } + unset($params['driver']); + + } elseif ($params['dsn'] ?? null) { + return self::createDriverFromDsn(...$params); + + } else { + throw new \LogicException("Missing options 'driver' or 'driverClass'."); } + $params = array_diff_key($params, array_flip(self::TypeConverterOptions)); + return new $class($params); + } + + + private static function createDriverFromDsn( + string $dsn, + ?string $username, + #[\SensitiveParameter] + ?string $password, + array $options = [], + ): Drivers\Driver + { + $options = array_diff_key($options, array_flip(self::TypeConverterOptions)); + $driver = explode(':', $dsn)[0]; + $class = self::Drivers['pdo-' . $driver] ?? null; + if (!$class) { + throw new \LogicException("Unknown PDO driver '$driver'."); + } return new $class(['dsn' => $dsn, 'username' => $username, 'password' => $password, 'options' => $options]); } - /** @internal */ - public static function configure(Explorer $explorer, array $options): void + private static function createExplorer(Drivers\Driver $driver, array $options): Explorer { + $explorer = new Explorer($driver); $converter = $explorer->getTypeConverter(); - foreach (self::TypeConverterOptions as $opt) { - if (isset($options[$opt])) { - $converter->$opt = (bool) $options[$opt]; - unset($options[$opt]); + foreach (self::TypeConverterOptions as $key) { + if (isset($options[$key])) { + $converter->$key = (bool) $options[$key]; + unset($options[$key]); } } + return $explorer; } }