Skip to content

Commit

Permalink
added Factory::createFromParameters() & createFromDsn() [WIP]
Browse files Browse the repository at this point in the history
merging Connection & Explorer classes into one (BC break) [WIP]
  • Loading branch information
dg committed Sep 2, 2024
1 parent 787349a commit 7990708
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/Bridges/DatabaseDI/DatabaseExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 3 additions & 2 deletions src/Database/Explorer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
71 changes: 59 additions & 12 deletions src/Database/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

0 comments on commit 7990708

Please sign in to comment.