static function generateFieldSpec($name, $type, $length = '', $attribute = '', $collation = '', $null = false, $default_type = 'USER_DEFINED', $default_value = '', $extra = '', $comment = '', $virtuality = '', $expression = '', $move_to = '')
{
$is_timestamp = mb_strpos(mb_strtoupper($type), 'TIMESTAMP') !== false;
$query = Util::backquote($name) . ' ' . $type;
// allow the possibility of a length for TIME, DATETIME and TIMESTAMP
// (will work on MySQL >= 5.6.4)
//
// MySQL permits a non-standard syntax for FLOAT and DOUBLE,
// see https://dev.mysql.com/doc/refman/5.5/en/floating-point-types.html
//
$pattern = '@^(DATE|TINYBLOB|TINYTEXT|BLOB|TEXT|' . 'MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT|SERIAL|BOOLEAN|UUID)$@i';
if (strlen($length) !== 0 && !preg_match($pattern, $type)) {
// Note: The variable $length here can contain several other things
// besides length - ENUM/SET value or length of DECIMAL (eg. 12,3)
// so we can't just convert it to integer
$query .= '(' . $length . ')';
}
if ($virtuality) {
$query .= ' AS (' . $expression . ') ' . $virtuality;
} else {
if ($attribute != '') {
$query .= ' ' . $attribute;
if ($is_timestamp && preg_match('/TIMESTAMP/i', $attribute) && $length !== 0) {
$query .= '(' . $length . ')';
}
}
$matches = preg_match('@^(TINYTEXT|TEXT|MEDIUMTEXT|LONGTEXT|VARCHAR|CHAR|ENUM|SET)$@i', $type);
if (!empty($collation) && $collation != 'NULL' && $matches) {
$query .= Util::getCharsetQueryPart($collation, true);
}
if ($null !== false) {
if ($null == 'NULL') {
$query .= ' NULL';
} else {
$query .= ' NOT NULL';
}
}
switch ($default_type) {
case 'USER_DEFINED':
if ($is_timestamp && $default_value === '0') {
// a TIMESTAMP does not accept DEFAULT '0'
// but DEFAULT 0 works
$query .= ' DEFAULT 0';
} elseif ($type == 'BIT') {
$query .= ' DEFAULT b\'' . preg_replace('/[^01]/', '0', $default_value) . '\'';
} elseif ($type == 'BOOLEAN') {
if (preg_match('/^1|T|TRUE|YES$/i', $default_value)) {
$query .= ' DEFAULT TRUE';
} elseif (preg_match('/^0|F|FALSE|NO$/i', $default_value)) {
$query .= ' DEFAULT FALSE';
} else {
// Invalid BOOLEAN value
$query .= ' DEFAULT \'' . $GLOBALS['dbi']->escapeString($default_value) . '\'';
}
} elseif ($type == 'BINARY' || $type == 'VARBINARY') {
$query .= ' DEFAULT 0x' . $default_value;
} else {
$query .= ' DEFAULT \'' . $GLOBALS['dbi']->escapeString($default_value) . '\'';
}
break;
/** @noinspection PhpMissingBreakStatementInspection */
/** @noinspection PhpMissingBreakStatementInspection */
case 'NULL':
// If user uncheck null checkbox and not change default value null,
// default value will be ignored.
if ($null !== false && $null !== 'NULL') {
break;
}
// else fall-through intended, no break here
// else fall-through intended, no break here
case 'CURRENT_TIMESTAMP':
$query .= ' DEFAULT ' . $default_type;
if ($length !== 0 && $is_timestamp) {
$query .= '(' . $length . ')';
}
break;
case 'NONE':
default:
break;
}
if (!empty($extra)) {
$query .= ' ' . $extra;
}
}
if (!empty($comment)) {
$query .= " COMMENT '" . $GLOBALS['dbi']->escapeString($comment) . "'";
}
// move column
if ($move_to == '-first') {
// dash can't appear as part of column name
$query .= ' FIRST';
} elseif ($move_to != '') {
$query .= ' AFTER ' . Util::backquote($move_to);
}
return $query;
}