Passed
Push — main ( b7ab9d...47f36d )
by Thierry
08:45
created

Server   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 49
dl 0
loc 194
rs 9.76
c 2
b 0
f 0
wmc 33

15 Methods

Rating   Name   Duplication   Size   Complexity  
A isInformationSchema() 0 4 4
A databaseSize() 0 8 3
A engines() 0 9 3
A collations() 0 15 4
A databases() 0 7 2
A databaseCollation() 0 11 3
A variables() 0 3 1
A dropDatabase() 0 4 1
A routineLanguages() 0 3 1
A processes() 0 3 1
A createDatabase() 0 5 2
A processAttr() 0 7 5
A statusVariables() 0 3 1
A renameDatabase() 0 4 1
A isSystemSchema() 0 4 1
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 isSystemSchema(string $database)
117
    {
118
        return in_array($database, ['sys', 'mysql',
119
            'performance_schema', 'information_schema']);
120
    }
121
122
    /**
123
     * @inheritDoc
124
     */
125
    public function createDatabase(string $database, string $collation)
126
    {
127
        $result = $this->driver->execute('CREATE DATABASE ' . $this->driver->escapeId($database) .
128
            ($collation ? ' COLLATE ' . $this->driver->quote($collation) : ''));
129
        return $result !== false;
130
    }
131
132
    /**
133
     * @inheritDoc
134
     */
135
    public function dropDatabase(string $database)
136
    {
137
        $result = $this->driver->execute('DROP DATABASE ' . $this->driver->escapeId($database));
138
        return $result !== false;
139
    }
140
141
    /**
142
     * @inheritDoc
143
     */
144
    public function renameDatabase(string $name, string $collation)
145
    {
146
        // The feature is not natively provided by latest MySQL versions, thus it is disabled here.
147
        return false;
148
        /*$renamed = false;
149
        if ($this->createDatabase($name, $collation)) {
150
            $tables = [];
151
            $views = [];
152
            foreach ($this->driver->tables() as $table => $type) {
153
                if ($type == 'VIEW') {
154
                    $views[] = $table;
155
                } else {
156
                    $tables[] = $table;
157
                }
158
            }
159
            $renamed = (!$tables && !$views) || $this->driver->moveTables($tables, $views, $name);
160
            $this->dropDatabase($renamed ? $this->driver->database() : '');
161
        }
162
        return $renamed;*/
163
    }
164
165
    /**
166
     * @inheritDoc
167
     */
168
    public function routineLanguages()
169
    {
170
        return []; // 'SQL' not required
171
    }
172
173
    /**
174
     * @inheritDoc
175
     */
176
    public function variables()
177
    {
178
        return $this->driver->keyValues('SHOW VARIABLES');
179
    }
180
181
    /**
182
     * @inheritDoc
183
     */
184
    public function processes()
185
    {
186
        return $this->driver->rows('SHOW FULL PROCESSLIST');
187
    }
188
189
    /**
190
     * @inheritDoc
191
     */
192
    public function processAttr(array $process, string $key, string $val): string
193
    {
194
        $match = array_key_exists('Command', $process) && preg_match('~Query|Killed~', $process['Command']);
195
        if ($key == 'Info' && $match && $val != '') {
196
            return '<code>' . $this->utils->str->shortenUtf8($val, 50) . '</code>' . $this->utils->trans->lang('Clone');
197
        }
198
        return parent::processAttr($process, $key, $val);
199
    }
200
201
    /**
202
     * @inheritDoc
203
     */
204
    public function statusVariables()
205
    {
206
        return $this->driver->keyValues('SHOW STATUS');
207
    }
208
209
    /**
210
     * @inheritDoc
211
     */
212
    // public function killProcess($val)
213
    // {
214
    //     return $this->driver->execute('KILL ' . $this->utils->str->number($val));
215
    // }
216
217
    /**
218
     * @inheritDoc
219
     */
220
    // public function maxConnections()
221
    // {
222
    //     return $this->driver->result('SELECT @@max_connections');
223
    // }
224
}
225