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 ),
164 "CONSTRAINT_CATALOG",
278 "GEOMETRYCOLLECTION",
367 "MASTER_AUTO_POSITION",
369 "MASTER_CONNECT_RETRY",
371 "MASTER_HEARTBEAT_PERIOD",
377 "MASTER_RETRY_COUNT",
385 "MASTER_SSL_CRLPATH",
387 "MASTER_SSL_VERIFY_SERVER_CERT",
388 "MASTER_TLS_VERSION",
392 "MAX_CONNECTIONS_PER_HOUR",
393 "MAX_QUERIES_PER_HOUR",
396 "MAX_STATEMENT_TIME",
397 "MAX_UPDATES_PER_HOUR",
398 "MAX_USER_CONNECTIONS",
410 "MINUTE_MICROSECOND",
439 "NO_WRITE_TO_BINLOG",
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",
557 "SECOND_MICROSECOND",
589 "SQL_AFTER_MTS_GAPS",
594 "SQL_CALC_FOUND_ROWS",
613 "STATS_SAMPLE_PAGES",
937 $this->db_instance = $ilDBInterface;
946 if (!$this->query_utils) {
963 'timestamp' =>
'1970-01-01 00:00:00',
964 'time' =>
'00:00:00',
965 'date' =>
'1970-01-01',
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.');
983 throw new ilDatabaseException(
"Invalid table name '" . $table_name .
"' (Reserved Word).");
986 if (strtolower(substr($table_name, 0, 4)) ==
"sys_") {
987 throw new ilDatabaseException(
"Invalid table name '" . $table_name .
"'. Name must not start with 'sys_'.");
990 if (strlen($table_name) > 22) {
991 throw new ilDatabaseException(
"Invalid table name '" . $table_name .
"'. Maximum table identifer length is 22 bytes.");
1078 if (!preg_match(
"/^[a-z]+[_a-z0-9]*$/", $column_name)) {
1080 .
"'. Column name must only contain _a-z0-9 and must start with a-z.");
1084 throw new ilDatabaseException(
"Invalid column name '" . $column_name .
"' (Reserved Word).");
1087 if (strtolower(substr($column_name, 0, 4)) ==
"sys_") {
1088 throw new ilDatabaseException(
"Invalid column name '" . $column_name .
"'. Name must not start with 'sys_'.");
1091 if (strlen($column_name) > 30) {
1092 throw new ilDatabaseException(
"Invalid column name '" . $column_name .
"'. Maximum column identifer length is 30 bytes.");
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.");
1114 if (strlen($a_name) > 3) {
1115 throw new ilDatabaseException(
"Invalid index name '" . $a_name .
"'. Maximum index identifer length is 3 bytes.");
1131 switch ($a_def[
"type"]) {
1133 throw new ilDatabaseException(
"Invalid column type '" . $a_def[
"type"] .
"'. Use integer(1) instead.");
1137 throw new ilDatabaseException(
"Invalid column type '" . $a_def[
"type"] .
"'. Use float or integer instead.");
1141 throw new ilDatabaseException(
"Invalid column type '" . $a_def[
"type"] .
"'. Allowed types are: " 1148 foreach ($a_def as $k => $v) {
1150 throw new ilDatabaseException(
"Attribute '" . $k .
"' is not allowed for column type '" . $a_def[
"type"] .
"'.");
1156 switch ($a_def[
"type"]) {
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 <= " 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).");
1173 if ($a_def[
"unsigned"]) {
1190 return in_array($attribute, $this->allowed_attributes[
$type]);
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;
1288 $types = is_array($types) ? $types :
array( $types );
1290 if (!isset($this->valid_default_values[
$type])) {
1292 if (empty($db->options[
'datatype_map'][$type])) {
1314 $value = rtrim($value);
1319 return intval($value);
1321 return !empty($value);
1325 return doubleval($value);
1334 $this->lobs[] =
array(
1337 'lob_index' => null,
1338 'endOfLOB' =>
false,
1339 'resource' => $value,
1344 $lob_index = key($this->lobs);
1345 $this->lobs[$lob_index][
'lob_index'] = $lob_index;
1347 return fopen(
'MDB2LOB://' . $lob_index .
'@' . $this->db_index,
'r+');
1363 if (is_null($value)) {
1368 if (!empty($db->options[
'datatype_map'][
$type])) {
1370 if (!empty($db->options[
'datatype_map_callback'][
$type])) {
1371 $parameter =
array(
'type' =>
$type,
'value' => $value,
'rtrim' => $rtrim );
1373 return call_user_func_array($db->options[
'datatype_map_callback'][
$type],
array( &$db, __FUNCTION__, $parameter ));
1391 if (empty($types[
$key])) {
1413 $n_types = count($types);
1414 if ($n_cols > $n_types) {
1415 for (
$i = $n_cols - $n_types;
$i >= 0;
$i--) {
1419 $sorted_types =
array();
1421 $sorted_types[$col] = null;
1424 if (array_key_exists(
$name, $sorted_types)) {
1426 unset($types[
$name]);
1431 if (count($types)) {
1433 foreach (array_keys($sorted_types) as $k) {
1434 if (is_null($sorted_types[$k])) {
1435 $sorted_types[$k] = current($types);
1441 return $sorted_types;
1456 if (!empty($db->options[
'datatype_map'][
$type])) {
1458 if (!empty($db->options[
'datatype_map_callback'][
$type])) {
1459 $parameter =
array(
'type' =>
$type,
'name' =>
$name,
'field' => $field );
1461 return call_user_func_array($db->options[
'datatype_map_callback'][
$type],
array( &$db, __FUNCTION__, $parameter ));
1463 $field[
'type'] =
$type;
1466 if (!method_exists($this,
"get{$type}Declaration")) {
1470 return $this->{
"get{$type}Declaration"}(
$name, $field);
1482 switch ($field[
'type']) {
1484 $length = !empty($field[
'length']) ? $field[
'length'] : $db->options[
'default_text_field_length'];
1485 $fixed = !empty($field[
'fixed']) ? $field[
'fixed'] :
false;
1487 return $fixed ? ($length ?
'CHAR(' . $length .
')' :
'CHAR(' . $db->options[
'default_text_field_length']
1488 .
')') : ($length ?
'VARCHAR(' . $length .
')' :
'TEXT');
1498 return 'CHAR (' . strlen(
'YYYY-MM-DD') .
')';
1500 return 'CHAR (' . strlen(
'HH:MM:SS') .
')';
1502 return 'CHAR (' . strlen(
'YYYY-MM-DD HH:MM:SS') .
')';
1523 $declaration_options = $db->getFieldDefinition()->getDeclarationOptions($field);
1539 if (array_key_exists(
'default', $field)) {
1540 if ($field[
'default'] ===
'') {
1543 if (empty($field[
'notnull'])) {
1544 $field[
'default'] = null;
1549 if ($field[
'default'] ===
'' 1550 && ($db->options[
'portability'] & 32)
1552 $field[
'default'] =
' ';
1555 $default =
' DEFAULT ' . $this->
quote($field[
'default'], $field[
'type']);
1556 } elseif (empty($field[
'notnull'])) {
1557 $default =
' DEFAULT NULL';
1560 $notnull = empty($field[
'notnull']) ?
'' :
' NOT NULL';
1562 if ($field[
'notnull'] ===
false) {
1569 return $charset . $default . $notnull . $collation;
1601 if (!empty($field[
'unsigned'])) {
1604 $db->warnings[] =
"unsigned integer field \"$name\" is being declared as signed integer";
1632 $notnull = empty($field[
'notnull']) ?
'' :
' NOT NULL';
1648 $notnull = empty($field[
'notnull']) ?
'' :
' NOT NULL';
1731 if (!method_exists($this,
"compare{$type}Definition")) {
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 ));
1744 if (empty($previous[
'type']) || $previous[
'type'] !=
$type) {
1748 $change = $this->{
"compare{$type}Definition"}(
$current, $previous);
1750 if ($previous[
'type'] !=
$type) {
1751 $change[
'type'] =
true;
1754 $previous_notnull = !empty($previous[
'notnull']) ? $previous[
'notnull'] :
false;
1756 if ($previous_notnull != $notnull) {
1757 $change[
'notnull'] =
true;
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;
1778 $previous_unsigned = !empty($previous[
'unsigned']) ? $previous[
'unsigned'] :
false;
1780 if ($previous_unsigned != $unsigned) {
1781 $change[
'unsigned'] =
true;
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;
1801 $previous_length = !empty($previous[
'length']) ? $previous[
'length'] : 0;
1803 if ($previous_length != $length) {
1804 $change[
'length'] =
true;
1806 $previous_fixed = !empty($previous[
'fixed']) ? $previous[
'fixed'] : 0;
1808 if ($previous_fixed != $fixed) {
1809 $change[
'fixed'] =
true;
1912 public function quote($value,
$type = null, $quote =
true, $escape_wildcards =
false)
1916 return $db->quote($value,
$type);
1928 if (is_null(
$type)) {
1929 switch (gettype($value)) {
1942 $value = serialize($value);
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)) {
1952 } elseif (preg_match(
'/^\d{4}-\d{2}-\d{2}$/', $value)) {
1959 } elseif (!empty($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 );
1964 return call_user_func_array($db->options[
'datatype_map_callback'][
$type],
array( &$db, __FUNCTION__, $parameter ));
1968 if (!method_exists($this,
"quote{$type}")) {
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']
1990 return (
int) $value;
2000 protected function quoteText($value, $quote, $escape_wildcards)
2008 $value = $db->escape($value, $escape_wildcards);
2010 return "'" . $value .
"'";
2021 if (preg_match(
'/^(\w+:\/\/)(.*)$/', $value, $match)) {
2023 if ($match[1] ==
'file://') {
2027 #$value = @fopen($value, 'r'); 2030 if (is_resource($value)) {
2035 while (!@feof($fp)) {
2036 $value .= @fread($fp, $db->options[
'lob_buffer_length']);
2053 protected function quoteLOB($value, $quote, $escape_wildcards)
2057 return $this->
quoteText($value, $quote, $escape_wildcards);
2067 protected function quoteCLOB($value, $quote, $escape_wildcards)
2069 return $this->
quoteLOB($value, $quote, $escape_wildcards);
2079 protected function quoteBLOB($value, $quote, $escape_wildcards)
2081 return $this->
quoteLOB($value, $quote, $escape_wildcards);
2093 return ($value ? 1 : 0);
2103 protected function quoteDate($value, $quote, $escape_wildcards)
2105 if ($value ===
'CURRENT_DATE') {
2108 return 'CURRENT_DATE';
2111 return $this->
quoteText($value, $quote, $escape_wildcards);
2123 if ($value ===
'CURRENT_TIMESTAMP') {
2126 if (isset($db->function) && is_a($db->function,
'MDB2_Driver_Function_Common')) {
2127 return $db->function->now(
'timestamp');
2130 return 'CURRENT_TIMESTAMP';
2133 return $this->
quoteText($value, $quote, $escape_wildcards);
2143 protected function quoteTime($value, $quote, $escape_wildcards)
2145 if ($value ===
'CURRENT_TIME') {
2148 if (isset($db->function) && is_a($db->function,
'MDB2_Driver_Function_Common')) {
2149 return $db->function->now(
'time');
2152 return 'CURRENT_TIME';
2155 return $this->
quoteText($value, $quote, $escape_wildcards);
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;
2173 $value = $this->
quoteDecimal($value, $quote, $escape_wildcards);
2188 $value = (
string) $value;
2189 $value = preg_replace(
'/[^\d\.,\-+eE]/',
'', $value);
2190 if (preg_match(
'/[^.0-9]/', $value)) {
2191 if (strpos($value,
',')) {
2193 if (!strpos($value,
'.')) {
2195 $value = strrev(str_replace(
',',
'.', strrev($value)));
2197 } elseif (strpos($value,
'.') && strpos($value,
'.') < strpos($value,
',')) {
2198 $value = str_replace(
'.',
'', $value);
2200 $value = strrev(str_replace(
',',
'.', strrev($value)));
2203 $value = str_replace(
',',
'', $value);
2222 if (preg_match(
'/^(\w+:\/\/)(.*)$/',
$file, $match)) {
2223 if ($match[1] ==
'file://') {
2228 $fp = @fopen(
$file,
'wb');
2229 while (!@feof($lob)) {
2230 $result = @fread($lob, $db->options[
'lob_buffer_length']);
2232 if (@fwrite($fp,
$result, $read) != $read) {
2250 if (is_null($lob[
'value'])) {
2251 $lob[
'value'] = $lob[
'resource'];
2253 $lob[
'loaded'] =
true;
2266 return substr($lob[
'value'], $lob[
'position'], $length);
2276 return $lob[
'endOfLOB'];
2286 $lob_data = stream_get_meta_data($lob);
2287 $lob_index = $lob_data[
'wrapper_data']->lob_index;
2289 if (isset($this->lobs[$lob_index])) {
2291 unset($this->lobs[$lob_index]);
2316 if (!is_array($array) || empty($array)) {
2320 foreach ($array as $value) {
2327 return implode(
', ', $return);
2343 if (!is_null($operator)) {
2344 $operator = strtoupper($operator);
2345 switch ($operator) {
2348 if (is_null($field)) {
2349 throw new ilDatabaseException(
'case insensitive LIKE matching requires passing the field name');
2351 $db->loadModule(
'Function', null,
true);
2352 $match = $db->function->lower($field) .
' LIKE ';
2356 $match = is_null($field) ?
'LIKE ' : $field .
' LIKE ';
2363 foreach ($pattern as
$key => $value) {
2367 if ($operator ===
'ILIKE') {
2368 $value = strtolower($value);
2370 $escaped = $db->escape($value);
2371 $match .= $db->escapePattern($escaped);
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 ));
2422 if (!empty($db->options[
'datatype_map'][
$type])) {
2424 if (!empty($db->options[
'datatype_map_callback'][
$type])) {
2427 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)
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)