Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"require": {
"php": ">=8.0",
"ext-pdo": "*",
"spiral/core": "^2.8",
"spiral/logger": "^2.8",
"spiral/pagination": "^2.8"
"spiral/core": "^2.9",
"spiral/logger": "^2.9",
"spiral/pagination": "^2.9"
},
"autoload": {
"files": [
Expand All @@ -31,9 +31,10 @@
"vimeo/psalm": "^4.10",
"phpunit/phpunit": "^8.5|^9.0",
"mockery/mockery": "^1.3",
"spiral/dumper": "^2.8",
"symfony/var-dumper": "^5.4",
"spiral/dumper": "^2.9",
"spiral/code-style": "^1.0",
"spiral/tokenizer": "^2.8"
"spiral/tokenizer": "^2.9"
},
"autoload-dev": {
"psr-4": {
Expand Down
78 changes: 78 additions & 0 deletions src/Config/ConnectionConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

/**
* This file is part of Cycle Database package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Cycle\Database\Config;

abstract class ConnectionConfig
{
/**
* @var array<non-empty-string>
*/
protected array $nonPrintableOptions = [
// Postgres and MySQL
'password',
// IBM, ODBC and DB2
'PWD',
];

/**
* @param non-empty-string|null $user
* @param non-empty-string|null $password
*/
public function __construct(
public ?string $user = null,
public ?string $password = null,
) {
}

/**
* @return non-empty-string|null
*/
public function getUsername(): ?string
{
return $this->user;
}

/**
* @return non-empty-string|null
*/
public function getPassword(): ?string
{
return $this->password;
}

/**
* @param bool $secure
* @return array
*/
protected function toArray(bool $secure = true): array
{
$options = \get_object_vars($this);

foreach ($options as $key => $value) {
if ($secure && \in_array($key, $this->nonPrintableOptions, true)) {
$value = '<hidden>';
}

$options[$key] = $value;
}

return $options;
}

/**
* @return array
*/
public function __debugInfo(): array
{
return $this->toArray();
}
}
48 changes: 48 additions & 0 deletions src/Config/DriverConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

/**
* This file is part of Cycle Database package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Cycle\Database\Config;

use Cycle\Database\Driver\DriverInterface;

/**
* Connection configuration described in DBAL config file. Any driver can be
* used as data source for multiple databases as table prefix and quotation
* defined on Database instance level.
*
* @template T of TcpConnectionConfig
*/
abstract class DriverConfig
{
/**
* @param T $connection
* @param bool $reconnect Allow reconnects
* @param non-empty-string $timezone All datetime objects will be converted
* relative to this timezone (must match with DB timezone!)
* @param bool $queryCache Enables query caching
* @param bool $readonlySchema Disable schema modifications
* @param bool $readonly Disable write expressions
*/
public function __construct(
public ConnectionConfig $connection,
public bool $reconnect = true,
public string $timezone = 'UTC',
public bool $queryCache = true,
public bool $readonlySchema = false,
public bool $readonly = false,
) {
}

/**
* @return DriverInterface
*/
abstract public function getDriver(): DriverInterface;
}
54 changes: 54 additions & 0 deletions src/Config/MySQL/ConnectionConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

/**
* This file is part of Cycle Database package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Cycle\Database\Config\MySQL;

use Cycle\Database\Config\PDOConnectionConfig as BaseConnectionConfig;

/**
* @psalm-import-type PDOFlag from TcpConnectionConfig
*/
abstract class ConnectionConfig extends BaseConnectionConfig
{
/**
* General driver specific PDO options.
*
* @var array<PDOFlag, mixed>
*/
protected const DEFAULT_PDO_OPTIONS = [
\PDO::ATTR_CASE => \PDO::CASE_NATURAL,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
// TODO Should be moved into common driver settings.
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES "UTF8"',
\PDO::ATTR_STRINGIFY_FETCHES => false,
];

/**
* @param non-empty-string|null $user
* @param non-empty-string|null $password
* @param array<non-empty-string|int, non-empty-string> $options
*/
public function __construct(
?string $user = null,
?string $password = null,
array $options = [],
) {
parent::__construct($user, $password, $options);
}

/**
* {@inheritDoc}
*/
public function getName(): string
{
return 'mysql';
}
}
64 changes: 64 additions & 0 deletions src/Config/MySQL/DsnConnectionConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/**
* This file is part of Cycle Database package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Cycle\Database\Config\MySQL;

use Cycle\Database\Config\ProvidesSourceString;
use Cycle\Database\Config\Support\DataSourceName;

class DsnConnectionConfig extends ConnectionConfig implements ProvidesSourceString
{
/**
* @var string|null
*/
private ?string $database = null;

/**
* @var non-empty-string
* @psalm-allow-private-mutation
*/
public string $dsn;

/**
* @param non-empty-string|\Stringable $dsn
* @param non-empty-string|null $user
* @param non-empty-string|null $password
* @param array $options
*/
public function __construct(
string|\Stringable $dsn,
?string $user = null,
?string $password = null,
array $options = []
) {
parent::__construct($user, $password, $options);

/** @psalm-suppress ArgumentTypeCoercion */
$this->dsn = DataSourceName::normalize((string)$dsn, $this->getName());
}

/**
* {@inheritDoc}
*/
public function getSourceString(): string
{
/** @psalm-suppress ArgumentTypeCoercion */
return $this->database ??= DataSourceName::read($this->getDsn(), 'dbname') ?? '*';
}

/**
* {@inheritDoc}
*/
public function getDsn(): string
{
return $this->dsn;
}
}
64 changes: 64 additions & 0 deletions src/Config/MySQL/SocketConnectionConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/**
* This file is part of Cycle Database package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Cycle\Database\Config\MySQL;

use Cycle\Database\Config\ProvidesSourceString;

class SocketConnectionConfig extends ConnectionConfig implements ProvidesSourceString
{
/**
* @param non-empty-string $socket
* @param non-empty-string $database
* @param non-empty-string|null $charset
* @param non-empty-string|null $user
* @param non-empty-string|null $password
* @param array<non-empty-string|int, non-empty-string> $options
*/
public function __construct(
public string $database,
public string $socket,
public ?string $charset = null,
?string $user = null,
?string $password = null,
array $options = []
) {
parent::__construct($user, $password, $options);
}

/**
* {@inheritDoc}
*/
public function getSourceString(): string
{
return $this->database;
}

/**
* Returns the MySQL-specific PDO DataSourceName with connection Unix socket,
* that looks like:
* <code>
* mysql:unix_socket=/tmp/mysql.sock;dbname=dbname
* </code>
*
* {@inheritDoc}
*/
public function getDsn(): string
{
$config = [
'unix_socket' => $this->socket,
'dbname' => $this->database,
'charset' => $this->charset,
];

return \sprintf('%s:%s', $this->getName(), $this->dsn($config));
}
}
Loading