Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
24 / 24
CRAP
100.00% covered (success)
100.00%
1 / 1
MysqlDialect
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
24 / 24
27
100.00% covered (success)
100.00%
1 / 1
 getType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 integer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 bigInteger
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 smallInteger
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 varchar
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 text
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 longText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 blob
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 boolean
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 timestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 date
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 char
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 currentTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 currentDate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 autoIncrement
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createTablePrefix
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 createTableSuffix
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addColumn
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 modifyColumn
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createIndex
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 dropIndex
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 supportsColumnPositioning
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 supportsCombinedAlter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 quoteIdentifier
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * MySQL/MariaDB specific SQL dialect.
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public License,
7 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8 * obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * @package   phpMyFAQ
11 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
12 * @copyright 2023-2026 phpMyFAQ Team
13 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14 * @link      https://www.phpmyfaq.de
15 * @since     2026-01-25
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Setup\Migration\QueryBuilder\Dialect;
21
22use phpMyFAQ\Setup\Migration\QueryBuilder\DialectInterface;
23use RuntimeException;
24
25class MysqlDialect implements DialectInterface
26{
27    public function getType(): string
28    {
29        return 'mysqli';
30    }
31
32    public function integer(): string
33    {
34        return 'INT';
35    }
36
37    public function bigInteger(): string
38    {
39        return 'BIGINT';
40    }
41
42    public function smallInteger(): string
43    {
44        return 'SMALLINT';
45    }
46
47    public function varchar(int $length): string
48    {
49        return "VARCHAR({$length})";
50    }
51
52    public function text(): string
53    {
54        return 'TEXT';
55    }
56
57    public function longText(): string
58    {
59        return 'LONGTEXT';
60    }
61
62    public function blob(): string
63    {
64        return 'BLOB';
65    }
66
67    public function boolean(): string
68    {
69        return 'TINYINT(1)';
70    }
71
72    public function timestamp(): string
73    {
74        return 'TIMESTAMP';
75    }
76
77    public function date(): string
78    {
79        return 'DATE';
80    }
81
82    public function char(int $length): string
83    {
84        return "CHAR({$length})";
85    }
86
87    public function currentTimestamp(): string
88    {
89        return 'CURRENT_TIMESTAMP';
90    }
91
92    public function currentDate(): string
93    {
94        return 'CURDATE()';
95    }
96
97    public function autoIncrement(string $columnName): string
98    {
99        return "{$columnName} INT NOT NULL PRIMARY KEY AUTO_INCREMENT";
100    }
101
102    public function createTablePrefix(string $tableName, bool $ifNotExists = false): string
103    {
104        $exists = $ifNotExists ? 'IF NOT EXISTS ' : '';
105        return "CREATE TABLE {$exists}{$tableName}";
106    }
107
108    public function createTableSuffix(): string
109    {
110        return 'DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB';
111    }
112
113    public function addColumn(string $tableName, string $columnName, string $type, ?string $after = null): string
114    {
115        $afterClause = $after !== null ? " AFTER {$after}" : '';
116        return "ALTER TABLE {$tableName} ADD COLUMN {$columnName} {$type}{$afterClause}";
117    }
118
119    public function modifyColumn(string $tableName, string $columnName, string $newType): string
120    {
121        return "ALTER TABLE {$tableName} MODIFY {$columnName} {$newType}";
122    }
123
124    /**
125     * @param string[] $columns
126     */
127    public function createIndex(string $indexName, string $tableName, array $columns, bool $ifNotExists = false): string
128    {
129        if ($ifNotExists) {
130            throw new RuntimeException(
131                'MySQL/MariaDB does not support IF NOT EXISTS for CREATE INDEX. '
132                . 'Check for index existence manually before creating it.',
133            );
134        }
135
136        $columnList = implode(', ', $columns);
137        return "CREATE INDEX {$indexName} ON {$tableName} ({$columnList})";
138    }
139
140    public function dropIndex(string $indexName, string $tableName): string
141    {
142        return "DROP INDEX {$indexName} ON {$tableName}";
143    }
144
145    public function supportsColumnPositioning(): bool
146    {
147        return true;
148    }
149
150    public function supportsCombinedAlter(): bool
151    {
152        return true;
153    }
154
155    public function quoteIdentifier(string $identifier): string
156    {
157        return '`' . str_replace(search: '`', replace: '``', subject: $identifier) . '`';
158    }
159}