Skip to content
This repository was archived by the owner on Jan 24, 2024. It is now read-only.

Commit 8fab9b2

Browse files
authored
Add supporting of general URI DSN (#78)
1 parent 0cfba1b commit 8fab9b2

File tree

3 files changed

+77
-16
lines changed

3 files changed

+77
-16
lines changed

src/Driver/Driver.php

+67-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use PDOStatement;
1919
use Psr\Log\LoggerAwareInterface;
2020
use Psr\Log\LoggerAwareTrait;
21+
use Spiral\Database\Exception\ConfigException;
2122
use Spiral\Database\Exception\DriverException;
2223
use Spiral\Database\Exception\ReadonlyConnectionException;
2324
use Spiral\Database\Exception\StatementException;
@@ -127,6 +128,33 @@ public function __construct(
127128
if ($this->options['readonlySchema']) {
128129
$this->schemaHandler = new ReadonlyHandler($this->schemaHandler);
129130
}
131+
132+
// Actualize DSN
133+
$this->updateDSN();
134+
}
135+
136+
/**
137+
* Updates an internal options
138+
*
139+
* @return void
140+
*/
141+
private function updateDSN(): void
142+
{
143+
[$connection, $this->options['username'], $this->options['password']] = $this->parseDSN();
144+
145+
// Update connection. The DSN field can be located in one of the
146+
// following keys of the configuration array.
147+
switch (true) {
148+
case \array_key_exists('dsn', $this->options):
149+
$this->options['dsn'] = $connection;
150+
break;
151+
case \array_key_exists('addr', $this->options):
152+
$this->options['addr'] = $connection;
153+
break;
154+
default:
155+
$this->options['connection'] = $connection;
156+
break;
157+
}
130158
}
131159

132160
/**
@@ -706,19 +734,52 @@ protected function rollbackSavepoint(int $level): void
706734
$this->execute('ROLLBACK TO SAVEPOINT ' . $this->identifier("SVP{$level}"));
707735
}
708736

737+
/**
738+
* @return array{string, string, string}
739+
*/
740+
private function parseDSN(): array
741+
{
742+
$dsn = $this->getDSN();
743+
744+
$user = (string)($this->options['username'] ?? '');
745+
$pass = (string)($this->options['password'] ?? '');
746+
747+
if (\strpos($dsn, '://') > 0) {
748+
$parts = \parse_url($dsn);
749+
750+
if (!isset($parts['scheme'])) {
751+
throw new ConfigException('Configuration database scheme must be defined');
752+
}
753+
754+
// Update username and password from DSN if not defined.
755+
$user = $user ?: $parts['user'] ?? '';
756+
$pass = $pass ?: $parts['pass'] ?? '';
757+
758+
// Build new DSN
759+
$dsn = \sprintf('%s:host=%s', $parts['scheme'], $parts['host'] ?? 'localhost');
760+
761+
if (isset($parts['port'])) {
762+
$dsn .= ';port=' . $parts['port'];
763+
}
764+
765+
if (isset($parts['path']) && \trim($parts['path'], '/')) {
766+
$dsn .= ';dbname=' . \trim($parts['path'], '/');
767+
}
768+
}
769+
770+
return [$dsn, $user, $pass];
771+
}
772+
709773
/**
710774
* Create instance of configured PDO class.
711775
*
712776
* @return PDO
713777
*/
714778
protected function createPDO(): PDO
715779
{
716-
return new PDO(
717-
$this->getDSN(),
718-
$this->options['username'],
719-
$this->options['password'],
720-
$this->options['options']
721-
);
780+
[$dsn, $user, $pass] = $this->parseDSN();
781+
782+
return new PDO($dsn, $user, $pass, $this->options['options']);
722783
}
723784

724785
/**

tests/Database/BaseTest.php

+9-7
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@ public function getDriver(array $options = []): Driver
6161
if (!isset($this->driver)) {
6262
$class = $config['driver'];
6363

64-
$this->driver = new $class(\array_merge($options, [
65-
'connection' => $config['conn'],
66-
'username' => $config['user'],
67-
'password' => $config['pass'],
68-
'options' => [],
69-
'queryCache' => true
70-
]));
64+
$this->driver = new $class(
65+
[
66+
'connection' => $config['conn'],
67+
'username' => $config['user'] ?? '',
68+
'password' => $config['pass'] ?? '',
69+
'options' => [],
70+
'queryCache' => true
71+
]
72+
);
7173
}
7274

7375
static::$logger = static::$logger ?? new TestLogger();

tests/bootstrap.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
],
3131
'mysql' => [
3232
'driver' => Database\Driver\MySQL\MySQLDriver::class,
33-
'conn' => 'mysql:host=127.0.0.1:13306;dbname=spiral',
34-
'user' => 'root',
35-
'pass' => 'root',
33+
'conn' => 'mysql://root:[email protected]:13306/spiral',
3634
'queryCache' => 100
3735
],
3836
'postgres' => [

0 commit comments

Comments
 (0)