diff --git a/src/Connection/PDO.php b/src/Connection/PDO.php index 04db4ec..46799b7 100644 --- a/src/Connection/PDO.php +++ b/src/Connection/PDO.php @@ -29,7 +29,6 @@ private function __construct(Url $dsn, array $options = []) $dsnPassword = $dsn->authority()->userInformation()->password(); $user = null; $password = null; - $charset = ''; if (!$dsnUser->equals(User::none())) { $user = $dsnUser->toString(); @@ -39,23 +38,12 @@ private function __construct(Url $dsn, array $options = []) $password = $dsnPassword->toString(); } - if (!$dsn->query()->equals(UrlQuery::none())) { - \parse_str($dsn->query()->toString(), $query); - - if (\array_key_exists('charset', $query)) { - /** @psalm-suppress MixedOperand */ - $charset = ';charset='.$query['charset']; - } - } - - $this->pdo = new \PDO(\sprintf( - '%s:host=%s;port=%s;dbname=%s%s', - $dsn->scheme()->toString(), - $dsn->authority()->host()->toString(), - $dsn->authority()->port()->toString(), - \substr($dsn->path()->toString(), 1), // substring to remove leading '/' - $charset, - ), $user, $password, $options); + $this->pdo = new \PDO( + self::parseDsn($dsn), + $user, + $password, + $options, + ); } public function __invoke(Query $query): Sequence @@ -87,6 +75,44 @@ public static function persistent(Url $dsn): self return new self($dsn, [\PDO::ATTR_PERSISTENT => true]); } + private function parseDsn(Url $dsn): string + { + $charset = ''; + + if (!$dsn->query()->equals(UrlQuery::none())) { + \parse_str($dsn->query()->toString(), $query); + + if (\array_key_exists('charset', $query)) { + /** @psalm-suppress MixedOperand */ + $charset = ';charset='.$query['charset']; + } + } + + // si pas de port alors socket + if (!$dsn->authority()->port()->value()) { + $path = $dsn->path()->toString(); + $dbName = \basename($path); + $socketPath = \dirname($path); + + return \sprintf( + '%s:unix_socket=%s;dbname=%s%s', + $dsn->scheme()->toString(), + $socketPath, + $dbName, + $charset, + ); + } + + return \sprintf( + '%s:host=%s;port=%s;dbname=%s%s', + $dsn->scheme()->toString(), + $dsn->authority()->host()->toString(), + $dsn->authority()->port()->toString(), + \substr($dsn->path()->toString(), 1), // substring to remove leading '/' + $charset, + ); + } + /** * @param callable(): bool $action *