ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilDBPdoFieldDefinition.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
26{
27 public array $lobs;
28 public const DEFAULT_DECIMAL_PLACES = 2;
29 public const DEFAULT_TEXT_LENGTH = 4000;
30 public const DEFINITION_COLUMN_NAME = "/^[a-z]+[_a-z0-9]*$/";
31 public const DEFINITION_TABLE_NAME = "/^[a-z]+[_a-z0-9]*$/";
32 public const INDEX_FORMAT = '%s_idx';
33 public const SEQUENCE_COLUMNS_NAME = 'sequence';
34 public const SEQUENCE_FORMAT = '%s_seq';
35 public const T_BLOB = 'blob';
36 public const T_CLOB = 'clob';
37 public const T_DATE = 'date';
38 public const T_DATETIME = 'datetime';
39 public const T_FLOAT = 'float';
40 public const T_INTEGER = 'integer';
41 public const T_TEXT = 'text';
42 public const T_TIME = 'time';
43 public const T_TIMESTAMP = 'timestamp';
44
45 private const MAX_TABLE_IDENTIFIER_LENGTH = 63;
46
47 protected static \ilDBPdoFieldDefinition $instance;
51 public array $allowed_attributes_old = [
52 self::T_TEXT => ['length', 'notnull', 'default', 'fixed'],
53 self::T_INTEGER => ['length', 'notnull', 'default', 'unsigned'],
54 self::T_FLOAT => ['notnull', 'default'],
55 self::T_DATE => ['notnull', 'default'],
56 self::T_TIME => ['notnull', 'default'],
57 self::T_TIMESTAMP => ['notnull', 'default'],
58 self::T_CLOB => ['notnull', 'default'],
59 self::T_BLOB => ['notnull', 'default'],
60 ];
64 public array $allowed_attributes = [
65 "text" => ["length", "notnull", "default", "fixed"],
66 "integer" => ["length", "notnull", "default", "unsigned"],
67 "float" => ["notnull", "default"],
68 "date" => ["notnull", "default"],
69 "time" => ["notnull", "default"],
70 "timestamp" => ["notnull", "default"],
71 "clob" => ["length", "notnull", "default"],
72 "blob" => ["length", "notnull", "default"],
73 ];
74 protected array $max_length = [
75 self::T_INTEGER => [1, 2, 3, 4, 8],
76 self::T_TEXT => 4000,
77 ];
81 protected array $available_types = [
90 ];
94 protected array $reserved_mysql = [
95 "ACCESSIBLE",
96 "ACCOUNT",
97 "ACTION",
98 "ADD",
99 "AFTER",
100 "AGAINST",
101 "AGGREGATE",
102 "ALGORITHM",
103 "ALL",
104 "ALTER",
105 "ALWAYS",
106 "ANALYSE",
107 "ANALYZE",
108 "AND",
109 "ANY",
110 "AS",
111 "ASC",
112 "ASCII",
113 "ASENSITIVE",
114 "AT",
115 "AUTHORS",
116 "AUTOEXTEND_SIZE",
117 "AUTO_INCREMENT",
118 "AVG",
119 "AVG_ROW_LENGTH",
120 "BACKUP",
121 "BEFORE",
122 "BEGIN",
123 "BETWEEN",
124 "BIGINT",
125 "BINARY",
126 "BINLOG",
127 "BIT",
128 "BLOB",
129 "BLOCK",
130 "BOOL",
131 "BOOLEAN",
132 "BOTH",
133 "BTREE",
134 "BY",
135 "BYTE",
136 "CACHE",
137 "CALL",
138 "CASCADE",
139 "CASCADED",
140 "CASE",
141 "CATALOG_NAME",
142 "CHAIN",
143 "CHANGE",
144 "CHANGED",
145 "CHANNEL",
146 "CHAR",
147 "CHARACTER",
148 "CHARSET",
149 "CHECK",
150 "CHECKSUM",
151 "CIPHER",
152 "CLASS_ORIGIN",
153 "CLIENT",
154 "CLOSE",
155 "COALESCE",
156 "CODE",
157 "COLLATE",
158 "COLLATION",
159 "COLUMN",
160 "COLUMNS",
161 "COLUMN_FORMAT",
162 "COLUMN_NAME",
163 "COMMENT",
164 "COMMIT",
165 "COMMITTED",
166 "COMPACT",
167 "COMPLETION",
168 "COMPRESSED",
169 "COMPRESSION",
170 "CONCURRENT",
171 "CONDITION",
172 "CONNECTION",
173 "CONSISTENT",
174 "CONSTRAINT",
175 "CONSTRAINT_CATALOG",
176 "CONSTRAINT_NAME",
177 "CONSTRAINT_SCHEMA",
178 "CONTAINS",
179 "CONTEXT",
180 "CONTINUE",
181 "CONTRIBUTORS",
182 "CONVERT",
183 "CPU",
184 "CREATE",
185 "CROSS",
186 "CUBE",
187 "CURRENT",
188 "CURRENT_DATE",
189 "CURRENT_TIME",
190 "CURRENT_TIMESTAMP",
191 "CURRENT_USER",
192 "CURSOR",
193 "CURSOR_NAME",
194 "DATA",
195 "DATABASE",
196 "DATABASES",
197 "DATAFILE",
198 "DATE",
199 "DATETIME",
200 "DAY",
201 "DAY_HOUR",
202 "DAY_MICROSECOND",
203 "DAY_MINUTE",
204 "DAY_SECOND",
205 "DEALLOCATE",
206 "DEC",
207 "DECIMAL",
208 "DECLARE",
209 "DEFAULT",
210 "DEFAULT_AUTH",
211 "DEFINER",
212 "DELAYED",
213 "DELAY_KEY_WRITE",
214 "DELETE",
215 "DESC",
216 "DESCRIBE",
217 "DES_KEY_FILE",
218 "DETERMINISTIC",
219 "DIAGNOSTICS",
220 "DIRECTORY",
221 "DISABLE",
222 "DISCARD",
223 "DISK",
224 "DISTINCT",
225 "DISTINCTROW",
226 "DIV",
227 "DO",
228 "DOUBLE",
229 "DROP",
230 "DUAL",
231 "DUMPFILE",
232 "DUPLICATE",
233 "DYNAMIC",
234 "EACH",
235 "ELSE",
236 "ELSEIF",
237 "ENABLE",
238 "ENCLOSED",
239 "ENCRYPTION",
240 "END",
241 "ENDS",
242 "ENGINE",
243 "ENGINES",
244 "ENUM",
245 "ERROR",
246 "ERRORS",
247 "ESCAPE",
248 "ESCAPED",
249 "EVENT",
250 "EVENTS",
251 "EVERY",
252 "EXCHANGE",
253 "EXECUTE",
254 "EXISTS",
255 "EXIT",
256 "EXPANSION",
257 "EXPIRE",
258 "EXPLAIN",
259 "EXPORT",
260 "EXTENDED",
261 "EXTENT_SIZE",
262 "FALSE",
263 "FAST",
264 "FAULTS",
265 "FETCH",
266 "FIELDS",
267 "FILE",
268 "FILE_BLOCK_SIZE",
269 "FILTER",
270 "FIRST",
271 "FIXED",
272 "FLOAT",
273 "FLOAT4",
274 "FLOAT8",
275 "FLUSH",
276 "FOLLOWS",
277 "FOR",
278 "FORCE",
279 "FOREIGN",
280 "FORMAT",
281 "FOUND",
282 "FROM",
283 "FULL",
284 "FULLTEXT",
285 "FUNCTION",
286 "GENERAL",
287 "GENERATED",
288 "GEOMETRY",
289 "GEOMETRYCOLLECTION",
290 "GET",
291 "GET_FORMAT",
292 "GLOBAL",
293 "GRANT",
294 "GRANTS",
295 "GROUP",
296 "GROUP_REPLICATION",
297 "HANDLER",
298 "HASH",
299 "HAVING",
300 "HELP",
301 "HIGH_PRIORITY",
302 "HOST",
303 "HOSTS",
304 "HOUR",
305 "HOUR_MICROSECOND",
306 "HOUR_MINUTE",
307 "HOUR_SECOND",
308 "IDENTIFIED",
309 "IF",
310 "IGNORE",
311 "IGNORE_SERVER_IDS",
312 "IMPORT",
313 "IN",
314 "INDEX",
315 "INDEXES",
316 "INFILE",
317 "INITIAL_SIZE",
318 "INNER",
319 "INOUT",
320 "INSENSITIVE",
321 "INSERT",
322 "INSERT_METHOD",
323 "INSTALL",
324 "INSTANCE",
325 "INT",
326 "INT1",
327 "INT2",
328 "INT3",
329 "INT4",
330 "INT8",
331 "INTEGER",
332 "INTERVAL",
333 "INTO",
334 "INVOKER",
335 "IO",
336 "IO_AFTER_GTIDS",
337 "IO_BEFORE_GTIDS",
338 "IO_THREAD",
339 "IPC",
340 "IS",
341 "ISOLATION",
342 "ISSUER",
343 "ITERATE",
344 "JOIN",
345 "JSON",
346 "KEY",
347 "KEYS",
348 "KEY_BLOCK_SIZE",
349 "KILL",
350 "LANGUAGE",
351 "LAST",
352 "LEADING",
353 "LEAVE",
354 "LEAVES",
355 "LEFT",
356 "LESS",
357 "LEVEL",
358 "LIKE",
359 "LIMIT",
360 "LINEAR",
361 "LINES",
362 "LINESTRING",
363 "LIST",
364 "LOAD",
365 "LOCAL",
366 "LOCALTIME",
367 "LOCALTIMESTAMP",
368 "LOCK",
369 "LOCKS",
370 "LOGFILE",
371 "LOGS",
372 "LONG",
373 "LONGBLOB",
374 "LONGTEXT",
375 "LOOP",
376 "LOW_PRIORITY",
377 "MASTER",
378 "MASTER_AUTO_POSITION",
379 "MASTER_BIND",
380 "MASTER_CONNECT_RETRY",
381 "MASTER_DELAY",
382 "MASTER_HEARTBEAT_PERIOD",
383 "MASTER_HOST",
384 "MASTER_LOG_FILE",
385 "MASTER_LOG_POS",
386 "MASTER_PASSWORD",
387 "MASTER_PORT",
388 "MASTER_RETRY_COUNT",
389 "MASTER_SERVER_ID",
390 "MASTER_SSL",
391 "MASTER_SSL_CA",
392 "MASTER_SSL_CAPATH",
393 "MASTER_SSL_CERT",
394 "MASTER_SSL_CIPHER",
395 "MASTER_SSL_CRL",
396 "MASTER_SSL_CRLPATH",
397 "MASTER_SSL_KEY",
398 "MASTER_SSL_VERIFY_SERVER_CERT",
399 "MASTER_TLS_VERSION",
400 "MASTER_USER",
401 "MATCH",
402 "MAXVALUE",
403 "MAX_CONNECTIONS_PER_HOUR",
404 "MAX_QUERIES_PER_HOUR",
405 "MAX_ROWS",
406 "MAX_SIZE",
407 "MAX_STATEMENT_TIME",
408 "MAX_UPDATES_PER_HOUR",
409 "MAX_USER_CONNECTIONS",
410 "MEDIUM",
411 "MEDIUMBLOB",
412 "MEDIUMINT",
413 "MEDIUMTEXT",
414 "MEMORY",
415 "MERGE",
416 "MESSAGE_TEXT",
417 "MICROSECOND",
418 "MIDDLEINT",
419 "MIGRATE",
420 "MINUTE",
421 "MINUTE_MICROSECOND",
422 "MINUTE_SECOND",
423 "MIN_ROWS",
424 "MOD",
425 "MODE",
426 "MODIFIES",
427 "MODIFY",
428 "MONTH",
429 "MULTILINESTRING",
430 "MULTIPOINT",
431 "MULTIPOLYGON",
432 "MUTEX",
433 "MYSQL_ERRNO",
434 "NAME",
435 "NAMES",
436 "NATIONAL",
437 "NATURAL",
438 "NCHAR",
439 "NDB",
440 "NDBCLUSTER",
441 "NEVER",
442 "NEW",
443 "NEXT",
444 "NO",
445 "NODEGROUP",
446 "NONBLOCKING",
447 "NONE",
448 "NOT",
449 "NO_WAIT",
450 "NO_WRITE_TO_BINLOG",
451 "NULL",
452 "NUMBER",
453 "NUMERIC",
454 "NVARCHAR",
455 "OFFSET",
456 "OLD_PASSWORD",
457 "ON",
458 "ONE",
459 "ONE_SHOT",
460 "ONLY",
461 "OPEN",
462 "OPTIMIZE",
463 "OPTIMIZER_COSTS",
464 "OPTION",
465 "OPTIONALLY",
466 "OPTIONS",
467 "OR",
468 "ORDER",
469 "OUT",
470 "OUTER",
471 "OUTFILE",
472 "OWNER",
473 "PACK_KEYS",
474 "PAGE",
475 "PARSER",
476 "PARSE_GCOL_EXPR",
477 "PARTIAL",
478 "PARTITION",
479 "PARTITIONING",
480 "PARTITIONS",
481 "PASSWORD",
482 "PHASE",
483 "PLUGIN",
484 "PLUGINS",
485 "PLUGIN_DIR",
486 "POINT",
487 "POLYGON",
488 "PORT",
489 "PRECEDES",
490 "PRECISION",
491 "PREPARE",
492 "PRESERVE",
493 "PREV",
494 "PRIMARY",
495 "PRIVILEGES",
496 "PROCEDURE",
497 "PROCESSLIST",
498 "PROFILE",
499 "PROFILES",
500 "PROXY",
501 "PURGE",
502 "QUARTER",
503 "QUERY",
504 "QUICK",
505 "RANGE",
506 "READ",
507 "READS",
508 "READ_ONLY",
509 "READ_WRITE",
510 "REAL",
511 "REBUILD",
512 "RECOVER",
513 "REDOFILE",
514 "REDO_BUFFER_SIZE",
515 "REDUNDANT",
516 "REFERENCES",
517 "REGEXP",
518 "RELAY",
519 "RELAYLOG",
520 "RELAY_LOG_FILE",
521 "RELAY_LOG_POS",
522 "RELAY_THREAD",
523 "RELEASE",
524 "RELOAD",
525 "REMOVE",
526 "RENAME",
527 "REORGANIZE",
528 "REPAIR",
529 "REPEAT",
530 "REPEATABLE",
531 "REPLACE",
532 "REPLICATE_DO_DB",
533 "REPLICATE_DO_TABLE",
534 "REPLICATE_IGNORE_DB",
535 "REPLICATE_IGNORE_TABLE",
536 "REPLICATE_REWRITE_DB",
537 "REPLICATE_WILD_DO_TABLE",
538 "REPLICATE_WILD_IGNORE_TABLE",
539 "REPLICATION",
540 "REQUIRE",
541 "RESET",
542 "RESIGNAL",
543 "RESTORE",
544 "RESTRICT",
545 "RESUME",
546 "RETURN",
547 "RETURNED_SQLSTATE",
548 "RETURNS",
549 "REVERSE",
550 "REVOKE",
551 "RIGHT",
552 "RLIKE",
553 "ROLLBACK",
554 "ROLLUP",
555 "ROTATE",
556 "ROUTINE",
557 "ROW",
558 "ROWS",
559 "ROW_COUNT",
560 "ROW_FORMAT",
561 "RTREE",
562 "SAVEPOINT",
563 "SCHEDULE",
564 "SCHEMA",
565 "SCHEMAS",
566 "SCHEMA_NAME",
567 "SECOND",
568 "SECOND_MICROSECOND",
569 "SECURITY",
570 "SELECT",
571 "SENSITIVE",
572 "SEPARATOR",
573 "SERIAL",
574 "SERIALIZABLE",
575 "SERVER",
576 "SESSION",
577 "SET",
578 "SHARE",
579 "SHOW",
580 "SHUTDOWN",
581 "SIGNAL",
582 "SIGNED",
583 "SIMPLE",
584 "SLAVE",
585 "SLOW",
586 "SMALLINT",
587 "SNAPSHOT",
588 "SOCKET",
589 "SOME",
590 "SONAME",
591 "SOUNDS",
592 "SOURCE",
593 "SPATIAL",
594 "SPECIFIC",
595 "SQL",
596 "SQLEXCEPTION",
597 "SQLSTATE",
598 "SQLWARNING",
599 "SQL_AFTER_GTIDS",
600 "SQL_AFTER_MTS_GAPS",
601 "SQL_BEFORE_GTIDS",
602 "SQL_BIG_RESULT",
603 "SQL_BUFFER_RESULT",
604 "SQL_CACHE",
605 "SQL_CALC_FOUND_ROWS",
606 "SQL_NO_CACHE",
607 "SQL_SMALL_RESULT",
608 "SQL_THREAD",
609 "SQL_TSI_DAY",
610 "SQL_TSI_HOUR",
611 "SQL_TSI_MINUTE",
612 "SQL_TSI_MONTH",
613 "SQL_TSI_QUARTER",
614 "SQL_TSI_SECOND",
615 "SQL_TSI_WEEK",
616 "SQL_TSI_YEAR",
617 "SSL",
618 "STACKED",
619 "START",
620 "STARTING",
621 "STARTS",
622 "STATS_AUTO_RECALC",
623 "STATS_PERSISTENT",
624 "STATS_SAMPLE_PAGES",
625 "STATUS",
626 "STOP",
627 "STORAGE",
628 "STORED",
629 "STRAIGHT_JOIN",
630 "STRING",
631 "SUBCLASS_ORIGIN",
632 "SUBJECT",
633 "SUBPARTITION",
634 "SUBPARTITIONS",
635 "SUPER",
636 "SUSPEND",
637 "SWAPS",
638 "SWITCHES",
639 "TABLE",
640 "TABLES",
641 "TABLESPACE",
642 "TABLE_CHECKSUM",
643 "TABLE_NAME",
644 "TEMPORARY",
645 "TEMPTABLE",
646 "TERMINATED",
647 "TEXT",
648 "THAN",
649 "THEN",
650 "TIME",
651 "TIMESTAMP",
652 "TIMESTAMPADD",
653 "TIMESTAMPDIFF",
654 "TINYBLOB",
655 "TINYINT",
656 "TINYTEXT",
657 "TO",
658 "TRAILING",
659 "TRANSACTION",
660 "TRIGGER",
661 "TRIGGERS",
662 "TRUE",
663 "TRUNCATE",
664 "TYPE",
665 "TYPES",
666 "UNCOMMITTED",
667 "UNDEFINED",
668 "UNDO",
669 "UNDOFILE",
670 "UNDO_BUFFER_SIZE",
671 "UNICODE",
672 "UNINSTALL",
673 "UNION",
674 "UNIQUE",
675 "UNKNOWN",
676 "UNLOCK",
677 "UNSIGNED",
678 "UNTIL",
679 "UPDATE",
680 "UPGRADE",
681 "USAGE",
682 "USE",
683 "USER",
684 "USER_RESOURCES",
685 "USE_FRM",
686 "USING",
687 "UTC_DATE",
688 "UTC_TIME",
689 "UTC_TIMESTAMP",
690 "VALIDATION",
691 "VALUE",
692 "VALUES",
693 "VARBINARY",
694 "VARCHAR",
695 "VARCHARACTER",
696 "VARIABLES",
697 "VARYING",
698 "VIEW",
699 "VIRTUAL",
700 "WAIT",
701 "WARNINGS",
702 "WEEK",
703 "WEIGHT_STRING",
704 "WHEN",
705 "WHERE",
706 "WHILE",
707 "WITH",
708 "WITHOUT",
709 "WORK",
710 "WRAPPER",
711 "WRITE",
712 "X509",
713 "XA",
714 "XID",
715 "XML",
716 "XOR",
717 "YEAR",
718 "YEAR_MONTH",
719 "ZEROFILL",
720 ];
724 protected array $reserved_postgres = [
725 "ALL",
726 "ANALYSE",
727 "ANALYZE",
728 "AND",
729 "ANY",
730 "ARRAY",
731 "AS",
732 "ASC",
733 "ASYMMETRIC",
734 "AUTHORIZATION",
735 "BETWEEN",
736 "BINARY",
737 "BOTH",
738 "CASE",
739 "CAST",
740 "CHECK",
741 "COLLATE",
742 "COLUMN",
743 "CONSTRAINT",
744 "CREATE",
745 "CROSS",
746 "CURRENT_DATE",
747 "CURRENT_ROLE",
748 "CURRENT_TIME",
749 "CURRENT_TIMESTAMP",
750 "CURRENT_USER",
751 "DEFAULT",
752 "DEFERRABLE",
753 "DESC",
754 "DISTINCT",
755 "DO",
756 "ELSE",
757 "END",
758 "EXCEPT",
759 "FALSE",
760 "FOR",
761 "FOREIGN",
762 "FREEZE",
763 "FROM",
764 "FULL",
765 "GRANT",
766 "GROUP",
767 "HAVING",
768 "ILIKE",
769 "IN",
770 "INITIALLY",
771 "INNER",
772 "INTERSECT",
773 "INTO",
774 "IS",
775 "ISNULL",
776 "JOIN",
777 "LEADING",
778 "LEFT",
779 "LIKE",
780 "LIMIT",
781 "LOCALTIME",
782 "LOCALTIMESTAMP",
783 "NATURAL",
784 "NEW",
785 "NOT",
786 "NOTNULL",
787 "NULL",
788 "OFF",
789 "OFFSET",
790 "OLD",
791 "ON",
792 "ONLY",
793 "OR",
794 "ORDER",
795 "OUTER",
796 "OVERLAPS",
797 "PLACING",
798 "PRIMARY",
799 "REFERENCES",
800 "RETURNING",
801 "RIGHT",
802 "SELECT",
803 "SESSION_USER",
804 "SIMILAR",
805 "SOME",
806 "SYMMETRIC",
807 "TABLE",
808 "THEN",
809 "TO",
810 "TRAILING",
811 "TRUE",
812 "UNION",
813 "UNIQUE",
814 "USER",
815 "USING",
816 "VERBOSE",
817 "WHEN",
818 "WHERE",
819 "WITH",
820 ];
825
829 public function __construct(protected \ilDBInterface $db_instance)
830 {
831 }
832
833 protected function getQueryUtils(): \ilMySQLQueryUtils
834 {
835 if ($this->query_utils === null) {
836 $this->query_utils = new ilMySQLQueryUtils($this->db_instance);
837 }
838
839 return $this->query_utils;
840 }
841
842 protected array $valid_default_values = [
843 'text' => '',
844 'boolean' => true,
845 'integer' => 0,
846 'decimal' => 0.0,
847 'float' => 0.0,
848 'timestamp' => '1970-01-01 00:00:00',
849 'time' => '00:00:00',
850 'date' => '1970-01-01',
851 'clob' => '',
852 'blob' => '',
853 ];
854
858 public function checkTableName(string $table_name): bool
859 {
860 if (!preg_match(self::DEFINITION_TABLE_NAME, $table_name)) {
861 throw new ilDatabaseException('Table name must only contain _a-z0-9 and must start with a-z.');
862 }
863
864 if ($this->isReserved($table_name)) {
865 throw new ilDatabaseException("Invalid table name '" . $table_name . "' (Reserved Word).");
866 }
867
868 if (stripos($table_name, "sys_") === 0) {
869 throw new ilDatabaseException("Invalid table name '" . $table_name . "'. Name must not start with 'sys_'.");
870 }
871
872 if (strlen($table_name) > self::MAX_TABLE_IDENTIFIER_LENGTH) {
873 throw new ilDatabaseException("Invalid table name '" . $table_name
874 . "'. Maximum table identifer length is " . self::MAX_TABLE_IDENTIFIER_LENGTH . " bytes.");
875 }
876
877 return true;
878 }
879
880 public function isReserved(string $table_name): bool
881 {
882 return false;
883 }
884
888 public function getAllReserved(): array
889 {
890 return $this->getReservedMysql();
891 }
892
896 public function getReservedMysql(): array
897 {
899 }
900
904 public function setReservedMysql(array $reserved_mysql): void
905 {
906 $this->reserved_mysql = $reserved_mysql;
907 }
908
909
913 public function checkColumnName(string $column_name): bool
914 {
915 if (!preg_match("/^[a-z]+[_a-z0-9]*$/", $column_name)) {
916 throw new ilDatabaseException("Invalid column name '" . $column_name
917 . "'. Column name must only contain _a-z0-9 and must start with a-z.");
918 }
919
920 if ($this->isReserved($column_name)) {
921 throw new ilDatabaseException("Invalid column name '" . $column_name . "' (Reserved Word).");
922 }
923
924 if (stripos($column_name, "sys_") === 0) {
925 throw new ilDatabaseException("Invalid column name '" . $column_name . "'. Name must not start with 'sys_'.");
926 }
927
928 if (strlen($column_name) > 30) {
929 throw new ilDatabaseException("Invalid column name '" . $column_name . "'. Maximum column identifer length is 30 bytes.");
930 }
931
932 return true;
933 }
934
938 public function checkIndexName(string $a_name): bool
939 {
940 if (!preg_match("/^[a-z]+[_a-z0-9]*$/", $a_name)) {
941 throw new ilDatabaseException("Invalid column name '" . $a_name . "'. Column name must only contain _a-z0-9 and must start with a-z.");
942 }
943
944 if ($this->isReserved($a_name)) {
945 throw new ilDatabaseException("Invalid column name '" . $a_name . "' (Reserved Word).");
946 }
947
948 if (strlen($a_name) > 3) {
949 throw new ilDatabaseException("Invalid index name '" . $a_name . "'. Maximum index identifer length is 3 bytes.");
950 }
951
952 return true;
953 }
954
958 public function checkColumnDefinition(array $a_def): bool
959 {
960 // check valid type
961 if (!in_array($a_def["type"], $this->getAvailableTypes(), true)) {
962 switch ($a_def["type"]) {
963 case "boolean":
964 throw new ilDatabaseException("Invalid column type '" . $a_def["type"] . "'. Use integer(1) instead.");
965
966 case "decimal":
967 throw new ilDatabaseException("Invalid column type '" . $a_def["type"] . "'. Use float or integer instead.");
968
969 default:
970 throw new ilDatabaseException("Invalid column type '" . $a_def["type"] . "'. Allowed types are: "
971 . implode(', ', $this->getAvailableTypes()));
972 }
973 }
974
975 // check used attributes
976 $allowed_attributes = $this->getAllowedAttributes();
977 foreach (array_keys($a_def) as $k) {
978 if ($k !== "type" && !in_array($k, $allowed_attributes[$a_def["type"]], true)) {
979 throw new ilDatabaseException("Attribute '" . $k . "' is not allowed for column type '" . $a_def["type"] . "'.");
980 }
981 }
982
983 // type specific checks
984 $max_length = $this->getMaxLength();
985 switch ($a_def["type"]) {
986 case self::T_TEXT:
987 if ((!isset($a_def["length"]) || $a_def["length"] < 1 || $a_def["length"] > $max_length[self::T_TEXT]) && isset($a_def["length"])) {
988 throw new ilDatabaseException("Invalid length '" . $a_def["length"] . "' for type text." . " Length must be >=1 and <= "
989 . $max_length[self::T_TEXT] . ".");
990 }
991 break;
992
993 case self::T_INTEGER:
994 if (isset($a_def["length"]) && !in_array((int) $a_def["length"], $max_length[self::T_INTEGER], true)) {
995 throw new ilDatabaseException("Invalid length '" . $a_def["length"] . "' for type integer." . " Length must be "
996 . implode(', ', $max_length[self::T_INTEGER]) . " (bytes).");
997 }
998 if ($a_def["unsigned"] ?? null) {
999 throw new ilDatabaseException("Unsigned attribut must not be true for type integer.");
1000 }
1001 break;
1002 }
1003
1004 return true;
1005 }
1006
1007 public function isAllowedAttribute(string $attribute, string $type): bool
1008 {
1009 return in_array($attribute, $this->allowed_attributes[$type], true);
1010 }
1011
1015 public function getAvailableTypes(): array
1016 {
1018 }
1019
1023 public function setAvailableTypes(array $available_types): void
1024 {
1025 $this->available_types = $available_types;
1026 }
1027
1031 public function getAllowedAttributes(): array
1032 {
1034 }
1035
1039 public function setAllowedAttributes(array $allowed_attributes): void
1040 {
1041 $this->allowed_attributes = $allowed_attributes;
1042 }
1043
1044 public function getMaxLength(): array
1045 {
1046 return $this->max_length;
1047 }
1048
1049 public function setMaxLength(array $max_length): void
1050 {
1051 $this->max_length = $max_length;
1052 }
1053
1054 protected function getDBInstance(): \ilDBInterface
1055 {
1056 return $this->db_instance;
1057 }
1058
1062 public function getValidTypes(): array
1063 {
1065 $db = $this->getDBInstance();
1066
1067 if (!empty($db->options['datatype_map'])) {
1068 foreach ($db->options['datatype_map'] as $type => $mapped_type) {
1069 if (array_key_exists($mapped_type, $types)) {
1070 $types[$type] = $types[$mapped_type];
1071 } elseif (!empty($db->options['datatype_map_callback'][$type])) {
1072 $parameter = ['type' => $type, 'mapped_type' => $mapped_type];
1073 $default = call_user_func_array(
1074 $db->options['datatype_map_callback'][$type],
1075 [&$db, __FUNCTION__, $parameter]
1076 );
1077 $types[$type] = $default;
1078 }
1079 }
1080 }
1081
1082 return $types;
1083 }
1084
1085
1086
1091 public function getDeclaration(string $type, string $name, array $field)
1092 {
1093 $db = $this->getDBInstance();
1094
1095 if (!empty($db->options['datatype_map'][$type])) {
1096 $type = $db->options['datatype_map'][$type];
1097 if (!empty($db->options['datatype_map_callback'][$type])) {
1098 $parameter = ['type' => $type, 'name' => $name, 'field' => $field];
1099
1100 return call_user_func_array(
1101 $db->options['datatype_map_callback'][$type],
1102 [&$db, __FUNCTION__, $parameter]
1103 );
1104 }
1105 $field['type'] = $type;
1106 }
1107
1108 if (!method_exists($this, "get{$type}Declaration")) {
1109 throw new ilDatabaseException('type not defined: ' . $type);
1110 }
1111
1112 return $this->{"get{$type}Declaration"}($name, $field);
1113 }
1114
1115 public function getTypeDeclaration(array $field): string
1116 {
1117 $db = $this->getDBInstance();
1118
1119 switch ($field['type']) {
1120 case 'text':
1121 $length = empty($field['length']) ? $db->options['default_text_field_length'] : $field['length'];
1122 $fixed = empty($field['fixed']) ? false : $field['fixed'];
1123 if ($fixed) {
1124 return $length ? 'CHAR(' . $length . ')' : 'CHAR(' . $db->options['default_text_field_length'] . ')';
1125 }
1126
1127 return $length ? 'VARCHAR(' . $length . ')' : 'TEXT';
1128 case 'clob':
1129 case 'decimal':
1130 case 'float':
1131 case 'blob':
1132 return 'TEXT';
1133 case 'integer':
1134 case 'boolean':
1135 return 'INT';
1136 case 'date':
1137 return 'CHAR (' . strlen('YYYY-MM-DD') . ')';
1138 case 'time':
1139 return 'CHAR (' . strlen('HH:MM:SS') . ')';
1140 case 'timestamp':
1141 return 'CHAR (' . strlen('YYYY-MM-DD HH:MM:SS') . ')';
1142 }
1143
1144 return '';
1145 }
1146
1147 protected function getInternalDeclaration(string $name, array $field): string
1148 {
1149 $db = $this->getDBInstance();
1150
1151 $name = $db->quoteIdentifier($name, true);
1152 $declaration_options = '';
1153 $fd = $db->getFieldDefinition();
1154 if ($fd !== null) {
1155 $declaration_options = $fd->getDeclarationOptions($field);
1156 }
1157
1158 return $name . ' ' . $this->getTypeDeclaration($field) . $declaration_options;
1159 }
1160
1164 protected function getDeclarationOptions(array $field): string
1165 {
1166 $charset = empty($field['charset']) ? '' : ' ' . $this->getCharsetFieldDeclaration($field['charset']);
1167
1168 $default = '';
1169 if (array_key_exists('default', $field)) {
1170 if ($field['default'] === '') {
1171 $db = $this->getDBInstance();
1172
1173 if (empty($field['notnull'])) {
1174 $field['default'] = null;
1175 } else {
1177 $field['default'] = $valid_default_values[$field['type']];
1178 }
1179 if ($field['default'] === ''
1180 && isset($db->options["portability"])
1181 && ($db->options['portability'] & 32)
1182 ) {
1183 $field['default'] = ' ';
1184 }
1185 }
1186 $default = ' DEFAULT ' . $this->quote($field['default'], $field['type']);
1187 } elseif (empty($field['notnull'])) {
1188 $default = ' DEFAULT NULL';
1189 }
1190
1191 $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
1192 // alex patch 28 Nov 2011 start
1193 if (isset($field["notnull"]) && $field['notnull'] === false) {
1194 $notnull = " NULL";
1195 }
1196 // alex patch 28 Nov 2011 end
1197
1198 $collation = empty($field['collation']) ? '' : ' ' . $this->getCollationFieldDeclaration($field['collation']);
1199
1200 return $charset . $default . $notnull . $collation;
1201 }
1202
1203 protected function getCharsetFieldDeclaration(string $charset): string
1204 {
1205 return '';
1206 }
1207
1208 protected function getCollationFieldDeclaration(string $collation): string
1209 {
1210 return '';
1211 }
1212
1216 protected function getIntegerDeclaration(string $name, array $field): string
1217 {
1218 return $this->getInternalDeclaration($name, $field);
1219 }
1220
1224 protected function getTextDeclaration(string $name, array $field): string
1225 {
1226 return $this->getInternalDeclaration($name, $field);
1227 }
1228
1229 protected function getCLOBDeclaration(string $name, array $field): string
1230 {
1231 $db = $this->getDBInstance();
1232
1233 $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
1234 $name = $db->quoteIdentifier($name, true);
1235
1236 return $name . ' ' . $this->getTypeDeclaration($field) . $notnull;
1237 }
1238
1239 protected function getBLOBDeclaration(string $name, array $field): string
1240 {
1241 $db = $this->getDBInstance();
1242
1243 $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
1244 $name = $db->quoteIdentifier($name, true);
1245
1246 return $name . ' ' . $this->getTypeDeclaration($field) . $notnull;
1247 }
1248
1249 protected function getBooleanDeclaration(string $name, array $field): string
1250 {
1251 return $this->getInternalDeclaration($name, $field);
1252 }
1253
1254 protected function getDateDeclaration(string $name, array $field): string
1255 {
1256 return $this->getInternalDeclaration($name, $field);
1257 }
1258
1259 protected function getTimestampDeclaration(string $name, array $field): string
1260 {
1261 return $this->getInternalDeclaration($name, $field);
1262 }
1263
1264 protected function getTimeDeclaration(string $name, array $field): string
1265 {
1266 return $this->getInternalDeclaration($name, $field);
1267 }
1268
1269 protected function getFloatDeclaration(string $name, array $field): string
1270 {
1271 return $this->getInternalDeclaration($name, $field);
1272 }
1273
1274 protected function getDecimalDeclaration(string $name, array $field): string
1275 {
1276 return $this->getInternalDeclaration($name, $field);
1277 }
1278
1284 public function compareDefinition(array $current, array $previous): array
1285 {
1286 $type = empty($current['type']) ? null : $current['type'];
1287
1288 if (!method_exists($this, "compare{$type}Definition")) {
1289 $db = $this->getDBInstance();
1290
1291 if (!empty($db->options['datatype_map_callback'][$type])) {
1292 $parameter = ['current' => $current, 'previous' => $previous];
1293
1294 return call_user_func_array(
1295 $db->options['datatype_map_callback'][$type],
1296 [&$db, __FUNCTION__, $parameter]
1297 );
1298 }
1299
1300 throw new ilDatabaseException('type "' . $current['type'] . '" is not yet supported');
1301 }
1302
1303 if (empty($previous['type']) || $previous['type'] != $type) {
1304 return $current;
1305 }
1306
1307 $change = $this->{"compare{$type}Definition"}($current, $previous);
1308
1309 if ($previous['type'] != $type) {
1310 $change['type'] = true;
1311 }
1312
1313 $previous_notnull = empty($previous['notnull']) ? false : $previous['notnull'];
1314 $notnull = empty($current['notnull']) ? false : $current['notnull'];
1315 if ($previous_notnull !== $notnull) {
1316 $change['notnull'] = true;
1317 }
1318
1319 $alt = $previous_notnull ? '' : null;
1320 $previous_default = array_key_exists(
1321 'default',
1322 $previous
1323 ) ? $previous['default'] : $alt;
1324 $alt = $notnull ? '' : null;
1325 $default = array_key_exists('default', $current) ? $current['default'] : $alt;
1326 if ($previous_default !== $default) {
1327 $change['default'] = true;
1328 }
1329
1330 return $change;
1331 }
1332
1336 protected function compareIntegerDefinition(array $current, array $previous): array
1337 {
1338 $change = [];
1339 $previous_unsigned = empty($previous['unsigned']) ? false : $previous['unsigned'];
1340 $unsigned = empty($current['unsigned']) ? false : $current['unsigned'];
1341 if ($previous_unsigned != $unsigned) {
1342 $change['unsigned'] = true;
1343 }
1344 $previous_autoincrement = empty($previous['autoincrement']) ? false : $previous['autoincrement'];
1345 $autoincrement = empty($current['autoincrement']) ? false : $current['autoincrement'];
1346 if ($previous_autoincrement != $autoincrement) {
1347 $change['autoincrement'] = true;
1348 }
1349
1350 return $change;
1351 }
1352
1356 protected function compareTextDefinition(array $current, array $previous): array
1357 {
1358 $change = [];
1359 $previous_length = empty($previous['length']) ? 0 : $previous['length'];
1360 $length = empty($current['length']) ? 0 : $current['length'];
1361 if ($previous_length != $length) {
1362 $change['length'] = true;
1363 }
1364 $previous_fixed = empty($previous['fixed']) ? 0 : $previous['fixed'];
1365 $fixed = empty($current['fixed']) ? 0 : $current['fixed'];
1366 if ($previous_fixed != $fixed) {
1367 $change['fixed'] = true;
1368 }
1369
1370 return $change;
1371 }
1372
1376 protected function compareCLOBDefinition(array $current, array $previous): array
1377 {
1378 return $this->compareTextDefinition($current, $previous);
1379 }
1380
1384 protected function compareBLOBDefinition(array $current, array $previous): array
1385 {
1386 return $this->compareTextDefinition($current, $previous);
1387 }
1388
1389 protected function compareDateDefinition(array $current, array $previous): array
1390 {
1391 return [];
1392 }
1393
1394 protected function compareTimeDefinition(array $current, array $previous): array
1395 {
1396 return [];
1397 }
1398
1399 protected function compareTimestampDefinition(array $current, array $previous): array
1400 {
1401 return [];
1402 }
1403
1404 protected function compareBooleanDefinition(array $current, array $previous): array
1405 {
1406 return [];
1407 }
1408
1409 protected function compareFloatDefinition(array $current, array $previous): array
1410 {
1411 return [];
1412 }
1413
1414 protected function compareDecimalDefinition(array $current, array $previous): array
1415 {
1416 return [];
1417 }
1418
1422 public function quote($value, ?string $type = null, bool $quote = true, bool $escape_wildcards = false): string
1423 {
1424 return $this->getDBInstance()->quote($value, $type ?? '');
1425 }
1426
1430 protected function quoteInteger($value, bool $quote, bool $escape_wildcards): int
1431 {
1432 return (int) $value;
1433 }
1434
1435 protected function quoteText(string $value, bool $quote, bool $escape_wildcards): string
1436 {
1437 if (!$quote) {
1438 return $value;
1439 }
1440
1441 $db = $this->getDBInstance();
1442
1443 $value = $db->escape($value, $escape_wildcards);
1444
1445 return "'" . $value . "'";
1446 }
1447
1451 protected function readFile($value): string
1452 {
1453 $close = false;
1454 if (is_string($value) && preg_match('/^(\w+:\/\/)(.*)$/', $value, $match)) {
1455 $close = true;
1456 if ($match[1] === 'file://') {
1457 $value = $match[2];
1458 }
1459 // do not try to open urls
1460 #$value = @fopen($value, 'r');
1461 }
1462
1463 if (is_resource($value)) {
1464 $db = $this->getDBInstance();
1465
1466 $fp = $value;
1467 $value = '';
1468 while (!@feof($fp)) {
1469 $value .= @fread($fp, $db->options['lob_buffer_length']);
1470 }
1471 if ($close) {
1472 @fclose($fp);
1473 }
1474 }
1475
1476 return $value;
1477 }
1478
1482 protected function quoteLOB($value, bool $quote, bool $escape_wildcards): string
1483 {
1484 $value = $this->readFile($value);
1485
1486 return $this->quoteText($value, $quote, $escape_wildcards);
1487 }
1491 protected function quoteCLOB($value, bool $quote, bool $escape_wildcards): string
1492 {
1493 return $this->quoteLOB($value, $quote, $escape_wildcards);
1494 }
1498 protected function quoteBLOB($value, bool $quote, bool $escape_wildcards): string
1499 {
1500 return $this->quoteLOB($value, $quote, $escape_wildcards);
1501 }
1502
1503 protected function quoteBoolean(bool $value, bool $quote, bool $escape_wildcards): int
1504 {
1505 return ($value ? 1 : 0);
1506 }
1507
1508 protected function quoteDate(string $value, bool $quote, bool $escape_wildcards): string
1509 {
1510 if ($value === 'CURRENT_DATE') {
1511 return 'CURRENT_DATE';
1512 }
1513
1514 return $this->quoteText($value, $quote, $escape_wildcards);
1515 }
1516
1520 protected function quoteTimestamp(int $value, bool $quote, bool $escape_wildcards): string
1521 {
1522 throw new ilDatabaseException("deprecated");
1523 }
1524
1528 protected function quoteTime(int $value, bool $quote, bool $escape_wildcards): string
1529 {
1530 throw new ilDatabaseException("deprecated");
1531 }
1532
1533 protected function quoteFloat(string $value, bool $quote, bool $escape_wildcards): ?string
1534 {
1535 if (preg_match('/^(.*)e([-+])(\d+)$/i', $value, $matches)) {
1536 $decimal = $this->quoteDecimal($matches[1], $quote, $escape_wildcards);
1537 $sign = $matches[2];
1538 $exponent = str_pad($matches[3], 2, '0', STR_PAD_LEFT);
1539 return $decimal . 'E' . $sign . $exponent;
1540 }
1541
1542 return $this->quoteDecimal($value, $quote, $escape_wildcards);
1543 }
1544
1545 protected function quoteDecimal(string $value, bool $quote, bool $escape_wildcards): ?string
1546 {
1547 $value = preg_replace('/[^\d\.,\-+eE]/', '', $value);
1548 if (preg_match('/[^.0-9]/', (string) $value) && strpos((string) $value, ',')) {
1549 // 1000,00
1550 if (!strpos((string) $value, '.')) {
1551 // convert the last "," to a "."
1552 $value = strrev(str_replace(',', '.', strrev((string) $value)));
1553 // 1.000,00
1554 } elseif (strpos((string) $value, '.') && strpos((string) $value, '.') < strpos((string) $value, ',')) {
1555 $value = str_replace('.', '', $value);
1556 // convert the last "," to a "."
1557 $value = strrev(str_replace(',', '.', strrev($value)));
1558 // 1,000.00
1559 } else {
1560 $value = str_replace(',', '', $value);
1561 }
1562 }
1563
1564 return $value;
1565 }
1566
1572 public function writeLOBToFile($lob, string $file): bool
1573 {
1574 $db = $this->getDBInstance();
1575
1576 if (preg_match('/^(\w+:\/\/)(.*)$/', $file, $match) && $match[1] === 'file://') {
1577 $file = $match[2];
1578 }
1579
1580 $fp = @fopen($file, 'wb');
1581 while (!@feof($lob)) {
1582 $result = @fread($lob, $db->options['lob_buffer_length']);
1583 $read = strlen($result);
1584 if (@fwrite($fp, $result, $read) !== $read) {
1585 @fclose($fp);
1586
1587 throw new ilDatabaseException('could not write to the output file');
1588 }
1589 }
1590 @fclose($fp);
1591
1592 return true;
1593 }
1594
1595 protected function retrieveLOB(array &$lob): bool
1596 {
1597 if (is_null($lob['value'])) {
1598 $lob['value'] = $lob['resource'];
1599 }
1600 $lob['loaded'] = true;
1601
1602 return true;
1603 }
1604
1605 protected function readLOB(array $lob, int $length): string
1606 {
1607 return substr((string) $lob['value'], $lob['position'], $length);
1608 }
1609
1613 protected function endOfLOB(array $lob)
1614 {
1615 return $lob['endOfLOB'];
1616 }
1617
1621 public function destroyLOB($lob): bool
1622 {
1623 $lob_data = stream_get_meta_data($lob);
1624 $lob_index = $lob_data['wrapper_data']->lob_index;
1625 fclose($lob);
1626 if (isset($this->lobs[$lob_index])) {
1627 unset($this->lobs[$lob_index]);
1628 }
1629
1630 return true;
1631 }
1632
1633
1637 public function matchPattern(array $pattern, $operator = null, $field = null): string
1638 {
1639 $db = $this->getDBInstance();
1640
1641 $match = '';
1642 if (!is_null($operator)) {
1643 $operator = strtoupper((string) $operator);
1644 switch ($operator) {
1645 // case insensitive
1646 case 'ILIKE':
1647 if (is_null($field)) {
1648 throw new ilDatabaseException('case insensitive LIKE matching requires passing the field name');
1649 }
1650 $db->loadModule('Function');
1651 $match = $db->lower($field) . ' LIKE ';
1652 break;
1653 // case sensitive
1654 case 'LIKE':
1655 $match = is_null($field) ? 'LIKE ' : $field . ' LIKE ';
1656 break;
1657 default:
1658 throw new ilDatabaseException('not a supported operator type:' . $operator);
1659 }
1660 }
1661 $match .= "'";
1662 foreach ($pattern as $key => $value) {
1663 if ($key % 2 !== 0) {
1664 $match .= $value;
1665 } else {
1666 if ($operator === 'ILIKE') {
1667 $value = strtolower((string) $value);
1668 }
1669 $escaped = $db->escape($value);
1670 $match .= $db->escapePattern($escaped);
1671 }
1672 }
1673 $match .= "'";
1674 $match .= $this->patternEscapeString();
1675
1676 return $match;
1677 }
1678
1679 public function patternEscapeString(): string
1680 {
1681 return '';
1682 }
1683
1687 public function mapNativeDatatype(array $field)
1688 {
1689 $db = $this->getDBInstance();
1690 $db_type = strtok($field['type'], '(), ');
1691 if (!empty($db->options['nativetype_map_callback'][$db_type])) {
1692 return call_user_func_array($db->options['nativetype_map_callback'][$db_type], [$db, $field]);
1693 }
1694
1695 return $this->mapNativeDatatypeInternal($field);
1696 }
1697
1701 abstract protected function mapNativeDatatypeInternal(array $field): array;
1702
1706 public function mapPrepareDatatype(string $type)
1707 {
1708 $db = $this->getDBInstance();
1709
1710 if (!empty($db->options['datatype_map'][$type])) {
1711 $type = $db->options['datatype_map'][$type];
1712 if (!empty($db->options['datatype_map_callback'][$type])) {
1713 $parameter = ['type' => $type];
1714
1715 return call_user_func_array(
1716 $db->options['datatype_map_callback'][$type],
1717 [&$db, __FUNCTION__, $parameter]
1718 );
1719 }
1720 }
1721
1722 return $type;
1723 }
1724}
Class ilDBPdoFieldDefinition.
isAllowedAttribute(string $attribute, string $type)
getDateDeclaration(string $name, array $field)
quoteInteger($value, bool $quote, bool $escape_wildcards)
mapNativeDatatypeInternal(array $field)
compareIntegerDefinition(array $current, array $previous)
compareTextDefinition(array $current, array $previous)
compareBooleanDefinition(array $current, array $previous)
getIntegerDeclaration(string $name, array $field)
getCollationFieldDeclaration(string $collation)
quoteBLOB($value, bool $quote, bool $escape_wildcards)
quoteCLOB($value, bool $quote, bool $escape_wildcards)
static ilDBPdoFieldDefinition $instance
getCLOBDeclaration(string $name, array $field)
quoteLOB($value, bool $quote, bool $escape_wildcards)
compareCLOBDefinition(array $current, array $previous)
quoteText(string $value, bool $quote, bool $escape_wildcards)
getDeclaration(string $type, string $name, array $field)
quoteDecimal(string $value, bool $quote, bool $escape_wildcards)
getBooleanDeclaration(string $name, array $field)
setAvailableTypes(array $available_types)
getInternalDeclaration(string $name, array $field)
quoteTime(int $value, bool $quote, bool $escape_wildcards)
quoteBoolean(bool $value, bool $quote, bool $escape_wildcards)
compareDefinition(array $current, array $previous)
quoteDate(string $value, bool $quote, bool $escape_wildcards)
setAllowedAttributes(array $allowed_attributes)
getBLOBDeclaration(string $name, array $field)
compareTimeDefinition(array $current, array $previous)
compareDateDefinition(array $current, array $previous)
getTextDeclaration(string $name, array $field)
getDecimalDeclaration(string $name, array $field)
quote($value, ?string $type=null, bool $quote=true, bool $escape_wildcards=false)
__construct(protected \ilDBInterface $db_instance)
ilDBPdoFieldDefinition constructor.
quoteFloat(string $value, bool $quote, bool $escape_wildcards)
compareTimestampDefinition(array $current, array $previous)
getFloatDeclaration(string $name, array $field)
setReservedMysql(array $reserved_mysql)
compareFloatDefinition(array $current, array $previous)
matchPattern(array $pattern, $operator=null, $field=null)
compareBLOBDefinition(array $current, array $previous)
getTimeDeclaration(string $name, array $field)
quoteTimestamp(int $value, bool $quote, bool $escape_wildcards)
compareDecimalDefinition(array $current, array $previous)
getTimestampDeclaration(string $name, array $field)
Class ilDatabaseException.
Class ilMySQLQueryUtils.
Interface ilDBInterface.