Translated using Weblate (Portuguese)
[phpmyadmin.git] / src / Table / Indexes.php
blobe4489b6dee528b890e0689ebf8ea82233caf159c
1 <?php
3 declare(strict_types=1);
5 namespace PhpMyAdmin\Table;
7 use PhpMyAdmin\DatabaseInterface;
8 use PhpMyAdmin\Identifiers\DatabaseName;
9 use PhpMyAdmin\Index;
10 use PhpMyAdmin\Message;
11 use PhpMyAdmin\Query\Compatibility;
12 use PhpMyAdmin\Query\Generator as QueryGenerator;
13 use PhpMyAdmin\Util;
15 use function __;
16 use function implode;
17 use function in_array;
18 use function sprintf;
20 final class Indexes
22 private Message|null $error = null;
24 public function __construct(private readonly DatabaseInterface $dbi)
28 public function getError(): Message|null
30 return $this->error;
33 /**
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,
40 Index $index,
41 string $dbName,
42 string $tableName,
43 ): string {
44 // $sql_query is the one displayed in the query box
45 $sqlQuery = sprintf(
46 'ALTER TABLE %s.%s',
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,';
55 } else {
56 $sqlQuery .= sprintf(
57 ' DROP INDEX %s,',
58 Util::backquote($oldIndexName),
63 // Builds the new one
64 switch ($index->getChoice()) {
65 case 'PRIMARY':
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';
75 break;
76 case 'FULLTEXT':
77 case 'UNIQUE':
78 case 'INDEX':
79 case 'SPATIAL':
80 if ($index->getName() === 'PRIMARY') {
81 $this->error = Message::error(
82 __('Can\'t rename index to PRIMARY!'),
86 $sqlQuery .= sprintf(
87 ' ADD %s',
88 $index->getChoice(),
90 if ($index->getName() !== '') {
91 $sqlQuery .= ' ' . Util::backquote($index->getName());
94 break;
97 $indexFields = [];
98 foreach ($index->getColumns() as $key => $column) {
99 $indexFields[$key] = Util::backquote($column->getName());
100 if (! $column->getSubPart()) {
101 continue;
104 $indexFields[$key] .= '(' . $column->getSubPart() . ')';
107 if ($indexFields === []) {
108 $this->error = Message::error(__('No index parts defined!'));
109 } else {
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();
122 if (
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(
139 ' COMMENT %s',
140 $this->dbi->quoteString($comment),
144 $sqlQuery .= ';';
146 return $sqlQuery;
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(
172 $db,
173 $table,
174 $oldIndexName,
175 $index->getName(),
179 public function executeAddIndexSql(string|DatabaseName $db, string $sql): Message
181 $this->dbi->selectDb($db);
182 $result = $this->dbi->tryQuery($sql);
184 if (! $result) {
185 return Message::error($this->dbi->getError());
188 return Message::success();