/** * Compute and return the difference between two column objects * * @param Column $fromColumn * @param Column $toColumn * @return ColumnDiff|boolean return false if the two columns are similar */ public static function computeDiff(Column $fromColumn, Column $toColumn) { if ($changedProperties = self::compareColumns($fromColumn, $toColumn)) { if ($fromColumn->hasPlatform() || $toColumn->hasPlatform()) { $platform = $fromColumn->hasPlatform() ? $fromColumn->getPlatform() : $toColumn->getPlatform(); if ($platform->getColumnDDL($fromColumn) == $platform->getColumnDDl($toColumn)) { return false; } } $columnDiff = new ColumnDiff($fromColumn, $toColumn); $columnDiff->setChangedProperties($changedProperties); return $columnDiff; } return false; }
/** * Builds the DDL SQL to modify a column * * @return string */ public function getModifyColumnDDL(ColumnDiff $columnDiff) { return $this->getChangeColumnDDL($columnDiff->getFromColumn(), $columnDiff->getToColumn()); }
/** * Overrides the implementation from DefaultPlatform * * @author Niklas Närhinen <*****@*****.**> * @return string * @see DefaultPlatform::getModifyColumnDDL */ public function getModifyColumnDDL(ColumnDiff $columnDiff) { $ret = ''; $changedProperties = $columnDiff->getChangedProperties(); $toColumn = $columnDiff->getToColumn(); $table = $toColumn->getTable(); $colName = $this->quoteIdentifier($toColumn->getName()); $pattern = "\nALTER TABLE %s ALTER COLUMN %s;\n"; foreach ($changedProperties as $key => $property) { switch ($key) { case 'defaultValueType': continue; case 'size': case 'type': case 'scale': $sqlType = $toColumn->getDomain()->getSqlType(); if ($toColumn->isAutoIncrement() && $table && $table->getIdMethodParameters() == null) { $sqlType = $toColumn->getType() === PropelTypes::BIGINT ? 'bigserial' : 'serial'; } if ($this->hasSize($sqlType)) { $sqlType .= $toColumn->getDomain()->printSize(); } $ret .= sprintf($pattern, $this->quoteIdentifier($table->getName()), $colName . ' TYPE ' . $sqlType); break; case 'defaultValueValue': if ($property[0] !== null && $property[1] === null) { $ret .= sprintf($pattern, $this->quoteIdentifier($table->getName()), $colName . ' DROP DEFAULT'); } else { $ret .= sprintf($pattern, $this->quoteIdentifier($table->getName()), $colName . ' SET ' . $this->getColumnDefaultValueDDL($toColumn)); } break; case 'notNull': $notNull = " DROP NOT NULL"; if ($property[1]) { $notNull = " SET NOT NULL"; } $ret .= sprintf($pattern, $this->quoteIdentifier($table->getName()), $colName . $notNull); break; } } return $ret; }
/** * Builds the DDL SQL to modify a column * * @return string */ public function getModifyColumnDDL(ColumnDiff $columnDiff) { $toColumn = $columnDiff->getToColumn(); $pattern = "\nALTER TABLE %s MODIFY %s;\n"; return sprintf($pattern, $this->quoteIdentifier($toColumn->getTable()->getName()), $this->getColumnDDL($toColumn)); }
public function testReverseDiffHasModifiedColumns() { $c1 = new Column('title', 'varchar', 50); $c2 = new Column('title', 'varchar', 100); $columnDiff = new ColumnDiff($c1, $c2); $reverseColumnDiff = $columnDiff->getReverseDiff(); $diff = $this->createTableDiff(); $diff->addModifiedColumn('title', $columnDiff); $reverseDiff = $diff->getReverseDiff(); $this->assertTrue($reverseDiff->hasModifiedColumns()); $this->assertEquals(['title' => $reverseColumnDiff], $reverseDiff->getModifiedColumns()); }
/** * Overrides the implementation from DefaultPlatform * * @author Niklas Närhinen <*****@*****.**> * @return string * @see DefaultPlatform::getModifyColumnDDL */ public function getModifyColumnDDL(ColumnDiff $columnDiff) { $ret = ''; $changedProperties = $columnDiff->getChangedProperties(); $fromColumn = $columnDiff->getFromColumn(); $toColumn = clone $columnDiff->getToColumn(); $fromTable = $fromColumn->getTable(); $table = $toColumn->getTable(); $colName = $this->quoteIdentifier($toColumn->getName()); $pattern = "\nALTER TABLE %s ALTER COLUMN %s;\n"; if (isset($changedProperties['autoIncrement'])) { $tableName = $table->getName(); $colPlainName = $toColumn->getName(); $seqName = "{$tableName}_{$colPlainName}_seq"; if ($toColumn->isAutoIncrement() && $table && $table->getIdMethodParameters() == null) { $defaultValue = "nextval('{$seqName}'::regclass)"; $toColumn->setDefaultValue($defaultValue); $changedProperties['defaultValueValue'] = [null, $defaultValue]; //add sequence if (!$fromTable->getDatabase()->hasSequence($seqName)) { $this->createOrDropSequences .= sprintf("\nCREATE SEQUENCE %s;\n", $seqName); $fromTable->getDatabase()->addSequence($seqName); } } if (!$toColumn->isAutoIncrement() && $fromColumn->isAutoIncrement()) { $changedProperties['defaultValueValue'] = [$fromColumn->getDefaultValueString(), null]; $toColumn->setDefaultValue(null); //remove sequence if ($fromTable->getDatabase()->hasSequence($seqName)) { $this->createOrDropSequences .= sprintf("\nDROP SEQUENCE %s CASCADE;\n", $seqName); $fromTable->getDatabase()->removeSequence($seqName); } } } if (isset($changedProperties['size']) || isset($changedProperties['type']) || isset($changedProperties['scale'])) { $sqlType = $toColumn->getDomain()->getSqlType(); if ($this->hasSize($sqlType) && $toColumn->isDefaultSqlType($this)) { if ($this->isNumber($sqlType)) { if ('NUMERIC' === strtoupper($sqlType)) { $sqlType .= $toColumn->getSizeDefinition(); } } else { $sqlType .= $toColumn->getSizeDefinition(); } } if ($using = $this->getUsingCast($fromColumn, $toColumn)) { $sqlType .= $using; } $ret .= sprintf($pattern, $this->quoteIdentifier($table->getName()), $colName . ' TYPE ' . $sqlType); } if (isset($changedProperties['defaultValueValue'])) { $property = $changedProperties['defaultValueValue']; if ($property[0] !== null && $property[1] === null) { $ret .= sprintf($pattern, $this->quoteIdentifier($table->getName()), $colName . ' DROP DEFAULT'); } else { $ret .= sprintf($pattern, $this->quoteIdentifier($table->getName()), $colName . ' SET ' . $this->getColumnDefaultValueDDL($toColumn)); } } if (isset($changedProperties['notNull'])) { $property = $changedProperties['notNull']; $notNull = ' DROP NOT NULL'; if ($property[1]) { $notNull = ' SET NOT NULL'; } $ret .= sprintf($pattern, $this->quoteIdentifier($table->getName()), $colName . $notNull); } return $ret; }