Completed
Pull Request — master (#7021)
by Joas
32:00 queued 07:53
created

OracleMigrator::quoteColumn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 1
dl 0
loc 19
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Morris Jobke <[email protected]>
6
 * @author Robin Appelman <[email protected]>
7
 * @author Thomas Müller <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OC\DB;
26
27
use Doctrine\DBAL\DBALException;
28
use Doctrine\DBAL\Schema\Column;
29
use Doctrine\DBAL\Schema\ColumnDiff;
30
use Doctrine\DBAL\Schema\Index;
31
use Doctrine\DBAL\Schema\Schema;
32
use Doctrine\DBAL\Schema\Table;
33
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
34
35
class OracleMigrator extends Migrator {
36
37
	/**
38
	 * Quote a column's name but changing the name requires recreating
39
	 * the column instance and copying over all properties.
40
	 *
41
	 * @param Column $column old column
42
	 * @return Column new column instance with new name
43
	 */
44
	protected function quoteColumn(Column $column) {
45
		$newColumn = new Column(
46
			$this->connection->quoteIdentifier($column->getName()),
47
			$column->getType()
48
		);
49
		$newColumn->setAutoincrement($column->getAutoincrement());
50
		$newColumn->setColumnDefinition($column->getColumnDefinition());
51
		$newColumn->setComment($column->getComment());
52
		$newColumn->setDefault($column->getDefault());
53
		$newColumn->setFixed($column->getFixed());
54
		$newColumn->setLength($column->getLength());
55
		$newColumn->setNotnull($column->getNotnull());
56
		$newColumn->setPrecision($column->getPrecision());
57
		$newColumn->setScale($column->getScale());
58
		$newColumn->setUnsigned($column->getUnsigned());
59
		$newColumn->setPlatformOptions($column->getPlatformOptions());
60
		$newColumn->setCustomSchemaOptions($column->getPlatformOptions());
61
		return $newColumn;
62
	}
63
64
	/**
65
	 * Quote an index's name but changing the name requires recreating
66
	 * the index instance and copying over all properties.
67
	 *
68
	 * @param Index $index old index
69
	 * @return Index new index instance with new name
70
	 */
71
	protected function quoteIndex($index) {
72
		return new Index(
73
		//TODO migrate existing uppercase indexes, then $this->connection->quoteIdentifier($index->getName()),
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
74
			$index->getName(),
75
			array_map(function($columnName) {
76
				return $this->connection->quoteIdentifier($columnName);
77
			}, $index->getColumns()),
78
			$index->isUnique(),
79
			$index->isPrimary(),
80
			$index->getFlags(),
81
			$index->getOptions()
82
		);
83
	}
84
85
	/**
86
	 * Quote an ForeignKeyConstraint's name but changing the name requires recreating
87
	 * the ForeignKeyConstraint instance and copying over all properties.
88
	 *
89
	 * @param ForeignKeyConstraint $fkc old fkc
90
	 * @return ForeignKeyConstraint new fkc instance with new name
91
	 */
92
	protected function quoteForeignKeyConstraint($fkc) {
93
		return new ForeignKeyConstraint(
94
			array_map(function($columnName) {
95
				return $this->connection->quoteIdentifier($columnName);
96
			}, $fkc->getLocalColumns()),
97
			$this->connection->quoteIdentifier($fkc->getForeignTableName()),
98
			array_map(function($columnName) {
99
				return $this->connection->quoteIdentifier($columnName);
100
			}, $fkc->getForeignColumns()),
101
			$fkc->getName(),
102
			$fkc->getOptions()
103
		);
104
	}
105
106
	/**
107
	 * @param Schema $targetSchema
108
	 * @param \Doctrine\DBAL\Connection $connection
109
	 * @return \Doctrine\DBAL\Schema\SchemaDiff
110
	 * @throws DBALException
111
	 */
112
	protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
113
		$schemaDiff = parent::getDiff($targetSchema, $connection);
114
115
		// oracle forces us to quote the identifiers
116
		$schemaDiff->newTables = array_map(function(Table $table) {
117
			return new Table(
118
				$this->connection->quoteIdentifier($table->getName()),
119
				array_map(function(Column $column) {
120
					return $this->quoteColumn($column);
121
				}, $table->getColumns()),
122
				array_map(function(Index $index) {
123
					return $this->quoteIndex($index);
124
				}, $table->getIndexes()),
125
				array_map(function(ForeignKeyConstraint $fck) {
126
					return $this->quoteForeignKeyConstraint($fck);
127
				}, $table->getForeignKeys()),
128
				0,
129
				$table->getOptions()
130
			);
131
		}, $schemaDiff->newTables);
132
133
		$schemaDiff->removedTables = array_map(function(Table $table) {
134
			return new Table(
135
				$this->connection->quoteIdentifier($table->getName()),
136
				$table->getColumns(),
137
				$table->getIndexes(),
138
				$table->getForeignKeys(),
139
				0,
140
				$table->getOptions()
141
			);
142
		}, $schemaDiff->removedTables);
143
144
		foreach ($schemaDiff->changedTables as $tableDiff) {
145
			$tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name);
146
147
			$tableDiff->addedColumns = array_map(function(Column $column) {
148
				return $this->quoteColumn($column);
149
			}, $tableDiff->addedColumns);
150
151
			foreach ($tableDiff->changedColumns as $column) {
152
				$column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName);
153
				// auto increment is not relevant for oracle and can anyhow not be applied on change
154
				$column->changedProperties = array_diff($column->changedProperties, ['autoincrement', 'unsigned']);
155
			}
156
			// remove columns that no longer have changed (because autoincrement and unsigned are not supported)
157
			$tableDiff->changedColumns = array_filter($tableDiff->changedColumns, function (ColumnDiff $column) {
158
				return count($column->changedProperties) > 0;
159
			});
160
161
			$tableDiff->removedColumns = array_map(function(Column $column) {
162
				return $this->quoteColumn($column);
163
			}, $tableDiff->removedColumns);
164
165
			$tableDiff->renamedColumns = array_map(function(Column $column) {
166
				return $this->quoteColumn($column);
167
			}, $tableDiff->renamedColumns);
168
169
			$tableDiff->addedIndexes = array_map(function(Index $index) {
170
				return $this->quoteIndex($index);
171
			}, $tableDiff->addedIndexes);
172
173
			$tableDiff->changedIndexes = array_map(function(Index $index) {
174
				return $this->quoteIndex($index);
175
			}, $tableDiff->changedIndexes);
176
177
			$tableDiff->removedIndexes = array_map(function(Index $index) {
178
				return $this->quoteIndex($index);
179
			}, $tableDiff->removedIndexes);
180
181
			$tableDiff->renamedIndexes = array_map(function(Index $index) {
182
				return $this->quoteIndex($index);
183
			}, $tableDiff->renamedIndexes);
184
185
			$tableDiff->addedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) {
186
				return $this->quoteForeignKeyConstraint($fkc);
187
			}, $tableDiff->addedForeignKeys);
188
189
			$tableDiff->changedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) {
190
				return $this->quoteForeignKeyConstraint($fkc);
191
			}, $tableDiff->changedForeignKeys);
192
193
			$tableDiff->removedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) {
194
				return $this->quoteForeignKeyConstraint($fkc);
195
			}, $tableDiff->removedForeignKeys);
196
		}
197
198
		return $schemaDiff;
199
	}
200
201
	/**
202
	 * @param string $name
203
	 * @return string
204
	 */
205
	protected function generateTemporaryTableName($name) {
206
		return 'oc_' . uniqid();
207
	}
208
209
	/**
210
	 * @param $statement
211
	 * @return string
212
	 */
213
	protected function convertStatementToScript($statement) {
214
		if (substr($statement, -1) === ';') {
215
			return $statement . PHP_EOL . '/' . PHP_EOL;
216
		}
217
		$script = $statement . ';';
218
		$script .= PHP_EOL;
219
		$script .= PHP_EOL;
220
		return $script;
221
	}
222
223
	protected function getFilterExpression() {
224
		return '/^"' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
225
	}
226
227
}
228