Passed
Push — main ( c14f91...15b099 )
by Thierry
03:07 queued 01:26
created

Server::processAttr()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

185
            return '<code>' . $this->shortenUtf8($val, 50) . '</code>' . $this->/** @scrutinizer ignore-call */ lang('Clone');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method shortenUtf8() does not exist on Lagdo\DbAdmin\Driver\MySql\Db\Server. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

185
            return '<code>' . $this->/** @scrutinizer ignore-call */ shortenUtf8($val, 50) . '</code>' . $this->lang('Clone');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
186
        }
187
        return parent::processAttr($process, $key, $val);
0 ignored issues
show
Bug introduced by
The method processAttr() does not exist on Lagdo\DbAdmin\Driver\Db\Server. Did you maybe mean processes()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

187
        return parent::/** @scrutinizer ignore-call */ processAttr($process, $key, $val);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
188
    }
189
190
    /**
191
     * @inheritDoc
192
     */
193
    public function statusVariables()
194
    {
195
        return $this->driver->keyValues("SHOW STATUS");
196
    }
197
198
    /**
199
     * @inheritDoc
200
     */
201
    // public function killProcess($val)
202
    // {
203
    //     return $this->driver->execute("KILL " . $this->util->number($val));
204
    // }
205
206
    /**
207
     * @inheritDoc
208
     */
209
    // public function maxConnections()
210
    // {
211
    //     return $this->connection->result("SELECT @@max_connections");
212
    // }
213
}
214