Passed
Pull Request — master (#31)
by Sébastien
12:54 queued 06:01
created

ConnectionRegistry::getDefaultConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Bdf\Prime\Connection;
4
5
use Bdf\Dsn\Dsn;
6
use Bdf\Prime\Connection\Configuration\ConfigurationResolver;
7
use Bdf\Prime\Connection\Configuration\ConfigurationResolverInterface;
8
use Bdf\Prime\Connection\Factory\ConnectionFactory;
9
use Bdf\Prime\Connection\Factory\ConnectionFactoryInterface;
10
use Bdf\Prime\ConnectionRegistryInterface;
11
use Bdf\Prime\Exception\DBALException;
12
13
/**
14
 * ConnectionRegistry
15
 */
16
class ConnectionRegistry implements ConnectionRegistryInterface
17
{
18
    /**
19
     * The connection factory
20
     *
21
     * @var ConnectionFactoryInterface
22
     */
23
    private $connectionFactory;
24
25
    /**
26
     * The configuration resolver
27
     *
28
     * @var ConfigurationResolverInterface
29
     */
30
    private $configResolver;
31
32
    /**
33
     * The configuration map
34
     * Contains configuration of some connections
35
     *
36
     * @var array
37
     */
38
    private $parametersMap;
39
40
    /**
41
     * The drive name alias
42
     *
43
     * @var array
44
     */
45
    static private $driverSchemeAliases = [
0 ignored issues
show
Coding Style introduced by
The static declaration must come after the visibility declaration
Loading history...
46
        'db2'        => 'ibm_db2',
47
        'mssql'      => 'pdo_sqlsrv',
48
        'mysql'      => 'pdo_mysql',
49
        'mysql2'     => 'pdo_mysql', // Amazon RDS, for some weird reason
0 ignored issues
show
Coding Style introduced by
Comments may not appear after statements
Loading history...
50
        'postgres'   => 'pdo_pgsql',
51
        'postgresql' => 'pdo_pgsql',
52
        'pgsql'      => 'pdo_pgsql',
53
        'sqlite'     => 'pdo_sqlite',
54
        'sqlite3'    => 'pdo_sqlite',
55
    ];
56
57
    /**
58
     * Set default configuration
59
     *
60
     * @param array $parametersMap
61
     * @param ConnectionFactoryInterface|null $connectionFactory
62
     * @param ConfigurationResolverInterface|null $configResolver
63
     */
64 205
    public function __construct(array $parametersMap = [], ConnectionFactoryInterface $connectionFactory = null, ConfigurationResolverInterface $configResolver = null)
65
    {
66 205
        $this->parametersMap = $parametersMap;
67 205
        $this->connectionFactory = $connectionFactory ?? new ConnectionFactory();
0 ignored issues
show
Coding Style introduced by
Operation must be bracketed
Loading history...
68 205
        $this->configResolver = $configResolver ?? new ConfigurationResolver();
0 ignored issues
show
Coding Style introduced by
Operation must be bracketed
Loading history...
69 205
    }
70
    
71
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $name should have a doc-comment as per coding-style.
Loading history...
72
     * {@inheritDoc}
73
     */
74 171
    public function getConnection(string $name): ConnectionInterface
75
    {
76 171
        return $this->connectionFactory->create($name, $this->getConnectionParameters($name), $this->configResolver->getConfiguration($name));
77
    }
78
79
    /**
80
     * Associate configuration to connection
81
     *
82
     * @param string $connectionName
83
     * @param string|array $parameters
84
     */
85 58
    public function declareConnection(string $connectionName, $parameters)
86
    {
87 58
        $this->parametersMap[$connectionName] = $parameters;
88 58
    }
89
90
    /**
91
     * {@inheritDoc}
92
     */
93 5
    public function getConnectionNames(): array
94
    {
95 5
        return array_keys($this->parametersMap);
96
    }
97
98
    /**
99
     * Create the doctrine config for the connection
100
     *
101
     * @param string $connectionName
102
     *
103
     * @return array
104
     */
0 ignored issues
show
Coding Style Documentation introduced by
Missing @throws tag in function comment
Loading history...
105 171
    private function getConnectionParameters(string $connectionName): array
0 ignored issues
show
Coding Style introduced by
Private method name "ConnectionRegistry::getConnectionParameters" must be prefixed with an underscore
Loading history...
106
    {
107 171
        if (!isset($this->parametersMap[$connectionName])) {
108 2
            throw new DBALException('Connection name "' . $connectionName . '" is not set');
109
        }
110
111 169
        $parameters = $this->parametersMap[$connectionName];
112
113
        // Manage string configuration as dsn
114 169
        if (is_string($parameters)) {
115 29
            $parameters = ['url' => $parameters];
116
        }
117
118
        //@todo move in factory ? Allows shard / slave to use url as parameter. Otherwise doctrine will evaluate the url
0 ignored issues
show
Coding Style introduced by
No space found before comment text; expected "// @todo move in factory ? Allows shard / slave to use url as parameter. Otherwise doctrine will evaluate the url" but found "//@todo move in factory ? Allows shard / slave to use url as parameter. Otherwise doctrine will evaluate the url"
Loading history...
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
119
        // Url key describe a dsn. Extract item from dsn and merge info the current config
120 169
        if (isset($parameters['url'])) {
121 32
            $parameters = array_merge($parameters, $this->parseDsn($parameters['url']));
122
            // Remove url: don't let doctrine parse the url
123 32
            unset($parameters['url']);
124
        }
125
126 169
        return $parameters;
127
    }
128
129
    /**
130
     * Parse the dsn string
131
     *
132
     * @param string $dsn
133
     *
134
     * @return array
135
     */
136 32
    private function parseDsn(string $dsn): array
0 ignored issues
show
Coding Style introduced by
Private method name "ConnectionRegistry::parseDsn" must be prefixed with an underscore
Loading history...
137
    {
138 32
        $request = Dsn::parse($dsn);
139
140 32
        $parameters = $request->getQuery() + [
0 ignored issues
show
Coding Style introduced by
Operation must be bracketed
Loading history...
141 32
                'host' => $request->getHost(),
0 ignored issues
show
Coding Style introduced by
Array key not indented correctly; expected 12 spaces but found 16
Loading history...
142 32
                'port' => $request->getPort(),
0 ignored issues
show
Coding Style introduced by
Array key not indented correctly; expected 12 spaces but found 16
Loading history...
143 32
                'user' => $request->getUser(),
0 ignored issues
show
Coding Style introduced by
Array key not indented correctly; expected 12 spaces but found 16
Loading history...
144 32
                'password' => $request->getPassword(),
0 ignored issues
show
Coding Style introduced by
Array key not indented correctly; expected 12 spaces but found 16
Loading history...
145
            ];
0 ignored issues
show
Coding Style introduced by
Array close brace not indented correctly; expected 8 spaces but found 12
Loading history...
introduced by
Array closing indentation error, expected 8 spaces but found 12
Loading history...
146
147
        // Get drive from alias or manage synthax 'pdo+mysql' because '_' are not allowed in scheme
148 32
        $parameters['driver'] = self::$driverSchemeAliases[$request->getScheme()] ?? str_replace('+', '_', $request->getScheme());
0 ignored issues
show
Coding Style introduced by
Operation must be bracketed
Loading history...
149
150
        // SQLite option: dont create dbname key use by many drivers
151
        // Sqlite drive needs memory or path key
152
        // Remove the 'path' if not used by sqlite
153 32
        if (strpos($parameters['driver'], 'sqlite') !== false) {
154 26
            if ($request->getPath() === ':memory:') {
155 24
                $parameters['memory'] = true;
156
            } else {
157 26
                $parameters['path'] = $request->getPath();
158
            }
159 6
        } elseif (!isset($parameters['dbname'])) {
0 ignored issues
show
Coding Style introduced by
Usage of ELSEIF not allowed; use ELSE IF instead
Loading history...
160 2
            $parameters['dbname'] = trim($request->getPath(), '/');
0 ignored issues
show
Bug introduced by
It seems like $request->getPath() can also be of type null; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

160
            $parameters['dbname'] = trim(/** @scrutinizer ignore-type */ $request->getPath(), '/');
Loading history...
161
        }
162
163 32
        return $parameters;
164
    }
165
}
166