diff --git a/CHANGELOG.md b/CHANGELOG.md index 2963e745..0a9c9a2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ - Enh #281: Update according changes in `ColumnSchemaInterface` (@Tigrov) - New #282, #291, #299, #302: Add `ColumnDefinitionBuilder` class (@Tigrov) - Bug #285: Fix `DMLQueryBuilder::insertBatch()` method (@Tigrov) -- Enh #283: Refactor `Dsn` class (@Tigrov) +- Enh #283, #344: Refactor `Dsn` class (@Tigrov) - Enh #286: Use constructor to create columns and initialize properties (@Tigrov) - Enh #288, #317: Refactor `Schema::findColumns()` method (@Tigrov) - Enh #289: Refactor `Schema::normalizeDefaultValue()` method and move it to `ColumnFactory` class (@Tigrov) diff --git a/src/Dsn.php b/src/Dsn.php index ea0fdcf5..e939552e 100644 --- a/src/Dsn.php +++ b/src/Dsn.php @@ -4,26 +4,27 @@ namespace Yiisoft\Db\Oracle; -use Yiisoft\Db\Connection\AbstractDsn; +use Stringable; /** - * Implement a Data Source Name (DSN) for an Oracle Server. + * Represents a Data Source Name (DSN) for an Oracle Server that's used to configure a {@see Driver} instance. + * + * To get DSN in string format, use the `(string)` type casting operator. * * @link https://www.php.net/manual/en/ref.pdo-oci.connection.php */ -final class Dsn extends AbstractDsn +final class Dsn implements Stringable { /** * @psalm-param array $options */ public function __construct( - string $driver = 'oci', - string $host = '127.0.0.1', - string|null $databaseName = null, - string $port = '1521', - array $options = [] + public readonly string $driver = 'oci', + public readonly string $host = '127.0.0.1', + public readonly string $databaseName = '', + public readonly string $port = '1521', + public readonly array $options = [], ) { - parent::__construct($driver, $host, $databaseName, $port, $options); } /** @@ -31,31 +32,25 @@ public function __construct( * * Please refer to the [PHP manual](https://php.net/manual/en/pdo.construct.php) on the format of the DSN string. * - * The `driver` array key is used as the driver prefix of the DSN, all further key-value pairs are rendered as - * `key=value` and concatenated by `;`. For example: + * The `driver` property is used as the driver prefix of the DSN. For example: * * ```php * $dsn = new Dsn('oci', 'localhost', 'yiitest', '1521', ['charset' => 'AL32UTF8']); - * $connection = new Connection($dsn->asString(), 'system', 'root'); + * $driver = new Driver($dsn, 'username', 'password'); + * $connection = new Connection($driver, 'system', 'root'); * ``` * * Will result in the DSN string `oci:dbname=localhost:1521/yiitest;charset=AL32UTF8`. */ - public function asString(): string + public function __toString(): string { - $driver = $this->getDriver(); - $host = $this->getHost(); - $databaseName = $this->getDatabaseName(); - $port = $this->getPort(); - $options = $this->getOptions(); - - $dsn = "$driver:dbname=$host:$port"; + $dsn = "$this->driver:dbname=$this->host:$this->port"; - if (!empty($databaseName)) { - $dsn .= "/$databaseName"; + if ($this->databaseName !== '') { + $dsn .= "/$this->databaseName"; } - foreach ($options as $key => $value) { + foreach ($this->options as $key => $value) { $dsn .= ";$key=$value"; } diff --git a/tests/DsnTest.php b/tests/DsnTest.php index 9239572c..67c2e74d 100644 --- a/tests/DsnTest.php +++ b/tests/DsnTest.php @@ -14,46 +14,39 @@ */ final class DsnTest extends TestCase { - public function testAsStringWithDatabaseName(): void + public function testConstruct(): void { - $this->assertSame( - 'oci:dbname=localhost:1521;charset=AL32UTF8', - (new Dsn('oci', 'localhost', port: '1521', options: ['charset' => 'AL32UTF8']))->asString(), - ); + $dsn = new Dsn('oci', 'localhost', 'yiitest', '1522', ['charset' => 'AL32UTF8']); + + $this->assertSame('oci', $dsn->driver); + $this->assertSame('localhost', $dsn->host); + $this->assertSame('yiitest', $dsn->databaseName); + $this->assertSame('1522', $dsn->port); + $this->assertSame(['charset' => 'AL32UTF8'], $dsn->options); + $this->assertSame('oci:dbname=localhost:1522/yiitest;charset=AL32UTF8', (string) $dsn); } - public function testAsStringWithDatabaseNameWithEmptyString(): void + public function testConstructDefaults(): void { - $this->assertSame( - 'oci:dbname=localhost:1521;charset=AL32UTF8', - (new Dsn('oci', 'localhost', '', '1521', ['charset' => 'AL32UTF8']))->asString(), - ); + $dsn = new Dsn(); + + $this->assertSame('oci', $dsn->driver); + $this->assertSame('127.0.0.1', $dsn->host); + $this->assertSame('', $dsn->databaseName); + $this->assertSame('1521', $dsn->port); + $this->assertSame([], $dsn->options); + $this->assertSame('oci:dbname=127.0.0.1:1521', (string) $dsn); } - public function testAsStringWithDatabaseNameWithNull(): void + public function testConstructWithEmptyPort(): void { - $this->assertSame( - 'oci:dbname=localhost:1521;charset=AL32UTF8', - (new Dsn('oci', 'localhost', null, '1521', ['charset' => 'AL32UTF8']))->asString(), - ); - } - - /** - * Oracle service name it support only in version 18 and higher, for docker image gvenzl/oracle-xe:18 - */ - public function testAsStringWithService(): void - { - $this->assertSame( - 'oci:dbname=localhost:1521/yiitest;charset=AL32UTF8', - (new Dsn('oci', 'localhost', 'yiitest', '1521', ['charset' => 'AL32UTF8']))->asString(), - ); - } - - public function testAsStringWithSID(): void - { - $this->assertSame( - 'oci:dbname=localhost:1521/XE;charset=AL32UTF8', - (new Dsn('oci', 'localhost', 'XE', '1521', ['charset' => 'AL32UTF8']))->asString(), - ); + $dsn = new Dsn('oci', 'localhost', port: ''); + + $this->assertSame('oci', $dsn->driver); + $this->assertSame('localhost', $dsn->host); + $this->assertSame('', $dsn->databaseName); + $this->assertSame('', $dsn->port); + $this->assertSame([], $dsn->options); + $this->assertSame('oci:dbname=localhost:', (string) $dsn); } } diff --git a/tests/Support/TestTrait.php b/tests/Support/TestTrait.php index 7e3ff72b..32a73a0b 100644 --- a/tests/Support/TestTrait.php +++ b/tests/Support/TestTrait.php @@ -37,12 +37,12 @@ protected function getConnection(bool $fixture = false): Connection protected static function getDb(): Connection { - $dsn = (new Dsn( + $dsn = (string) new Dsn( host: self::getHost(), databaseName: self::getSid(), port: self::getPort(), options: ['charset' => 'AL32UTF8'], - ))->asString(); + ); return new Connection(new Driver($dsn, self::getUsername(), self::getPassword()), DbHelper::getSchemaCache()); } @@ -50,12 +50,12 @@ protected static function getDb(): Connection protected function getDsn(): string { if ($this->dsn === '') { - $this->dsn = (new Dsn( + $this->dsn = (string) new Dsn( host: self::getHost(), databaseName: self::getSid(), port: self::getPort(), options: ['charset' => 'AL32UTF8'], - ))->asString(); + ); } return $this->dsn;