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' ),
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" ),
64 self::T_INTEGER =>
array( 1, 2, 3, 4, 8 ),
206 "MASTER_SSL_VERIFY_SERVER_CERT",
212 "MINUTE_MICROSECOND",
218 "NO_WRITE_TO_BINLOG",
253 "SECOND_MICROSECOND",
267 "SQL_CALC_FOUND_ROWS",
534 $this->db_instance = $ilDBInterface;
542 if (!$this->query_utils) {
559 'timestamp' =>
'1970-01-01 00:00:00',
560 'time' =>
'00:00:00',
561 'date' =>
'1970-01-01',
573 if (!preg_match(self::DEFINITION_TABLE_NAME, $table_name)) {
574 throw new ilDatabaseException(
'Table name must only contain _a-z0-9 and must start with a-z.');
578 throw new ilDatabaseException(
"Invalid table name '" . $table_name .
"' (Reserved Word).");
581 if (strtolower(substr($table_name, 0, 4)) ==
"sys_") {
582 throw new ilDatabaseException(
"Invalid table name '" . $table_name .
"'. Name must not start with 'sys_'.");
585 if (strlen($table_name) > 22) {
586 throw new ilDatabaseException(
"Invalid table name '" . $table_name .
"'. Maximum table identifer length is 22 bytes.");
598 return in_array(strtoupper($table_name), $this->
getAllReserved());
664 if (!preg_match(
"/^[a-z]+[_a-z0-9]*$/", $column_name)) {
666 .
"'. Column name must only contain _a-z0-9 and must start with a-z.");
670 throw new ilDatabaseException(
"Invalid column name '" . $column_name .
"' (Reserved Word).");
673 if (strtolower(substr($column_name, 0, 4)) ==
"sys_") {
674 throw new ilDatabaseException(
"Invalid column name '" . $column_name .
"'. Name must not start with 'sys_'.");
677 if (strlen($column_name) > 30) {
678 throw new ilDatabaseException(
"Invalid column name '" . $column_name .
"'. Maximum column identifer length is 30 bytes.");
691 if (!preg_match(
"/^[a-z]+[_a-z0-9]*$/", $a_name)) {
692 throw new ilDatabaseException(
"Invalid column name '" . $a_name .
"'. Column name must only contain _a-z0-9 and must start with a-z.");
699 if (strlen($a_name) > 3) {
700 throw new ilDatabaseException(
"Invalid index name '" . $a_name .
"'. Maximum index identifer length is 3 bytes.");
715 switch ($a_def[
"type"]) {
717 throw new ilDatabaseException(
"Invalid column type '" . $a_def[
"type"] .
"'. Use integer(1) instead.");
721 throw new ilDatabaseException(
"Invalid column type '" . $a_def[
"type"] .
"'. Use float or integer instead.");
725 throw new ilDatabaseException(
"Invalid column type '" . $a_def[
"type"] .
"'. Allowed types are: " 732 foreach ($a_def as $k => $v) {
734 throw new ilDatabaseException(
"Attribute '" . $k .
"' is not allowed for column type '" . $a_def[
"type"] .
"'.");
740 switch ($a_def[
"type"]) {
742 if ($a_def[
"length"] < 1 || $a_def[
"length"] >
$max_length[self::T_TEXT]) {
743 if (isset($a_def[
"length"])) {
744 throw new ilDatabaseException(
"Invalid length '" . $a_def[
"length"] .
"' for type text." .
" Length must be >=1 and <= " 750 case self::T_INTEGER:
751 if (!in_array($a_def[
"length"],
$max_length[self::T_INTEGER])) {
752 if (isset($a_def[
"length"])) {
753 throw new ilDatabaseException(
"Invalid length '" . $a_def[
"length"] .
"' for type integer." .
" Length must be " 754 . implode(
', ',
$max_length[self::T_INTEGER]) .
" (bytes).");
757 if ($a_def[
"unsigned"]) {
773 return in_array($attribute, $this->allowed_attributes[$type]);
840 if (!empty($db->options[
'datatype_map'])) {
841 foreach ($db->options[
'datatype_map'] as $type => $mapped_type) {
842 if (array_key_exists($mapped_type, $types)) {
843 $types[$type] = $types[$mapped_type];
844 } elseif (!empty($db->options[
'datatype_map_callback'][$type])) {
845 $parameter =
array(
'type' => $type,
'mapped_type' => $mapped_type );
846 $default = call_user_func_array($db->options[
'datatype_map_callback'][$type],
array( &$db, __FUNCTION__, $parameter ));
847 $types[$type] = $default;
862 $types = is_array($types) ? $types :
array( $types );
863 foreach ($types as $key => $type) {
864 if (!isset($this->valid_default_values[$type])) {
866 if (empty($db->options[
'datatype_map'][$type])) {
887 $value = rtrim($value);
892 return intval($value);
894 return !empty($value);
898 return doubleval($value);
907 $this->lobs[] =
array(
912 'resource' => $value,
917 $lob_index = key($this->lobs);
918 $this->lobs[$lob_index][
'lob_index'] = $lob_index;
920 return fopen(
'MDB2LOB://' . $lob_index .
'@' . $this->db_index,
'r+');
923 throw new ilDatabaseException(
'attempt to convert result value to an unknown type :' . $type);
935 if (is_null($value)) {
940 if (!empty($db->options[
'datatype_map'][$type])) {
941 $type = $db->options[
'datatype_map'][$type];
942 if (!empty($db->options[
'datatype_map_callback'][$type])) {
943 $parameter =
array(
'type' => $type,
'value' => $value,
'rtrim' => $rtrim );
945 return call_user_func_array($db->options[
'datatype_map_callback'][$type],
array( &$db, __FUNCTION__, $parameter ));
961 foreach (
$row as $key => $value) {
962 if (empty($types[$key])) {
983 $n_types = count($types);
984 if ($n_cols > $n_types) {
985 for ($i = $n_cols - $n_types; $i >= 0; $i --) {
989 $sorted_types =
array();
991 $sorted_types[$col] = null;
993 foreach ($types as $name => $type) {
994 if (array_key_exists($name, $sorted_types)) {
995 $sorted_types[$name] = $type;
996 unset($types[$name]);
1001 if (count($types)) {
1003 foreach (array_keys($sorted_types) as $k) {
1004 if (is_null($sorted_types[$k])) {
1005 $sorted_types[$k] = current($types);
1011 return $sorted_types;
1025 if (!empty($db->options[
'datatype_map'][$type])) {
1026 $type = $db->options[
'datatype_map'][$type];
1027 if (!empty($db->options[
'datatype_map_callback'][$type])) {
1028 $parameter =
array(
'type' => $type,
'name' => $name,
'field' => $field );
1030 return call_user_func_array($db->options[
'datatype_map_callback'][$type],
array( &$db, __FUNCTION__, $parameter ));
1032 $field[
'type'] = $type;
1035 if (!method_exists($this,
"get{$type}Declaration")) {
1039 return $this->{
"get{$type}Declaration"}($name, $field);
1050 switch ($field[
'type']) {
1052 $length = !empty($field[
'length']) ? $field[
'length'] : $db->options[
'default_text_field_length'];
1053 $fixed = !empty($field[
'fixed']) ? $field[
'fixed'] :
false;
1055 return $fixed ? ($length ?
'CHAR(' . $length .
')' :
'CHAR(' . $db->options[
'default_text_field_length']
1056 .
')') : ($length ?
'VARCHAR(' . $length .
')' :
'TEXT');
1066 return 'CHAR (' . strlen(
'YYYY-MM-DD') .
')';
1068 return 'CHAR (' . strlen(
'HH:MM:SS') .
')';
1070 return 'CHAR (' . strlen(
'YYYY-MM-DD HH:MM:SS') .
')';
1089 $name = $db->quoteIdentifier($name,
true);
1090 $declaration_options = $db->getFieldDefinition()->getDeclarationOptions($field);
1105 if (array_key_exists(
'default', $field)) {
1106 if ($field[
'default'] ===
'') {
1109 if (empty($field[
'notnull'])) {
1110 $field[
'default'] = null;
1115 if ($field[
'default'] ===
'' 1116 && ($db->options[
'portability'] & 32)
1118 $field[
'default'] =
' ';
1121 $default =
' DEFAULT ' . $this->
quote($field[
'default'], $field[
'type']);
1122 } elseif (empty($field[
'notnull'])) {
1123 $default =
' DEFAULT NULL';
1126 $notnull = empty($field[
'notnull']) ?
'' :
' NOT NULL';
1128 if ($field[
'notnull'] ===
false) {
1135 return $charset . $default . $notnull . $collation;
1164 if (!empty($field[
'unsigned'])) {
1167 $db->warnings[] =
"unsigned integer field \"$name\" is being declared as signed integer";
1193 $notnull = empty($field[
'notnull']) ?
'' :
' NOT NULL';
1194 $name = $db->quoteIdentifier($name,
true);
1208 $notnull = empty($field[
'notnull']) ?
'' :
' NOT NULL';
1209 $name = $db->quoteIdentifier($name,
true);
1282 $type = !empty($current[
'type']) ? $current[
'type'] : null;
1284 if (!method_exists($this,
"compare{$type}Definition")) {
1287 if (!empty($db->options[
'datatype_map_callback'][$type])) {
1288 $parameter =
array(
'current' => $current,
'previous' => $previous );
1289 $change = call_user_func_array($db->options[
'datatype_map_callback'][$type],
array( &$db, __FUNCTION__, $parameter ));
1297 if (empty($previous[
'type']) || $previous[
'type'] != $type) {
1301 $change = $this->{
"compare{$type}Definition"}($current, $previous);
1303 if ($previous[
'type'] != $type) {
1304 $change[
'type'] =
true;
1307 $previous_notnull = !empty($previous[
'notnull']) ? $previous[
'notnull'] :
false;
1308 $notnull = !empty($current[
'notnull']) ? $current[
'notnull'] :
false;
1309 if ($previous_notnull != $notnull) {
1310 $change[
'notnull'] =
true;
1313 $previous_default = array_key_exists(
'default', $previous) ? $previous[
'default'] : ($previous_notnull ?
'' : null);
1314 $default = array_key_exists(
'default', $current) ? $current[
'default'] : ($notnull ?
'' : null);
1315 if ($previous_default !== $default) {
1316 $change[
'default'] =
true;
1330 $previous_unsigned = !empty($previous[
'unsigned']) ? $previous[
'unsigned'] :
false;
1331 $unsigned = !empty($current[
'unsigned']) ? $current[
'unsigned'] :
false;
1332 if ($previous_unsigned != $unsigned) {
1333 $change[
'unsigned'] =
true;
1335 $previous_autoincrement = !empty($previous[
'autoincrement']) ? $previous[
'autoincrement'] :
false;
1336 $autoincrement = !empty($current[
'autoincrement']) ? $current[
'autoincrement'] :
false;
1337 if ($previous_autoincrement != $autoincrement) {
1338 $change[
'autoincrement'] =
true;
1352 $previous_length = !empty($previous[
'length']) ? $previous[
'length'] : 0;
1353 $length = !empty($current[
'length']) ? $current[
'length'] : 0;
1354 if ($previous_length != $length) {
1355 $change[
'length'] =
true;
1357 $previous_fixed = !empty($previous[
'fixed']) ? $previous[
'fixed'] : 0;
1358 $fixed = !empty($current[
'fixed']) ? $current[
'fixed'] : 0;
1359 if ($previous_fixed != $fixed) {
1360 $change[
'fixed'] =
true;
1455 public function quote($value, $type = null, $quote =
true, $escape_wildcards =
false) {
1458 return $db->quote($value, $type);
1470 if (is_null($type)) {
1471 switch (gettype($value)) {
1484 $value = serialize($value);
1489 if (preg_match(
'/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $value)) {
1490 $type =
'timestamp';
1491 } elseif (preg_match(
'/^\d{2}:\d{2}$/', $value)) {
1493 } elseif (preg_match(
'/^\d{4}-\d{2}-\d{2}$/', $value)) {
1500 } elseif (!empty($db->options[
'datatype_map'][$type])) {
1501 $type = $db->options[
'datatype_map'][$type];
1502 if (!empty($db->options[
'datatype_map_callback'][$type])) {
1503 $parameter =
array(
'type' => $type,
'value' => $value,
'quote' => $quote,
'escape_wildcards' => $escape_wildcards );
1505 return call_user_func_array($db->options[
'datatype_map_callback'][$type],
array( &$db, __FUNCTION__, $parameter ));
1509 if (!method_exists($this,
"quote{$type}")) {
1512 $value = $this->{
"quote{$type}"}($value, $quote, $escape_wildcards);
1513 if ($quote && $escape_wildcards && $db->string_quoting[
'escape_pattern']
1514 && $db->string_quoting[
'escape'] !== $db->string_quoting[
'escape_pattern']
1540 protected function quoteText($value, $quote, $escape_wildcards) {
1547 $value = $db->escape($value, $escape_wildcards);
1549 return "'" . $value .
"'";
1559 if (preg_match(
'/^(\w+:\/\/)(.*)$/', $value, $match)) {
1561 if ($match[1] ==
'file://') {
1565 #$value = @fopen($value, 'r'); 1568 if (is_resource($value)) {
1573 while (!@feof($fp)) {
1574 $value .= @fread($fp, $db->options[
'lob_buffer_length']);
1591 protected function quoteLOB($value, $quote, $escape_wildcards) {
1594 return $this->
quoteText($value, $quote, $escape_wildcards);
1604 protected function quoteCLOB($value, $quote, $escape_wildcards) {
1605 return $this->
quoteLOB($value, $quote, $escape_wildcards);
1615 protected function quoteBLOB($value, $quote, $escape_wildcards) {
1616 return $this->
quoteLOB($value, $quote, $escape_wildcards);
1627 return ($value ? 1 : 0);
1637 protected function quoteDate($value, $quote, $escape_wildcards) {
1638 if ($value ===
'CURRENT_DATE') {
1641 return 'CURRENT_DATE';
1644 return $this->
quoteText($value, $quote, $escape_wildcards);
1655 if ($value ===
'CURRENT_TIMESTAMP') {
1658 if (isset($db->function) && is_a($db->function,
'MDB2_Driver_Function_Common')) {
1659 return $db->function->now(
'timestamp');
1662 return 'CURRENT_TIMESTAMP';
1665 return $this->
quoteText($value, $quote, $escape_wildcards);
1675 protected function quoteTime($value, $quote, $escape_wildcards) {
1676 if ($value ===
'CURRENT_TIME') {
1679 if (isset($db->function) && is_a($db->function,
'MDB2_Driver_Function_Common')) {
1680 return $db->function->now(
'time');
1683 return 'CURRENT_TIME';
1686 return $this->
quoteText($value, $quote, $escape_wildcards);
1696 protected function quoteFloat($value, $quote, $escape_wildcards) {
1697 if (preg_match(
'/^(.*)e([-+])(\d+)$/i', $value, $matches)) {
1698 $decimal = $this->
quoteDecimal($matches[1], $quote, $escape_wildcards);
1699 $sign = $matches[2];
1700 $exponent = str_pad($matches[3], 2,
'0', STR_PAD_LEFT);
1701 $value = $decimal .
'E' . $sign . $exponent;
1703 $value = $this->
quoteDecimal($value, $quote, $escape_wildcards);
1718 $value = preg_replace(
'/[^\d\.,\-+eE]/',
'', $value);
1719 if (preg_match(
'/[^.0-9]/', $value)) {
1720 if (strpos($value,
',')) {
1722 if (!strpos($value,
'.')) {
1724 $value = strrev(str_replace(
',',
'.', strrev($value)));
1726 } elseif (strpos($value,
'.') && strpos($value,
'.') < strpos($value,
',')) {
1727 $value = str_replace(
'.',
'', $value);
1729 $value = strrev(str_replace(
',',
'.', strrev($value)));
1732 $value = str_replace(
',',
'', $value);
1750 if (preg_match(
'/^(\w+:\/\/)(.*)$/',
$file, $match)) {
1751 if ($match[1] ==
'file://') {
1756 $fp = @fopen(
$file,
'wb');
1757 while (!@feof($lob)) {
1758 $result = @fread($lob, $db->options[
'lob_buffer_length']);
1777 if (is_null($lob[
'value'])) {
1778 $lob[
'value'] = $lob[
'resource'];
1780 $lob[
'loaded'] =
true;
1792 return substr($lob[
'value'], $lob[
'position'], $length);
1801 return $lob[
'endOfLOB'];
1810 $lob_data = stream_get_meta_data($lob);
1811 $lob_index = $lob_data[
'wrapper_data']->lob_index;
1813 if (isset($this->lobs[$lob_index])) {
1815 unset($this->lobs[$lob_index]);
1838 if (!is_array($array) || empty($array)) {
1842 foreach ($array as $value) {
1843 $return[] = $this->
quote($value, $type);
1849 return implode(
', ', $return);
1864 if (!is_null($operator)) {
1865 $operator = strtoupper($operator);
1866 switch ($operator) {
1869 if (is_null($field)) {
1870 throw new ilDatabaseException(
'case insensitive LIKE matching requires passing the field name');
1872 $db->loadModule(
'Function', null,
true);
1873 $match = $db->function->lower($field) .
' LIKE ';
1877 $match = is_null($field) ?
'LIKE ' : $field .
' LIKE ';
1884 foreach ($pattern as $key => $value) {
1888 if ($operator ===
'ILIKE') {
1889 $value = strtolower($value);
1891 $escaped = $db->escape($value);
1892 $match .= $db->escapePattern($escaped);
1916 $db_type = strtok($field[
'type'],
'(), ');
1917 if (!empty($db->options[
'nativetype_map_callback'][$db_type])) {
1918 return call_user_func_array($db->options[
'nativetype_map_callback'][$db_type],
array( $db, $field ));
1940 if (!empty($db->options[
'datatype_map'][$type])) {
1941 $type = $db->options[
'datatype_map'][$type];
1942 if (!empty($db->options[
'datatype_map_callback'][$type])) {
1943 $parameter =
array(
'type' => $type );
1945 return call_user_func_array($db->options[
'datatype_map_callback'][$type],
array( &$db, __FUNCTION__, $parameter ));
compareCLOBDefinition($current, $previous)
const MDB2_OK(!class_exists('PEAR'))
The method mapErrorCode in each MDB2_dbtype implementation maps native error codes to one of these...
compareTimestampDefinition($current, $previous)
setAllowedAttributes($allowed_attributes)
quoteDate($value, $quote, $escape_wildcards)
getDateDeclaration($name, $field)
quote($value, $type=null, $quote=true, $escape_wildcards=false)
isAllowedAttribute($attribute, $type)
baseConvertResult($value, $type, $rtrim=true)
quoteLOB($value, $quote, $escape_wildcards)
quoteInteger($value, $quote, $escape_wildcards)
implodeArray($array, $type=false)
const MDB2_PORTABILITY_EMPTY_TO_NULL
Portability: convert empty values to null strings in data output by query*() and fetch*().
quoteTimestamp($value, $quote, $escape_wildcards)
compareBLOBDefinition($current, $previous)
Class ilDBPdoFieldDefinition.
quoteDecimal($value, $quote, $escape_wildcards)
compareBooleanDefinition($current, $previous)
compareFloatDefinition($current, $previous)
const DEFINITION_COLUMN_NAME
getCLOBDeclaration($name, $field)
Add rich text string
The name of the decorator.
getFloatDeclaration($name, $field)
mapNativeDatatype($field)
getCharsetFieldDeclaration($charset)
getDecimalDeclaration($name, $field)
Class ilDatabaseException.
getDeclaration($type, $name, $field)
checkColumnDefinition($a_def)
compareDateDefinition($current, $previous)
writeLOBToFile($lob, $file)
setReservedMysql($reserved_mysql)
getTypeDeclaration($field)
compareTextDefinition($current, $previous)
quoteFloat($value, $quote, $escape_wildcards)
checkTableName($table_name)
getTimeDeclaration($name, $field)
matchPattern($pattern, $operator=null, $field=null)
mapPrepareDatatype($type)
const DEFAULT_DECIMAL_PLACES
Create styles array
The data for the language used.
setReservedPostgres($reserved_postgres)
const SEQUENCE_COLUMNS_NAME
quoteCLOB($value, $quote, $escape_wildcards)
quoteBoolean($value, $quote, $escape_wildcards)
quoteText($value, $quote, $escape_wildcards)
setReservedOracle($reserved_oracle)
getBLOBDeclaration($name, $field)
getIntegerDeclaration($name, $field)
getDeclarationOptions($field)
destroyLOBInternal(&$lob)
compareDefinition($current, $previous)
getInternalDeclaration($name, $field)
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
getCollationFieldDeclaration($collation)
getTextDeclaration($name, $field)
quoteBLOB($value, $quote, $escape_wildcards)
compareIntegerDefinition($current, $previous)
quoteTime($value, $quote, $escape_wildcards)
getTimestampDeclaration($name, $field)
sortResultFieldTypes($columns, $types)
__construct(\ilDBInterface $ilDBInterface)
ilDBPdoFieldDefinition constructor.
convertResultRow($types, $row, $rtrim=true)
const DEFINITION_TABLE_NAME
getBooleanDeclaration($name, $field)
compareTimeDefinition($current, $previous)
setMaxLength($max_length)
checkColumnName($column_name)
mapNativeDatatypeInternal($field)
convertResult($value, $type, $rtrim=true)
compareDecimalDefinition($current, $previous)
const DEFAULT_TEXT_LENGTH
setAvailableTypes($available_types)