Passed
Push — main ( 0045ac...21c3d8 )
by Thierry
08:18 queued 01:36
created

Server::engines()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 9
rs 10
1
<?php
2
3
namespace Lagdo\DbAdmin\Driver\MySql\Db;
4
5
use Lagdo\DbAdmin\Driver\Db\Server as AbstractServer;
6
use Lagdo\DbAdmin\Driver\Db\StatementInterface;
7
8
use function array_key_exists;
9
use function is_a;
10
use function intval;
11
use function preg_match;
12
13
class Server extends AbstractServer
14
{
15
    /**
16
     * @inheritDoc
17
     */
18
    public function databases(bool $flush)
19
    {
20
        // !!! Caching and slow query handling are temporarily disabled !!!
21
        $query = $this->driver->minVersion(5) ?
22
            'SELECT SCHEMA_NAME FROM information_schema.SCHEMATA ORDER BY SCHEMA_NAME' :
23
            'SHOW DATABASES';
24
        return $this->driver->values($query);
25
26
        // SHOW DATABASES can take a very long time so it is cached
27
        // $databases = get_session('dbs');
28
        // if ($databases === null) {
29
        //     $query = ($this->driver->minVersion(5)
30
        //         ? 'SELECT SCHEMA_NAME FROM information_schema.SCHEMATA ORDER BY SCHEMA_NAME'
31
        //         : 'SHOW DATABASES'
32
        //     ); // SHOW DATABASES can be disabled by skip_show_database
33
        //     $databases = ($flush ? slow_query($query) : $this->driver->values($query));
34
        //     restart_session();
35
        //     set_session('dbs', $databases);
36
        //     stop_session();
37
        // }
38
        // return $databases;
39
    }
40
41
    /**
42
     * @inheritDoc
43
     */
44
    public function databaseSize(string $database)
45
    {
46
        $statement = $this->driver->execute('SELECT SUM(data_length + index_length) ' .
47
            'FROM information_schema.tables where table_schema=' . $this->driver->quote($database));
48
        if (is_a($statement, StatementInterface::class) && ($row = $statement->fetchRow())) {
49
            return intval($row[0]);
50
        }
51
        return 0;
52
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57
    public function databaseCollation(string $database, array $collations)
58
    {
59
        $collation = null;
60
        $create = $this->driver->result('SHOW CREATE DATABASE ' . $this->driver->escapeId($database), 1);
61
        if (preg_match('~ COLLATE ([^ ]+)~', $create, $match)) {
62
            $collation = $match[1];
63
        } elseif (preg_match('~ CHARACTER SET ([^ ]+)~', $create, $match)) {
64
            // default collation
65
            $collation = $collations[$match[1]][-1];
66
        }
67
        return $collation;
68
    }
69
70
    /**
71
     * @inheritDoc
72
     */
73
    public function engines()
74
    {
75
        $engines = [];
76
        foreach ($this->driver->rows('SHOW ENGINES') as $row) {
77
            if (preg_match('~YES|DEFAULT~', $row['Support'])) {
78
                $engines[] = $row['Engine'];
79
            }
80
        }
81
        return $engines;
82
    }
83
84
    /**
85
     * @inheritDoc
86
     */
87
    public function collations()
88
    {
89
        $collations = [];
90
        foreach ($this->driver->rows('SHOW COLLATION') as $row) {
91
            if ($row['Default']) {
92
                $collations[$row['Charset']][-1] = $row['Collation'];
93
            } else {
94
                $collations[$row['Charset']][] = $row['Collation'];
95
            }
96
        }
97
        ksort($collations);
98
        foreach ($collations as $key => $val) {
99
            asort($collations[$key]);
100
        }
101
        return $collations;
102
    }
103
104
    /**
105
     * @inheritDoc
106
     */
107
    public function isInformationSchema(string $database)
108
    {
109
        return ($this->driver->minVersion(5) && $database == 'information_schema') ||
110
            ($this->driver->minVersion(5.5) && $database == 'performance_schema');
111
    }
112
113
    /**
114
     * @inheritDoc
115
     */
116
    public function createDatabase(string $database, string $collation)
117
    {
118
        $result = $this->driver->execute('CREATE DATABASE ' . $this->driver->escapeId($database) .
119
            ($collation ? ' COLLATE ' . $this->driver->quote($collation) : ''));
120
        return $result !== false;
121
    }
122
123
    /**
124
     * @inheritDoc
125
     */
126
    public function dropDatabase(string $database)
127
    {
128
        $result = $this->driver->execute('DROP DATABASE ' . $this->driver->escapeId($database));
129
        return $result !== false;
130
    }
131
132
    /**
133
     * @inheritDoc
134
     */
135
    public function renameDatabase(string $name, string $collation)
136
    {
137
        // The feature is not natively provided by latest MySQL versions, thus it is disabled here.
138
        return false;
139
        /*$renamed = false;
140
        if ($this->createDatabase($name, $collation)) {
141
            $tables = [];
142
            $views = [];
143
            foreach ($this->driver->tables() as $table => $type) {
144
                if ($type == 'VIEW') {
145
                    $views[] = $table;
146
                } else {
147
                    $tables[] = $table;
148
                }
149
            }
150
            $renamed = (!$tables && !$views) || $this->driver->moveTables($tables, $views, $name);
151
            $this->dropDatabase($renamed ? $this->driver->database() : '');
152
        }
153
        return $renamed;*/
154
    }
155
156
    /**
157
     * @inheritDoc
158
     */
159
    public function routineLanguages()
160
    {
161
        return []; // 'SQL' not required
162
    }
163
164
    /**
165
     * @inheritDoc
166
     */
167
    public function variables()
168
    {
169
        return $this->driver->keyValues('SHOW VARIABLES');
170
    }
171
172
    /**
173
     * @inheritDoc
174
     */
175
    public function processes()
176
    {
177
        return $this->driver->rows('SHOW FULL PROCESSLIST');
178
    }
179
180
    /**
181
     * @inheritDoc
182
     */
183
    public function processAttr(array $process, string $key, string $val): string
184
    {
185
        $match = array_key_exists('Command', $process) && preg_match('~Query|Killed~', $process['Command']);
186
        if ($key == 'Info' && $match && $val != '') {
187
            return '<code>' . $this->util->shortenUtf8($val, 50) . '</code>' . $this->trans->lang('Clone');
188
        }
189
        return parent::processAttr($process, $key, $val);
190
    }
191
192
    /**
193
     * @inheritDoc
194
     */
195
    public function statusVariables()
196
    {
197
        return $this->driver->keyValues('SHOW STATUS');
198
    }
199
200
    /**
201
     * @inheritDoc
202
     */
203
    // public function killProcess($val)
204
    // {
205
    //     return $this->driver->execute('KILL ' . $this->util->number($val));
206
    // }
207
208
    /**
209
     * @inheritDoc
210
     */
211
    // public function maxConnections()
212
    // {
213
    //     return $this->driver->result('SELECT @@max_connections');
214
    // }
215
}
216