94 return isset(self::$types[
$type]);
106 public function getLength($charWidth, $maxLength =
null)
108 $length = $maxLength ?? intval($this->length);
130 if (isset($fixed[$this->type]))
134 if ($this->type ===
'BINARY')
138 if ($this->type ===
'VARBINARY')
142 if ($this->type ===
'TINYBLOB' || $this->type ===
'TINYTEXT')
144 return (
$length ?: pow(2, 8)) + 1;
146 if ($this->type ===
'BLOB' || $this->type ===
'TEXT')
148 return (
$length ?: pow(2, 16)) + 2;
150 if ($this->type ===
'MEDIUMBLOB' || $this->type ===
'MEDIUMTEXT')
152 return (
$length ?: pow(2, 24)) + 3;
154 if ($this->type ===
'LONGBLOB' || $this->type ===
'LONGTEXT')
156 return (
$length ?: pow(2, 32)) + 3;
158 if ($this->type ===
'CHAR')
162 if ($this->type ===
'VARCHAR')
182 $columnName = $tokenizer->getCurrentToken()->text;
184 $tokenizer->nextToken();
185 $tokenizer->skipWhiteSpace();
186 $token = $tokenizer->getCurrentToken();
187 if ($token->upper ===
'RESTART')
191 $tokenizer->nextToken();
196 $columnType = $token->upper;
197 if (!self::checkType($columnType))
199 throw new NotSupportedException(
'column type expected but [' . $tokenizer->getCurrentToken()->text .
'] found. line: ' . $tokenizer->getCurrentToken()->line);
202 $column =
new self($columnName);
207 $column->type = $columnType;
209 $level = $token->level;
211 $columnDefinition =
'';
214 if ($token->level == $level && $token->text ===
',')
218 if ($token->level < $level && $token->text ===
')')
223 $columnDefinition .= $token->text;
225 if ($token->upper ===
'NOT')
227 $column->nullable =
false;
229 elseif ($token->upper ===
'DEFAULT')
231 $column->default =
false;
233 elseif ($token->upper ===
'UNSIGNED')
235 $column->unsigned =
true;
237 elseif ($token->upper ===
'PRECISION')
239 $column->typeAddition = $token->upper;
241 elseif ($token->upper ===
'VARYING')
243 $column->typeAddition = $token->upper;
245 elseif ($token->upper ===
'PRIMARY')
248 $constraint->columns[] = $column->name;
249 $constraint->
setBody(
'PRIMARY KEY (' . $column->name .
')');
250 $constraint->setParent($column->parent);
251 $column->parent->constraints->add($constraint);
253 elseif ($column->default ===
false)
257 $column->default = $token->text;
261 $token = $tokenizer->nextToken();
264 if ($lengthLevel == -1)
266 if ($token->text ===
'(')
268 if ($column->type ===
'ENUM')
270 $lengthLevel = $token->level;
273 $columnDefinition .= $token->text;
275 $token = $tokenizer->nextToken();
277 if ($token->level === $lengthLevel && $token->text ===
')')
284 $column->enum[] = trim($token->text,
"'");
288 $column->enum[] = trim($token->text,
'"');
294 $lengthLevel = $token->level;
297 $columnDefinition .= $token->text;
299 $token = $tokenizer->nextToken();
301 if ($token->level === $lengthLevel && $token->text ===
')')
308 if (!$column->length)
310 $column->length = (int)$token->text;
314 $column->precision = (int)$token->text;
328 $column->setBody($columnDefinition);
340 return ($this->
unsigned ?
'UNSIGNED ' :
'')
342 . ($this->typeAddition ?
' ' . $this->typeAddition :
'')
343 . ($this->length !==
'' ?
'(' . $this->length . ($this->precision !== 0 ?
',' . $this->precision :
'') .
')' :
'');
359 return 'ALTER TABLE ' . $this->parent->name .
' ADD ' . $this->name .
' ' .
$this->body;
361 return 'ALTER TABLE ' . $this->parent->name .
' ADD COLUMN ' . $this->name .
' ' .
$this->body;
363 return 'ALTER TABLE ' . $this->parent->name .
' ADD (' . $this->name .
' ' . $this->body .
')';
365 return '// ' . get_class($this) .
':getCreateDdl for database type [' .
$dbType .
'] not implemented';
381 return 'ALTER TABLE ' . $this->parent->name .
' DROP ' .
$this->name;
384 return 'ALTER TABLE ' . $this->parent->name .
' DROP COLUMN ' .
$this->name;
386 return 'ALTER TABLE ' . $this->parent->name .
' DROP (' . $this->name .
')';
388 return '// ' . get_class($this) .
':getDropDdl for database type [' .
$dbType .
'] not implemented';
408 return 'ALTER TABLE ' . $this->parent->name .
' CHANGE ' . $this->name .
' ' . $target->name .
' ' . $target->body;
410 $defaultDropped =
false;
413 $targetType = $target->getDdlType();
414 if ($sourceType !== $targetType)
416 $alter[] =
'ALTER COLUMN ' . $this->name .
' DROP DEFAULT';
417 $defaultDropped =
true;
418 $alter[] =
'ALTER COLUMN ' . $this->name .
' TYPE ' . $targetType;
421 if ($this->
default ===
null)
423 if ($target->default !==
null)
425 $alter[] =
'ALTER COLUMN ' . $this->name .
' SET DEFAULT ' . $target->default;
430 if ($target->default ===
null)
432 if (!$defaultDropped)
434 $alter[] =
'ALTER COLUMN ' . $this->name .
' DROP DEFAULT';
437 elseif ($this->
default != $target->default)
439 $alter[] =
'ALTER COLUMN ' . $this->name .
' SET DEFAULT ' . $target->default;
443 if ($this->nullable != $target->nullable)
445 $alter[] =
'ALTER COLUMN ' . $this->name .
' ' . ($target->nullable ?
'DROP' :
'SET') .
' NOT NULL ';
450 return 'ALTER TABLE ' . $this->parent->name .
' ' . implode(
', ', $alter);
454 return '// ' . get_class($this) .
':getModifyDdl for database type [' .
$dbType .
'] not implemented. Change requested from [' . $this->body .
'] to [' . $target->body .
'].';
457 if ($this->nullable !== $target->nullable)
459 $nullDdl = ($target->nullable ?
' NULL' :
' NOT NULL');
467 $this->type === $target->type
468 && $this->default === $target->default
470 intval($this->length) < intval($target->length)
472 intval($target->length) < intval($this->length)
473 && mb_strtoupper($this->type) ===
'CHAR'
480 foreach ($this->parent->indexes->getList() as $index)
482 if (in_array($this->name, $index->columns,
true))
484 $sql[] = $index->getDropDdl(
$dbType);
487 $sql[] =
'ALTER TABLE ' . $this->parent->name .
' ALTER COLUMN ' . $this->name .
' ' . $target->body . $nullDdl;
488 foreach ($this->parent->indexes->getList() as $index)
490 if (in_array($this->name, $index->columns,
true))
492 $sql[] = $index->getCreateDdl(
$dbType);
498 $this->type === $target->type
499 && $this->default === $target->default
500 && intval($this->length) === intval($target->length)
501 && $this->nullable !== $target->nullable
504 return 'ALTER TABLE ' . $this->parent->name .
' ALTER COLUMN ' . $this->name .
' ' . $target->body;
508 return '// ' . get_class($this) .
':getModifyDdl for database type [' .
$dbType .
"] not implemented. Change requested from [${this}->body] to [${target}->body].";
512 $this->type === $target->type
513 && $this->default === $target->default
515 intval($this->length) < intval($target->length)
517 intval($target->length) < intval($this->length)
518 && mb_strtoupper($this->type) ===
'CHAR'
523 return 'ALTER TABLE ' . $this->parent->name .
' MODIFY (' . $this->name .
' ' . $target->type .
'(' . $target->length .
')' .
')';
526 $this->type === $target->type
527 && $this->default === $target->default
528 && intval($this->length) === intval($target->length)
529 && $this->nullable !== $target->nullable
534 l_nullable varchar2(1);
536 select nullable into l_nullable
537 from user_tab_columns
538 where table_name = '" . $this->parent->name .
"'
539 and column_name = '" . $this->name .
"';
540 if l_nullable = '" . ($target->nullable ?
'N' :
'Y') .
"' then
541 execute immediate 'alter table " . $this->parent->name .
' modify (' . $this->name .
' ' . ($target->nullable ?
'NULL' :
'NOT NULL') .
")';
548 return '// ' . get_class($this) .
':getModifyDdl for database type [' .
$dbType .
"] not implemented. Change requested from [${this}->body] to [${target}->body].";
551 return '// ' . get_class($this) .
':getModifyDdl for database type [' .
$dbType .
"] not implemented. Change requested from [${this}->body] to [${target}->body].";
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)