/**
  * Builds the DDL SQL to alter a table
  * based on a TableDiff instance
  *
  * @return string
  */
 public function getModifyTableColumnsDDL(TableDiff $tableDiff)
 {
     $ret = '';
     foreach ($tableDiff->getRemovedColumns() as $column) {
         $ret .= $this->getRemoveColumnDDL($column);
     }
     foreach ($tableDiff->getRenamedColumns() as $columnRenaming) {
         $ret .= $this->getRenameColumnDDL($columnRenaming[0], $columnRenaming[1]);
     }
     if ($modifiedColumns = $tableDiff->getModifiedColumns()) {
         $ret .= $this->getModifyColumnsDDL($modifiedColumns);
     }
     if ($addedColumns = $tableDiff->getAddedColumns()) {
         $ret .= $this->getAddColumnsDDL($addedColumns);
     }
     return $ret;
 }
 /**
  * Creates a temporarily created table with the new schema,
  * moves all items into it and drops the origin as well as renames the temp table to the origin then.
  *
  * @param  TableDiff $tableDiff
  * @return string
  */
 public function getMigrationTableDDL(TableDiff $tableDiff)
 {
     $pattern = "\nCREATE TEMPORARY TABLE %s AS SELECT %s FROM %s;\nDROP TABLE %s;\n%s\nINSERT INTO %s (%s) SELECT %s FROM %s;\nDROP TABLE %s;\n";
     $originTable = clone $tableDiff->getFromTable();
     $newTable = clone $tableDiff->getToTable();
     $originTableName = $originTable->getName();
     $tempTableName = $newTable->getCommonName() . '__temp__' . uniqid();
     $originTableFields = $this->getColumnListDDL($originTable->getColumns());
     $fieldMap = [];
     /** struct: [<oldCol> => <newCol>] */
     //start with modified columns
     foreach ($tableDiff->getModifiedColumns() as $diff) {
         $fieldMap[$diff->getFromColumn()->getName()] = $diff->getToColumn()->getName();
     }
     foreach ($tableDiff->getRenamedColumns() as $col) {
         list($from, $to) = $col;
         $fieldMap[$from->getName()] = $to->getName();
     }
     foreach ($newTable->getColumns() as $col) {
         if ($originTable->hasColumn($col)) {
             if (!isset($fieldMap[$col->getName()])) {
                 $fieldMap[$col->getName()] = $col->getName();
             }
         }
     }
     $createTable = $this->getAddTableDDL($newTable);
     $createTable .= $this->getAddIndicesDDL($newTable);
     $sql = sprintf($pattern, $this->quoteIdentifier($tempTableName), $originTableFields, $this->quoteIdentifier($originTableName), $this->quoteIdentifier($originTableName), $createTable, $this->quoteIdentifier($originTableName), implode(', ', $fieldMap), implode(', ', array_keys($fieldMap)), $this->quoteIdentifier($tempTableName), $this->quoteIdentifier($tempTableName));
     return $sql;
 }
Beispiel #3
0
 public function getModifyTableDDL(TableDiff $tableDiff)
 {
     $alterTableStatements = '';
     $toTable = $tableDiff->getToTable();
     // drop indices, foreign keys
     foreach ($tableDiff->getRemovedFks() as $fk) {
         $alterTableStatements .= $this->getDropForeignKeyDDL($fk);
     }
     foreach ($tableDiff->getModifiedFks() as $fkModification) {
         list($fromFk) = $fkModification;
         $alterTableStatements .= $this->getDropForeignKeyDDL($fromFk);
     }
     foreach ($tableDiff->getRemovedIndices() as $index) {
         $alterTableStatements .= $this->getDropIndexDDL($index);
     }
     foreach ($tableDiff->getModifiedIndices() as $indexModification) {
         list($fromIndex) = $indexModification;
         $alterTableStatements .= $this->getDropIndexDDL($fromIndex);
     }
     // alter table structure
     if ($tableDiff->hasModifiedPk()) {
         $alterTableStatements .= $this->getDropPrimaryKeyDDL($tableDiff->getFromTable());
     }
     foreach ($tableDiff->getRenamedColumns() as $columnRenaming) {
         $alterTableStatements .= $this->getRenameColumnDDL($columnRenaming[0], $columnRenaming[1]);
     }
     if ($modifiedColumns = $tableDiff->getModifiedColumns()) {
         $alterTableStatements .= $this->getModifyColumnsDDL($modifiedColumns);
     }
     if ($addedColumns = $tableDiff->getAddedColumns()) {
         $alterTableStatements .= $this->getAddColumnsDDL($addedColumns);
     }
     foreach ($tableDiff->getRemovedColumns() as $column) {
         $alterTableStatements .= $this->getRemoveColumnDDL($column);
     }
     // add new indices and foreign keys
     if ($tableDiff->hasModifiedPk()) {
         $alterTableStatements .= $this->getAddPrimaryKeyDDL($tableDiff->getToTable());
     }
     // create indices, foreign keys
     foreach ($tableDiff->getModifiedIndices() as $indexModification) {
         list($oldIndex, $toIndex) = $indexModification;
         $alterTableStatements .= $this->getAddIndexDDL($toIndex);
     }
     foreach ($tableDiff->getAddedIndices() as $index) {
         $alterTableStatements .= $this->getAddIndexDDL($index);
     }
     foreach ($tableDiff->getModifiedFks() as $fkModification) {
         list(, $toFk) = $fkModification;
         $alterTableStatements .= $this->getAddForeignKeyDDL($toFk);
     }
     foreach ($tableDiff->getAddedFks() as $fk) {
         $alterTableStatements .= $this->getAddForeignKeyDDL($fk);
     }
     $ret = '';
     if (trim($alterTableStatements)) {
         //merge all changes into one command. This prevents https://github.com/propelorm/Propel2/issues/1115
         $changes = explode(';', $alterTableStatements);
         $changeFragments = [];
         foreach ($changes as $change) {
             if (trim($change)) {
                 $changeFragments[] = preg_replace(sprintf('/ALTER TABLE %s /', $this->quoteIdentifier($toTable->getName())), "\n\n  ", trim($change));
             }
         }
         $ret .= sprintf("\nALTER TABLE %s%s;\n", $this->quoteIdentifier($toTable->getName()), implode(',', $changeFragments));
     }
     return $ret;
 }