3 declare(strict_types
=1);
5 namespace PhpMyAdmin\Table
;
7 use PhpMyAdmin\DatabaseInterface
;
8 use PhpMyAdmin\Identifiers\DatabaseName
;
10 use PhpMyAdmin\Message
;
11 use PhpMyAdmin\Query\Compatibility
;
12 use PhpMyAdmin\Query\Generator
as QueryGenerator
;
17 use function in_array
;
22 private Message|
null $error = null;
24 public function __construct(private readonly DatabaseInterface
$dbi)
28 public function getError(): Message|
null
34 * Function to get the sql query for index creation or edit
36 * @param Index $index current index
38 public function getSqlQueryForIndexCreateOrEdit(
39 string|
null $oldIndexName,
44 // $sql_query is the one displayed in the query box
47 Util
::backquote($dbName),
48 Util
::backquote($tableName),
51 // Drops the old index
52 if ($oldIndexName !== null) {
53 if ($oldIndexName === 'PRIMARY') {
54 $sqlQuery .= ' DROP PRIMARY KEY,';
58 Util
::backquote($oldIndexName),
64 switch ($index->getChoice()) {
66 if ($index->getName() == '') {
67 $index->setName('PRIMARY');
68 } elseif ($index->getName() !== 'PRIMARY') {
69 $this->error
= Message
::error(
70 __('The name of the primary key must be "PRIMARY"!'),
74 $sqlQuery .= ' ADD PRIMARY KEY';
80 if ($index->getName() === 'PRIMARY') {
81 $this->error
= Message
::error(
82 __('Can\'t rename index to PRIMARY!'),
90 if ($index->getName() !== '') {
91 $sqlQuery .= ' ' . Util
::backquote($index->getName());
98 foreach ($index->getColumns() as $key => $column) {
99 $indexFields[$key] = Util
::backquote($column->getName());
100 if (! $column->getSubPart()) {
104 $indexFields[$key] .= '(' . $column->getSubPart() . ')';
107 if ($indexFields === []) {
108 $this->error
= Message
::error(__('No index parts defined!'));
110 $sqlQuery .= ' (' . implode(', ', $indexFields) . ')';
113 $keyBlockSizes = $index->getKeyBlockSize();
114 if ($keyBlockSizes !== 0) {
115 $sqlQuery .= ' KEY_BLOCK_SIZE = ' . $keyBlockSizes;
118 // specifying index type is allowed only for primary, unique and index only
119 // TokuDB is using Fractal Tree, Using Type is not useless
120 // Ref: https://mariadb.com/kb/en/storage-engine-index-types/
121 $type = $index->getType();
123 $index->getChoice() !== 'SPATIAL'
124 && $index->getChoice() !== 'FULLTEXT'
125 && in_array($type, Index
::getIndexTypes(), true)
126 && ! $this->dbi
->getTable($dbName, $tableName)->isEngine('TOKUDB')
128 $sqlQuery .= ' USING ' . $type;
131 $parser = $index->getParser();
132 if ($index->getChoice() === 'FULLTEXT' && $parser !== '') {
133 $sqlQuery .= ' WITH PARSER ' . $parser;
136 $comment = $index->getComment();
137 if ($comment !== '') {
138 $sqlQuery .= sprintf(
140 $this->dbi
->quoteString($comment),
149 public function getSqlQueryForRename(string $oldIndexName, Index
$index, string $db, string $table): string
151 if (! Compatibility
::isCompatibleRenameIndex($this->dbi
->getVersion())) {
152 return $this->getSqlQueryForIndexCreateOrEdit($oldIndexName, $index, $db, $table);
155 if ($oldIndexName === 'PRIMARY') {
156 if ($index->getName() === '') {
157 $index->setName('PRIMARY');
158 } elseif ($index->getName() !== 'PRIMARY') {
159 $this->error
= Message
::error(
160 __('The name of the primary key must be "PRIMARY"!'),
165 if ($index->getName() === 'PRIMARY') {
166 $this->error
= Message
::error(
167 __('Can\'t rename index to PRIMARY!'),
171 return QueryGenerator
::getSqlQueryForIndexRename(
179 public function executeAddIndexSql(string|DatabaseName
$db, string $sql): Message
181 $this->dbi
->selectDb($db);
182 $result = $this->dbi
->tryQuery($sql);
185 return Message
::error($this->dbi
->getError());
188 return Message
::success();