Skip to content

Commit 290336b

Browse files
msmakouzSerafimArtsroxblnfk
authored
Configuration using DTO (#14)
Co-authored-by: SerafimArts <[email protected]> Co-authored-by: roxblnfk <[email protected]>
1 parent b96ecc8 commit 290336b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1844
-770
lines changed

README.md

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
Cycle DBAL
2-
========
1+
# Cycle DBAL
2+
33
[![Latest Stable Version](https://poser.pugx.org/cycle/database/v/stable)](https://packagist.org/packages/cycle/database)
44
[![Build Status](https://github.com/cycle/database/workflows/build/badge.svg)](https://github.com/cycle/database/actions)
55
[![Codecov](https://codecov.io/gh/cycle/database/branch/master/graph/badge.svg)](https://codecov.io/gh/cycle/database/)
66

77
Secure, multiple SQL dialects (MySQL, PostgreSQL, SQLite, SQLServer), schema introspection, schema declaration, smart identifier wrappers, database partitions, query builders, nested queries.
88

9-
Documentation
10-
--------
9+
## Documentation
10+
1111
* [Installation and Configuration](https://spiral.dev/docs/database-configuration)
1212
* [Access Database](https://spiral.dev/docs/database-access)
1313
* [Database Isolation](https://spiral.dev/docs/database-isolation)
@@ -18,20 +18,22 @@ Documentation
1818
* [Migrations](https://spiral.dev/docs/database-migrations)
1919
* [Errata](https://spiral.dev/docs/database-errata)
2020

21-
Requirements
22-
--------
21+
## Requirements
22+
2323
Make sure that your server is configured with following PHP version and extensions:
24-
* PHP 7.2+
24+
* PHP 8.0+
2525
* PDO Extension with desired database drivers
2626

2727
## Installation
28+
2829
To install the component:
2930

3031
```
3132
$ composer require cycle/database
3233
```
3334

3435
## Example
36+
3537
Given example demonstrates the connection to SQLite database, creation of table schema, data insertion and selection:
3638

3739
```php
@@ -40,19 +42,19 @@ declare(strict_types=1);
4042

4143
require_once "vendor/autoload.php";
4244

43-
use Cycle\Database\Config\DatabaseConfig;
45+
use Cycle\Database\Config;
4446
use Cycle\Database\DatabaseManager;
45-
use Cycle\Database\Driver\SQLite\SQLiteDriver;
4647

47-
$dbm = new DatabaseManager(new DatabaseConfig([
48+
$dbm = new DatabaseManager(new Config\DatabaseConfig([
4849
'databases' => [
4950
'default' => ['connection' => 'sqlite'],
5051
],
5152
'connections' => [
52-
'sqlite' => [
53-
'driver' => SQLiteDriver::class,
54-
'connection' => 'sqlite:database.db',
55-
],
53+
'sqlite' => new Config\SQLiteDriverConfig(
54+
connection: new Config\SQLite\FileConnectionConfig(
55+
database: 'runtime/database.db'
56+
),
57+
),
5658
],
5759
]));
5860

@@ -79,6 +81,6 @@ foreach ($users->select()->where(['name' => 'test']) as $u) {
7981
}
8082
```
8183

82-
License:
83-
--------
84+
## License:
85+
8486
MIT License (MIT). Please see [`LICENSE`](./LICENSE) for more information. Maintained by [Spiral Scout](https://spiralscout.com).

composer.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
"require": {
1616
"php": ">=8.0",
1717
"ext-pdo": "*",
18-
"spiral/core": "^2.8",
19-
"spiral/logger": "^2.8",
20-
"spiral/pagination": "^2.8"
18+
"spiral/core": "^2.9",
19+
"spiral/logger": "^2.9",
20+
"spiral/pagination": "^2.9"
2121
},
2222
"autoload": {
2323
"files": [
@@ -32,9 +32,8 @@
3232
"vimeo/psalm": "^4.10",
3333
"phpunit/phpunit": "^8.5|^9.0",
3434
"mockery/mockery": "^1.3",
35-
"spiral/dumper": "^2.8",
3635
"spiral/code-style": "^1.0",
37-
"spiral/tokenizer": "^2.8"
36+
"spiral/tokenizer": "^2.9"
3837
},
3938
"autoload-dev": {
4039
"psr-4": {

src/Config/ConnectionConfig.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Cycle Database package.
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Cycle\Database\Config;
13+
14+
abstract class ConnectionConfig
15+
{
16+
/**
17+
* @var array<non-empty-string>
18+
*/
19+
protected array $nonPrintableOptions = [
20+
// Postgres and MySQL
21+
'password',
22+
// IBM, ODBC and DB2
23+
'PWD',
24+
];
25+
26+
/**
27+
* @param non-empty-string|null $user
28+
* @param non-empty-string|null $password
29+
*/
30+
public function __construct(
31+
public ?string $user = null,
32+
public ?string $password = null,
33+
) {
34+
}
35+
36+
/**
37+
* @return non-empty-string|null
38+
*/
39+
public function getUsername(): ?string
40+
{
41+
return $this->user;
42+
}
43+
44+
/**
45+
* @return non-empty-string|null
46+
*/
47+
public function getPassword(): ?string
48+
{
49+
return $this->password;
50+
}
51+
52+
/**
53+
* @param bool $secure
54+
* @return array
55+
*/
56+
protected function toArray(bool $secure = true): array
57+
{
58+
$options = \get_object_vars($this);
59+
60+
foreach ($options as $key => $value) {
61+
if ($secure && \in_array($key, $this->nonPrintableOptions, true)) {
62+
$value = '<hidden>';
63+
}
64+
65+
$options[$key] = $value;
66+
}
67+
68+
return $options;
69+
}
70+
71+
/**
72+
* @return array
73+
*/
74+
public function __debugInfo(): array
75+
{
76+
return $this->toArray();
77+
}
78+
}

src/Config/DatabaseConfig.php

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
namespace Cycle\Database\Config;
1313

14-
use Spiral\Core\Container\Autowire;
1514
use Spiral\Core\InjectableConfig;
1615
use Spiral\Core\Traits\Config\AliasTrait;
16+
use Cycle\Database\Driver\DriverInterface;
1717
use Cycle\Database\Exception\ConfigException;
1818

1919
final class DatabaseConfig extends InjectableConfig
@@ -60,7 +60,7 @@ public function getDatabases(): array
6060
/**
6161
* Get names list of all driver connections.
6262
*
63-
* @return Autowire[]
63+
* @return DriverInterface[]
6464
*/
6565
public function getDrivers(): array
6666
{
@@ -114,26 +114,27 @@ public function hasDriver(string $driver): bool
114114

115115
/**
116116
* @param string $driver
117-
* @return Autowire
117+
* @return DriverInterface
118118
*
119119
* @throws ConfigException
120120
*/
121-
public function getDriver(string $driver): Autowire
121+
public function getDriver(string $driver): DriverInterface
122122
{
123123
if (!$this->hasDriver($driver)) {
124124
throw new ConfigException("Undefined driver `{$driver}`");
125125
}
126126

127127
$config = $this->config['connections'][$driver] ?? $this->config['drivers'][$driver];
128-
if ($config instanceof Autowire) {
129-
return $config;
130-
}
131128

132-
$options = $config;
133-
if (isset($config['options']) && $config['options'] !== []) {
134-
$options = $config['options'] + $config;
129+
if ($config instanceof DriverConfig) {
130+
return $config->driver::create($config);
135131
}
136132

137-
return new Autowire($config['driver'] ?? $config['class'], ['options' => $options]);
133+
throw new \InvalidArgumentException(
134+
\vsprintf('Driver config must be an instance of %s, but %s passed', [
135+
DriverConfig::class,
136+
\get_debug_type($config)
137+
])
138+
);
138139
}
139140
}

src/Config/DriverConfig.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Cycle Database package.
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Cycle\Database\Config;
13+
14+
use Cycle\Database\Driver\DriverInterface;
15+
use Cycle\Database\Config\PDOConnectionConfig;
16+
17+
/**
18+
* Connection configuration described in DBAL config file. Any driver can be
19+
* used as data source for multiple databases as table prefix and quotation
20+
* defined on Database instance level.
21+
*
22+
* @template T of PDOConnectionConfig
23+
*/
24+
abstract class DriverConfig
25+
{
26+
/**
27+
* @param T $connection
28+
* @param class-string<DriverInterface> $driver
29+
* @param bool $reconnect Allow reconnects
30+
* @param non-empty-string $timezone All datetime objects will be converted
31+
* relative to this timezone (must match with DB timezone!)
32+
* @param bool $queryCache Enables query caching
33+
* @param bool $readonlySchema Disable schema modifications
34+
* @param bool $readonly Disable write expressions
35+
*/
36+
public function __construct(
37+
public ConnectionConfig $connection,
38+
public string $driver,
39+
public bool $reconnect = true,
40+
public string $timezone = 'UTC',
41+
public bool $queryCache = true,
42+
public bool $readonlySchema = false,
43+
public bool $readonly = false,
44+
) {
45+
}
46+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Cycle Database package.
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Cycle\Database\Config\MySQL;
13+
14+
use Cycle\Database\Config\PDOConnectionConfig as BaseConnectionConfig;
15+
16+
/**
17+
* @psalm-import-type PDOFlag from BaseConnectionConfig
18+
*/
19+
abstract class ConnectionConfig extends BaseConnectionConfig
20+
{
21+
/**
22+
* General driver specific PDO options.
23+
*
24+
* @var array<PDOFlag, mixed>
25+
*/
26+
protected const DEFAULT_PDO_OPTIONS = [
27+
\PDO::ATTR_CASE => \PDO::CASE_NATURAL,
28+
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
29+
// TODO Should be moved into common driver settings.
30+
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES "UTF8"',
31+
\PDO::ATTR_STRINGIFY_FETCHES => false,
32+
];
33+
34+
/**
35+
* @param non-empty-string|null $user
36+
* @param non-empty-string|null $password
37+
* @param array<non-empty-string|int, non-empty-string> $options
38+
*/
39+
public function __construct(
40+
?string $user = null,
41+
?string $password = null,
42+
array $options = [],
43+
) {
44+
parent::__construct($user, $password, $options);
45+
}
46+
47+
/**
48+
* {@inheritDoc}
49+
*/
50+
public function getName(): string
51+
{
52+
return 'mysql';
53+
}
54+
}

0 commit comments

Comments
 (0)