ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilDBPdoMySQL.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
24abstract class ilDBPdoMySQL extends ilDBPdo
25{
29 protected array $modes = [
30 'STRICT_TRANS_TABLES',
31 'STRICT_ALL_TABLES',
32 'IGNORE_SPACE',
33 'NO_ZERO_IN_DATE',
34 'NO_ZERO_DATE',
35 'ERROR_FOR_DIVISION_BY_ZERO',
36 'NO_ENGINE_SUBSTITUTION',
37 ];
38
39 #[\Override]
40 public function supportsTransactions(): bool
41 {
42 return false;
43 }
44
45 public function initHelpers(): void
46 {
47 $this->manager = new ilDBPdoManager($this->pdo, $this);
48 $this->reverse = new ilDBPdoReverse($this->pdo, $this);
49 $this->field_definition = new ilDBPdoMySQLFieldDefinition($this);
50 }
51
52 protected function initSQLMode(): void
53 {
54 $this->pdo->exec("SET SESSION sql_mode = '" . implode(",", $this->modes) . "';");
55 }
56
57 #[\Override]
58 public function supportsEngineMigration(): bool
59 {
60 return true;
61 }
62
66 #[\Override]
67 protected function getAdditionalAttributes(): array
68 {
69 return [
70 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
71 PDO::ATTR_TIMEOUT => 300 * 60,
72 ];
73 }
74
75 public function migrateTableToEngine(string $table_name, string $engine = ilDBConstants::MYSQL_ENGINE_INNODB): void
76 {
77 try {
78 $this->pdo->exec("ALTER TABLE {$table_name} ENGINE={$engine}");
79 if ($this->sequenceExists($table_name)) {
80 $this->pdo->exec("ALTER TABLE {$table_name}_seq ENGINE={$engine}");
81 }
82 } catch (PDOException $e) {
83 throw new ilDatabaseException($e->getMessage(), $e->getCode(), $e);
84 }
85 }
86
90 #[\Override]
91 public function migrateAllTablesToEngine(string $engine = ilDBConstants::MYSQL_ENGINE_INNODB): array
92 {
93 $engines = $this->queryCol('SHOW ENGINES');
94 if (!in_array($engine, $engines, true)) {
95 return [];
96 }
97 $errors = [];
98 $tables = $this->listTables();
99 array_walk($tables, function (string $table_name) use (&$errors, $engine): void {
100 try {
101 $this->pdo->exec("ALTER TABLE $table_name ENGINE=$engine");
102 if ($this->sequenceExists($table_name)) {
103 $this->pdo->exec("ALTER TABLE {$table_name}_seq ENGINE=$engine");
104 }
105 } catch (Exception $e) {
106 $errors[$table_name] = $e->getMessage();
107 }
108 });
109
110 return $errors;
111 }
112
113 public function migrateTableCollation(
114 string $table_name,
116 ): bool {
117 $collation_split = explode("_", $collation);
118 $character = $collation_split[0] ?? 'utf8mb4';
119 $collate = $collation;
120 $q = "ALTER TABLE {$this->quoteIdentifier($table_name)} CONVERT TO CHARACTER SET {$character} COLLATE {$collate};";
121 try {
122 $this->pdo->exec($q);
123 } catch (PDOException) {
124 return false;
125 }
126 return true;
127 }
128
132 #[\Override]
133 public function migrateAllTablesToCollation(string $collation = ilDBConstants::MYSQL_COLLATION_UTF8MB4): array
134 {
135 $manager = $this->loadModule(ilDBConstants::MODULE_MANAGER);
136 $errors = [];
137 foreach ($manager->listTables() as $table_name) {
138 if (!$this->migrateTableCollation($table_name, $collation)) {
139 $errors[] = $table_name;
140 }
141 }
142
143 return $errors;
144 }
145
149 #[\Override]
150 public function supportsCollationMigration(): bool
151 {
152 return true;
153 }
154
155 public function nextId(string $table_name): int
156 {
157 $sequence_name = $this->quoteIdentifier($this->getSequenceName($table_name), true);
158 $seqcol_name = $this->quoteIdentifier('sequence');
159 $query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (NULL)";
160 try {
161 $this->pdo->exec($query);
162 } catch (PDOException) {
163 // no such table check
164 }
165
166 $result = $this->query('SELECT LAST_INSERT_ID() AS next');
167 $value = $result->fetchObject()->next;
168
169 if (is_numeric($value)) {
170 $query = "DELETE FROM $sequence_name WHERE $seqcol_name < $value";
171 $this->pdo->exec($query);
172 }
173
174 return (int) $value;
175 }
176
180 #[\Override]
181 public function doesCollationSupportMB4Strings(): bool
182 {
183 // Currently ILIAS does not support utf8mb4, after that ilDB could check like this:
184 // static $supported;
185 // if (!isset($supported)) {
186 // $q = "SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = %s;";
187 // $res = $this->queryF($q, ['text'], [$this->getDbname()]);
188 // $data = $this->fetchObject($res);
189 // $supported = ($data->default_character_set_name === 'utf8mb4');
190 // }
191
192 return false;
193 }
194}
Class ilDBPdoManager.
Class ilDBPdoMySQLFieldDefinition.
Class ilDBPdoMySQL.
nextId(string $table_name)
supportsCollationMigration()
@inheritDoc
doesCollationSupportMB4Strings()
@inheritDoc
migrateTableCollation(string $table_name, string $collation=ilDBConstants::MYSQL_COLLATION_UTF8MB4)
migrateTableToEngine(string $table_name, string $engine=ilDBConstants::MYSQL_ENGINE_INNODB)
migrateAllTablesToCollation(string $collation=ilDBConstants::MYSQL_COLLATION_UTF8MB4)
@inheritDoc
migrateAllTablesToEngine(string $engine=ilDBConstants::MYSQL_ENGINE_INNODB)
Class ilDBPdoReverse.
Class pdoDB.
sequenceExists(string $sequence)
queryCol(string $query, int $type=PDO::FETCH_ASSOC, int $colnum=0)
Class ilDatabaseException.
$q
Definition: shib_logout.php:23