Test Setup Failed
Push — master ( 455f41...6456b5 )
by Gabriel
11:14 queued 12s
created

MySqlConnector::setModes()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 4
nc 4
nop 2
1
<?php
2
3
namespace Nip\Database\Connectors;
4
5
use PDO;
6
7
/**
8
 * Class MySqlConnector
9
 * @package Nip\Database\Connectors
10
 */
11
class MySqlConnector extends Connector
12
{
13
14
    /**
15
     * Establish a database connection.
16
     *
17
     * @param array $config
18
     * @return \PDO
19
     */
20
    public function connect(array $config)
21
    {
22
        $dsn = $this->getDsn($config);
23
24
        $options = $this->getOptions($config);
25
26
        // We need to grab the PDO options that should be used while making the brand
27
        // new connection instance. The PDO options control various aspects of the
28
        // connection's behavior, and some might be specified by the developers.
29
        $connection = $this->createConnection($dsn, $config, $options);
30
31
        if (!empty($config['database'])) {
32
            $connection->exec("use `{$config['database']}`;");
33
        }
34
35
        $this->configureIsolationLevel($connection, $config);
36
37
        $this->configureEncoding($connection, $config);
38
39
        // Next, we will check to see if a timezone has been specified in this config
40
        // and if it has we will issue a statement to modify the timezone with the
41
        // database. Setting this DB timezone is an optional configuration item.
42
        $this->configureTimezone($connection, $config);
43
44
        $this->setModes($connection, $config);
45
46
        return $connection;
47
    }
48
49
    /**
50
     * Set the connection transaction isolation level.
51
     *
52
     * @param \PDO $connection
53
     * @param array $config
54
     * @return void
55
     */
56
    protected function configureIsolationLevel($connection, array $config)
57
    {
58
        if (!isset($config['isolation_level'])) {
59
            return;
60
        }
61
62
        $connection->prepare(
63
            "SET SESSION TRANSACTION ISOLATION LEVEL {$config['isolation_level']}"
64
        )->execute();
65
    }
66
67
68
    /**
69
     * Set the connection character set and collation.
70
     *
71
     * @param \PDO $connection
72
     * @param array $config
73
     * @return void|\PDO
74
     */
75
    protected function configureEncoding($connection, array $config)
76
    {
77
        if (!isset($config['charset'])) {
78
            return $connection;
79
        }
80
81
        $connection->prepare(
82
            "set names '{$config['charset']}'".$this->getCollation($config)
83
        )->execute();
84
    }
85
86
    /**
87
     * Get the collation for the configuration.
88
     *
89
     * @param array $config
90
     * @return string
91
     */
92
    protected function getCollation(array $config)
93
    {
94
        return isset($config['collation']) ? " collate '{$config['collation']}'" : '';
95
    }
96
97
    /**
98
     * Set the timezone on the connection.
99
     *
100
     * @param \PDO $connection
101
     * @param array $config
102
     * @return void
103
     */
104
    protected function configureTimezone($connection, array $config)
105
    {
106
        if (isset($config['timezone'])) {
107
            $connection->prepare('set time_zone="'.$config['timezone'].'"')->execute();
108
        }
109
    }
110
111
    /**
112
     * Create a DSN string from a configuration.
113
     *
114
     * Chooses socket or host/port based on the 'unix_socket' config value.
115
     *
116
     * @param array $config
117
     * @return string
118
     */
119
    protected function getDsn(array $config)
120
    {
121
        return $this->hasSocket($config)
122
            ? $this->getSocketDsn($config)
123
            : $this->getHostDsn($config);
124
    }
125
126
    /**
127
     * Determine if the given configuration array has a UNIX socket value.
128
     *
129
     * @param array $config
130
     * @return bool
131
     */
132
    protected function hasSocket(array $config)
133
    {
134
        return isset($config['unix_socket']) && !empty($config['unix_socket']);
135
    }
136
137
    /**
138
     * Get the DSN string for a socket configuration.
139
     *
140
     * @param array $config
141
     * @return string
142
     */
143
    protected function getSocketDsn(array $config)
144
    {
145
        return "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}";
146
    }
147
148
    /**
149
     * Get the DSN string for a host / port configuration.
150
     *
151
     * @param array $config
152
     * @return string
153
     */
154
    protected function getHostDsn(array $config)
155
    {
156
        extract($config, EXTR_SKIP);
157
158
        return isset($port)
159
            ? "mysql:host={$host};port={$port};dbname={$database}"
160
            : "mysql:host={$host};dbname={$database}";
161
    }
162
163
    /**
164
     * Set the modes for the connection.
165
     *
166
     * @param \PDO $connection
167
     * @param array $config
168
     * @return void
169
     */
170
    protected function setModes(PDO $connection, array $config)
171
    {
172
        if (isset($config['modes'])) {
173
            $this->setCustomModes($connection, $config);
174
        } elseif (isset($config['strict'])) {
175
            if ($config['strict']) {
176
                $connection->prepare($this->strictMode($connection, $config))->execute();
177
            } else {
178
                $connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
179
            }
180
        }
181
    }
182
183
    /**
184
     * Set the custom modes on the connection.
185
     *
186
     * @param \PDO $connection
187
     * @param array $config
188
     * @return void
189
     */
190
    protected function setCustomModes(PDO $connection, array $config)
191
    {
192
        $modes = implode(',', $config['modes']);
193
194
        $connection->prepare("set session sql_mode='{$modes}'")->execute();
195
    }
196
197
    /**
198
     * Get the query to enable strict mode.
199
     *
200
     * @param \PDO $connection
201
     * @param array $config
202
     * @return string
203
     */
204
    protected function strictMode(PDO $connection, $config)
205
    {
206
        $version = $config['version'] ?? $connection->getAttribute(PDO::ATTR_SERVER_VERSION);
207
208
        if (version_compare($version, '8.0.11') >= 0) {
209
            return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
210
        }
211
212
        return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'";
213
    }
214
}