Completed
Push — master ( c4e3cd...c5cae6 )
by Anton
05:38
created

DatabaseManager   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 154
Duplicated Lines 18.18 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 6
Bugs 0 Features 1
Metric Value
wmc 13
c 6
b 0
f 1
lcom 1
cbo 4
dl 28
loc 154
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B database() 28 28 4
A driver() 0 22 3
A getDatabases() 0 9 2
A getDrivers() 0 9 2
A createInjection() 0 5 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\Database;
9
10
use Spiral\Core\Component;
11
use Spiral\Core\FactoryInterface;
12
use Spiral\Core\Container\InjectorInterface;
13
use Spiral\Database\Configs\DatabasesConfig;
14
use Spiral\Database\Entities\Database;
15
use Spiral\Database\Entities\Driver;
16
use Spiral\Database\Exceptions\DatabaseException;
17
18
/**
19
 * DatabaseManager responsible for database creation, configuration storage and drivers factory.
20
 */
21
class DatabaseManager extends Component implements InjectorInterface, DatabasesInterface
22
{
23
    /**
24
     * Declares to Spiral IoC that component instance should be treated as singleton.
25
     */
26
    const SINGLETON = self::class;
27
28
    /**
29
     * By default spiral will force time conversion into single timezone before storing in
30
     * database, it will help us to ensure that we have no problems with switching timezones and
31
     * save a lot of time while development (potentially).
32
     * 
33
     * Current implementation of drivers leaves a room and possibility to define driver/connection
34
     * specific timezone.
35
     */
36
    const DEFAULT_TIMEZONE = 'UTC';
37
38
    /**
39
     * @var Database[]
40
     */
41
    private $databases = [];
42
43
    /**
44
     * @var Driver[]
45
     */
46
    private $drivers = [];
47
48
    /**
49
     * @var DatabasesConfig
50
     */
51
    protected $config = null;
52
53
    /**
54
     * @invisible
55
     * @var FactoryInterface
56
     */
57
    protected $factory = null;
58
59
    /**
60
     * @param DatabasesConfig  $config
61
     * @param FactoryInterface $factory
62
     */
63
    public function __construct(DatabasesConfig $config, FactoryInterface $factory)
64
    {
65
        $this->config = $config;
66
        $this->factory = $factory;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     *
72
     * @return Database
73
     */
74 View Code Duplication
    public function database($database = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
    {
76
        if (empty($database)) {
77
            $database = $this->config->defaultDatabase();
78
        }
79
80
        //Spiral support ability to link multiple virtual databases together using aliases
81
        $database = $this->config->resolveAlias($database);
82
83
        if (isset($this->databases[$database])) {
84
            return $this->databases[$database];
85
        }
86
87
        if (!$this->config->hasDatabase($database)) {
88
            throw new DatabaseException(
89
                "Unable to create database, no presets for '{$database}' found."
90
            );
91
        }
92
93
        //No need to benchmark here, due connection will happen later
94
        $this->databases[$database] = $this->factory->make(Database::class, [
95
            'name'   => $database,
96
            'driver' => $this->driver($this->config->databaseConnection($database)),
97
            'prefix' => $this->config->databasePrefix($database)
98
        ]);
99
100
        return $this->databases[$database];
101
    }
102
103
    /**
104
     * Get driver by it's name. Every driver associated with configured connection, there is minor
105
     * de-sync in naming due legacy code.
106
     *
107
     * @param string $connection
108
     * @return Driver
109
     * @throws DatabaseException
110
     */
111
    public function driver($connection)
112
    {
113
        if (isset($this->drivers[$connection])) {
114
            return $this->drivers[$connection];
115
        }
116
117
        if (!$this->config->hasConnection($connection)) {
118
            throw new DatabaseException(
119
                "Unable to create Driver, no presets for '{$connection}' found."
120
            );
121
        }
122
123
        $this->drivers[$connection] = $this->factory->make(
124
            $this->config->connectionDriver($connection),
125
            [
126
                'name'   => $connection,
127
                'config' => $this->config->connectionConfig($connection)
128
            ]
129
        );
130
131
        return $this->drivers[$connection];
132
    }
133
134
    /**
135
     * Get instance of every available database.
136
     *
137
     * @return Database[]
138
     * @throws DatabaseException
139
     */
140
    public function getDatabases()
141
    {
142
        $result = [];
143
        foreach ($this->config->databaseNames() as $name) {
144
            $result[] = $this->database($name);
145
        }
146
147
        return $result;
148
    }
149
150
    /**
151
     * Get instance of every available driver/connection.
152
     *
153
     * @return Driver[]
154
     * @throws DatabaseException
155
     */
156
    public function getDrivers()
157
    {
158
        $result = [];
159
        foreach ($this->config->connectionNames() as $name) {
160
            $result[] = $this->driver($name);
161
        }
162
163
        return $result;
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     */
169
    public function createInjection(\ReflectionClass $class, $context = null)
170
    {
171
        //If context is empty default database will be returned
172
        return $this->database($context);
173
    }
174
}
175