ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilDBPdoFieldDefinition.php
Go to the documentation of this file.
1 <?php
2 
8 abstract class ilDBPdoFieldDefinition
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  );
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  );
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 
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  {
1040  return $this->reserved_postgres;
1041  }
1042 
1043 
1048  {
1049  $this->reserved_postgres = $reserved_postgres;
1050  }
1051 
1052 
1056  public function getReservedOracle()
1057  {
1058  return $this->reserved_oracle;
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  {
1199  return $this->available_types;
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  {
1262  $types = $this->valid_default_values;
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 }
compareCLOBDefinition($current, $previous)
Add rich text string
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
compareTimestampDefinition($current, $previous)
quoteDate($value, $quote, $escape_wildcards)
quote($value, $type=null, $quote=true, $escape_wildcards=false)
$result
$type
baseConvertResult($value, $type, $rtrim=true)
quoteLOB($value, $quote, $escape_wildcards)
quoteInteger($value, $quote, $escape_wildcards)
const MDB2_PORTABILITY_EMPTY_TO_NULL
Portability: convert empty values to null strings in data output by query*() and fetch*().
Definition: MDB2.php:203
quoteTimestamp($value, $quote, $escape_wildcards)
compareBLOBDefinition($current, $previous)
Class ilDBPdoFieldDefinition.
quoteDecimal($value, $quote, $escape_wildcards)
compareBooleanDefinition($current, $previous)
compareFloatDefinition($current, $previous)
Class ilDatabaseException.
compareDateDefinition($current, $previous)
Interface ilDBInterface.
if($format !==null) $name
Definition: metadata.php:146
compareTextDefinition($current, $previous)
quoteFloat($value, $quote, $escape_wildcards)
matchPattern($pattern, $operator=null, $field=null)
Create styles array
The data for the language used.
quoteCLOB($value, $quote, $escape_wildcards)
quoteBoolean($value, $quote, $escape_wildcards)
quoteText($value, $quote, $escape_wildcards)
Class ilMySQLQueryUtils.
$i
Definition: disco.tpl.php:19
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
quoteBLOB($value, $quote, $escape_wildcards)
compareIntegerDefinition($current, $previous)
quoteTime($value, $quote, $escape_wildcards)
__construct(\ilDBInterface $ilDBInterface)
ilDBPdoFieldDefinition constructor.
if(! $in) $columns
Definition: Utf8Test.php:45
$key
Definition: croninfo.php:18
convertResultRow($types, $row, $rtrim=true)
compareTimeDefinition($current, $previous)
mapNativeDatatypeInternal($field)
convertResult($value, $type, $rtrim=true)
compareDecimalDefinition($current, $previous)