You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
7.7 KiB
231 lines
7.7 KiB
<?php |
|
/** |
|
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|
* |
|
* @author Joas Schilling <coding@schilljs.com> |
|
* @author Jörn Friedrich Dreyer <jfd@butonic.de> |
|
* @author Morris Jobke <hey@morrisjobke.de> |
|
* @author Piotr Mrowczynski <mrow4a@yahoo.com> |
|
* @author Robin Appelman <robin@icewind.nl> |
|
* @author Thomas Müller <thomas.mueller@tmit.eu> |
|
* @author Victor Dubiniuk <dubiniuk@owncloud.com> |
|
* |
|
* @license AGPL-3.0 |
|
* |
|
* This code is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU Affero General Public License, version 3, |
|
* as published by the Free Software Foundation. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU Affero General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU Affero General Public License, version 3, |
|
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|
* |
|
*/ |
|
|
|
namespace OC\DB; |
|
|
|
use Doctrine\DBAL\DBALException; |
|
use Doctrine\DBAL\Schema\Column; |
|
use Doctrine\DBAL\Schema\ColumnDiff; |
|
use Doctrine\DBAL\Schema\Index; |
|
use Doctrine\DBAL\Schema\Schema; |
|
use Doctrine\DBAL\Schema\Table; |
|
use Doctrine\DBAL\Schema\ForeignKeyConstraint; |
|
|
|
class OracleMigrator extends Migrator { |
|
|
|
/** |
|
* Quote a column's name but changing the name requires recreating |
|
* the column instance and copying over all properties. |
|
* |
|
* @param Column $column old column |
|
* @return Column new column instance with new name |
|
*/ |
|
protected function quoteColumn(Column $column) { |
|
$newColumn = new Column( |
|
$this->connection->quoteIdentifier($column->getName()), |
|
$column->getType() |
|
); |
|
$newColumn->setAutoincrement($column->getAutoincrement()); |
|
$newColumn->setColumnDefinition($column->getColumnDefinition()); |
|
$newColumn->setComment($column->getComment()); |
|
$newColumn->setDefault($column->getDefault()); |
|
$newColumn->setFixed($column->getFixed()); |
|
$newColumn->setLength($column->getLength()); |
|
$newColumn->setNotnull($column->getNotnull()); |
|
$newColumn->setPrecision($column->getPrecision()); |
|
$newColumn->setScale($column->getScale()); |
|
$newColumn->setUnsigned($column->getUnsigned()); |
|
$newColumn->setPlatformOptions($column->getPlatformOptions()); |
|
$newColumn->setCustomSchemaOptions($column->getPlatformOptions()); |
|
return $newColumn; |
|
} |
|
|
|
/** |
|
* Quote an index's name but changing the name requires recreating |
|
* the index instance and copying over all properties. |
|
* |
|
* @param Index $index old index |
|
* @return Index new index instance with new name |
|
*/ |
|
protected function quoteIndex($index) { |
|
return new Index( |
|
//TODO migrate existing uppercase indexes, then $this->connection->quoteIdentifier($index->getName()), |
|
$index->getName(), |
|
array_map(function($columnName) { |
|
return $this->connection->quoteIdentifier($columnName); |
|
}, $index->getColumns()), |
|
$index->isUnique(), |
|
$index->isPrimary(), |
|
$index->getFlags(), |
|
$index->getOptions() |
|
); |
|
} |
|
|
|
/** |
|
* Quote an ForeignKeyConstraint's name but changing the name requires recreating |
|
* the ForeignKeyConstraint instance and copying over all properties. |
|
* |
|
* @param ForeignKeyConstraint $fkc old fkc |
|
* @return ForeignKeyConstraint new fkc instance with new name |
|
*/ |
|
protected function quoteForeignKeyConstraint($fkc) { |
|
return new ForeignKeyConstraint( |
|
array_map(function($columnName) { |
|
return $this->connection->quoteIdentifier($columnName); |
|
}, $fkc->getLocalColumns()), |
|
$this->connection->quoteIdentifier($fkc->getForeignTableName()), |
|
array_map(function($columnName) { |
|
return $this->connection->quoteIdentifier($columnName); |
|
}, $fkc->getForeignColumns()), |
|
$fkc->getName(), |
|
$fkc->getOptions() |
|
); |
|
} |
|
|
|
/** |
|
* @param Schema $targetSchema |
|
* @param \Doctrine\DBAL\Connection $connection |
|
* @return \Doctrine\DBAL\Schema\SchemaDiff |
|
* @throws DBALException |
|
*/ |
|
protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { |
|
$schemaDiff = parent::getDiff($targetSchema, $connection); |
|
|
|
// oracle forces us to quote the identifiers |
|
$schemaDiff->newTables = array_map(function(Table $table) { |
|
return new Table( |
|
$this->connection->quoteIdentifier($table->getName()), |
|
array_map(function(Column $column) { |
|
return $this->quoteColumn($column); |
|
}, $table->getColumns()), |
|
array_map(function(Index $index) { |
|
return $this->quoteIndex($index); |
|
}, $table->getIndexes()), |
|
array_map(function(ForeignKeyConstraint $fck) { |
|
return $this->quoteForeignKeyConstraint($fck); |
|
}, $table->getForeignKeys()), |
|
0, |
|
$table->getOptions() |
|
); |
|
}, $schemaDiff->newTables); |
|
|
|
$schemaDiff->removedTables = array_map(function(Table $table) { |
|
return new Table( |
|
$this->connection->quoteIdentifier($table->getName()), |
|
$table->getColumns(), |
|
$table->getIndexes(), |
|
$table->getForeignKeys(), |
|
0, |
|
$table->getOptions() |
|
); |
|
}, $schemaDiff->removedTables); |
|
|
|
foreach ($schemaDiff->changedTables as $tableDiff) { |
|
$tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name); |
|
|
|
$tableDiff->addedColumns = array_map(function(Column $column) { |
|
return $this->quoteColumn($column); |
|
}, $tableDiff->addedColumns); |
|
|
|
foreach ($tableDiff->changedColumns as $column) { |
|
$column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName); |
|
// auto increment is not relevant for oracle and can anyhow not be applied on change |
|
$column->changedProperties = array_diff($column->changedProperties, ['autoincrement', 'unsigned']); |
|
} |
|
// remove columns that no longer have changed (because autoincrement and unsigned are not supported) |
|
$tableDiff->changedColumns = array_filter($tableDiff->changedColumns, function (ColumnDiff $column) { |
|
return count($column->changedProperties) > 0; |
|
}); |
|
|
|
$tableDiff->removedColumns = array_map(function(Column $column) { |
|
return $this->quoteColumn($column); |
|
}, $tableDiff->removedColumns); |
|
|
|
$tableDiff->renamedColumns = array_map(function(Column $column) { |
|
return $this->quoteColumn($column); |
|
}, $tableDiff->renamedColumns); |
|
|
|
$tableDiff->addedIndexes = array_map(function(Index $index) { |
|
return $this->quoteIndex($index); |
|
}, $tableDiff->addedIndexes); |
|
|
|
$tableDiff->changedIndexes = array_map(function(Index $index) { |
|
return $this->quoteIndex($index); |
|
}, $tableDiff->changedIndexes); |
|
|
|
$tableDiff->removedIndexes = array_map(function(Index $index) { |
|
return $this->quoteIndex($index); |
|
}, $tableDiff->removedIndexes); |
|
|
|
$tableDiff->renamedIndexes = array_map(function(Index $index) { |
|
return $this->quoteIndex($index); |
|
}, $tableDiff->renamedIndexes); |
|
|
|
$tableDiff->addedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) { |
|
return $this->quoteForeignKeyConstraint($fkc); |
|
}, $tableDiff->addedForeignKeys); |
|
|
|
$tableDiff->changedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) { |
|
return $this->quoteForeignKeyConstraint($fkc); |
|
}, $tableDiff->changedForeignKeys); |
|
|
|
$tableDiff->removedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) { |
|
return $this->quoteForeignKeyConstraint($fkc); |
|
}, $tableDiff->removedForeignKeys); |
|
} |
|
|
|
return $schemaDiff; |
|
} |
|
|
|
/** |
|
* @param string $name |
|
* @return string |
|
*/ |
|
protected function generateTemporaryTableName($name) { |
|
return 'oc_' . uniqid(); |
|
} |
|
|
|
/** |
|
* @param $statement |
|
* @return string |
|
*/ |
|
protected function convertStatementToScript($statement) { |
|
if (substr($statement, -1) === ';') { |
|
return $statement . PHP_EOL . '/' . PHP_EOL; |
|
} |
|
$script = $statement . ';'; |
|
$script .= PHP_EOL; |
|
$script .= PHP_EOL; |
|
return $script; |
|
} |
|
|
|
protected function getFilterExpression() { |
|
return '/^"' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; |
|
} |
|
|
|
}
|
|
|