/** * {@inheritdoc} */ public function abstractType() { if (!empty($this->enumValues)) { return 'enum'; } return parent::abstractType(); }
/** * Cast default value based on column type. Required to prevent conflicts when not nullable * column added to existed table with data in. * * @param AbstractTable $table * @param AbstractColumn $column * @return bool|float|int|mixed|string */ private function castDefault(AbstractTable $table, AbstractColumn $column) { if ($column->abstractType() == 'timestamp' || $column->abstractType() == 'datetime') { $driver = $table->driver(); return $driver::DEFAULT_DATETIME; } if ($column->abstractType() == 'enum') { //We can use first enum value as default return $column->getEnumValues()[0]; } switch ($column->phpType()) { case 'int': return 0; break; case 'float': return 0.0; break; case 'bool': return false; break; } return ''; }
/** * Generate set of altering operations should be applied to column to change it's type, size, * default value or null flag. * * @param AbstractColumn $original * @return array */ public function alteringOperations(AbstractColumn $original) { $operations = []; $typeDefinition = [$this->type, $this->size, $this->precision, $this->scale]; $originalType = [$original->type, $original->size, $original->precision, $original->scale]; if ($typeDefinition != $originalType) { if ($this->abstractType() == 'enum') { //Getting longest value $enumSize = $this->size; foreach ($this->enumValues as $value) { $enumSize = max($enumSize, strlen($value)); } $type = "ALTER COLUMN {$this->getName(true)} TYPE character({$enumSize})"; $operations[] = $type; } else { $type = "ALTER COLUMN {$this->getName(true)} TYPE {$this->type}"; if (!empty($this->size)) { $type .= "({$this->size})"; } elseif (!empty($this->precision)) { $type .= "({$this->precision}, {$this->scale})"; } //Required to perform cross conversion $operations[] = "{$type} USING {$this->getName(true)}::{$this->type}"; } } if ($original->abstractType() == 'enum' && !empty($this->enumConstraint)) { $operations[] = 'DROP CONSTRAINT ' . $this->enumConstraint(true); } if ($original->defaultValue != $this->defaultValue) { if (is_null($this->defaultValue)) { $operations[] = "ALTER COLUMN {$this->getName(true)} DROP DEFAULT"; } else { $operations[] = "ALTER COLUMN {$this->getName(true)} SET DEFAULT {$this->prepareDefault()}"; } } if ($original->nullable != $this->nullable) { $operations[] = "ALTER COLUMN {$this->getName(true)} " . (!$this->nullable ? 'SET' : 'DROP') . " NOT NULL"; } if ($this->abstractType() == 'enum') { $enumValues = []; foreach ($this->enumValues as $value) { $enumValues[] = $this->table->driver()->getPDO()->quote($value); } $operations[] = "ADD CONSTRAINT {$this->enumConstraint(true)} " . "CHECK ({$this->getName(true)} IN (" . join(', ', $enumValues) . "))"; } return $operations; }
/** * Resolve correct abstract type to represent inner or outer key. Primary types will be * converted to appropriate sized integers. * * @param AbstractColumn $column * @return string */ protected function resolveAbstract(AbstractColumn $column) { switch ($column->abstractType()) { case 'bigPrimary': return 'bigInteger'; case 'primary': return 'integer'; default: //Not primary key return $column->abstractType(); } }