ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilDBPdoFieldDefinition.php
Go to the documentation of this file.
1<?php
2
9{
11 const DEFAULT_TEXT_LENGTH = 4000;
12 const DEFINITION_COLUMN_NAME = "/^[a-z]+[_a-z0-9]*$/";
13 const DEFINITION_TABLE_NAME = "/^[a-z]+[_a-z0-9]*$/";
14 const INDEX_FORMAT = '%s_idx';
15 const SEQUENCE_COLUMNS_NAME = 'sequence';
16 const SEQUENCE_FORMAT = '%s_seq';
17 const T_BLOB = 'blob';
18 const T_CLOB = 'clob';
19 const T_DATE = 'date';
20 const T_DATETIME = 'datetime';
21 const T_FLOAT = 'float';
22 const T_INTEGER = 'integer';
23 const T_TEXT = 'text';
24 const T_TIME = 'time';
25 const T_TIMESTAMP = 'timestamp';
29 protected static $instance;
34 self::T_TEXT => array( 'length', 'notnull', 'default', 'fixed' ),
35 self::T_INTEGER => array( 'length', 'notnull', 'default', 'unsigned' ),
36 self::T_FLOAT => array( 'notnull', 'default' ),
37 self::T_DATE => array( 'notnull', 'default' ),
38 self::T_TIME => array( 'notnull', 'default' ),
39 self::T_TIMESTAMP => array( 'notnull', 'default' ),
40 self::T_CLOB => array( 'notnull', 'default' ),
41 self::T_BLOB => array( 'notnull', 'default' ),
42 );
46 public $allowed_attributes = array(
47 "text" => array( "length", "notnull", "default", "fixed" ),
48 "integer" => array( "length", "notnull", "default", "unsigned" ),
49 "float" => array( "notnull", "default" ),
50 "date" => array( "notnull", "default" ),
51 "time" => array( "notnull", "default" ),
52 "timestamp" => array( "notnull", "default" ),
53 "clob" => array( "length", "notnull", "default" ),
54 "blob" => array( "length", "notnull", "default" ),
55 );
59 protected $db_instance;
63 protected $max_length = array(
64 self::T_INTEGER => array( 1, 2, 3, 4, 8 ),
65 self::T_TEXT => 4000,
66 );
70 protected $available_types = array(
71 self::T_TEXT,
72 self::T_INTEGER,
73 self::T_FLOAT,
74 self::T_DATE,
75 self::T_TIME,
76 self::T_TIMESTAMP,
77 self::T_CLOB,
78 self::T_BLOB,
79 );
83 protected $reserved_mysql = array(
84 "ACCESSIBLE",
85 "ACCOUNT",
86 "ACTION",
87 "ADD",
88 "AFTER",
89 "AGAINST",
90 "AGGREGATE",
91 "ALGORITHM",
92 "ALL",
93 "ALTER",
94 "ALWAYS",
95 "ANALYSE",
96 "ANALYZE",
97 "AND",
98 "ANY",
99 "AS",
100 "ASC",
101 "ASCII",
102 "ASENSITIVE",
103 "AT",
104 "AUTHORS",
105 "AUTOEXTEND_SIZE",
106 "AUTO_INCREMENT",
107 "AVG",
108 "AVG_ROW_LENGTH",
109 "BACKUP",
110 "BEFORE",
111 "BEGIN",
112 "BETWEEN",
113 "BIGINT",
114 "BINARY",
115 "BINLOG",
116 "BIT",
117 "BLOB",
118 "BLOCK",
119 "BOOL",
120 "BOOLEAN",
121 "BOTH",
122 "BTREE",
123 "BY",
124 "BYTE",
125 "CACHE",
126 "CALL",
127 "CASCADE",
128 "CASCADED",
129 "CASE",
130 "CATALOG_NAME",
131 "CHAIN",
132 "CHANGE",
133 "CHANGED",
134 "CHANNEL",
135 "CHAR",
136 "CHARACTER",
137 "CHARSET",
138 "CHECK",
139 "CHECKSUM",
140 "CIPHER",
141 "CLASS_ORIGIN",
142 "CLIENT",
143 "CLOSE",
144 "COALESCE",
145 "CODE",
146 "COLLATE",
147 "COLLATION",
148 "COLUMN",
149 "COLUMNS",
150 "COLUMN_FORMAT",
151 "COLUMN_NAME",
152 "COMMENT",
153 "COMMIT",
154 "COMMITTED",
155 "COMPACT",
156 "COMPLETION",
157 "COMPRESSED",
158 "COMPRESSION",
159 "CONCURRENT",
160 "CONDITION",
161 "CONNECTION",
162 "CONSISTENT",
163 "CONSTRAINT",
164 "CONSTRAINT_CATALOG",
165 "CONSTRAINT_NAME",
166 "CONSTRAINT_SCHEMA",
167 "CONTAINS",
168 "CONTEXT",
169 "CONTINUE",
170 "CONTRIBUTORS",
171 "CONVERT",
172 "CPU",
173 "CREATE",
174 "CROSS",
175 "CUBE",
176 "CURRENT",
177 "CURRENT_DATE",
178 "CURRENT_TIME",
179 "CURRENT_TIMESTAMP",
180 "CURRENT_USER",
181 "CURSOR",
182 "CURSOR_NAME",
183 "DATA",
184 "DATABASE",
185 "DATABASES",
186 "DATAFILE",
187 "DATE",
188 "DATETIME",
189 "DAY",
190 "DAY_HOUR",
191 "DAY_MICROSECOND",
192 "DAY_MINUTE",
193 "DAY_SECOND",
194 "DEALLOCATE",
195 "DEC",
196 "DECIMAL",
197 "DECLARE",
198 "DEFAULT",
199 "DEFAULT_AUTH",
200 "DEFINER",
201 "DELAYED",
202 "DELAY_KEY_WRITE",
203 "DELETE",
204 "DESC",
205 "DESCRIBE",
206 "DES_KEY_FILE",
207 "DETERMINISTIC",
208 "DIAGNOSTICS",
209 "DIRECTORY",
210 "DISABLE",
211 "DISCARD",
212 "DISK",
213 "DISTINCT",
214 "DISTINCTROW",
215 "DIV",
216 "DO",
217 "DOUBLE",
218 "DROP",
219 "DUAL",
220 "DUMPFILE",
221 "DUPLICATE",
222 "DYNAMIC",
223 "EACH",
224 "ELSE",
225 "ELSEIF",
226 "ENABLE",
227 "ENCLOSED",
228 "ENCRYPTION",
229 "END",
230 "ENDS",
231 "ENGINE",
232 "ENGINES",
233 "ENUM",
234 "ERROR",
235 "ERRORS",
236 "ESCAPE",
237 "ESCAPED",
238 "EVENT",
239 "EVENTS",
240 "EVERY",
241 "EXCHANGE",
242 "EXECUTE",
243 "EXISTS",
244 "EXIT",
245 "EXPANSION",
246 "EXPIRE",
247 "EXPLAIN",
248 "EXPORT",
249 "EXTENDED",
250 "EXTENT_SIZE",
251 "FALSE",
252 "FAST",
253 "FAULTS",
254 "FETCH",
255 "FIELDS",
256 "FILE",
257 "FILE_BLOCK_SIZE",
258 "FILTER",
259 "FIRST",
260 "FIXED",
261 "FLOAT",
262 "FLOAT4",
263 "FLOAT8",
264 "FLUSH",
265 "FOLLOWS",
266 "FOR",
267 "FORCE",
268 "FOREIGN",
269 "FORMAT",
270 "FOUND",
271 "FROM",
272 "FULL",
273 "FULLTEXT",
274 "FUNCTION",
275 "GENERAL",
276 "GENERATED",
277 "GEOMETRY",
278 "GEOMETRYCOLLECTION",
279 "GET",
280 "GET_FORMAT",
281 "GLOBAL",
282 "GRANT",
283 "GRANTS",
284 "GROUP",
285 "GROUP_REPLICATION",
286 "HANDLER",
287 "HASH",
288 "HAVING",
289 "HELP",
290 "HIGH_PRIORITY",
291 "HOST",
292 "HOSTS",
293 "HOUR",
294 "HOUR_MICROSECOND",
295 "HOUR_MINUTE",
296 "HOUR_SECOND",
297 "IDENTIFIED",
298 "IF",
299 "IGNORE",
300 "IGNORE_SERVER_IDS",
301 "IMPORT",
302 "IN",
303 "INDEX",
304 "INDEXES",
305 "INFILE",
306 "INITIAL_SIZE",
307 "INNER",
308 "INOUT",
309 "INSENSITIVE",
310 "INSERT",
311 "INSERT_METHOD",
312 "INSTALL",
313 "INSTANCE",
314 "INT",
315 "INT1",
316 "INT2",
317 "INT3",
318 "INT4",
319 "INT8",
320 "INTEGER",
321 "INTERVAL",
322 "INTO",
323 "INVOKER",
324 "IO",
325 "IO_AFTER_GTIDS",
326 "IO_BEFORE_GTIDS",
327 "IO_THREAD",
328 "IPC",
329 "IS",
330 "ISOLATION",
331 "ISSUER",
332 "ITERATE",
333 "JOIN",
334 "JSON",
335 "KEY",
336 "KEYS",
337 "KEY_BLOCK_SIZE",
338 "KILL",
339 "LANGUAGE",
340 "LAST",
341 "LEADING",
342 "LEAVE",
343 "LEAVES",
344 "LEFT",
345 "LESS",
346 "LEVEL",
347 "LIKE",
348 "LIMIT",
349 "LINEAR",
350 "LINES",
351 "LINESTRING",
352 "LIST",
353 "LOAD",
354 "LOCAL",
355 "LOCALTIME",
356 "LOCALTIMESTAMP",
357 "LOCK",
358 "LOCKS",
359 "LOGFILE",
360 "LOGS",
361 "LONG",
362 "LONGBLOB",
363 "LONGTEXT",
364 "LOOP",
365 "LOW_PRIORITY",
366 "MASTER",
367 "MASTER_AUTO_POSITION",
368 "MASTER_BIND",
369 "MASTER_CONNECT_RETRY",
370 "MASTER_DELAY",
371 "MASTER_HEARTBEAT_PERIOD",
372 "MASTER_HOST",
373 "MASTER_LOG_FILE",
374 "MASTER_LOG_POS",
375 "MASTER_PASSWORD",
376 "MASTER_PORT",
377 "MASTER_RETRY_COUNT",
378 "MASTER_SERVER_ID",
379 "MASTER_SSL",
380 "MASTER_SSL_CA",
381 "MASTER_SSL_CAPATH",
382 "MASTER_SSL_CERT",
383 "MASTER_SSL_CIPHER",
384 "MASTER_SSL_CRL",
385 "MASTER_SSL_CRLPATH",
386 "MASTER_SSL_KEY",
387 "MASTER_SSL_VERIFY_SERVER_CERT",
388 "MASTER_TLS_VERSION",
389 "MASTER_USER",
390 "MATCH",
391 "MAXVALUE",
392 "MAX_CONNECTIONS_PER_HOUR",
393 "MAX_QUERIES_PER_HOUR",
394 "MAX_ROWS",
395 "MAX_SIZE",
396 "MAX_STATEMENT_TIME",
397 "MAX_UPDATES_PER_HOUR",
398 "MAX_USER_CONNECTIONS",
399 "MEDIUM",
400 "MEDIUMBLOB",
401 "MEDIUMINT",
402 "MEDIUMTEXT",
403 "MEMORY",
404 "MERGE",
405 "MESSAGE_TEXT",
406 "MICROSECOND",
407 "MIDDLEINT",
408 "MIGRATE",
409 "MINUTE",
410 "MINUTE_MICROSECOND",
411 "MINUTE_SECOND",
412 "MIN_ROWS",
413 "MOD",
414 "MODE",
415 "MODIFIES",
416 "MODIFY",
417 "MONTH",
418 "MULTILINESTRING",
419 "MULTIPOINT",
420 "MULTIPOLYGON",
421 "MUTEX",
422 "MYSQL_ERRNO",
423 "NAME",
424 "NAMES",
425 "NATIONAL",
426 "NATURAL",
427 "NCHAR",
428 "NDB",
429 "NDBCLUSTER",
430 "NEVER",
431 "NEW",
432 "NEXT",
433 "NO",
434 "NODEGROUP",
435 "NONBLOCKING",
436 "NONE",
437 "NOT",
438 "NO_WAIT",
439 "NO_WRITE_TO_BINLOG",
440 "NULL",
441 "NUMBER",
442 "NUMERIC",
443 "NVARCHAR",
444 "OFFSET",
445 "OLD_PASSWORD",
446 "ON",
447 "ONE",
448 "ONE_SHOT",
449 "ONLY",
450 "OPEN",
451 "OPTIMIZE",
452 "OPTIMIZER_COSTS",
453 "OPTION",
454 "OPTIONALLY",
455 "OPTIONS",
456 "OR",
457 "ORDER",
458 "OUT",
459 "OUTER",
460 "OUTFILE",
461 "OWNER",
462 "PACK_KEYS",
463 "PAGE",
464 "PARSER",
465 "PARSE_GCOL_EXPR",
466 "PARTIAL",
467 "PARTITION",
468 "PARTITIONING",
469 "PARTITIONS",
470 "PASSWORD",
471 "PHASE",
472 "PLUGIN",
473 "PLUGINS",
474 "PLUGIN_DIR",
475 "POINT",
476 "POLYGON",
477 "PORT",
478 "PRECEDES",
479 "PRECISION",
480 "PREPARE",
481 "PRESERVE",
482 "PREV",
483 "PRIMARY",
484 "PRIVILEGES",
485 "PROCEDURE",
486 "PROCESSLIST",
487 "PROFILE",
488 "PROFILES",
489 "PROXY",
490 "PURGE",
491 "QUARTER",
492 "QUERY",
493 "QUICK",
494 "RANGE",
495 "READ",
496 "READS",
497 "READ_ONLY",
498 "READ_WRITE",
499 "REAL",
500 "REBUILD",
501 "RECOVER",
502 "REDOFILE",
503 "REDO_BUFFER_SIZE",
504 "REDUNDANT",
505 "REFERENCES",
506 "REGEXP",
507 "RELAY",
508 "RELAYLOG",
509 "RELAY_LOG_FILE",
510 "RELAY_LOG_POS",
511 "RELAY_THREAD",
512 "RELEASE",
513 "RELOAD",
514 "REMOVE",
515 "RENAME",
516 "REORGANIZE",
517 "REPAIR",
518 "REPEAT",
519 "REPEATABLE",
520 "REPLACE",
521 "REPLICATE_DO_DB",
522 "REPLICATE_DO_TABLE",
523 "REPLICATE_IGNORE_DB",
524 "REPLICATE_IGNORE_TABLE",
525 "REPLICATE_REWRITE_DB",
526 "REPLICATE_WILD_DO_TABLE",
527 "REPLICATE_WILD_IGNORE_TABLE",
528 "REPLICATION",
529 "REQUIRE",
530 "RESET",
531 "RESIGNAL",
532 "RESTORE",
533 "RESTRICT",
534 "RESUME",
535 "RETURN",
536 "RETURNED_SQLSTATE",
537 "RETURNS",
538 "REVERSE",
539 "REVOKE",
540 "RIGHT",
541 "RLIKE",
542 "ROLLBACK",
543 "ROLLUP",
544 "ROTATE",
545 "ROUTINE",
546 "ROW",
547 "ROWS",
548 "ROW_COUNT",
549 "ROW_FORMAT",
550 "RTREE",
551 "SAVEPOINT",
552 "SCHEDULE",
553 "SCHEMA",
554 "SCHEMAS",
555 "SCHEMA_NAME",
556 "SECOND",
557 "SECOND_MICROSECOND",
558 "SECURITY",
559 "SELECT",
560 "SENSITIVE",
561 "SEPARATOR",
562 "SERIAL",
563 "SERIALIZABLE",
564 "SERVER",
565 "SESSION",
566 "SET",
567 "SHARE",
568 "SHOW",
569 "SHUTDOWN",
570 "SIGNAL",
571 "SIGNED",
572 "SIMPLE",
573 "SLAVE",
574 "SLOW",
575 "SMALLINT",
576 "SNAPSHOT",
577 "SOCKET",
578 "SOME",
579 "SONAME",
580 "SOUNDS",
581 "SOURCE",
582 "SPATIAL",
583 "SPECIFIC",
584 "SQL",
585 "SQLEXCEPTION",
586 "SQLSTATE",
587 "SQLWARNING",
588 "SQL_AFTER_GTIDS",
589 "SQL_AFTER_MTS_GAPS",
590 "SQL_BEFORE_GTIDS",
591 "SQL_BIG_RESULT",
592 "SQL_BUFFER_RESULT",
593 "SQL_CACHE",
594 "SQL_CALC_FOUND_ROWS",
595 "SQL_NO_CACHE",
596 "SQL_SMALL_RESULT",
597 "SQL_THREAD",
598 "SQL_TSI_DAY",
599 "SQL_TSI_HOUR",
600 "SQL_TSI_MINUTE",
601 "SQL_TSI_MONTH",
602 "SQL_TSI_QUARTER",
603 "SQL_TSI_SECOND",
604 "SQL_TSI_WEEK",
605 "SQL_TSI_YEAR",
606 "SSL",
607 "STACKED",
608 "START",
609 "STARTING",
610 "STARTS",
611 "STATS_AUTO_RECALC",
612 "STATS_PERSISTENT",
613 "STATS_SAMPLE_PAGES",
614 "STATUS",
615 "STOP",
616 "STORAGE",
617 "STORED",
618 "STRAIGHT_JOIN",
619 "STRING",
620 "SUBCLASS_ORIGIN",
621 "SUBJECT",
622 "SUBPARTITION",
623 "SUBPARTITIONS",
624 "SUPER",
625 "SUSPEND",
626 "SWAPS",
627 "SWITCHES",
628 "TABLE",
629 "TABLES",
630 "TABLESPACE",
631 "TABLE_CHECKSUM",
632 "TABLE_NAME",
633 "TEMPORARY",
634 "TEMPTABLE",
635 "TERMINATED",
636 "TEXT",
637 "THAN",
638 "THEN",
639 "TIME",
640 "TIMESTAMP",
641 "TIMESTAMPADD",
642 "TIMESTAMPDIFF",
643 "TINYBLOB",
644 "TINYINT",
645 "TINYTEXT",
646 "TO",
647 "TRAILING",
648 "TRANSACTION",
649 "TRIGGER",
650 "TRIGGERS",
651 "TRUE",
652 "TRUNCATE",
653 "TYPE",
654 "TYPES",
655 "UNCOMMITTED",
656 "UNDEFINED",
657 "UNDO",
658 "UNDOFILE",
659 "UNDO_BUFFER_SIZE",
660 "UNICODE",
661 "UNINSTALL",
662 "UNION",
663 "UNIQUE",
664 "UNKNOWN",
665 "UNLOCK",
666 "UNSIGNED",
667 "UNTIL",
668 "UPDATE",
669 "UPGRADE",
670 "USAGE",
671 "USE",
672 "USER",
673 "USER_RESOURCES",
674 "USE_FRM",
675 "USING",
676 "UTC_DATE",
677 "UTC_TIME",
678 "UTC_TIMESTAMP",
679 "VALIDATION",
680 "VALUE",
681 "VALUES",
682 "VARBINARY",
683 "VARCHAR",
684 "VARCHARACTER",
685 "VARIABLES",
686 "VARYING",
687 "VIEW",
688 "VIRTUAL",
689 "WAIT",
690 "WARNINGS",
691 "WEEK",
692 "WEIGHT_STRING",
693 "WHEN",
694 "WHERE",
695 "WHILE",
696 "WITH",
697 "WITHOUT",
698 "WORK",
699 "WRAPPER",
700 "WRITE",
701 "X509",
702 "XA",
703 "XID",
704 "XML",
705 "XOR",
706 "YEAR",
707 "YEAR_MONTH",
708 "ZEROFILL",
709 );
713 protected $reserved_postgres = array(
714 "ALL",
715 "ANALYSE",
716 "ANALYZE",
717 "AND",
718 "ANY",
719 "ARRAY",
720 "AS",
721 "ASC",
722 "ASYMMETRIC",
723 "AUTHORIZATION",
724 "BETWEEN",
725 "BINARY",
726 "BOTH",
727 "CASE",
728 "CAST",
729 "CHECK",
730 "COLLATE",
731 "COLUMN",
732 "CONSTRAINT",
733 "CREATE",
734 "CROSS",
735 "CURRENT_DATE",
736 "CURRENT_ROLE",
737 "CURRENT_TIME",
738 "CURRENT_TIMESTAMP",
739 "CURRENT_USER",
740 "DEFAULT",
741 "DEFERRABLE",
742 "DESC",
743 "DISTINCT",
744 "DO",
745 "ELSE",
746 "END",
747 "EXCEPT",
748 "FALSE",
749 "FOR",
750 "FOREIGN",
751 "FREEZE",
752 "FROM",
753 "FULL",
754 "GRANT",
755 "GROUP",
756 "HAVING",
757 "ILIKE",
758 "IN",
759 "INITIALLY",
760 "INNER",
761 "INTERSECT",
762 "INTO",
763 "IS",
764 "ISNULL",
765 "JOIN",
766 "LEADING",
767 "LEFT",
768 "LIKE",
769 "LIMIT",
770 "LOCALTIME",
771 "LOCALTIMESTAMP",
772 "NATURAL",
773 "NEW",
774 "NOT",
775 "NOTNULL",
776 "NULL",
777 "OFF",
778 "OFFSET",
779 "OLD",
780 "ON",
781 "ONLY",
782 "OR",
783 "ORDER",
784 "OUTER",
785 "OVERLAPS",
786 "PLACING",
787 "PRIMARY",
788 "REFERENCES",
789 "RETURNING",
790 "RIGHT",
791 "SELECT",
792 "SESSION_USER",
793 "SIMILAR",
794 "SOME",
795 "SYMMETRIC",
796 "TABLE",
797 "THEN",
798 "TO",
799 "TRAILING",
800 "TRUE",
801 "UNION",
802 "UNIQUE",
803 "USER",
804 "USING",
805 "VERBOSE",
806 "WHEN",
807 "WHERE",
808 "WITH",
809 );
813 protected $reserved_oracle = array(
814 "ACCESS",
815 "ADD",
816 "ALL",
817 "ALTER",
818 "AND",
819 "ANY",
820 "AS",
821 "ASC",
822 "AUDIT",
823 "BETWEEN",
824 "BY",
825 "CHAR",
826 "CHECK",
827 "CLUSTER",
828 "COLUMN",
829 "COMMENT",
830 "COMPRESS",
831 "CONNECT",
832 "CREATE",
833 "CURRENT",
834 "DATE",
835 "DECIMAL",
836 "DEFAULT",
837 "DELETE",
838 "DESC",
839 "DISTINCT",
840 "DROP",
841 "ELSE",
842 "EXCLUSIVE",
843 "EXISTS",
844 "FILE",
845 "FLOAT",
846 "FOR",
847 "FROM",
848 "GRANT",
849 "GROUP",
850 "HAVING",
851 "IDENTIFIED",
852 "IMMEDIATE",
853 "IN",
854 "INCREMENT",
855 "INDEX",
856 "INITIAL",
857 "INSERT",
858 "INTEGER",
859 "INTERSECT",
860 "INTO",
861 "IS",
862 "LEVEL",
863 "LIKE",
864 "LOCK",
865 "LONG",
866 "MAXEXTENTS",
867 "MINUS",
868 "MLSLABEL",
869 "MODE",
870 "MODIFY",
871 "NOAUDIT",
872 "NOCOMPRESS",
873 "NOT",
874 "NOWAIT",
875 "NULL",
876 "NUMBER",
877 "OF",
878 "OFFLINE",
879 "ON",
880 "ONLINE",
881 "OPTION",
882 "OR",
883 "ORDER",
884 "PCTFREE",
885 "PRIOR",
886 "PRIVILEGES",
887 "PUBLIC",
888 "RAW",
889 "RENAME",
890 "RESOURCE",
891 "REVOKE",
892 "ROW",
893 "ROWID",
894 "ROWNUM",
895 "ROWS",
896 "SELECT",
897 "SESSION",
898 "SET",
899 "SHARE",
900 "SIZE",
901 "SMALLINT",
902 "START",
903 "SUCCESSFUL",
904 "SYNONYM",
905 "SYSDATE",
906 "TABLE",
907 "THEN",
908 "TO",
909 "TRIGGER",
910 "UID",
911 "UNION",
912 "UNIQUE",
913 "UPDATE",
914 "USER",
915 "VALIDATE",
916 "VALUES",
917 "VARCHAR",
918 "VARCHAR2",
919 "VIEW",
920 "WHENEVER",
921 "WHERE",
922 "WITH",
923 );
927 protected $query_utils;
928
929
935 public function __construct(\ilDBInterface $ilDBInterface)
936 {
937 $this->db_instance = $ilDBInterface;
938 }
939
940
944 protected function getQueryUtils()
945 {
946 if (!$this->query_utils) {
947 $this->query_utils = new ilMySQLQueryUtils($this->db_instance);
948 }
949
950 return $this->query_utils;
951 }
952
953
957 protected $valid_default_values = array(
958 'text' => '',
959 'boolean' => true,
960 'integer' => 0,
961 'decimal' => 0.0,
962 'float' => 0.0,
963 'timestamp' => '1970-01-01 00:00:00',
964 'time' => '00:00:00',
965 'date' => '1970-01-01',
966 'clob' => '',
967 'blob' => '',
968 );
969
970
976 public function checkTableName($table_name)
977 {
978 if (!preg_match(self::DEFINITION_TABLE_NAME, $table_name)) {
979 throw new ilDatabaseException('Table name must only contain _a-z0-9 and must start with a-z.');
980 }
981
982 if ($this->isReserved($table_name)) {
983 throw new ilDatabaseException("Invalid table name '" . $table_name . "' (Reserved Word).");
984 }
985
986 if (strtolower(substr($table_name, 0, 4)) == "sys_") {
987 throw new ilDatabaseException("Invalid table name '" . $table_name . "'. Name must not start with 'sys_'.");
988 }
989
990 if (strlen($table_name) > 22) {
991 throw new ilDatabaseException("Invalid table name '" . $table_name . "'. Maximum table identifer length is 22 bytes.");
992 }
993
994 return true;
995 }
996
997
1002 public function isReserved($table_name)
1003 {
1004 return false;
1005 }
1006
1007
1011 public function getAllReserved()
1012 {
1013 return array_merge($this->getReservedMysql(), $this->getReservedOracle(), $this->getReservedPostgres());
1014 }
1015
1016
1020 public function getReservedMysql()
1021 {
1022 return $this->reserved_mysql;
1023 }
1024
1025
1030 {
1031 $this->reserved_mysql = $reserved_mysql;
1032 }
1033
1034
1038 public function getReservedPostgres()
1039 {
1041 }
1042
1043
1048 {
1049 $this->reserved_postgres = $reserved_postgres;
1050 }
1051
1052
1056 public function getReservedOracle()
1057 {
1059 }
1060
1061
1066 {
1067 $this->reserved_oracle = $reserved_oracle;
1068 }
1069
1070
1076 public function checkColumnName($column_name)
1077 {
1078 if (!preg_match("/^[a-z]+[_a-z0-9]*$/", $column_name)) {
1079 throw new ilDatabaseException("Invalid column name '" . $column_name
1080 . "'. Column name must only contain _a-z0-9 and must start with a-z.");
1081 }
1082
1083 if ($this->isReserved($column_name)) {
1084 throw new ilDatabaseException("Invalid column name '" . $column_name . "' (Reserved Word).");
1085 }
1086
1087 if (strtolower(substr($column_name, 0, 4)) == "sys_") {
1088 throw new ilDatabaseException("Invalid column name '" . $column_name . "'. Name must not start with 'sys_'.");
1089 }
1090
1091 if (strlen($column_name) > 30) {
1092 throw new ilDatabaseException("Invalid column name '" . $column_name . "'. Maximum column identifer length is 30 bytes.");
1093 }
1094
1095 return true;
1096 }
1097
1098
1104 public function checkIndexName($a_name)
1105 {
1106 if (!preg_match("/^[a-z]+[_a-z0-9]*$/", $a_name)) {
1107 throw new ilDatabaseException("Invalid column name '" . $a_name . "'. Column name must only contain _a-z0-9 and must start with a-z.");
1108 }
1109
1110 if ($this->isReserved($a_name)) {
1111 throw new ilDatabaseException("Invalid column name '" . $a_name . "' (Reserved Word).");
1112 }
1113
1114 if (strlen($a_name) > 3) {
1115 throw new ilDatabaseException("Invalid index name '" . $a_name . "'. Maximum index identifer length is 3 bytes.");
1116 }
1117
1118 return true;
1119 }
1120
1121
1127 public function checkColumnDefinition($a_def)
1128 {
1129 // check valid type
1130 if (!in_array($a_def["type"], $this->getAvailableTypes())) {
1131 switch ($a_def["type"]) {
1132 case "boolean":
1133 throw new ilDatabaseException("Invalid column type '" . $a_def["type"] . "'. Use integer(1) instead.");
1134 break;
1135
1136 case "decimal":
1137 throw new ilDatabaseException("Invalid column type '" . $a_def["type"] . "'. Use float or integer instead.");
1138 break;
1139
1140 default:
1141 throw new ilDatabaseException("Invalid column type '" . $a_def["type"] . "'. Allowed types are: "
1142 . implode(', ', $this->getAvailableTypes()));
1143 }
1144 }
1145
1146 // check used attributes
1148 foreach ($a_def as $k => $v) {
1149 if ($k != "type" && !in_array($k, $allowed_attributes[$a_def["type"]])) {
1150 throw new ilDatabaseException("Attribute '" . $k . "' is not allowed for column type '" . $a_def["type"] . "'.");
1151 }
1152 }
1153
1154 // type specific checks
1155 $max_length = $this->getMaxLength();
1156 switch ($a_def["type"]) {
1157 case self::T_TEXT:
1158 if ($a_def["length"] < 1 || $a_def["length"] > $max_length[self::T_TEXT]) {
1159 if (isset($a_def["length"])) {
1160 throw new ilDatabaseException("Invalid length '" . $a_def["length"] . "' for type text." . " Length must be >=1 and <= "
1161 . $max_length[self::T_TEXT] . ".");
1162 }
1163 }
1164 break;
1165
1166 case self::T_INTEGER:
1167 if (!in_array($a_def["length"], $max_length[self::T_INTEGER])) {
1168 if (isset($a_def["length"])) {
1169 throw new ilDatabaseException("Invalid length '" . $a_def["length"] . "' for type integer." . " Length must be "
1170 . implode(', ', $max_length[self::T_INTEGER]) . " (bytes).");
1171 }
1172 }
1173 if ($a_def["unsigned"]) {
1174 throw new ilDatabaseException("Unsigned attribut must not be true for type integer.");
1175 }
1176 break;
1177 }
1178
1179 return true;
1180 }
1181
1182
1188 public function isAllowedAttribute($attribute, $type)
1189 {
1190 return in_array($attribute, $this->allowed_attributes[$type]);
1191 }
1192
1193
1197 public function getAvailableTypes()
1198 {
1200 }
1201
1202
1207 {
1208 $this->available_types = $available_types;
1209 }
1210
1211
1215 public function getAllowedAttributes()
1216 {
1218 }
1219
1220
1225 {
1226 $this->allowed_attributes = $allowed_attributes;
1227 }
1228
1229
1233 public function getMaxLength()
1234 {
1235 return $this->max_length;
1236 }
1237
1238
1242 public function setMaxLength($max_length)
1243 {
1244 $this->max_length = $max_length;
1245 }
1246
1247
1251 protected function getDBInstance()
1252 {
1253 return $this->db_instance;
1254 }
1255
1256
1260 public function getValidTypes()
1261 {
1263 $db = $this->getDBInstance();
1264
1265 if (!empty($db->options['datatype_map'])) {
1266 foreach ($db->options['datatype_map'] as $type => $mapped_type) {
1267 if (array_key_exists($mapped_type, $types)) {
1268 $types[$type] = $types[$mapped_type];
1269 } elseif (!empty($db->options['datatype_map_callback'][$type])) {
1270 $parameter = array( 'type' => $type, 'mapped_type' => $mapped_type );
1271 $default = call_user_func_array($db->options['datatype_map_callback'][$type], array( &$db, __FUNCTION__, $parameter ));
1272 $types[$type] = $default;
1273 }
1274 }
1275 }
1276
1277 return $types;
1278 }
1279
1280
1286 protected function checkResultTypes($types)
1287 {
1288 $types = is_array($types) ? $types : array( $types );
1289 foreach ($types as $key => $type) {
1290 if (!isset($this->valid_default_values[$type])) {
1291 $db = $this->getDBInstance();
1292 if (empty($db->options['datatype_map'][$type])) {
1293 throw new ilDatabaseException($type . ' for ' . $key . ' is not a supported column type');
1294 }
1295 }
1296 }
1297
1298 return $types;
1299 }
1300
1301
1309 protected function baseConvertResult($value, $type, $rtrim = true)
1310 {
1311 switch ($type) {
1312 case 'text':
1313 if ($rtrim) {
1314 $value = rtrim($value);
1315 }
1316
1317 return $value;
1318 case 'integer':
1319 return intval($value);
1320 case 'boolean':
1321 return !empty($value);
1322 case 'decimal':
1323 return $value;
1324 case 'float':
1325 return doubleval($value);
1326 case 'date':
1327 return $value;
1328 case 'time':
1329 return $value;
1330 case 'timestamp':
1331 return $value;
1332 case 'clob':
1333 case 'blob':
1334 $this->lobs[] = array(
1335 'buffer' => null,
1336 'position' => 0,
1337 'lob_index' => null,
1338 'endOfLOB' => false,
1339 'resource' => $value,
1340 'value' => null,
1341 'loaded' => false,
1342 );
1343 end($this->lobs);
1344 $lob_index = key($this->lobs);
1345 $this->lobs[$lob_index]['lob_index'] = $lob_index;
1346
1347 return fopen('MDB2LOB://' . $lob_index . '@' . $this->db_index, 'r+');
1348 }
1349
1350 throw new ilDatabaseException('attempt to convert result value to an unknown type :' . $type);
1351 }
1352
1353
1361 public function convertResult($value, $type, $rtrim = true)
1362 {
1363 if (is_null($value)) {
1364 return null;
1365 }
1366 $db = $this->getDBInstance();
1367
1368 if (!empty($db->options['datatype_map'][$type])) {
1369 $type = $db->options['datatype_map'][$type];
1370 if (!empty($db->options['datatype_map_callback'][$type])) {
1371 $parameter = array( 'type' => $type, 'value' => $value, 'rtrim' => $rtrim );
1372
1373 return call_user_func_array($db->options['datatype_map_callback'][$type], array( &$db, __FUNCTION__, $parameter ));
1374 }
1375 }
1376
1377 return $this->baseConvertResult($value, $type, $rtrim);
1378 }
1379
1380
1387 public function convertResultRow($types, $row, $rtrim = true)
1388 {
1389 $types = $this->sortResultFieldTypes(array_keys($row), $types);
1390 foreach ($row as $key => $value) {
1391 if (empty($types[$key])) {
1392 continue;
1393 }
1394 $value = $this->convertResult($row[$key], $types[$key], $rtrim);
1395
1396 $row[$key] = $value;
1397 }
1398
1399 return $row;
1400 }
1401
1402 // }}}
1403 // {{{ _sortResultFieldTypes()
1404
1410 protected function sortResultFieldTypes($columns, $types)
1411 {
1412 $n_cols = count($columns);
1413 $n_types = count($types);
1414 if ($n_cols > $n_types) {
1415 for ($i = $n_cols - $n_types; $i >= 0; $i--) {
1416 $types[] = null;
1417 }
1418 }
1419 $sorted_types = array();
1420 foreach ($columns as $col) {
1421 $sorted_types[$col] = null;
1422 }
1423 foreach ($types as $name => $type) {
1424 if (array_key_exists($name, $sorted_types)) {
1425 $sorted_types[$name] = $type;
1426 unset($types[$name]);
1427 }
1428 }
1429 // if there are left types in the array, fill the null values of the
1430 // sorted array with them, in order.
1431 if (count($types)) {
1432 reset($types);
1433 foreach (array_keys($sorted_types) as $k) {
1434 if (is_null($sorted_types[$k])) {
1435 $sorted_types[$k] = current($types);
1436 next($types);
1437 }
1438 }
1439 }
1440
1441 return $sorted_types;
1442 }
1443
1444
1452 public function getDeclaration($type, $name, $field)
1453 {
1454 $db = $this->getDBInstance();
1455
1456 if (!empty($db->options['datatype_map'][$type])) {
1457 $type = $db->options['datatype_map'][$type];
1458 if (!empty($db->options['datatype_map_callback'][$type])) {
1459 $parameter = array( 'type' => $type, 'name' => $name, 'field' => $field );
1460
1461 return call_user_func_array($db->options['datatype_map_callback'][$type], array( &$db, __FUNCTION__, $parameter ));
1462 }
1463 $field['type'] = $type;
1464 }
1465
1466 if (!method_exists($this, "get{$type}Declaration")) {
1467 throw new ilDatabaseException('type not defined: ' . $type);
1468 }
1469
1470 return $this->{"get{$type}Declaration"}($name, $field);
1471 }
1472
1473
1478 public function getTypeDeclaration($field)
1479 {
1480 $db = $this->getDBInstance();
1481
1482 switch ($field['type']) {
1483 case 'text':
1484 $length = !empty($field['length']) ? $field['length'] : $db->options['default_text_field_length'];
1485 $fixed = !empty($field['fixed']) ? $field['fixed'] : false;
1486
1487 return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(' . $db->options['default_text_field_length']
1488 . ')') : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
1489 case 'clob':
1490 return 'TEXT';
1491 case 'blob':
1492 return 'TEXT';
1493 case 'integer':
1494 return 'INT';
1495 case 'boolean':
1496 return 'INT';
1497 case 'date':
1498 return 'CHAR (' . strlen('YYYY-MM-DD') . ')';
1499 case 'time':
1500 return 'CHAR (' . strlen('HH:MM:SS') . ')';
1501 case 'timestamp':
1502 return 'CHAR (' . strlen('YYYY-MM-DD HH:MM:SS') . ')';
1503 case 'float':
1504 return 'TEXT';
1505 case 'decimal':
1506 return 'TEXT';
1507 }
1508
1509 return '';
1510 }
1511
1512
1518 protected function getInternalDeclaration($name, $field)
1519 {
1520 $db = $this->getDBInstance();
1521
1522 $name = $db->quoteIdentifier($name, true);
1523 $declaration_options = $db->getFieldDefinition()->getDeclarationOptions($field);
1524
1525 return $name . ' ' . $this->getTypeDeclaration($field) . $declaration_options;
1526 }
1527
1528
1534 protected function getDeclarationOptions($field)
1535 {
1536 $charset = empty($field['charset']) ? '' : ' ' . $this->getCharsetFieldDeclaration($field['charset']);
1537
1538 $default = '';
1539 if (array_key_exists('default', $field)) {
1540 if ($field['default'] === '') {
1541 $db = $this->getDBInstance();
1542
1543 if (empty($field['notnull'])) {
1544 $field['default'] = null;
1545 } else {
1547 $field['default'] = $valid_default_values[$field['type']];
1548 }
1549 if ($field['default'] === ''
1550 && ($db->options['portability'] & 32)
1551 ) {
1552 $field['default'] = ' ';
1553 }
1554 }
1555 $default = ' DEFAULT ' . $this->quote($field['default'], $field['type']);
1556 } elseif (empty($field['notnull'])) {
1557 $default = ' DEFAULT NULL';
1558 }
1559
1560 $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
1561 // alex patch 28 Nov 2011 start
1562 if ($field['notnull'] === false) {
1563 $notnull = " NULL";
1564 }
1565 // alex patch 28 Nov 2011 end
1566
1567 $collation = empty($field['collation']) ? '' : ' ' . $this->getCollationFieldDeclaration($field['collation']);
1568
1569 return $charset . $default . $notnull . $collation;
1570 }
1571
1572
1577 protected function getCharsetFieldDeclaration($charset)
1578 {
1579 return '';
1580 }
1581
1582
1587 protected function getCollationFieldDeclaration($collation)
1588 {
1589 return '';
1590 }
1591
1592
1599 protected function getIntegerDeclaration($name, $field)
1600 {
1601 if (!empty($field['unsigned'])) {
1602 $db = $this->getDBInstance();
1603
1604 $db->warnings[] = "unsigned integer field \"$name\" is being declared as signed integer";
1605 }
1606
1607 return $this->getInternalDeclaration($name, $field);
1608 }
1609
1610
1617 protected function getTextDeclaration($name, $field)
1618 {
1619 return $this->getInternalDeclaration($name, $field);
1620 }
1621
1622
1628 protected function getCLOBDeclaration($name, $field)
1629 {
1630 $db = $this->getDBInstance();
1631
1632 $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
1633 $name = $db->quoteIdentifier($name, true);
1634
1635 return $name . ' ' . $this->getTypeDeclaration($field) . $notnull;
1636 }
1637
1638
1644 protected function getBLOBDeclaration($name, $field)
1645 {
1646 $db = $this->getDBInstance();
1647
1648 $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
1649 $name = $db->quoteIdentifier($name, true);
1650
1651 return $name . ' ' . $this->getTypeDeclaration($field) . $notnull;
1652 }
1653
1654
1660 protected function getBooleanDeclaration($name, $field)
1661 {
1662 return $this->getInternalDeclaration($name, $field);
1663 }
1664
1665
1671 protected function getDateDeclaration($name, $field)
1672 {
1673 return $this->getInternalDeclaration($name, $field);
1674 }
1675
1676
1682 protected function getTimestampDeclaration($name, $field)
1683 {
1684 return $this->getInternalDeclaration($name, $field);
1685 }
1686
1687
1693 protected function getTimeDeclaration($name, $field)
1694 {
1695 return $this->getInternalDeclaration($name, $field);
1696 }
1697
1698
1704 protected function getFloatDeclaration($name, $field)
1705 {
1706 return $this->getInternalDeclaration($name, $field);
1707 }
1708
1709
1715 protected function getDecimalDeclaration($name, $field)
1716 {
1717 return $this->getInternalDeclaration($name, $field);
1718 }
1719
1720
1727 public function compareDefinition($current, $previous)
1728 {
1729 $type = !empty($current['type']) ? $current['type'] : null;
1730
1731 if (!method_exists($this, "compare{$type}Definition")) {
1732 $db = $this->getDBInstance();
1733
1734 if (!empty($db->options['datatype_map_callback'][$type])) {
1735 $parameter = array( 'current' => $current, 'previous' => $previous );
1736 $change = call_user_func_array($db->options['datatype_map_callback'][$type], array( &$db, __FUNCTION__, $parameter ));
1737
1738 return $change;
1739 }
1740
1741 throw new ilDatabaseException('type "' . $current['type'] . '" is not yet supported');
1742 }
1743
1744 if (empty($previous['type']) || $previous['type'] != $type) {
1745 return $current;
1746 }
1747
1748 $change = $this->{"compare{$type}Definition"}($current, $previous);
1749
1750 if ($previous['type'] != $type) {
1751 $change['type'] = true;
1752 }
1753
1754 $previous_notnull = !empty($previous['notnull']) ? $previous['notnull'] : false;
1755 $notnull = !empty($current['notnull']) ? $current['notnull'] : false;
1756 if ($previous_notnull != $notnull) {
1757 $change['notnull'] = true;
1758 }
1759
1760 $previous_default = array_key_exists('default', $previous) ? $previous['default'] : ($previous_notnull ? '' : null);
1761 $default = array_key_exists('default', $current) ? $current['default'] : ($notnull ? '' : null);
1762 if ($previous_default !== $default) {
1763 $change['default'] = true;
1764 }
1765
1766 return $change;
1767 }
1768
1769
1775 protected function compareIntegerDefinition($current, $previous)
1776 {
1777 $change = array();
1778 $previous_unsigned = !empty($previous['unsigned']) ? $previous['unsigned'] : false;
1779 $unsigned = !empty($current['unsigned']) ? $current['unsigned'] : false;
1780 if ($previous_unsigned != $unsigned) {
1781 $change['unsigned'] = true;
1782 }
1783 $previous_autoincrement = !empty($previous['autoincrement']) ? $previous['autoincrement'] : false;
1784 $autoincrement = !empty($current['autoincrement']) ? $current['autoincrement'] : false;
1785 if ($previous_autoincrement != $autoincrement) {
1786 $change['autoincrement'] = true;
1787 }
1788
1789 return $change;
1790 }
1791
1792
1798 protected function compareTextDefinition($current, $previous)
1799 {
1800 $change = array();
1801 $previous_length = !empty($previous['length']) ? $previous['length'] : 0;
1802 $length = !empty($current['length']) ? $current['length'] : 0;
1803 if ($previous_length != $length) {
1804 $change['length'] = true;
1805 }
1806 $previous_fixed = !empty($previous['fixed']) ? $previous['fixed'] : 0;
1807 $fixed = !empty($current['fixed']) ? $current['fixed'] : 0;
1808 if ($previous_fixed != $fixed) {
1809 $change['fixed'] = true;
1810 }
1811
1812 return $change;
1813 }
1814
1815
1821 protected function compareCLOBDefinition($current, $previous)
1822 {
1823 return $this->compareTextDefinition($current, $previous);
1824 }
1825
1826
1832 protected function compareBLOBDefinition($current, $previous)
1833 {
1834 return $this->compareTextDefinition($current, $previous);
1835 }
1836
1837
1843 protected function compareDateDefinition($current, $previous)
1844 {
1845 return array();
1846 }
1847
1848
1854 protected function compareTimeDefinition($current, $previous)
1855 {
1856 return array();
1857 }
1858
1859
1865 protected function compareTimestampDefinition($current, $previous)
1866 {
1867 return array();
1868 }
1869
1870
1876 protected function compareBooleanDefinition($current, $previous)
1877 {
1878 return array();
1879 }
1880
1881
1887 protected function compareFloatDefinition($current, $previous)
1888 {
1889 return array();
1890 }
1891
1892
1898 protected function compareDecimalDefinition($current, $previous)
1899 {
1900 return array();
1901 }
1902
1903
1912 public function quote($value, $type = null, $quote = true, $escape_wildcards = false)
1913 {
1914 $db = $this->getDBInstance();
1915
1916 return $db->quote($value, $type);
1917
1918 if (is_null($value)
1919 || ($value === '' && $db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL)
1920 ) {
1921 if (!$quote) {
1922 return null;
1923 }
1924
1925 return 'NULL';
1926 }
1927
1928 if (is_null($type)) {
1929 switch (gettype($value)) {
1930 case 'integer':
1931 $type = 'integer';
1932 break;
1933 case 'double':
1934 // todo: default to decimal as float is quite unusual
1935 // $type = 'float';
1936 $type = 'decimal';
1937 break;
1938 case 'boolean':
1939 $type = 'boolean';
1940 break;
1941 case 'array':
1942 $value = serialize($value);
1943 // no break
1944 case 'object':
1945 $type = 'text';
1946 break;
1947 default:
1948 if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $value)) {
1949 $type = 'timestamp';
1950 } elseif (preg_match('/^\d{2}:\d{2}$/', $value)) {
1951 $type = 'time';
1952 } elseif (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
1953 $type = 'date';
1954 } else {
1955 $type = 'text';
1956 }
1957 break;
1958 }
1959 } elseif (!empty($db->options['datatype_map'][$type])) {
1960 $type = $db->options['datatype_map'][$type];
1961 if (!empty($db->options['datatype_map_callback'][$type])) {
1962 $parameter = array( 'type' => $type, 'value' => $value, 'quote' => $quote, 'escape_wildcards' => $escape_wildcards );
1963
1964 return call_user_func_array($db->options['datatype_map_callback'][$type], array( &$db, __FUNCTION__, $parameter ));
1965 }
1966 }
1967
1968 if (!method_exists($this, "quote{$type}")) {
1969 throw new ilDatabaseException('type not defined: ' . $type);
1970 }
1971 $value = $this->{"quote{$type}"}($value, $quote, $escape_wildcards);
1972 if ($quote && $escape_wildcards && $db->string_quoting['escape_pattern']
1973 && $db->string_quoting['escape'] !== $db->string_quoting['escape_pattern']
1974 ) {
1975 $value .= $this->patternEscapeString();
1976 }
1977
1978 return $value;
1979 }
1980
1981
1988 protected function quoteInteger($value, $quote, $escape_wildcards)
1989 {
1990 return (int) $value;
1991 }
1992
1993
2000 protected function quoteText($value, $quote, $escape_wildcards)
2001 {
2002 if (!$quote) {
2003 return $value;
2004 }
2005
2006 $db = $this->getDBInstance();
2007
2008 $value = $db->escape($value, $escape_wildcards);
2009
2010 return "'" . $value . "'";
2011 }
2012
2013
2018 protected function readFile($value)
2019 {
2020 $close = false;
2021 if (preg_match('/^(\w+:\/\/)(.*)$/', $value, $match)) {
2022 $close = true;
2023 if ($match[1] == 'file://') {
2024 $value = $match[2];
2025 }
2026 // do not try to open urls
2027 #$value = @fopen($value, 'r');
2028 }
2029
2030 if (is_resource($value)) {
2031 $db = $this->getDBInstance();
2032
2033 $fp = $value;
2034 $value = '';
2035 while (!@feof($fp)) {
2036 $value .= @fread($fp, $db->options['lob_buffer_length']);
2037 }
2038 if ($close) {
2039 @fclose($fp);
2040 }
2041 }
2042
2043 return $value;
2044 }
2045
2046
2053 protected function quoteLOB($value, $quote, $escape_wildcards)
2054 {
2055 $value = $this->readFile($value);
2056
2057 return $this->quoteText($value, $quote, $escape_wildcards);
2058 }
2059
2060
2067 protected function quoteCLOB($value, $quote, $escape_wildcards)
2068 {
2069 return $this->quoteLOB($value, $quote, $escape_wildcards);
2070 }
2071
2072
2079 protected function quoteBLOB($value, $quote, $escape_wildcards)
2080 {
2081 return $this->quoteLOB($value, $quote, $escape_wildcards);
2082 }
2083
2084
2091 protected function quoteBoolean($value, $quote, $escape_wildcards)
2092 {
2093 return ($value ? 1 : 0);
2094 }
2095
2096
2103 protected function quoteDate($value, $quote, $escape_wildcards)
2104 {
2105 if ($value === 'CURRENT_DATE') {
2106 $db = $this->getDBInstance();
2107
2108 return 'CURRENT_DATE';
2109 }
2110
2111 return $this->quoteText($value, $quote, $escape_wildcards);
2112 }
2113
2114
2121 protected function quoteTimestamp($value, $quote, $escape_wildcards)
2122 {
2123 if ($value === 'CURRENT_TIMESTAMP') {
2124 $db = $this->getDBInstance();
2125
2126 if (isset($db->function) && is_a($db->function, 'MDB2_Driver_Function_Common')) {
2127 return $db->function->now('timestamp');
2128 }
2129
2130 return 'CURRENT_TIMESTAMP';
2131 }
2132
2133 return $this->quoteText($value, $quote, $escape_wildcards);
2134 }
2135
2136
2143 protected function quoteTime($value, $quote, $escape_wildcards)
2144 {
2145 if ($value === 'CURRENT_TIME') {
2146 $db = $this->getDBInstance();
2147
2148 if (isset($db->function) && is_a($db->function, 'MDB2_Driver_Function_Common')) {
2149 return $db->function->now('time');
2150 }
2151
2152 return 'CURRENT_TIME';
2153 }
2154
2155 return $this->quoteText($value, $quote, $escape_wildcards);
2156 }
2157
2158
2165 protected function quoteFloat($value, $quote, $escape_wildcards)
2166 {
2167 if (preg_match('/^(.*)e([-+])(\d+)$/i', $value, $matches)) {
2168 $decimal = $this->quoteDecimal($matches[1], $quote, $escape_wildcards);
2169 $sign = $matches[2];
2170 $exponent = str_pad($matches[3], 2, '0', STR_PAD_LEFT);
2171 $value = $decimal . 'E' . $sign . $exponent;
2172 } else {
2173 $value = $this->quoteDecimal($value, $quote, $escape_wildcards);
2174 }
2175
2176 return $value;
2177 }
2178
2179
2186 protected function quoteDecimal($value, $quote, $escape_wildcards)
2187 {
2188 $value = (string) $value;
2189 $value = preg_replace('/[^\d\.,\-+eE]/', '', $value);
2190 if (preg_match('/[^.0-9]/', $value)) {
2191 if (strpos($value, ',')) {
2192 // 1000,00
2193 if (!strpos($value, '.')) {
2194 // convert the last "," to a "."
2195 $value = strrev(str_replace(',', '.', strrev($value)));
2196 // 1.000,00
2197 } elseif (strpos($value, '.') && strpos($value, '.') < strpos($value, ',')) {
2198 $value = str_replace('.', '', $value);
2199 // convert the last "," to a "."
2200 $value = strrev(str_replace(',', '.', strrev($value)));
2201 // 1,000.00
2202 } else {
2203 $value = str_replace(',', '', $value);
2204 }
2205 }
2206 }
2207
2208 return $value;
2209 }
2210
2211
2218 public function writeLOBToFile($lob, $file)
2219 {
2220 $db = $this->getDBInstance();
2221
2222 if (preg_match('/^(\w+:\/\/)(.*)$/', $file, $match)) {
2223 if ($match[1] == 'file://') {
2224 $file = $match[2];
2225 }
2226 }
2227
2228 $fp = @fopen($file, 'wb');
2229 while (!@feof($lob)) {
2230 $result = @fread($lob, $db->options['lob_buffer_length']);
2231 $read = strlen($result);
2232 if (@fwrite($fp, $result, $read) != $read) {
2233 @fclose($fp);
2234
2235 throw new ilDatabaseException('could not write to the output file');
2236 }
2237 }
2238 @fclose($fp);
2239
2240 return MDB2_OK;
2241 }
2242
2243
2248 protected function retrieveLOB(&$lob)
2249 {
2250 if (is_null($lob['value'])) {
2251 $lob['value'] = $lob['resource'];
2252 }
2253 $lob['loaded'] = true;
2254
2255 return MDB2_OK;
2256 }
2257
2258
2264 protected function readLOB($lob, $length)
2265 {
2266 return substr($lob['value'], $lob['position'], $length);
2267 }
2268
2269
2274 protected function endOfLOB($lob)
2275 {
2276 return $lob['endOfLOB'];
2277 }
2278
2279
2284 public function destroyLOB($lob)
2285 {
2286 $lob_data = stream_get_meta_data($lob);
2287 $lob_index = $lob_data['wrapper_data']->lob_index;
2288 fclose($lob);
2289 if (isset($this->lobs[$lob_index])) {
2290 $this->destroyLOBInternal($this->lobs[$lob_index]);
2291 unset($this->lobs[$lob_index]);
2292 }
2293
2294 return true;
2295 }
2296
2297
2302 protected function destroyLOBInternal(&$lob)
2303 {
2304 return true;
2305 }
2306
2307
2314 public function implodeArray($array, $type = false)
2315 {
2316 if (!is_array($array) || empty($array)) {
2317 return 'NULL';
2318 }
2319 if ($type) {
2320 foreach ($array as $value) {
2321 $return[] = $this->quote($value, $type);
2322 }
2323 } else {
2324 $return = $array;
2325 }
2326
2327 return implode(', ', $return);
2328 }
2329
2330
2338 public function matchPattern($pattern, $operator = null, $field = null)
2339 {
2340 $db = $this->getDBInstance();
2341
2342 $match = '';
2343 if (!is_null($operator)) {
2344 $operator = strtoupper($operator);
2345 switch ($operator) {
2346 // case insensitive
2347 case 'ILIKE':
2348 if (is_null($field)) {
2349 throw new ilDatabaseException('case insensitive LIKE matching requires passing the field name');
2350 }
2351 $db->loadModule('Function', null, true);
2352 $match = $db->function->lower($field) . ' LIKE ';
2353 break;
2354 // case sensitive
2355 case 'LIKE':
2356 $match = is_null($field) ? 'LIKE ' : $field . ' LIKE ';
2357 break;
2358 default:
2359 throw new ilDatabaseException('not a supported operator type:' . $operator);
2360 }
2361 }
2362 $match .= "'";
2363 foreach ($pattern as $key => $value) {
2364 if ($key % 2) {
2365 $match .= $value;
2366 } else {
2367 if ($operator === 'ILIKE') {
2368 $value = strtolower($value);
2369 }
2370 $escaped = $db->escape($value);
2371 $match .= $db->escapePattern($escaped);
2372 }
2373 }
2374 $match .= "'";
2375 $match .= $this->patternEscapeString();
2376
2377 return $match;
2378 }
2379
2380
2384 public function patternEscapeString()
2385 {
2386 return '';
2387 }
2388
2389
2394 public function mapNativeDatatype($field)
2395 {
2396 $db = $this->getDBInstance();
2397 $db_type = strtok($field['type'], '(), ');
2398 if (!empty($db->options['nativetype_map_callback'][$db_type])) {
2399 return call_user_func_array($db->options['nativetype_map_callback'][$db_type], array( $db, $field ));
2400 }
2401
2402 return $this->mapNativeDatatypeInternal($field);
2403 }
2404
2405
2411 abstract protected function mapNativeDatatypeInternal($field);
2412
2413
2418 public function mapPrepareDatatype($type)
2419 {
2420 $db = $this->getDBInstance();
2421
2422 if (!empty($db->options['datatype_map'][$type])) {
2423 $type = $db->options['datatype_map'][$type];
2424 if (!empty($db->options['datatype_map_callback'][$type])) {
2425 $parameter = array( 'type' => $type );
2426
2427 return call_user_func_array($db->options['datatype_map_callback'][$type], array( &$db, __FUNCTION__, $parameter ));
2428 }
2429 }
2430
2431 return $type;
2432 }
2433}
$result
const MDB2_OK(!class_exists('PEAR'))
The method mapErrorCode in each MDB2_dbtype implementation maps native error codes to one of these.
Definition: MDB2.php:72
const MDB2_PORTABILITY_EMPTY_TO_NULL
Portability: convert empty values to null strings in data output by query*() and fetch*().
Definition: MDB2.php:203
if(! $in) $columns
Definition: Utf8Test.php:45
An exception for terminatinating execution or to throw for unit testing.
Class ilDBPdoFieldDefinition.
quoteText($value, $quote, $escape_wildcards)
quoteFloat($value, $quote, $escape_wildcards)
compareIntegerDefinition($current, $previous)
quoteDecimal($value, $quote, $escape_wildcards)
quoteTime($value, $quote, $escape_wildcards)
compareDecimalDefinition($current, $previous)
compareBLOBDefinition($current, $previous)
compareCLOBDefinition($current, $previous)
__construct(\ilDBInterface $ilDBInterface)
ilDBPdoFieldDefinition constructor.
quote($value, $type=null, $quote=true, $escape_wildcards=false)
compareTextDefinition($current, $previous)
quoteBLOB($value, $quote, $escape_wildcards)
compareFloatDefinition($current, $previous)
quoteBoolean($value, $quote, $escape_wildcards)
compareTimestampDefinition($current, $previous)
convertResult($value, $type, $rtrim=true)
quoteLOB($value, $quote, $escape_wildcards)
compareDateDefinition($current, $previous)
mapNativeDatatypeInternal($field)
matchPattern($pattern, $operator=null, $field=null)
convertResultRow($types, $row, $rtrim=true)
quoteInteger($value, $quote, $escape_wildcards)
quoteTimestamp($value, $quote, $escape_wildcards)
baseConvertResult($value, $type, $rtrim=true)
quoteDate($value, $quote, $escape_wildcards)
compareBooleanDefinition($current, $previous)
compareTimeDefinition($current, $previous)
quoteCLOB($value, $quote, $escape_wildcards)
Class ilDatabaseException.
Class ilMySQLQueryUtils.
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
Interface ilDBInterface.
if($format !==null) $name
Definition: metadata.php:146
$type
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file