Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
91e5e33
Add base DTO config compatibility
SerafimArts Oct 6, 2021
5fcbf99
Fix tests driver memoization
SerafimArts Oct 6, 2021
fc391ed
Apply phpcs
SerafimArts Oct 6, 2021
1e32030
Rename config DTOs (Info -> Config)
SerafimArts Oct 6, 2021
87d01ca
Add DSN connection configuration classes
SerafimArts Oct 6, 2021
17a9025
Fix SQLite and SQLServer DSN db source
SerafimArts Oct 6, 2021
77d26be
Improve constructor docblock
SerafimArts Oct 6, 2021
bf8b88d
Rename "Uri" to "Tcp"
SerafimArts Oct 7, 2021
c9dd36d
Deshuffle methods in the Driver class
roxblnfk Oct 13, 2021
42b0807
Update src/Driver/Driver.php
SerafimArts Oct 13, 2021
23e331f
Update composer.json
SerafimArts Oct 13, 2021
5287004
Rename driver "addr" to "connection"
SerafimArts Oct 14, 2021
7b128b4
Improve tests docblocks
SerafimArts Oct 14, 2021
2728e09
Improve read pcre
SerafimArts Oct 14, 2021
075ed5d
Add TODO with parameter escaping
SerafimArts Oct 14, 2021
dd173e2
Improve postgres driver config param description
SerafimArts Oct 14, 2021
418bf66
Add sqlite's config database parameter description.
SerafimArts Oct 14, 2021
5b76fee
Remove unused config class
SerafimArts Oct 14, 2021
8f5eb17
Remove final keyword from config DTO
SerafimArts Oct 14, 2021
5187cfb
Improve and fix driver configs
SerafimArts Oct 21, 2021
4f9f4d6
add static method create to DriverInterface and all drivers
msmakouz Nov 2, 2021
5c24fd7
remove optional parameters from create method
msmakouz Nov 3, 2021
c2e1988
fix cs
msmakouz Nov 3, 2021
aaa6322
fix creation driver, fix tests
msmakouz Nov 3, 2021
fe66193
fix docblock on method getDrivers
msmakouz Nov 3, 2021
99a8577
Merge remote-tracking branch 'origin/master' into feature/configs-dto
msmakouz Nov 8, 2021
8ba832e
update readme
msmakouz Nov 9, 2021
66c2e8d
remove unused import
msmakouz Nov 9, 2021
56f2249
change connection example in readme
msmakouz Nov 9, 2021
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
34 changes: 18 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Cycle DBAL
========
# Cycle DBAL

[![Latest Stable Version](https://poser.pugx.org/cycle/database/v/stable)](https://packagist.org/packages/cycle/database)
[![Build Status](https://github.com/cycle/database/workflows/build/badge.svg)](https://github.com/cycle/database/actions)
[![Codecov](https://codecov.io/gh/cycle/database/branch/master/graph/badge.svg)](https://codecov.io/gh/cycle/database/)

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

Documentation
--------
## Documentation

* [Installation and Configuration](https://spiral.dev/docs/database-configuration)
* [Access Database](https://spiral.dev/docs/database-access)
* [Database Isolation](https://spiral.dev/docs/database-isolation)
Expand All @@ -18,20 +18,22 @@ Documentation
* [Migrations](https://spiral.dev/docs/database-migrations)
* [Errata](https://spiral.dev/docs/database-errata)

Requirements
--------
## Requirements

Make sure that your server is configured with following PHP version and extensions:
* PHP 7.2+
* PHP 8.0+
* PDO Extension with desired database drivers

## Installation

To install the component:

```
$ composer require cycle/database
```

## Example

Given example demonstrates the connection to SQLite database, creation of table schema, data insertion and selection:

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

require_once "vendor/autoload.php";

use Cycle\Database\Config\DatabaseConfig;
use Cycle\Database\Config;
use Cycle\Database\DatabaseManager;
use Cycle\Database\Driver\SQLite\SQLiteDriver;

$dbm = new DatabaseManager(new DatabaseConfig([
$dbm = new DatabaseManager(new Config\DatabaseConfig([
'databases' => [
'default' => ['connection' => 'sqlite'],
],
'connections' => [
'sqlite' => [
'driver' => SQLiteDriver::class,
'connection' => 'sqlite:database.db',
],
'sqlite' => new Config\SQLiteDriverConfig(
connection: new Config\SQLite\FileConnectionConfig(
database: 'runtime/database.db'
),
),
],
]));

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

License:
--------
## License:

MIT License (MIT). Please see [`LICENSE`](./LICENSE) for more information. Maintained by [Spiral Scout](https://spiralscout.com).
9 changes: 4 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 @@ -32,9 +32,8 @@
"vimeo/psalm": "^4.10",
"phpunit/phpunit": "^8.5|^9.0",
"mockery/mockery": "^1.3",
"spiral/dumper": "^2.8",
"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();
}
}
23 changes: 12 additions & 11 deletions src/Config/DatabaseConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

namespace Cycle\Database\Config;

use Spiral\Core\Container\Autowire;
use Spiral\Core\InjectableConfig;
use Spiral\Core\Traits\Config\AliasTrait;
use Cycle\Database\Driver\DriverInterface;
use Cycle\Database\Exception\ConfigException;

final class DatabaseConfig extends InjectableConfig
Expand Down Expand Up @@ -60,7 +60,7 @@ public function getDatabases(): array
/**
* Get names list of all driver connections.
*
* @return Autowire[]
* @return DriverInterface[]
*/
public function getDrivers(): array
{
Expand Down Expand Up @@ -114,26 +114,27 @@ public function hasDriver(string $driver): bool

/**
* @param string $driver
* @return Autowire
* @return DriverInterface
*
* @throws ConfigException
*/
public function getDriver(string $driver): Autowire
public function getDriver(string $driver): DriverInterface
{
if (!$this->hasDriver($driver)) {
throw new ConfigException("Undefined driver `{$driver}`");
}

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

$options = $config;
if (isset($config['options']) && $config['options'] !== []) {
$options = $config['options'] + $config;
if ($config instanceof DriverConfig) {
return $config->driver::create($config);
}

return new Autowire($config['driver'] ?? $config['class'], ['options' => $options]);
throw new \InvalidArgumentException(
\vsprintf('Driver config must be an instance of %s, but %s passed', [
DriverConfig::class,
\get_debug_type($config)
])
);
}
}
46 changes: 46 additions & 0 deletions src/Config/DriverConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?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;
use Cycle\Database\Config\PDOConnectionConfig;

/**
* 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 PDOConnectionConfig
*/
abstract class DriverConfig
{
/**
* @param T $connection
* @param class-string<DriverInterface> $driver
* @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 string $driver,
public bool $reconnect = true,
public string $timezone = 'UTC',
public bool $queryCache = true,
public bool $readonlySchema = false,
public bool $readonly = false,
) {
}
}
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 BaseConnectionConfig
*/
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';
}
}
Loading