ILIAS  trunk Revision v12.0_alpha-1221-g4e438232683
ilDBPdo.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
26
31class ilDBPdo implements Internal
32{
33 public array $options = [];
34
35 public const FEATURE_TRANSACTIONS = 'transactions';
36 public const FEATURE_FULLTEXT = 'fulltext';
37 public const FEATURE_SLAVE = 'slave';
38
39 private string $host = '';
40 private string $dbname = '';
41 private string $charset = 'utf8';
42 private string $username = '';
43 private string $password = '';
44 private int $port = 3306;
45 private ?PDO $pdo = null;
48 private ?int $limit = null;
49 private ?int $offset = null;
50 private string $storage_engine = 'InnoDB';
51 private string $dsn = '';
52 private string $db_type = '';
53 private int $error_code = 0;
55
56 private const SESSION_MODES = [
57 'STRICT_TRANS_TABLES',
58 'STRICT_ALL_TABLES',
59 'IGNORE_SPACE',
60 'NO_ZERO_IN_DATE',
61 'NO_ZERO_DATE',
62 'ERROR_FOR_DIVISION_BY_ZERO',
63 'NO_ENGINE_SUBSTITUTION',
64 ];
65
66 public function __construct(private readonly Details $details)
67 {
68 }
69
73 public function connect(bool $return_false_for_error = false): ?bool
74 {
75 $this->generateDSN();
76 try {
77 $options = $this->getAttributes();
78 $this->pdo = new PDO($this->getDSN(), $this->getUsername(), $this->getPassword(), $options);
79 $this->pdo->exec("SET SESSION sql_mode = '" . implode(",", self::SESSION_MODES) . "';");
80 $this->manager = new ilDBPdoManager($this->pdo, $this);
81 $this->reverse = new ilDBPdoReverse($this->pdo, $this);
82 $this->field_definition = new ilDBPdoMySQLFieldDefinition($this);
83 } catch (Exception $e) {
84 $this->error_code = $e->getCode();
85 if ($return_false_for_error) {
86 return false;
87 }
88 throw $e;
89 }
90
91 return ($this->pdo->errorCode() === PDO::ERR_NONE);
92 }
93
97 public function initHelpers(): void
98 {
99 }
100
101 protected function getAttributes(): array
102 {
103 return [
104 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
105 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
106 PDO::ATTR_TIMEOUT => 300 * 60,
107 ];
108 }
109
111 {
113 }
114
116 {
117 $this->field_definition = $field_definition;
118 }
119
120 public function createDatabase(string $a_name, string $a_charset = "utf8", string $a_collation = ""): bool
121 {
122 $this->setDbname('');
123 $this->generateDSN();
124 $this->connect(true);
125 try {
126 $this->query($this->manager->getQueryUtils()->createDatabase($a_name, $a_charset, $a_collation));
127 return true;
128 } catch (PDOException) {
129 return false;
130 }
131 }
132
136 public function getLastErrorCode()
137 {
138 if ($this->pdo instanceof PDO) {
139 return $this->pdo->errorCode();
140 }
141
142 return $this->error_code;
143 }
144
145 public function initFromIniFile(?ilIniFile $ini = null): void
146 {
147 global $DIC;
148
149 if ($ini instanceof ilIniFile) {
150 $clientIniFile = $ini;
151 } elseif ($DIC->offsetExists('ilClientIniFile')) {
152 $clientIniFile = $DIC['ilClientIniFile'];
153 } else {
154 throw new InvalidArgumentException('$tmpClientIniFile is not an instance of ilIniFile');
155 }
156
157 $this->setUsername($clientIniFile->readVariable("db", "user"));
158 $this->setHost($clientIniFile->readVariable("db", "host"));
159 $this->setPort((int) $clientIniFile->readVariable("db", "port"));
160 $this->setPassword((string) $clientIniFile->readVariable("db", "pass"));
161 $this->setDbname($clientIniFile->readVariable("db", "name"));
162 $this->setDBType($clientIniFile->readVariable("db", "type"));
163
164 $this->generateDSN();
165 }
166
167 public function generateDSN(): void
168 {
169 $port = $this->getPort() !== 0 ? ";port=" . $this->getPort() : "";
170 $dbname = $this->getDbname() !== '' ? ';dbname=' . $this->getDbname() : '';
171 $host = $this->getHost();
172 $charset = ';charset=' . $this->getCharset();
173 $this->dsn = 'mysql:host=' . $host . $port . $dbname . $charset;
174 }
175
176 public function quoteIdentifier(string $identifier, bool $check_option = false): string
177 {
178 return '`' . preg_replace('/[^a-zA-Z0-9_$]/', '', $identifier) . '`';
179 }
180
181 #[\Override]
182 public function nextId(string $table_name): int
183 {
184 $sequence_name = $this->quoteIdentifier($this->getSequenceName($table_name), true);
185 $seqcol_name = $this->quoteIdentifier('sequence');
186 $query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (NULL)";
187 try {
188 $this->pdo->exec($query);
189 } catch (PDOException) {
190 // no such table check
191 }
192
193 $result = $this->query('SELECT LAST_INSERT_ID() AS next');
194 $value = $result->fetchObject()->next;
195
196 if (is_numeric($value)) {
197 $query = "DELETE FROM $sequence_name WHERE $seqcol_name < $value";
198 $this->pdo->exec($query);
199 }
200
201 return (int) $value;
202 }
203
207 public function createTable(
208 string $table_name,
209 array $fields,
210 bool $drop_table = false,
211 bool $ignore_erros = false
212 ): bool {
213 // check table name
214 if (!$ignore_erros && !$this->checkTableName($table_name)) {
215 throw new ilDatabaseException("ilDB Error: createTable(" . $table_name . ")");
216 }
217
218 // check definition array
219 if (!$ignore_erros && !$this->checkTableColumns($fields)) {
220 throw new ilDatabaseException("ilDB Error: createTable(" . $table_name . ")");
221 }
222
223 if ($drop_table) {
224 $this->dropTable($table_name, false);
225 }
226
227 return $this->manager->createTable($table_name, $fields, []);
228 }
229
230 private function checkTableColumns(array $a_cols): bool
231 {
232 foreach ($a_cols as $col => $def) {
233 if (!$this->checkColumn($col, $def)) {
234 return false;
235 }
236 }
237
238 return true;
239 }
240
241 private function checkColumn(string $a_col, array $a_def): bool
242 {
243 if (!$this->checkColumnName($a_col)) {
244 return false;
245 }
246 return $this->checkColumnDefinition($a_def);
247 }
248
249 private function checkColumnDefinition(array $a_def, bool $a_modify_mode = false): bool
250 {
251 return $this->field_definition->checkColumnDefinition($a_def);
252 }
253
254 public function checkColumnName(string $a_name): bool
255 {
256 return $this->field_definition->checkColumnName($a_name);
257 }
258
262 public function addPrimaryKey(string $table_name, array $primary_keys): bool
263 {
264 $fields = [];
265 foreach ($primary_keys as $f) {
266 $fields[$f] = [];
267 }
268 $definition = [
269 'primary' => true,
270 'fields' => $fields,
271 ];
272 $this->manager->createConstraint(
273 $table_name,
274 $this->constraintName($table_name, $this->getPrimaryKeyIdentifier()),
275 $definition
276 );
277
278 return true;
279 }
280
284 public function dropIndexByFields(string $table_name, array $fields): bool
285 {
286 foreach ($this->manager->listTableIndexes($table_name) as $idx_name) {
287 $def = $this->reverse->getTableIndexDefinition($table_name, $idx_name);
288 $idx_fields = array_keys($def['fields']);
289
290 if ($idx_fields === $fields) {
291 return $this->dropIndex($table_name, $idx_name);
292 }
293 }
294
295 return false;
296 }
297
298 public function getPrimaryKeyIdentifier(): string
299 {
300 return "PRIMARY";
301 }
302
303 public function createSequence(string $table_name, int $start = 1): bool
304 {
305 $this->manager->createSequence($table_name, $start);
306 return true;
307 }
308
309 public function tableExists(string $table_name): bool
310 {
311 $result = $this->pdo->prepare("SHOW TABLES LIKE :table_name");
312 $result->execute(['table_name' => $table_name]);
313 $return = $result->rowCount();
314 $result->closeCursor();
315
316 return $return > 0;
317 }
318
319 public function tableColumnExists(string $table_name, string $column_name): bool
320 {
321 return in_array($column_name, $this->manager->listTableFields($table_name), true);
322 }
323
327 public function addTableColumn(string $table_name, string $column_name, array $attributes): bool
328 {
329 if (!$this->checkColumnName($column_name)) {
330 throw new ilDatabaseException("ilDB Error: addTableColumn(" . $table_name . ", " . $column_name . ")");
331 }
332 if (!$this->checkColumnDefinition($attributes)) {
333 throw new ilDatabaseException("ilDB Error: addTableColumn(" . $table_name . ", " . $column_name . ")");
334 }
335
336 $changes = [
337 "add" => [
338 $column_name => $attributes,
339 ],
340 ];
341
342 return $this->manager->alterTable($table_name, $changes, false);
343 }
344
348 public function dropTable(string $table_name, bool $error_if_not_existing = true): bool
349 {
350 $tables = $this->manager->listTables();
351 $table_exists = in_array($table_name, $tables);
352 if (!$table_exists && $error_if_not_existing) {
353 throw new ilDatabaseException("Table $table_name does not exist");
354 }
355
356 // drop sequence
357 $sequences = $this->manager->listSequences();
358 if (in_array($table_name, $sequences)) {
359 $this->manager->dropSequence($table_name);
360 }
361
362 // drop table
363 if ($table_exists) {
364 $this->manager->dropTable($table_name);
365 }
366
367 return true;
368 }
369
373 public function query(string $query): ilDBStatement
374 {
375 global $DIC;
376 $ilBench = $DIC['ilBench'] ?? null;
377
378 $query = $this->appendLimit($query);
379
380 try {
381 if ($ilBench instanceof ilBenchmark) {
382 $ilBench->startDbBench($query);
383 }
384 $res = $this->pdo->query($query);
385 if ($ilBench instanceof ilBenchmark) {
386 $ilBench->stopDbBench();
387 }
388 } catch (PDOException $e) {
389 throw new ilDatabaseException($e->getMessage() . ' QUERY: ' . $query, (int) $e->getCode());
390 }
391
392 $err = $this->pdo->errorCode();
393 if ($err !== PDO::ERR_NONE) {
394 $info = $this->pdo->errorInfo();
395 $info_message = $info[2];
396 throw new ilDatabaseException($info_message . ' QUERY: ' . $query);
397 }
398
399 return new ilPDOStatement($res);
400 }
401
402 public function fetchAll(ilDBStatement $statement, int $fetch_mode = ilDBConstants::FETCHMODE_ASSOC): array
403 {
404 $return = [];
405 while ($data = $statement->fetch($fetch_mode)) {
406 $return[] = $data;
407 }
408
409 return $return;
410 }
411
412 public function dropSequence(string $table_name): bool
413 {
414 $this->manager->dropSequence($table_name);
415 return true;
416 }
417
421 public function dropTableColumn(string $table_name, string $column_name): bool
422 {
423 $changes = [
424 "remove" => [
425 $column_name => [],
426 ],
427 ];
428
429 return $this->manager->alterTable($table_name, $changes, false);
430 }
431
435 public function renameTableColumn(string $table_name, string $column_old_name, string $column_new_name): bool
436 {
437 // check table name
438 if (!$this->checkColumnName($column_new_name)) {
439 throw new ilDatabaseException("ilDB Error: renameTableColumn(" . $table_name . "," . $column_old_name . "," . $column_new_name . ")");
440 }
441
442 $def = $this->reverse->getTableFieldDefinition($table_name, $column_old_name);
443
444 $analyzer = new ilDBAnalyzer($this);
445 $best_alt = $analyzer->getBestDefinitionAlternative($def);
446 $def = $def[$best_alt];
447 unset($def["nativetype"]);
448 unset($def["mdb2type"]);
449
450 $f["definition"] = $def;
451 $f["name"] = $column_new_name;
452
453 $changes = [
454 "rename" => [
455 $column_old_name => $f,
456 ],
457 ];
458
459 return $this->manager->alterTable($table_name, $changes, false);
460 }
461
462 public function insert(string $table_name, array $values): int
463 {
464 $real = [];
465 $fields = [];
466 foreach ($values as $key => $val) {
467 $real[] = $this->quote($val[1], $val[0]);
468 $fields[] = $this->quoteIdentifier($key);
469 }
470 $values_string = implode(",", $real);
471 $fields_string = implode(",", $fields);
472 $query = "INSERT INTO " . $this->quoteIdentifier($table_name) . " (" . $fields_string . ") VALUES (" . $values_string . ")";
473
474 $query = $this->sanitizeMB4StringIfNotSupported($query);
475
476 return (int) $this->pdo->exec($query);
477 }
478
479 public function fetchObject(ilDBStatement $query_result): ?stdClass
480 {
481 $res = $query_result->fetchObject();
482 if ($res === null) {
483 $query_result->closeCursor();
484
485 return null;
486 }
487
488 return $res;
489 }
490
491 public function update(string $table_name, array $columns, array $where): int
492 {
493 $fields = [];
494 $field_values = [];
495 $placeholders = [];
496 $placeholders_full = [];
497 $types = [];
498 $values = [];
499 $lobs = false;
500 $lob = [];
501 foreach ($columns as $k => $col) {
502 $field_value = $col[1];
503 $fields[] = $k;
504 $placeholders[] = "%s";
505 $placeholders_full[] = ":$k";
506 $types[] = $col[0];
507
508 if (($col[0] === "blob" || $col[0] === "clob" || $col[0] === 'text') && is_string($field_value)) {
509 $field_value = $this->sanitizeMB4StringIfNotSupported($field_value);
510 }
511
512 // integer auto-typecast (this casts bool values to integer)
513 if ($col[0] === 'integer' && !is_null($field_value)) {
514 $field_value = (int) $field_value;
515 }
516
517 $values[] = $field_value;
518 $field_values[$k] = $field_value;
519 if ($col[0] === "blob" || $col[0] === "clob") {
520 $lobs = true;
521 }
522 }
523
524 if ($lobs) {
525 $q = "UPDATE " . $this->quoteIdentifier($table_name) . " SET ";
526 $lim = "";
527 foreach ($fields as $k => $field) {
528 $q .= $lim . $this->quoteIdentifier($field) . " = " . $placeholders_full[$k];
529 $lim = ", ";
530 }
531 $q .= " WHERE ";
532 $lim = "";
533 foreach ($where as $k => $col) {
534 $q .= $lim . $this->quoteIdentifier($k) . " = " . $this->quote($col[1], $col[0]);
535 $lim = " AND ";
536 }
537
538 $r = $this->prepareManip($q, $types);
539 $this->execute($r, $field_values);
540
541 $num_affected_rows = $r->rowCount();
542
543 $this->free($r);
544 } else {
545 foreach ($where as $k => $col) {
546 $types[] = $col[0];
547 $values[] = $col[1];
548 $field_values[$k] = $col;
549 }
550 $q = "UPDATE " . $this->quoteIdentifier($table_name) . " SET ";
551 $lim = "";
552 foreach ($fields as $k => $field) {
553 $q .= $lim . $this->quoteIdentifier($field) . " = " . $placeholders[$k];
554 $lim = ", ";
555 }
556 $q .= " WHERE ";
557 $lim = "";
558 foreach (array_keys($where) as $k) {
559 $q .= $lim . $this->quoteIdentifier($k) . " = %s";
560 $lim = " AND ";
561 }
562
563 $num_affected_rows = $this->manipulateF($q, $types, $values);
564 }
565
566 return $num_affected_rows;
567 }
568
572 public function manipulate(string $query): int
573 {
574 global $DIC;
575 $ilBench = $DIC['ilBench'] ?? null;
576 try {
577 $query = $this->sanitizeMB4StringIfNotSupported($query);
578 if ($ilBench instanceof ilBenchmark) {
579 $ilBench->startDbBench($query);
580 }
581 $num_affected_rows = $this->pdo->exec($query);
582 if ($ilBench instanceof ilBenchmark) {
583 $ilBench->stopDbBench();
584 }
585 } catch (PDOException $e) {
586 throw new ilDatabaseException($e->getMessage() . ' QUERY: ' . $query, (int) $e->getCode());
587 }
588
589 return (int) $num_affected_rows;
590 }
591
592 public function fetchAssoc(ilDBStatement $statement): ?array
593 {
594 $res = $statement->fetch(PDO::FETCH_ASSOC);
595 if ($res === null || $res === false) {
596 $statement->closeCursor();
597
598 return null;
599 }
600
601 return $res;
602 }
603
604 public function numRows(ilDBStatement $statement): int
605 {
606 return $statement->rowCount();
607 }
608
609 public function quote($value, ?string $type = null): string
610 {
611 if ($value === null) {
612 return 'NULL';
613 }
614
615 $pdo_type = PDO::PARAM_STR;
616 switch ($type) {
620 if ($value === '') {
621 return 'NULL';
622 }
623 if ($value === $this->now()) {
624 return $value;
625 }
626 $value = (string) $value;
627 break;
629 return (string) (int) $value;
631 $pdo_type = PDO::PARAM_INT;
632 $value = (string) $value;
633 break;
635 default:
636 $value = (string) $value;
637 $pdo_type = PDO::PARAM_STR;
638 break;
639 }
640
641 return $this->pdo->quote((string) $value, $pdo_type);
642 }
643
644 public function indexExistsByFields(string $table_name, array $fields): bool
645 {
646 foreach ($this->manager->listTableIndexes($table_name) as $idx_name) {
647 $def = $this->reverse->getTableIndexDefinition($table_name, $idx_name);
648 $idx_fields = array_keys($def['fields']);
649
650 if ($idx_fields === $fields) {
651 return true;
652 }
653 }
654
655 return false;
656 }
657
658 public function addIndex(string $table_name, array $fields, string $index_name = '', bool $fulltext = false): bool
659 {
660 $this->field_definition->checkIndexName($index_name);
661
662 $definition_fields = [];
663 foreach ($fields as $f) {
664 $definition_fields[$f] = [];
665 }
666 $definition = [
667 'fields' => $definition_fields,
668 ];
669
670 if (!$fulltext) {
671 $this->manager->createIndex($table_name, $this->constraintName($table_name, $index_name), $definition);
672 } elseif ($this->supportsFulltext()) {
673 $this->addFulltextIndex($table_name, $fields, $index_name);
674 // TODO
675 }
676
677 return true;
678 }
679
680 public function addFulltextIndex(string $table_name, array $fields, string $name = 'in'): bool
681 {
682 return false;
683 }
684
688 public function dropFulltextIndex(string $a_table, string $a_name): bool
689 {
690 $i_name = $this->constraintName($a_table, $a_name) . "_idx";
691 $this->query("ALTER TABLE $a_table DROP FULLTEXT $i_name");
692 return true;
693 }
694
698 public function isFulltextIndex(string $a_table, string $a_name): bool
699 {
700 $set = $this->query("SHOW INDEX FROM " . $a_table);
701 while ($rec = $this->fetchAssoc($set)) {
702 if ($rec["Key_name"] === $a_name && $rec["Index_type"] === "FULLTEXT") {
703 return true;
704 }
705 }
706
707 return false;
708 }
709
710 public function getIndexName(string $index_name_base): string
711 {
712 return sprintf(FieldDefinition::INDEX_FORMAT, preg_replace('/[^a-z0-9_\$]/i', '_', $index_name_base));
713 }
714
715 public function getSequenceName(string $table_name): string
716 {
717 return sprintf(FieldDefinition::SEQUENCE_FORMAT, preg_replace('/[^a-z0-9_\$.]/i', '_', $table_name));
718 }
719
724 public function constraintName(string $a_table, string $a_constraint): string
725 {
726 return $a_constraint;
727 }
728
729 public function getDSN(): string
730 {
731 return $this->dsn;
732 }
733
734 public function getDBType(): string
735 {
736 return $this->db_type;
737 }
738
739 public function setDBType(string $type): void
740 {
741 $this->db_type = $type;
742 }
743
749 public static function getReservedWords(): array
750 {
751 global $DIC;
752 $ilDB = $DIC->database();
753
757 $fd = $ilDB->getFieldDefinition();
758 if ($fd !== null) {
759 return $fd->getReservedMysql();
760 }
761 return [];
762 }
763
767 public function lockTables(array $tables): void
768 {
769 $lock = $this->manager->getQueryUtils()->lock($tables);
770 $this->pdo->exec($lock);
771 }
772
777 public function unlockTables(): void
778 {
779 $this->pdo->exec($this->manager->getQueryUtils()->unlock());
780 }
781
782 public function in(string $field, array $values, bool $negate = false, string $type = ""): string
783 {
784 return $this->manager->getQueryUtils()->in($field, $values, $negate, $type);
785 }
786
791 public function queryF(string $query, array $types, array $values): ilDBStatement
792 {
793 if (count($types) !== count($values)) {
794 throw new ilDatabaseException("ilDB::queryF: Types and values must be arrays of same size. ($query)");
795 }
796 $quoted_values = [];
797 foreach ($types as $k => $t) {
798 $quoted_values[] = $this->quote($values[$k], $t);
799 }
800 $query = vsprintf($query, $quoted_values);
801
802 return $this->query($query);
803 }
804
809 public function manipulateF(string $query, array $types, array $values): int
810 {
811 if (count($types) !== count($values)) {
812 throw new ilDatabaseException("ilDB::manipulateF: types and values must be arrays of same size. ($query)");
813 }
814 $quoted_values = [];
815 foreach ($types as $k => $t) {
816 $quoted_values[] = $this->quote($values[$k], $t);
817 }
818 $query = vsprintf($query, $quoted_values);
819
820 return $this->manipulate($query);
821 }
822
823 public function useSlave(bool $bool): bool
824 {
825 return false;
826 }
827
831 public function setLimit(int $limit, int $offset = 0): void
832 {
833 $this->limit = $limit;
834 $this->offset = $offset;
835 }
836
840 public function like(string $column, string $type, string $value = "?", bool $case_insensitive = true): string
841 {
842 return $this->manager->getQueryUtils()->like($column, $type, $value, $case_insensitive);
843 }
844
848 public function now(): string
849 {
850 return $this->manager->getQueryUtils()->now();
851 }
852
853 public function replace(string $table, array $primary_keys, array $other_columns): int
854 {
855 $a_columns = array_merge($primary_keys, $other_columns);
856 $fields = [];
857 $placeholders = [];
858 $types = [];
859 $values = [];
860
861 foreach ($a_columns as $k => $col) {
862 $fields[] = $this->quoteIdentifier($k);
863 $placeholders[] = "%s";
864 $placeholders2[] = ":$k";
865 $types[] = $col[0];
866
867 // integer auto-typecast (this casts bool values to integer)
868 if ($col[0] === 'integer' && !is_null($col[1])) {
869 $col[1] = (int) $col[1];
870 }
871
872 $values[] = $col[1];
873 }
874
875 $q = "REPLACE INTO " . $table . " (" . implode(",", $fields) . ") VALUES (" . implode(",", $placeholders) . ")";
876
877 return $this->manipulateF($q, $types, $values);
878 }
879
883 public function equals(string $columns, $value, string $type, bool $emptyOrNull = false): string
884 {
885 if (!$emptyOrNull || $value != "") {
886 return $columns . " = " . $this->quote($value, $type);
887 }
888
889 return "(" . $columns . " = '' OR $columns IS NULL)";
890 }
891
892 public function getHost(): string
893 {
894 return $this->host;
895 }
896
897 public function setHost(string $host): void
898 {
899 $this->host = $host;
900 }
901
902 public function getDbname(): string
903 {
904 return $this->dbname;
905 }
906
907 public function setDbname(string $dbname): void
908 {
909 $this->dbname = $dbname;
910 }
911
912 public function getCharset(): string
913 {
914 return $this->charset;
915 }
916
917 public function setCharset(string $charset): void
918 {
919 $this->charset = $charset;
920 }
921
922 public function getUsername(): string
923 {
924 return $this->username;
925 }
926
927 public function setUsername(string $username): void
928 {
929 $this->username = $username;
930 }
931
932 public function getPassword(): string
933 {
934 return $this->password;
935 }
936
937 public function setPassword(string $password): void
938 {
939 $this->password = $password;
940 }
941
942 public function getPort(): int
943 {
944 return $this->port;
945 }
946
947 public function setPort(int $port): void
948 {
949 $this->port = $port;
950 }
951
952 public function setDBUser(string $user): void
953 {
954 $this->setUsername($user);
955 }
956
957 public function setDBPort(int $port): void
958 {
959 $this->setPort($port);
960 }
961
962 public function setDBPassword(string $password): void
963 {
964 $this->setPassword($password);
965 }
966
967 public function setDBHost(string $host): void
968 {
969 $this->setHost($host);
970 }
971
972 public function upper(string $expression): string
973 {
974 return " UPPER(" . $expression . ") ";
975 }
976
977 public function lower(string $expression): string
978 {
979 return " LOWER(" . $expression . ") ";
980 }
981
982 public function substr(string $a_exp, int $a_pos = 1, int $a_len = -1): string
983 {
984 $lenstr = "";
985 if ($a_len > -1) {
986 $lenstr = ", " . $a_len;
987 }
988 return " SUBSTR(" . $a_exp . ", " . $a_pos . $lenstr . ") ";
989 }
990
991 public function prepareManip(string $query, ?array $types = null): ilDBStatement
992 {
993 return new ilPDOStatement($this->pdo->prepare($query));
994 }
995
996 public function prepare(string $query, ?array $types = null, ?array $result_types = null): ilDBStatement
997 {
998 return new ilPDOStatement($this->pdo->prepare($query));
999 }
1000
1001 public function enableResultBuffering(bool $a_status): void
1002 {
1003 $this->pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $a_status);
1004 }
1005
1009 public function execute(ilDBStatement $stmt, array $data = []): ilDBStatement
1010 {
1011 return $stmt->execute($data);
1012 }
1013
1014 public function supportsSlave(): bool
1015 {
1016 return false;
1017 }
1018
1019 public function supportsFulltext(): bool
1020 {
1021 return false;
1022 }
1023
1024 public function supportsTransactions(): bool
1025 {
1026 return $this->details->supportsTransactions();
1027 }
1028
1029 public function supports(string $feature): bool
1030 {
1031 return match ($feature) {
1032 self::FEATURE_TRANSACTIONS => $this->supportsTransactions(),
1033 self::FEATURE_FULLTEXT => $this->supportsFulltext(),
1034 self::FEATURE_SLAVE => $this->supportsSlave(),
1035 default => false,
1036 };
1037 }
1038
1042 public function listTables(): array
1043 {
1044 return $this->manager->listTables();
1045 }
1046
1050 public function loadModule(string $module)
1051 {
1052 return match ($module) {
1053 ilDBConstants::MODULE_MANAGER => $this->manager,
1054 ilDBConstants::MODULE_REVERSE => $this->reverse,
1055 default => throw new LogicException('module "' . $module . '" not available'),
1056 };
1057 }
1058
1059 public function getAllowedAttributes(): array
1060 {
1061 return $this->field_definition->getAllowedAttributes();
1062 }
1063
1064 public function sequenceExists(string $sequence): bool
1065 {
1066 return in_array($sequence, $this->listSequences(), true);
1067 }
1068
1069 public function listSequences(): array
1070 {
1071 return $this->manager->listSequences();
1072 }
1073
1074 public function concat(array $values, bool $allow_null = true): string
1075 {
1076 return $this->manager->getQueryUtils()->concat($values, $allow_null);
1077 }
1078
1079 private function appendLimit(string $query): string
1080 {
1081 if ($this->limit !== null && $this->offset !== null) {
1082 $query .= ' LIMIT ' . $this->offset . ', ' . $this->limit;
1083 $this->limit = null;
1084 $this->offset = null;
1085
1086 return $query;
1087 }
1088
1089 return $query;
1090 }
1091
1092 public function locate(string $needle, string $string, int $start_pos = 1): string
1093 {
1094 return $this->manager->getQueryUtils()->locate($needle, $string, $start_pos);
1095 }
1096
1100 public function modifyTableColumn(string $table, string $column, array $attributes): bool
1101 {
1102 $def = $this->reverse->getTableFieldDefinition($table, $column);
1103
1104 $analyzer = new ilDBAnalyzer($this);
1105 $best_alt = $analyzer->getBestDefinitionAlternative($def);
1106 $def = $def[$best_alt];
1107 unset($def["nativetype"], $def["mdb2type"]);
1108
1109 // check attributes
1110 $ilDBPdoFieldDefinition = $this->field_definition;
1111
1112 $type = $attributes["type"] ?? $def["type"];
1113
1114 foreach (array_keys($def) as $k) {
1115 if ($k !== "type" && !$ilDBPdoFieldDefinition->isAllowedAttribute($k, $type)) {
1116 unset($def[$k]);
1117 }
1118 }
1119 $check_array = $def;
1120 foreach ($attributes as $k => $v) {
1121 $check_array[$k] = $v;
1122 }
1123 if (!$this->checkColumnDefinition($check_array, true)) {
1124 throw new ilDatabaseException("ilDB Error: modifyTableColumn(" . $table . ", " . $column . ")");
1125 }
1126
1127 foreach ($attributes as $a => $v) {
1128 $def[$a] = $v;
1129 }
1130
1131 $attributes["definition"] = $def;
1132
1133 $changes = [
1134 "change" => [
1135 $column => $attributes,
1136 ],
1137 ];
1138
1139 return $this->manager->alterTable($table, $changes, false);
1140 }
1141
1142 public function free(ilDBStatement $a_st): void
1143 {
1144 $a_st->closeCursor();
1145 }
1146
1150 public function renameTable(string $name, string $new_name): bool
1151 {
1152 // check table name
1153 try {
1154 $this->checkTableName($new_name);
1155 } catch (ilDatabaseException $e) {
1156 throw new ilDatabaseException("ilDB Error: renameTable(" . $name . "," . $new_name . ")<br />" . $e->getMessage(), $e->getCode());
1157 }
1158
1159 $this->manager->alterTable($name, ["name" => $new_name], false);
1160 if ($this->sequenceExists($name)) {
1161 $this->manager->alterTable(
1162 $this->getSequenceName($name),
1163 ["name" => $this->getSequenceName($new_name)],
1164 false
1165 );
1166 }
1167 // The abstraction_progress is no longer used in ILIAS, see http://www.ilias.de/mantis/view.php?id=19513
1168 // $query = "UPDATE abstraction_progress " . "SET table_name = " . $this->quote($a_new_name, 'text') . " " . "WHERE table_name = "
1169 // . $this->quote($a_name, 'text');
1170 // $this->pdo->query($query);
1171
1172 return true;
1173 }
1174
1178 public function checkTableName(string $a_name): bool
1179 {
1180 return $this->field_definition->checkTableName($a_name);
1181 }
1182
1183 public static function isReservedWord(string $a_word): bool
1184 {
1185 global $DIC;
1186 return (new ilDBPdoMySQLFieldDefinition($DIC->database()))->isReserved($a_word);
1187 }
1188
1192 public function beginTransaction(): bool
1193 {
1194 if (!$this->supports(self::FEATURE_TRANSACTIONS)) {
1195 throw new ilDatabaseException("ilDB::beginTransaction: Transactions are not supported.");
1196 }
1197
1198 return $this->pdo->beginTransaction();
1199 }
1200
1204 public function commit(): bool
1205 {
1206 if (!$this->supports(self::FEATURE_TRANSACTIONS)) {
1207 throw new ilDatabaseException("ilDB::beginTransaction: Transactions are not supported.");
1208 }
1209
1210 return $this->pdo->commit();
1211 }
1212
1216 public function rollback(): bool
1217 {
1218 if (!$this->supports(self::FEATURE_TRANSACTIONS)) {
1219 throw new ilDatabaseException("ilDB::beginTransaction: Transactions are not supported.");
1220 }
1221
1222 return $this->pdo->rollBack();
1223 }
1224
1225 public function dropIndex(string $a_table, string $a_name = "i1"): bool
1226 {
1227 return $this->manager->dropIndex($a_table, $a_name);
1228 }
1229
1230 public function setStorageEngine(string $storage_engine): void
1231 {
1232 $this->storage_engine = $storage_engine;
1233 }
1234
1235 public function getStorageEngine(): string
1236 {
1237 return $this->storage_engine;
1238 }
1239
1240 public function queryCol(string $query, int $type = PDO::FETCH_ASSOC, int $colnum = 0): array
1241 {
1242 $type = match ($type) {
1243 ilDBConstants::FETCHMODE_ASSOC => PDO::FETCH_ASSOC,
1244 ilDBConstants::FETCHMODE_OBJECT => PDO::FETCH_OBJ,
1245 default => PDO::FETCH_ASSOC,
1246 };
1247
1248 return $this->pdo->query($query, PDO::FETCH_ASSOC)->fetchAll(PDO::FETCH_COLUMN, $colnum);
1249 }
1250
1251 public function queryRow(
1252 string $query,
1253 ?array $types = null,
1254 int $fetchmode = ilDBConstants::FETCHMODE_DEFAULT
1255 ): array {
1256 $type = match ($fetchmode) {
1257 ilDBConstants::FETCHMODE_ASSOC => PDO::FETCH_ASSOC,
1258 ilDBConstants::FETCHMODE_OBJECT => PDO::FETCH_OBJ,
1259 default => PDO::FETCH_ASSOC,
1260 };
1261
1262 return $this->pdo->query($query, $type)->fetch();
1263 }
1264
1265 public function getServerVersion(bool $native = false): int
1266 {
1267 return $this->pdo->query('SELECT VERSION()')->fetchColumn();
1268 }
1269
1270 public function escape(string $value, bool $escape_wildcards = false): string
1271 {
1272 return $value;
1273 }
1274
1275 public function escapePattern(string $text): string
1276 {
1277 return $text;
1278 }
1279
1283 #[\Override]
1284 public function migrateAllTablesToEngine(string $engine = ilDBConstants::MYSQL_ENGINE_INNODB): array
1285 {
1286 $engines = $this->queryCol('SHOW ENGINES');
1287 if (!in_array($engine, $engines, true)) {
1288 return [];
1289 }
1290 $errors = [];
1291 $tables = $this->listTables();
1292 array_walk($tables, function (string $table_name) use (&$errors, $engine): void {
1293 try {
1294 $this->pdo->exec("ALTER TABLE $table_name ENGINE=$engine");
1295 if ($this->sequenceExists($table_name)) {
1296 $this->pdo->exec("ALTER TABLE {$table_name}_seq ENGINE=$engine");
1297 }
1298 } catch (Exception $e) {
1299 $errors[$table_name] = $e->getMessage();
1300 }
1301 });
1302
1303 return $errors;
1304 }
1305
1306 #[\Override]
1308 {
1309 $errors = [];
1310 foreach ($this->manager->listTables() as $table_name) {
1311 if (!$this->migrateTableCollation($table_name, $collation)) {
1312 $errors[] = $table_name;
1313 }
1314 }
1315
1316 return $errors;
1317 }
1318
1319 #[\Override]
1320 public function supportsCollationMigration(): bool
1321 {
1322 return true;
1323 }
1324
1325 public function supportsEngineMigration(): bool
1326 {
1327 return true;
1328 }
1329
1333 public function checkIndexName(string $name): bool
1334 {
1335 $fd = $this->getFieldDefinition();
1336 if ($fd !== null) {
1337 return $fd->checkIndexName($name);
1338 }
1339 return false;
1340 }
1341
1345 public function addUniqueConstraint(string $table, array $fields, string $name = "con"): bool
1346 {
1347 $manager = $this->manager;
1348
1349 // check index name
1350 if (!$this->checkIndexName($name)) {
1351 throw new ilDatabaseException("ilDB Error: addUniqueConstraint(" . $table . "," . $name . ")");
1352 }
1353
1354 $fields_corrected = [];
1355 foreach ($fields as $f) {
1356 $fields_corrected[$f] = [];
1357 }
1358 $definition = [
1359 'unique' => true,
1360 'fields' => $fields_corrected,
1361 ];
1362
1363 return $manager->createConstraint($table, $this->constraintName($table, $name), $definition);
1364 }
1365
1366 public function dropUniqueConstraint(string $table, string $name = "con"): bool
1367 {
1368 return $this->manager->dropConstraint($table, $this->constraintName($table, $name), false);
1369 }
1370
1371 public function dropUniqueConstraintByFields(string $table, array $fields): bool
1372 {
1373 $analyzer = new ilDBAnalyzer();
1374 $cons = $analyzer->getConstraintsInformation($table);
1375 foreach ($cons as $c) {
1376 if ($c["type"] === "unique" && count($fields) === count($c["fields"])) {
1377 $all_in = true;
1378 foreach ($fields as $f) {
1379 if (!isset($c["fields"][$f])) {
1380 $all_in = false;
1381 }
1382 }
1383 if ($all_in) {
1384 return $this->dropUniqueConstraint($table, $c['name']);
1385 }
1386 }
1387 }
1388
1389 return false;
1390 }
1391
1392 public function getLastInsertId(): int
1393 {
1394 return (int) $this->pdo->lastInsertId();
1395 }
1396
1397 public function buildAtomQuery(): ilAtomQuery
1398 {
1399 return $this->details->atomQuery($this);
1400 }
1401
1402 public function uniqueConstraintExists(string $table, array $fields): bool
1403 {
1404 $analyzer = new ilDBAnalyzer();
1405 $cons = $analyzer->getConstraintsInformation($table);
1406 foreach ($cons as $c) {
1407 if ($c["type"] === "unique" && count($fields) === count($c["fields"])) {
1408 $all_in = true;
1409 foreach ($fields as $f) {
1410 if (!isset($c["fields"][$f])) {
1411 $all_in = false;
1412 }
1413 }
1414 if ($all_in) {
1415 return true;
1416 }
1417 }
1418 }
1419
1420 return false;
1421 }
1422
1423 public function dropPrimaryKey(string $table_name): bool
1424 {
1425 return $this->manager->dropConstraint($table_name, "PRIMARY", true);
1426 }
1427
1428 public function executeMultiple(ilDBStatement $stmt, array $data): array
1429 {
1430 foreach ($data as $set) {
1431 $this->execute($stmt, $set);
1432 }
1433 return [];
1434 }
1435
1436 public function fromUnixtime(string $expr, bool $to_text = true): string
1437 {
1438 return "FROM_UNIXTIME(" . $expr . ")";
1439 }
1440
1441 public function unixTimestamp(): string
1442 {
1443 return "UNIX_TIMESTAMP()";
1444 }
1445
1449 public function getDBVersion(): string
1450 {
1451 $d = $this->fetchObject($this->query("SELECT VERSION() AS version"));
1452
1453 if ($d !== null && $d->version) {
1454 return $d->version;
1455 }
1456 return 'Unknown';
1457 }
1458
1459 public function sanitizeMB4StringIfNotSupported(string $query): string
1460 {
1461 if (!$this->doesCollationSupportMB4Strings()) {
1462 $query_replaced = preg_replace(
1463 '/[\x{10000}-\x{10FFFF}]/u',
1465 $query
1466 );
1467 if (!empty($query_replaced)) {
1468 return $query_replaced;
1469 }
1470 }
1471
1472 return $query;
1473 }
1474
1475 #[\Override]
1476 public function doesCollationSupportMB4Strings(): bool
1477 {
1478 // Currently ILIAS does not support utf8mb4, after that ilDB could check like this:
1479 // static $supported;
1480 // if (!isset($supported)) {
1481 // $q = "SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = %s;";
1482 // $res = $this->queryF($q, ['text'], [$this->getDbname()]);
1483 // $data = $this->fetchObject($res);
1484 // $supported = ($data->default_character_set_name === 'utf8mb4');
1485 // }
1486
1487 return false;
1488 }
1489
1490 public function groupConcat(string $a_field_name, string $a_seperator = ",", ?string $a_order = null): string
1491 {
1492 return $this->manager->getQueryUtils()->groupConcat($a_field_name, $a_seperator, $a_order);
1493 }
1494
1495 public function cast(string $a_field_name, string $a_dest_type): string
1496 {
1497 return $a_field_name;
1498 }
1499
1500 public function addForeignKey(
1501 string $foreign_key_name,
1502 array $field_names,
1503 string $table_name,
1504 array $reference_field_names,
1505 string $reference_table,
1506 ?ForeignKeyConstraints $on_update = null,
1507 ?ForeignKeyConstraints $on_delete = null
1508 ): bool {
1509 return $this->manager->addForeignKey($foreign_key_name, $field_names, $table_name, $reference_field_names, $reference_table, $on_update, $on_delete);
1510 }
1511
1512 public function dropForeignKey(string $foreign_key_name, string $table_name): bool
1513 {
1514 return $this->manager->dropForeignKey($foreign_key_name, $table_name);
1515 }
1516
1517 public function foreignKeyExists(string $foreign_key_name, string $table_name): bool
1518 {
1519 return $this->manager->foreignKeyExists($foreign_key_name, $table_name);
1520 }
1521
1523 {
1524 return new Integrity($this);
1525 }
1526
1527 public function primaryExistsByFields(string $table_name, array $fields): bool
1528 {
1529 $constraints = $this->manager->listTableConstraints($table_name);
1530
1531 if (in_array('primary', $constraints)) {
1532 $definitions = $this->reverse->getTableConstraintDefinition($table_name, 'primary');
1533 $primary_fields = array_keys($definitions['fields']);
1534 sort($primary_fields);
1535 sort($fields);
1536
1537 return $primary_fields === $fields;
1538 }
1539 return false;
1540 }
1541
1542 #[\Override]
1543 public function migrateTableCollation(string $table_name, string $collation = ilDBConstants::MYSQL_COLLATION_UTF8MB4): bool
1544 {
1545 $collation_split = explode("_", $collation);
1546 $character = $collation_split[0] ?? 'utf8mb4';
1547 $collate = $collation;
1548 $q = "ALTER TABLE {$this->quoteIdentifier($table_name)} CONVERT TO CHARACTER SET {$character} COLLATE {$collate};";
1549 try {
1550 $this->pdo->exec($q);
1551 } catch (PDOException) {
1552 return false;
1553 }
1554 return true;
1555 }
1556
1557 public function migrateTableToEngine(string $table_name, string $engine = ilDBConstants::MYSQL_ENGINE_INNODB): void
1558 {
1559 try {
1560 $this->pdo->exec("ALTER TABLE {$table_name} ENGINE={$engine}");
1561 if ($this->sequenceExists($table_name)) {
1562 $this->pdo->exec("ALTER TABLE {$table_name}_seq ENGINE={$engine}");
1563 }
1564 } catch (PDOException $e) {
1565 throw new ilDatabaseException($e->getMessage(), $e->getCode());
1566 }
1567 }
1568}
Class ilBenchmark.
This class gives all kind of DB information using the database manager and reverse module.
const MODULE_MANAGER
const FETCHMODE_DEFAULT
const FETCHMODE_OBJECT
const MODULE_REVERSE
const FETCHMODE_ASSOC
const MYSQL_ENGINE_INNODB
const MYSQL_COLLATION_UTF8MB4
const MB4_REPLACEMENT
Class ilDBPdoManager.
Class ilDBPdoMySQLFieldDefinition.
Class ilDBPdoReverse.
getLastInsertId()
Definition: ilDBPdo.php:1392
string $db_type
Definition: ilDBPdo.php:52
renameTable(string $name, string $new_name)
Definition: ilDBPdo.php:1150
fetchAll(ilDBStatement $statement, int $fetch_mode=ilDBConstants::FETCHMODE_ASSOC)
Definition: ilDBPdo.php:402
listTables()
Definition: ilDBPdo.php:1042
getStorageEngine()
Definition: ilDBPdo.php:1235
addForeignKey(string $foreign_key_name, array $field_names, string $table_name, array $reference_field_names, string $reference_table, ?ForeignKeyConstraints $on_update=null, ?ForeignKeyConstraints $on_delete=null)
Definition: ilDBPdo.php:1500
setUsername(string $username)
Definition: ilDBPdo.php:927
dropUniqueConstraintByFields(string $table, array $fields)
Definition: ilDBPdo.php:1371
supportsTransactions()
Definition: ilDBPdo.php:1024
checkColumnName(string $a_name)
Definition: ilDBPdo.php:254
string $dbname
Definition: ilDBPdo.php:40
commit()
Definition: ilDBPdo.php:1204
setLimit(int $limit, int $offset=0)
Set the Limit for the next Query.
Definition: ilDBPdo.php:831
createTable(string $table_name, array $fields, bool $drop_table=false, bool $ignore_erros=false)
Definition: ilDBPdo.php:207
in(string $field, array $values, bool $negate=false, string $type="")
Definition: ilDBPdo.php:782
tableExists(string $table_name)
Definition: ilDBPdo.php:309
getFieldDefinition()
Definition: ilDBPdo.php:110
manipulateF(string $query, array $types, array $values)
Definition: ilDBPdo.php:809
string $storage_engine
Definition: ilDBPdo.php:50
supportsFulltext()
Definition: ilDBPdo.php:1019
dropTable(string $table_name, bool $error_if_not_existing=true)
Definition: ilDBPdo.php:348
string $username
Definition: ilDBPdo.php:42
sanitizeMB4StringIfNotSupported(string $query)
Definition: ilDBPdo.php:1459
isFulltextIndex(string $a_table, string $a_name)
Is index a fulltext index?
Definition: ilDBPdo.php:698
numRows(ilDBStatement $statement)
Definition: ilDBPdo.php:604
setStorageEngine(string $storage_engine)
Definition: ilDBPdo.php:1230
int $limit
Definition: ilDBPdo.php:48
escapePattern(string $text)
Definition: ilDBPdo.php:1275
free(ilDBStatement $a_st)
Definition: ilDBPdo.php:1142
connect(bool $return_false_for_error=false)
Definition: ilDBPdo.php:73
insert(string $table_name, array $values)
Definition: ilDBPdo.php:462
fromUnixtime(string $expr, bool $to_text=true)
Definition: ilDBPdo.php:1436
setPort(int $port)
Definition: ilDBPdo.php:947
groupConcat(string $a_field_name, string $a_seperator=",", ?string $a_order=null)
Definition: ilDBPdo.php:1490
getPort()
Definition: ilDBPdo.php:942
enableResultBuffering(bool $a_status)
Definition: ilDBPdo.php:1001
checkIndexName(string $name)
Definition: ilDBPdo.php:1333
dropIndex(string $a_table, string $a_name="i1")
Definition: ilDBPdo.php:1225
getDbname()
Definition: ilDBPdo.php:902
addPrimaryKey(string $table_name, array $primary_keys)
Definition: ilDBPdo.php:262
dropForeignKey(string $foreign_key_name, string $table_name)
Definition: ilDBPdo.php:1512
substr(string $a_exp, int $a_pos=1, int $a_len=-1)
Definition: ilDBPdo.php:982
queryF(string $query, array $types, array $values)
Definition: ilDBPdo.php:791
getPassword()
Definition: ilDBPdo.php:932
string $dsn
Definition: ilDBPdo.php:51
migrateTableToEngine(string $table_name, string $engine=ilDBConstants::MYSQL_ENGINE_INNODB)
Definition: ilDBPdo.php:1557
getLastErrorCode()
Definition: ilDBPdo.php:136
supportsEngineMigration()
Definition: ilDBPdo.php:1325
string $host
Definition: ilDBPdo.php:39
getDBVersion()
Definition: ilDBPdo.php:1449
query(string $query)
Definition: ilDBPdo.php:373
getPrimaryKeyIdentifier()
Definition: ilDBPdo.php:298
executeMultiple(ilDBStatement $stmt, array $data)
Definition: ilDBPdo.php:1428
string $password
Definition: ilDBPdo.php:43
getAllowedAttributes()
Definition: ilDBPdo.php:1059
checkTableName(string $a_name)
Definition: ilDBPdo.php:1178
setDBPassword(string $password)
Definition: ilDBPdo.php:962
setHost(string $host)
Definition: ilDBPdo.php:897
sequenceExists(string $sequence)
Definition: ilDBPdo.php:1064
getDBType()
Get DSN.
Definition: ilDBPdo.php:734
array $options
Definition: ilDBPdo.php:33
escape(string $value, bool $escape_wildcards=false)
Definition: ilDBPdo.php:1270
buildIntegrityAnalyser()
Definition: ilDBPdo.php:1522
getServerVersion(bool $native=false)
Definition: ilDBPdo.php:1265
modifyTableColumn(string $table, string $column, array $attributes)
Definition: ilDBPdo.php:1100
string $charset
Definition: ilDBPdo.php:41
addUniqueConstraint(string $table, array $fields, string $name="con")
Definition: ilDBPdo.php:1345
ilDBManager $manager
Definition: ilDBPdo.php:46
migrateAllTablesToCollation(string $collation=ilDBConstants::MYSQL_COLLATION_UTF8MB4)
Definition: ilDBPdo.php:1307
setCharset(string $charset)
Definition: ilDBPdo.php:917
dropFulltextIndex(string $a_table, string $a_name)
Drop fulltext index.
Definition: ilDBPdo.php:688
buildAtomQuery()
Definition: ilDBPdo.php:1397
dropUniqueConstraint(string $table, string $name="con")
Definition: ilDBPdo.php:1366
unixTimestamp()
Definition: ilDBPdo.php:1441
addIndex(string $table_name, array $fields, string $index_name='', bool $fulltext=false)
Definition: ilDBPdo.php:658
getSequenceName(string $table_name)
Definition: ilDBPdo.php:715
createSequence(string $table_name, int $start=1)
Definition: ilDBPdo.php:303
dropPrimaryKey(string $table_name)
Definition: ilDBPdo.php:1423
const FEATURE_SLAVE
Definition: ilDBPdo.php:37
supportsCollationMigration()
Definition: ilDBPdo.php:1320
appendLimit(string $query)
Definition: ilDBPdo.php:1079
prepareManip(string $query, ?array $types=null)
Definition: ilDBPdo.php:991
loadModule(string $module)
Definition: ilDBPdo.php:1050
getHost()
Definition: ilDBPdo.php:892
setDBHost(string $host)
Definition: ilDBPdo.php:967
queryCol(string $query, int $type=PDO::FETCH_ASSOC, int $colnum=0)
Definition: ilDBPdo.php:1240
setDBType(string $type)
Definition: ilDBPdo.php:739
setDbname(string $dbname)
Definition: ilDBPdo.php:907
indexExistsByFields(string $table_name, array $fields)
Definition: ilDBPdo.php:644
concat(array $values, bool $allow_null=true)
Definition: ilDBPdo.php:1074
renameTableColumn(string $table_name, string $column_old_name, string $column_new_name)
Definition: ilDBPdo.php:435
equals(string $columns, $value, string $type, bool $emptyOrNull=false)
Definition: ilDBPdo.php:883
lockTables(array $tables)
Definition: ilDBPdo.php:767
const SESSION_MODES
Definition: ilDBPdo.php:56
checkColumn(string $a_col, array $a_def)
Definition: ilDBPdo.php:241
migrateAllTablesToEngine(string $engine=ilDBConstants::MYSQL_ENGINE_INNODB)
Definition: ilDBPdo.php:1284
addFulltextIndex(string $table_name, array $fields, string $name='in')
Definition: ilDBPdo.php:680
int $port
Definition: ilDBPdo.php:44
primaryExistsByFields(string $table_name, array $fields)
Definition: ilDBPdo.php:1527
prepare(string $query, ?array $types=null, ?array $result_types=null)
Prepare a query (SELECT) statement to be used with execute.
Definition: ilDBPdo.php:996
__construct(private readonly Details $details)
Definition: ilDBPdo.php:66
getAttributes()
Definition: ilDBPdo.php:101
getUsername()
Definition: ilDBPdo.php:922
int $error_code
Definition: ilDBPdo.php:53
like(string $column, string $type, string $value="?", bool $case_insensitive=true)
Definition: ilDBPdo.php:840
dropIndexByFields(string $table_name, array $fields)
Definition: ilDBPdo.php:284
quoteIdentifier(string $identifier, bool $check_option=false)
Definition: ilDBPdo.php:176
unlockTables()
Definition: ilDBPdo.php:777
doesCollationSupportMB4Strings()
Definition: ilDBPdo.php:1476
const FEATURE_TRANSACTIONS
Definition: ilDBPdo.php:35
dropTableColumn(string $table_name, string $column_name)
Definition: ilDBPdo.php:421
createDatabase(string $a_name, string $a_charset="utf8", string $a_collation="")
Definition: ilDBPdo.php:120
PDO $pdo
Definition: ilDBPdo.php:45
getIndexName(string $index_name_base)
Definition: ilDBPdo.php:710
manipulate(string $query)
Definition: ilDBPdo.php:572
ilDBReverse $reverse
Definition: ilDBPdo.php:47
addTableColumn(string $table_name, string $column_name, array $attributes)
Definition: ilDBPdo.php:327
constraintName(string $a_table, string $a_constraint)
Determine contraint name by table name and constraint name.
Definition: ilDBPdo.php:724
useSlave(bool $bool)
Definition: ilDBPdo.php:823
migrateTableCollation(string $table_name, string $collation=ilDBConstants::MYSQL_COLLATION_UTF8MB4)
Definition: ilDBPdo.php:1543
fetchAssoc(ilDBStatement $statement)
Definition: ilDBPdo.php:592
checkTableColumns(array $a_cols)
Definition: ilDBPdo.php:230
int $offset
Definition: ilDBPdo.php:49
replace(string $table, array $primary_keys, array $other_columns)
Replace into method.
Definition: ilDBPdo.php:853
locate(string $needle, string $string, int $start_pos=1)
Definition: ilDBPdo.php:1092
checkColumnDefinition(array $a_def, bool $a_modify_mode=false)
Definition: ilDBPdo.php:249
upper(string $expression)
Definition: ilDBPdo.php:972
generateDSN()
Definition: ilDBPdo.php:167
beginTransaction()
Definition: ilDBPdo.php:1192
setDBUser(string $user)
Definition: ilDBPdo.php:952
const FEATURE_FULLTEXT
Definition: ilDBPdo.php:36
rollback()
Definition: ilDBPdo.php:1216
setDBPort(int $port)
Definition: ilDBPdo.php:957
foreignKeyExists(string $foreign_key_name, string $table_name)
Definition: ilDBPdo.php:1517
dropSequence(string $table_name)
Definition: ilDBPdo.php:412
uniqueConstraintExists(string $table, array $fields)
Definition: ilDBPdo.php:1402
nextId(string $table_name)
Definition: ilDBPdo.php:182
supportsSlave()
Definition: ilDBPdo.php:1014
getDSN()
Get DSN.
Definition: ilDBPdo.php:729
listSequences()
Definition: ilDBPdo.php:1069
cast(string $a_field_name, string $a_dest_type)
Definition: ilDBPdo.php:1495
fetchObject(ilDBStatement $query_result)
Definition: ilDBPdo.php:479
update(string $table_name, array $columns, array $where)
@description $where MUST contain existing columns only.
Definition: ilDBPdo.php:491
static isReservedWord(string $a_word)
Definition: ilDBPdo.php:1183
supports(string $feature)
Definition: ilDBPdo.php:1029
execute(ilDBStatement $stmt, array $data=[])
Definition: ilDBPdo.php:1009
setPassword(string $password)
Definition: ilDBPdo.php:937
setFieldDefinition(FieldDefinition $field_definition)
Definition: ilDBPdo.php:115
tableColumnExists(string $table_name, string $column_name)
Definition: ilDBPdo.php:319
initHelpers()
Definition: ilDBPdo.php:97
queryRow(string $query, ?array $types=null, int $fetchmode=ilDBConstants::FETCHMODE_DEFAULT)
Definition: ilDBPdo.php:1251
initFromIniFile(?ilIniFile $ini=null)
Definition: ilDBPdo.php:145
getCharset()
Definition: ilDBPdo.php:912
FieldDefinition $field_definition
Definition: ilDBPdo.php:54
quote($value, ?string $type=null)
Definition: ilDBPdo.php:609
lower(string $expression)
Definition: ilDBPdo.php:977
Class ilDatabaseException.
INIFile Parser Early access in init proceess! Avoid further dependencies like logging or other servic...
Class ilPDOStatement is a Wrapper Class for PDOStatement.
$c
Definition: deliver.php:25
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$info
Definition: entry_point.php:21
Interface ilAtomQuery Use ilAtomQuery to fire Database-Actions which have to be done without beeing i...
Definition: ilAtomQuery.php:28
Interface ilDBManager.
Definition: ilDBManager.php:28
createConstraint(string $table, string $name, array $definition)
Interface ilDBReverse.
Definition: ilDBReverse.php:27
Interface ilDBStatement.
execute(?array $a_data=null)
fetch(int $fetch_mode=ilDBConstants::FETCHMODE_ASSOC)
$res
Definition: ltiservices.php:69
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$ini
Definition: raiseError.php:20
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:25
$text
Definition: xapiexit.php:21