/** * Checks whether a given column diff is a logically unchanged binary type column. * * Used to determine whether a column alteration for a binary type column can be skipped. * Doctrine's {@link \Doctrine\DBAL\Types\BinaryType} and {@link \Doctrine\DBAL\Types\BlobType} * are mapped to the same database column type on this platform as this platform * does not have a native VARBINARY/BINARY column type. Therefore the {@link \Doctrine\DBAL\Schema\Comparator} * might detect differences for binary type columns which do not have to be propagated * to database as there actually is no difference at database level. * * @param ColumnDiff $columnDiff The column diff to check against. * * @return boolean True if the given column diff is an unchanged binary type column, false otherwise. */ private function isUnchangedBinaryColumn(ColumnDiff $columnDiff) { $columnType = $columnDiff->column->getType(); if (!$columnType instanceof BinaryType && !$columnType instanceof BlobType) { return false; } $fromColumn = $columnDiff->fromColumn instanceof Column ? $columnDiff->fromColumn : null; if ($fromColumn) { $fromColumnType = $fromColumn->getType(); if (!$fromColumnType instanceof BinaryType && !$fromColumnType instanceof BlobType) { return false; } return count(array_diff($columnDiff->changedProperties, array('type', 'length', 'fixed'))) === 0; } if ($columnDiff->hasChanged('type')) { return false; } return count(array_diff($columnDiff->changedProperties, array('length', 'fixed'))) === 0; }
/** * Returns the SQL clause for altering a column in a table alteration. * * This method returns null in case that only the column comment has changed. * Changes in column comments have to be handled differently. * * @param ColumnDiff $columnDiff The diff of the column to alter. * * @return string|null */ protected function getAlterTableChangeColumnClause(ColumnDiff $columnDiff) { $column = $columnDiff->column; // Do not return alter clause if only comment has changed. if (!($columnDiff->hasChanged('comment') && count($columnDiff->changedProperties) === 1)) { $columnAlterationClause = 'ALTER ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); if ($columnDiff->hasChanged('default') && null === $column->getDefault()) { $columnAlterationClause .= ', ALTER ' . $column->getQuotedName($this) . ' DROP DEFAULT'; } return $columnAlterationClause; } }
/** * Checks whether a column alteration requires dropping its default constraint first. * * Different to other database vendors SQL Server implements column default values * as constraints and therefore changes in a column's default value as well as changes * in a column's type require dropping the default constraint first before being to * alter the particular column to the new definition. * * @param ColumnDiff $columnDiff The column diff to evaluate. * * @return boolean True if the column alteration requires dropping its default constraint first, false otherwise. */ private function alterColumnRequiresDropDefaultConstraint(ColumnDiff $columnDiff) { // We can only decide whether to drop an existing default constraint // if we know the original default value. if (!$columnDiff->fromColumn instanceof Column) { return false; } // We only need to drop an existing default constraint if we know the // column was defined with a default value before. if ($columnDiff->fromColumn->getDefault() === null) { return false; } // We need to drop an existing default constraint if the column was // defined with a default value before and it has changed. if ($columnDiff->hasChanged('default')) { return true; } // We need to drop an existing default constraint if the column was // defined with a default value before and the native column type has changed. if ($columnDiff->hasChanged('type') || $columnDiff->hasChanged('fixed')) { return true; } return false; }
/** * Returns the ALTER COLUMN SQL clauses for altering a column described by the given column diff. * * @param ColumnDiff $columnDiff The column diff to evaluate. * * @return array */ private function getAlterColumnClausesSQL(ColumnDiff $columnDiff) { $column = $columnDiff->column->toArray(); $alterClause = 'ALTER COLUMN ' . $columnDiff->column->getQuotedName($this); if ($column['columnDefinition']) { return array($alterClause . ' ' . $column['columnDefinition']); } $clauses = array(); if ($columnDiff->hasChanged('type') || $columnDiff->hasChanged('length') || $columnDiff->hasChanged('precision') || $columnDiff->hasChanged('scale') || $columnDiff->hasChanged('fixed')) { $clauses[] = $alterClause . ' SET DATA TYPE ' . $column['type']->getSQLDeclaration($column, $this); } if ($columnDiff->hasChanged('notnull')) { $clauses[] = $column['notnull'] ? $alterClause . ' SET NOT NULL' : $alterClause . ' DROP NOT NULL'; } if ($columnDiff->hasChanged('default')) { if (isset($column['default'])) { $defaultClause = $this->getDefaultValueDeclarationSQL($column); if ($defaultClause) { $clauses[] = $alterClause . ' SET' . $defaultClause; } } else { $clauses[] = $alterClause . ' DROP DEFAULT'; } } return $clauses; }
/** * Do checks for column diffs. * * @param ColumnDiff $columnDiff * @param IgnoredChange $ignoredChange * * @return boolean */ protected function checkColumnDiff(ColumnDiff $columnDiff, IgnoredChange $ignoredChange) { if (count($columnDiff->changedProperties) !== 1 && !$columnDiff->hasChanged($ignoredChange->getPropertyName())) { return false; } $propertyName = $columnDiff->changedProperties[0]; $before = $columnDiff->fromColumn->getType()->getName(); $after = $columnDiff->column->getType()->getName(); if ($ignoredChange->matches('changedColumns', $propertyName, $before, $after)) { return true; } return false; }
/** * Do checks for column diffs. * * @param ColumnDiff $columnDiff * @param array $alterData * * @return boolean */ protected function checkColumnDiff(ColumnDiff $columnDiff, array $alterData) { if (count($columnDiff->changedProperties) !== 1 && !$columnDiff->hasChanged($alterData['propertyName'])) { return false; } foreach ($alterData['ignoredChanges'] as $keys) { if ($keys['before'] === $columnDiff->fromColumn->getType()->getName() && $keys['after'] === $columnDiff->column->getType()->getName()) { return true; } } return false; }
/** * Returns the SQL clause for altering a column in a table alteration. * * This method returns null in case that only the column comment has changed. * Changes in column comments have to be handled differently. * * @param ColumnDiff $columnDiff The diff of the column to alter. * * @return string|null */ protected function getAlterTableChangeColumnClause(ColumnDiff $columnDiff) { $column = $columnDiff->column; // Do not return alter clause if only comment has changed. if (!($columnDiff->hasChanged('comment') && count($columnDiff->changedProperties) === 1)) { return 'ALTER ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); } }