Passed
Push — main ( 6013bc...7fab15 )
by Thierry
01:29
created

Driver::setUtf8mb4()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 2
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Lagdo\DbAdmin\Driver;
4
5
use Lagdo\DbAdmin\Driver\Db\ConnectionInterface;
6
use Lagdo\DbAdmin\Driver\Db\ServerInterface;
7
use Lagdo\DbAdmin\Driver\Db\DatabaseInterface;
8
use Lagdo\DbAdmin\Driver\Db\TableInterface;
9
use Lagdo\DbAdmin\Driver\Db\QueryInterface;
10
use Lagdo\DbAdmin\Driver\Db\GrammarInterface;
11
use Lagdo\DbAdmin\Driver\Entity\ConfigEntity;
12
use Lagdo\DbAdmin\Driver\Exception\AuthException;
13
14
use function in_array;
15
use function is_object;
16
use function preg_match;
17
use function version_compare;
18
19
abstract class Driver implements DriverInterface
20
{
21
    use ErrorTrait;
22
    use ConfigTrait;
0 ignored issues
show
introduced by
The trait Lagdo\DbAdmin\Driver\ConfigTrait requires some properties which are not provided by Lagdo\DbAdmin\Driver\Driver: $onActions, $jush, $numberRegex, $grouping, $editFunctions, $inout, $version, $unsigned, $enumLength, $functions, $types, $operators
Loading history...
23
    use ConnectionTrait;
24
    use ServerTrait;
25
    use TableTrait;
26
    use DatabaseTrait;
27
    use QueryTrait;
28
    use GrammarTrait;
29
30
    /**
31
     * @var UtilInterface
32
     */
33
    protected $util;
34
35
    /**
36
     * @var TranslatorInterface
37
     */
38
    protected $trans;
39
40
    /**
41
     * @var ServerInterface
42
     */
43
    protected $server;
44
45
    /**
46
     * @var DatabaseInterface
47
     */
48
    protected $database;
49
50
    /**
51
     * @var TableInterface
52
     */
53
    protected $table;
54
55
    /**
56
     * @var QueryInterface
57
     */
58
    protected $query;
59
60
    /**
61
     * @var GrammarInterface
62
     */
63
    protected $grammar;
64
65
    /**
66
     * @var ConnectionInterface
67
     */
68
    protected $connection;
69
70
    /**
71
     * @var ConnectionInterface
72
     */
73
    protected $mainConnection;
74
75
    /**
76
     * @var ConfigEntity
77
     */
78
    protected $config;
79
80
    /**
81
     * @var History
82
     */
83
    protected $history;
84
85
    /**
86
     * The constructor
87
     *
88
     * @param UtilInterface $util
89
     * @param TranslatorInterface $trans
90
     * @param array $options
91
     */
92
    public function __construct(UtilInterface $util, TranslatorInterface $trans, array $options)
93
    {
94
        $this->util = $util;
95
        $this->util->setDriver($this);
96
        $this->trans = $trans;
97
        $this->config = new ConfigEntity($trans, $options);
98
        $this->history = new History($trans);
99
        $this->initConfig();
100
        // Create and set the main connection.
101
        $this->mainConnection = $this->createConnection();
102
    }
103
104
    /**
105
     * Set driver config
106
     *
107
     * @return void
108
     */
109
    abstract protected function initConfig();
110
111
    /**
112
     * Set driver config
113
     *
114
     * @return void
115
     */
116
    abstract protected function postConnectConfig();
117
118
    /**
119
     * Create a connection to the server, based on the config and available packages
120
     *
121
     * @return ConnectionInterface|null
122
     */
123
    abstract protected function createConnection();
124
125
    /**
126
     * @param ConnectionInterface $connection
127
     *
128
     * @return Driver
129
     */
130
    public function useConnection(ConnectionInterface $connection)
131
    {
132
        $this->connection = $connection;
133
        return $this;
134
    }
135
136
    /**
137
     * @return Driver
138
     */
139
    public function useMainConnection()
140
    {
141
        $this->connection = $this->mainConnection;
142
        return $this;
143
    }
144
145
    /**
146
     * @inheritDoc
147
     */
148
    public function support(string $feature)
149
    {
150
        return in_array($feature, $this->config->features);
151
    }
152
153
    /**
154
     * @inheritDoc
155
     * @throws AuthException
156
     */
157
    public function open(string $database, string $schema = '')
158
    {
159
        if (!$this->connection->open($database, $schema)) {
160
            throw new AuthException($this->error());
161
        }
162
        $this->config->database = $database;
163
        $this->config->schema = $schema;
164
165
        $this->postConnectConfig();
166
        return $this->connection;
167
    }
168
169
    /**
170
     * @inheritDoc
171
     * @throws AuthException
172
     */
173
    public function connect(string $database, string $schema = '')
174
    {
175
        $this->createConnection();
176
        return $this->open($database, $schema);
177
    }
178
179
    /**
180
     * @inheritDoc
181
     */
182
    public function minVersion(string $version, string $mariaDb = '')
183
    {
184
        $info = $this->connection->serverInfo();
185
        if ($mariaDb && preg_match('~([\d.]+)-MariaDB~', $info, $match)) {
186
            $info = $match[1];
187
            $version = $mariaDb;
188
        }
189
        return (version_compare($info, $version) >= 0);
190
    }
191
192
    /**
193
     * @inheritDoc
194
     */
195
    public function charset()
196
    {
197
        // SHOW CHARSET would require an extra query
198
        return ($this->minVersion('5.5.3', 0) ? 'utf8mb4' : 'utf8');
199
    }
200
201
    /**
202
     * @inheritDoc
203
     */
204
    public function begin()
205
    {
206
        $result = $this->connection->query("BEGIN");
207
        return $result !== false;
208
    }
209
210
    /**
211
     * @inheritDoc
212
     */
213
    public function commit()
214
    {
215
        $result = $this->connection->query("COMMIT");
216
        return $result !== false;
217
    }
218
219
    /**
220
     * @inheritDoc
221
     */
222
    public function rollback()
223
    {
224
        $result = $this->connection->query("ROLLBACK");
225
        return $result !== false;
226
    }
227
228
    /**
229
     * @inheritDoc
230
     */
231
    public function setUtf8mb4(string $create)
232
    {
233
        static $set = false;
234
        // possible false positive
235
        if (!$set && preg_match('~\butf8mb4~i', $create)) {
236
            $set = true;
237
            return 'SET NAMES ' . $this->charset() . ";\n\n";
238
        }
239
        return '';
240
    }
241
242
    /**
243
     * @inheritDoc
244
     */
245
    public function execute(string $query)
246
    {
247
        $this->history->save($query);
248
        return $this->connection->query($query);
249
    }
250
251
    /**
252
     * @inheritDoc
253
     */
254
    public function queries()
255
    {
256
        return $this->history->queries();
257
    }
258
259
    /**
260
     * @inheritDoc
261
     */
262
    public function applyQueries(string $query, array $tables, $escape = null)
263
    {
264
        if (!$escape) {
265
            $escape = function ($table) {
266
                return $this->table($table);
267
            };
268
        }
269
        foreach ($tables as $table) {
270
            if (!$this->execute("$query " . $escape($table))) {
271
                return false;
272
            }
273
        }
274
        return true;
275
    }
276
277
    /**
278
     * @inheritDoc
279
     */
280
    public function values(string $query, int $column = 0)
281
    {
282
        $statement = $this->execute($query);
283
        if (!is_object($statement)) {
284
            return [];
285
        }
286
        $values = [];
287
        while ($row = $statement->fetchRow()) {
288
            $values[] = $row[$column];
289
        }
290
        return $values;
291
    }
292
293
    /**
294
     * @inheritDoc
295
     */
296
    public function colValues(string $query, string $column)
297
    {
298
        $statement = $this->execute($query);
299
        if (!is_object($statement)) {
300
            return [];
301
        }
302
        $values = [];
303
        while ($row = $statement->fetchAssoc()) {
304
            $values[] = $row[$column];
305
        }
306
        return $values;
307
    }
308
309
    /**
310
     * @inheritDoc
311
     */
312
    public function keyValues(string $query, int $keyColumn = 0, int $valueColumn = 1)
313
    {
314
        $statement = $this->execute($query);
315
        if (!is_object($statement)) {
316
            return [];
317
        }
318
        $values = [];
319
        while ($row = $statement->fetchRow()) {
320
            $values[$row[$keyColumn]] = $row[$valueColumn];
321
        }
322
        return $values;
323
    }
324
325
    /**
326
     * @inheritDoc
327
     */
328
    public function rows(string $query)
329
    {
330
        $statement = $this->execute($query);
331
        if (!is_object($statement)) { // can return true
332
            return [];
333
        }
334
        $rows = [];
335
        while ($row = $statement->fetchAssoc()) {
336
            $rows[] = $row;
337
        }
338
        return $rows;
339
    }
340
}
341