Skip to content

Commit 264e808

Browse files
authored
Refactor Dsn class (#427)
1 parent 2b3668d commit 264e808

File tree

4 files changed

+90
-54
lines changed

4 files changed

+90
-54
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
- New #360: Realize `ColumnBuilder` class (@Tigrov)
1919
- Enh #362: Update according changes in `ColumnSchemaInterface` (@Tigrov)
2020
- New #364, #372: Add `ColumnDefinitionBuilder` class (@Tigrov)
21-
- Enh #365: Refactor `Dsn` class (@Tigrov)
21+
- Enh #365, #427: Refactor `Dsn` class (@Tigrov)
2222
- Enh #366: Use constructor to create columns and initialize properties (@Tigrov)
2323
- Enh #370: Refactor `Schema::normalizeDefaultValue()` method and move it to `ColumnFactory` class (@Tigrov)
2424
- New #373: Override `QueryBuilder::prepareBinary()` method (@Tigrov)

src/Dsn.php

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,67 @@
44

55
namespace Yiisoft\Db\Pgsql;
66

7-
use Yiisoft\Db\Connection\AbstractDsn;
7+
use Stringable;
88

99
/**
10-
* Implement a Data Source Name (DSN) for a PostgreSQL Server.
10+
* Represents a Data Source Name (DSN) for a PostgreSQL Server that's used to configure a {@see Driver} instance.
11+
*
12+
* To get DSN in string format, use the `(string)` type casting operator.
1113
*
1214
* @link https://www.php.net/manual/en/ref.pdo-pgsql.connection.php
1315
*/
14-
final class Dsn extends AbstractDsn
16+
final class Dsn implements Stringable
1517
{
1618
/**
19+
* @param string $driver The database driver name.
20+
* @param string $host The database host name or IP address.
21+
* @param string $databaseName The database name to connect to.
22+
* @param string $port The database port. Empty string if not set.
23+
* @param string[] $options The database connection options. Default value to an empty array.
24+
*
1725
* @psalm-param array<string,string> $options
1826
*/
1927
public function __construct(
20-
string $driver = 'pgsql',
21-
string $host = '127.0.0.1',
22-
string|null $databaseName = 'postgres',
23-
string $port = '5432',
24-
array $options = []
28+
public readonly string $driver = 'pgsql',
29+
public readonly string $host = '127.0.0.1',
30+
public readonly string $databaseName = 'postgres',
31+
public readonly string $port = '5432',
32+
public readonly array $options = [],
2533
) {
26-
if (empty($databaseName)) {
27-
$databaseName = 'postgres';
34+
}
35+
36+
/**
37+
* @return string The Data Source Name, or DSN, has the information required to connect to the database.
38+
*
39+
* Please refer to the [PHP manual](https://php.net/manual/en/pdo.construct.php) on the format of the DSN string.
40+
*
41+
* The `driver` property is used as the driver prefix of the DSN, all further property-value pairs
42+
* or key-value pairs of `options` property are rendered as `key=value` and concatenated by `;`. For example:
43+
*
44+
* ```php
45+
* $dsn = new Dsn('pgsql', '127.0.0.1', 'postgres', '5432', ['sslmode' => 'disable']);
46+
* $driver = new Driver($dsn, 'username', 'password');
47+
* $connection = new Connection($driver, $schemaCache);
48+
* ```
49+
*
50+
* Will result in the DSN string `pgsql:host=127.0.0.1;dbname=postgres;port=5432;sslmode=disable`.
51+
*/
52+
public function __toString(): string
53+
{
54+
$dsn = "$this->driver:host=$this->host";
55+
56+
if ($this->databaseName !== '') {
57+
$dsn .= ";dbname=$this->databaseName";
58+
}
59+
60+
if ($this->port !== '') {
61+
$dsn .= ";port=$this->port";
62+
}
63+
64+
foreach ($this->options as $key => $value) {
65+
$dsn .= ";$key=$value";
2866
}
2967

30-
parent::__construct($driver, $host, $databaseName, $port, $options);
68+
return $dsn;
3169
}
3270
}

tests/DsnTest.php

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,56 +9,54 @@
99

1010
/**
1111
* @group pgsql
12-
*
13-
* @psalm-suppress PropertyNotSetInConstructor
1412
*/
1513
final class DsnTest extends TestCase
1614
{
17-
public function testAsString(): void
15+
public function testConstruct(): void
1816
{
19-
$this->assertSame(
20-
'pgsql:host=localhost;dbname=yiitest;port=5432',
21-
(new Dsn('pgsql', 'localhost', 'yiitest'))->asString(),
22-
);
17+
$dsn = new Dsn('pgsql', 'localhost', 'yiitest', '5433', ['sslmode' => 'disable']);
18+
19+
$this->assertSame('pgsql', $dsn->driver);
20+
$this->assertSame('localhost', $dsn->host);
21+
$this->assertSame('yiitest', $dsn->databaseName);
22+
$this->assertSame('5433', $dsn->port);
23+
$this->assertSame(['sslmode' => 'disable'], $dsn->options);
24+
$this->assertSame('pgsql:host=localhost;dbname=yiitest;port=5433;sslmode=disable', (string) $dsn);
2325
}
2426

25-
public function testAsStringWithDatabaseName(): void
27+
public function testConstructDefaults(): void
2628
{
27-
$this->assertSame(
28-
'pgsql:host=localhost;dbname=postgres;port=5432',
29-
(new Dsn('pgsql', 'localhost'))->asString(),
30-
);
29+
$dsn = new Dsn();
30+
31+
$this->assertSame('pgsql', $dsn->driver);
32+
$this->assertSame('127.0.0.1', $dsn->host);
33+
$this->assertSame('postgres', $dsn->databaseName);
34+
$this->assertSame('5432', $dsn->port);
35+
$this->assertSame([], $dsn->options);
36+
$this->assertSame('pgsql:host=127.0.0.1;dbname=postgres;port=5432', (string) $dsn);
3137
}
3238

33-
public function testAsStringWithDatabaseNameWithEmptyString(): void
39+
public function testConstructWithEmptyDatabase(): void
3440
{
35-
$this->assertSame(
36-
'pgsql:host=localhost;dbname=postgres;port=5432',
37-
(new Dsn('pgsql', 'localhost', ''))->asString(),
38-
);
41+
$dsn = new Dsn(databaseName: '');
42+
43+
$this->assertSame('pgsql', $dsn->driver);
44+
$this->assertSame('127.0.0.1', $dsn->host);
45+
$this->assertSame('', $dsn->databaseName);
46+
$this->assertSame('5432', $dsn->port);
47+
$this->assertSame([], $dsn->options);
48+
$this->assertSame('pgsql:host=127.0.0.1;port=5432', (string) $dsn);
3949
}
4050

41-
public function testAsStringWithDatabaseNameWithNull(): void
51+
public function testConstructWithEmptyPort(): void
4252
{
43-
$this->assertSame(
44-
'pgsql:host=localhost;dbname=postgres;port=5432',
45-
(new Dsn('pgsql', 'localhost', null))->asString(),
46-
);
47-
}
48-
49-
public function testAsStringWithOptions(): void
50-
{
51-
$this->assertSame(
52-
'pgsql:host=localhost;dbname=yiitest;port=5433;charset=utf8',
53-
(new Dsn('pgsql', 'localhost', 'yiitest', '5433', ['charset' => 'utf8']))->asString(),
54-
);
55-
}
56-
57-
public function testAsStringWithPort(): void
58-
{
59-
$this->assertSame(
60-
'pgsql:host=localhost;dbname=yiitest;port=5433',
61-
(new Dsn('pgsql', 'localhost', 'yiitest', '5433'))->asString(),
62-
);
53+
$dsn = new Dsn(port: '');
54+
55+
$this->assertSame('pgsql', $dsn->driver);
56+
$this->assertSame('127.0.0.1', $dsn->host);
57+
$this->assertSame('postgres', $dsn->databaseName);
58+
$this->assertSame('', $dsn->port);
59+
$this->assertSame([], $dsn->options);
60+
$this->assertSame('pgsql:host=127.0.0.1;dbname=postgres', (string) $dsn);
6361
}
6462
}

tests/Support/TestTrait.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ protected function getConnection(bool $fixture = false): Connection
3636

3737
protected static function getDb(): Connection
3838
{
39-
$dsn = (new Dsn(
39+
$dsn = (string) new Dsn(
4040
host: self::getHost(),
4141
databaseName: self::getDatabaseName(),
4242
port: self::getPort(),
43-
))->asString();
43+
);
4444
$driver = new Driver($dsn, self::getUsername(), self::getPassword());
4545
$driver->charset('utf8');
4646

@@ -50,11 +50,11 @@ protected static function getDb(): Connection
5050
protected function getDsn(): string
5151
{
5252
if ($this->dsn === '') {
53-
$this->dsn = (new Dsn(
53+
$this->dsn = (string) new Dsn(
5454
host: self::getHost(),
5555
databaseName: self::getDatabaseName(),
5656
port: self::getPort(),
57-
))->asString();
57+
);
5858
}
5959

6060
return $this->dsn;

0 commit comments

Comments
 (0)