ConnectionFactory::createPdoInstance()   B
last analyzed

Complexity

Conditions 7
Paths 7

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 19
c 1
b 0
f 0
nc 7
nop 1
dl 0
loc 32
rs 8.8333
1
<?php
2
/**
3
 * Framy Framework
4
 *
5
 * @copyright Copyright Framy
6
 * @Author Marco Bier <[email protected]>
7
 */
8
9
namespace app\framework\Component\Database\Connection;
10
11
use app\framework\Component\Config\Config;
12
use app\framework\Component\StdLib\SingletonTrait;
13
use PDO;
14
15
/**
16
 * Class ConnectionFactory
17
 * Created to be an convenient way of creating connections
18
 * based on configurations. But will be modified to hold the
19
 * instances of the connections as well, so for every connection
20
 * used only one instance of it will exist.
21
 *
22
 * @package app\framework\Component\Database\Connection
23
 */
24
class ConnectionFactory
25
{
26
    use SingletonTrait;
27
28
    const defaultConfigElements = [
29
        'driver',
30
        'host',
31
        'port',
32
        'database',
33
        'username',
34
        'password',
35
        'charset',
36
        'collation',
37
        'prefix',
38
        'strict',
39
        'engine',
40
    ];
41
42
    /**
43
     * @var Connection[]
44
     */
45
    private $connections = [];
46
47
    /**
48
     * Contains the connection configuration information's
49
     *
50
     * @var array
51
     */
52
    private $configuration = [];
53
54
    /**
55
     * @param string|null $name
56
     * @return Connection
57
     * @throws ConnectionNotConfiguredException
58
     */
59
    public function get(string $name = null): Connection
60
    {
61
        // check if connection with $name was already instantiated if yes return
62
        if(isset($this->connections[$name])) {
63
            return $this->connections[$name];
64
        }
65
66
        // otherwise create and save in $connections
67
        return $this->make($name);
68
    }
69
70
    /**
71
     * Establish a PDO connection based on the configuration.
72
     * Set up default connection or the one defined and save in $connections
73
     *
74
     * @param $name String Name of the connection. If null use default.
75
     * @return Connection
76
     * @throws ConnectionNotConfiguredException
77
     */
78
    public function make(string $name = null): Connection
79
    {
80
        $this->extractConfig();
81
82
        $connection = $this->createSingleConnection(
83
            $this->getConnectionName($name)
0 ignored issues
show
Bug introduced by
It seems like $this->getConnectionName($name) can also be of type null; however, parameter $name of app\framework\Component\...reateSingleConnection() 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

83
            /** @scrutinizer ignore-type */ $this->getConnectionName($name)
Loading history...
84
        );
85
86
        $this->connections[$name] = $connection;
87
88
        return $connection;
89
    }
90
91
    /**
92
     *  Sets the $configuration value
93
     */
94
    private function extractConfig()
95
    {
96
        $connByConfig = Config::getInstance()->get("connections");
97
        $config = [];
98
99
        foreach ($connByConfig as $name => $con) {
100
            $config[$name] = $this->parseConfig($con);
101
        }
102
103
        $this->configuration = $config;
104
    }
105
106
    /**
107
     * @param string|null $name
108
     * @return int|string|null
109
     * @throws ConnectionNotConfiguredException
110
     */
111
    private function getConnectionName(string $name = null)
112
    {
113
        $config = $this->configuration;
114
115
        if (is_null($name)) {
116
            reset($config);
117
            return key($config);
118
        }
119
120
        if (isset($config[$name])) {
121
            return $name;
122
        } else {
123
            // if conf not found Exception
124
            throw new ConnectionNotConfiguredException("Connection $name is not Configured");
125
        }
126
    }
127
    
128
    /**
129
     * To be sure that the config array is as he is supposed to be.
130
     *
131
     * @param array $config
132
     * @return array the connection config
133
     */
134
    private function parseConfig(array $config): array
135
    {
136
        // make sure that the default config elements exist to prevent an undefined index warning
137
        foreach(self::defaultConfigElements as $configElement) {
138
            if(!array_key_exists($configElement, $config)) {
139
                $config[$configElement];
140
            }
141
        }
142
143
        return $config;
144
    }
145
146
    /**
147
     * Create a single database connection instance.
148
     *
149
     * @param string $name
150
     * @return Connection
151
     */
152
    private function createSingleConnection(string $name): Connection
153
    {
154
        $config = $this->configuration;
155
156
        $Pdo = $this->createPdoInstance($config[$name]);
157
158
        return $this->createConnection($Pdo, $config[$name]['database'], $name, $config);
159
    }
160
161
    /**
162
     * @param array $config
163
     * @return PDO
164
     */
165
    private function createPdoInstance(array $config)
166
    {
167
        $dsn = "";
168
169
        switch ($config['driver']) {
170
            case Driver::MariaDB:
171
            case Driver::MySql:
172
                $dsn = Driver::mysql($config);
173
                break;
174
175
            case Driver::PgSql:
176
                $dsn = Driver::pgsql($config);
177
                break;
178
179
            case Driver::SyBase:
180
                $dsn = Driver::sybase($config);
181
                break;
182
183
            case Driver::Oracle:
184
                $dsn = Driver::oracle($config);
185
                break;
186
187
            case Driver::MsSql:
188
                $dsn = Driver::mssql($config);
189
                break;
190
191
            //case 'sqlite':
192
            //    $this->pdo = new PDO('sqlite:' . $config['database_file'], null, null, $this->option);
193
            //    break;
194
        }
195
196
        return new PDO($dsn, $config['username'], $config['password']);
197
    }
198
199
    /**
200
     * @param PDO $Pdo
201
     * @param string $database
202
     * @param string $name
203
     * @param array $config
204
     * @return Connection
205
     */
206
    private function createConnection(PDO $Pdo, $database = "", string $name = '', array $config = [])
207
    {
208
        return new Connection($Pdo, $database, $name, $config);
209
    }
210
}
211