aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-migration
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-12-15 11:01:02 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-12-16 14:35:27 +0100
commit714a50e499fb1f029590d44773454e453f7ed782 (patch)
tree66ffcadc3436e910b9fe2419bf082f1763dd93eb /server/sonar-db-migration
parent695c9b54d7e7a97075180f17beba537114d404f1 (diff)
downloadsonarqube-714a50e499fb1f029590d44773454e453f7ed782.tar.gz
sonarqube-714a50e499fb1f029590d44773454e453f7ed782.zip
SONAR-8445 move def and sql builder classes to sonar-db-migration
Diffstat (limited to 'server/sonar-db-migration')
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/AbstractColumnDef.java51
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BigIntegerColumnDef.java67
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BlobColumnDef.java84
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BooleanColumnDef.java90
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/ClobColumnDef.java84
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/ColumnDef.java35
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/DecimalColumnDef.java109
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/IntegerColumnDef.java89
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/TimestampColumnDef.java87
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/TinyIntColumnDef.java82
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/Validations.java125
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/VarcharColumnDef.java125
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/package-info.java24
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AddColumnsBuilder.java100
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilder.java147
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateIndexBuilder.java121
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilder.java282
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropColumnsBuilder.java75
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropIndexBuilder.java75
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropTableBuilder.java79
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/RenameTableBuilder.java85
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/package-info.java24
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchema.java32
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToCeActivity.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToEvents.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToMeasures.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddBColumnsToProjects.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnToMeasures.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnsToSnapshots.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnAnalysisUuidOfMeasures.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnComponentUuidOfMeasures.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddLastUsedColumnToRulesProfiles.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddProfileKeyToActivities.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUniqueIndexOnUuidOfSnapshots.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUserUpdatedAtToRulesProfiles.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnToSnapshots.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToProjects.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToResourceIndex.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidPathColumnToProjects.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreatePermTemplatesCharacteristics.java18
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreateTemporaryIndicesFor1211.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromProjects.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromResourceIndex.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromSnapshots.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexDuplicationsIndexSidFromDuplicationsIndex.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexEventsSnapshotIdFromEvents.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexOnSnapshotIdOfMeasures.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsRootIdFromProjects.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsUuidFromProjects.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndicesOnTreeColumnsOfSnapshots.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropProjectIdColumnFromMeasures.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropRememberMeColumnsFromUsers.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropResourceIndexRidFromResourceIndex.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromCeActivity.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromEvents.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromMeasures.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnsFromDuplicationsIndex.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotProjectIdFromSnapshots.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTemporaryIndicesOf1210.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTreeColumnsFromSnapshots.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropUnusedMeasuresColumns.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnEvents.java10
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnMeasures.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java10
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidColumnsNotNullOnSnapshots.java10
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidNotNullOnMeasures.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeProfileKeyNotNullOnActivities.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnNotNullOnSnapshots.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnProjects.java10
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnResourceIndex.java10
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidPathColumnNotNullOnProjects.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/RecreateIndexProjectsUuidFromProjects.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/TemporarilyDropIndexOfAnalysisUuidOnMeasures.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddBUuidPathToProjects.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddErrorColumnsToCeActivity.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableCeTaskInput.java10
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableInternalProperties.java12
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableProperties2.java20
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableQprofileChanges.java8
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableRuleRepositories.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableScannerContext.java10
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropIsGlobalFromDashboards.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableActivities.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableProperties.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/RenameTableProperties2ToProperties.java8
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/ShrinkModuleUuidPathOfProjects.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddIsRootColumnOnTableUsers.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroupRoles.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroups.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToPermissionTemplates.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToUserRoles.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableOrganizations.java12
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableWebhookDeliveries.java18
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropIssueFiltersTables.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropMeasureFiltersTables.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropRelatedDashboardTables.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/IncludeOrganizationUuidInUniqueIndexOfGroupRoles.java8
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroupRoles.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroups.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnPermissionTemplates.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnUserRoles.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeRootColumnNotNullOnTableUsers.java4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/AddUuidToEvents.java6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/MakeUuidNotNullOnEvents.java10
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BigIntegerColumnDefTest.java91
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BlobColumnDefTest.java113
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BooleanColumnDefTest.java94
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/ClobColumnDefTest.java102
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/DecimalColumnDefTest.java142
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/IntegerColumnDefTest.java124
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/TimestampColumnDefTest.java90
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/TinyIntColumnDefTest.java81
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/ValidationsTest.java85
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/VarcharColumnDefTest.java120
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/AddColumnsBuilderTest.java92
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilderTest.java166
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateIndexBuilderTest.java163
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilderDbTesterTest.java134
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilderTest.java582
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropColumnsBuilderTest.java63
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropIndexBuilderTest.java98
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropTableBuilderTest.java97
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/RenameTableBuilderTest.java92
125 files changed, 4811 insertions, 242 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/AbstractColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/AbstractColumnDef.java
new file mode 100644
index 00000000000..870b08c6d6e
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/AbstractColumnDef.java
@@ -0,0 +1,51 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public abstract class AbstractColumnDef implements ColumnDef {
+ private final String columnName;
+ private final boolean isNullable;
+ @CheckForNull
+ private final Object defaultValue;
+
+ public AbstractColumnDef(String columnName, boolean isNullable, @Nullable Object defaultValue) {
+ this.columnName = columnName;
+ this.isNullable = isNullable;
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
+ public String getName() {
+ return columnName;
+ }
+
+ @Override
+ public boolean isNullable() {
+ return isNullable;
+ }
+
+ @Override
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BigIntegerColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BigIntegerColumnDef.java
new file mode 100644
index 00000000000..d12628cec08
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BigIntegerColumnDef.java
@@ -0,0 +1,67 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.Oracle;
+
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+@Immutable
+public class BigIntegerColumnDef extends AbstractColumnDef {
+
+ private BigIntegerColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, null);
+ }
+
+ public static Builder newBigIntegerColumnDefBuilder() {
+ return new Builder();
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ return dialect.getId().equals(Oracle.ID) ? "NUMBER (38)" : "BIGINT";
+ }
+
+ public static class Builder {
+ @CheckForNull
+ private String columnName;
+
+ private boolean isNullable = true;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public BigIntegerColumnDef build() {
+ validateColumnName(columnName);
+ return new BigIntegerColumnDef(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BlobColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BlobColumnDef.java
new file mode 100644
index 00000000000..3edc45ed9cd
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BlobColumnDef.java
@@ -0,0 +1,84 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+@Immutable
+public class BlobColumnDef extends AbstractColumnDef {
+ public BlobColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, null);
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case MsSql.ID:
+ return "VARBINARY(MAX)";
+ case MySql.ID:
+ return "LONGBLOB";
+ case Oracle.ID:
+ case H2.ID:
+ return "BLOB";
+ case PostgreSql.ID:
+ return "BYTEA";
+ default:
+ throw new IllegalArgumentException("Unsupported dialect id " + dialect.getId());
+ }
+ }
+
+ public static Builder newBlobColumnDefBuilder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ @CheckForNull
+ private String columnName;
+ private boolean isNullable = true;
+
+ private Builder() {
+ // prevents instantiation outside
+ }
+
+ public BlobColumnDef.Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public BlobColumnDef.Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public BlobColumnDef build() {
+ validateColumnName(columnName);
+ return new BlobColumnDef(this);
+ }
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BooleanColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BooleanColumnDef.java
new file mode 100644
index 00000000000..f8d7919a830
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/BooleanColumnDef.java
@@ -0,0 +1,90 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+/**
+ * Used to define VARCHAR column
+ */
+@Immutable
+public class BooleanColumnDef extends AbstractColumnDef {
+
+ private BooleanColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, builder.defaultValue);
+ }
+
+ public static Builder newBooleanColumnDefBuilder() {
+ return new Builder();
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case PostgreSql.ID:
+ case H2.ID:
+ return "BOOLEAN";
+ case Oracle.ID:
+ return "NUMBER(1)";
+ case MsSql.ID:
+ return "BIT";
+ case MySql.ID:
+ return "TINYINT(1)";
+ default:
+ throw new UnsupportedOperationException(String.format("Unknown dialect '%s'", dialect.getId()));
+ }
+ }
+
+ public static class Builder {
+ private String columnName;
+ private Boolean defaultValue = null;
+ private boolean isNullable = true;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public Builder setDefaultValue(@Nullable Boolean b) {
+ this.defaultValue = b;
+ return this;
+ }
+
+ public BooleanColumnDef build() {
+ validateColumnName(columnName);
+ return new BooleanColumnDef(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/ClobColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/ClobColumnDef.java
new file mode 100644
index 00000000000..c50b00e7487
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/ClobColumnDef.java
@@ -0,0 +1,84 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+/**
+ * Used to define CLOB columns
+ */
+@Immutable
+public class ClobColumnDef extends AbstractColumnDef {
+
+ private ClobColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, null);
+ }
+
+ public static Builder newClobColumnDefBuilder() {
+ return new Builder();
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case MsSql.ID:
+ return "NVARCHAR (MAX)";
+ case MySql.ID:
+ return "LONGTEXT";
+ case Oracle.ID:
+ return "CLOB";
+ case H2.ID:
+ return "CLOB(2147483647)";
+ case PostgreSql.ID:
+ return "TEXT";
+ default:
+ throw new IllegalArgumentException("Unsupported dialect id " + dialect.getId());
+ }
+ }
+
+ public static class Builder {
+ private String columnName;
+ private boolean isNullable = true;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public ClobColumnDef build() {
+ validateColumnName(columnName);
+ return new ClobColumnDef(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/ColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/ColumnDef.java
new file mode 100644
index 00000000000..b2634eb1cdc
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/ColumnDef.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.CheckForNull;
+import org.sonar.db.dialect.Dialect;
+
+public interface ColumnDef {
+
+ boolean isNullable();
+
+ String getName();
+
+ String generateSqlType(Dialect dialect);
+
+ @CheckForNull
+ Object getDefaultValue();
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/DecimalColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/DecimalColumnDef.java
new file mode 100644
index 00000000000..28b41d922da
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/DecimalColumnDef.java
@@ -0,0 +1,109 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+@Immutable
+public class DecimalColumnDef extends AbstractColumnDef {
+
+ public static final int DEFAULT_PRECISION = 38;
+ public static final int DEFAULT_SCALE = 20;
+
+ private final int precision;
+ private final int scale;
+
+ private DecimalColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, null);
+ this.precision = builder.precision;
+ this.scale = builder.scale;
+ }
+
+ public static Builder newDecimalColumnDefBuilder() {
+ return new Builder();
+ }
+
+ public int getPrecision() {
+ return precision;
+ }
+
+ public int getScale() {
+ return scale;
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case PostgreSql.ID:
+ case Oracle.ID:
+ return String.format("NUMERIC (%s,%s)", precision, scale);
+ case MySql.ID:
+ case MsSql.ID:
+ return String.format("DECIMAL (%s,%s)", precision, scale);
+ case H2.ID:
+ return "DOUBLE";
+ default:
+ throw new UnsupportedOperationException(String.format("Unknown dialect '%s'", dialect.getId()));
+ }
+ }
+
+ public static class Builder {
+ @CheckForNull
+ private String columnName;
+ private int precision = DEFAULT_PRECISION;
+ private int scale = DEFAULT_SCALE;
+ private boolean isNullable = true;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public Builder setPrecision(int precision) {
+ this.precision = precision;
+ return this;
+ }
+
+ public Builder setScale(int scale) {
+ this.scale = scale;
+ return this;
+ }
+
+ public DecimalColumnDef build() {
+ validateColumnName(columnName);
+ return new DecimalColumnDef(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/IntegerColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/IntegerColumnDef.java
new file mode 100644
index 00000000000..cf04816cb7e
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/IntegerColumnDef.java
@@ -0,0 +1,89 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+@Immutable
+public class IntegerColumnDef extends AbstractColumnDef {
+
+ private IntegerColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, builder.defaultValue);
+ }
+
+ public static Builder newIntegerColumnDefBuilder() {
+ return new Builder();
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case PostgreSql.ID:
+ case MySql.ID:
+ case H2.ID:
+ return "INTEGER";
+ case MsSql.ID:
+ return "INT";
+ case Oracle.ID:
+ return "NUMBER(38,0)";
+ default:
+ throw new IllegalArgumentException("Unsupported dialect id " + dialect.getId());
+ }
+ }
+
+ public static class Builder {
+ @CheckForNull
+ private String columnName;
+ private boolean isNullable = true;
+ @CheckForNull
+ private Integer defaultValue = null;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public Builder setDefaultValue(@Nullable Integer i) {
+ this.defaultValue = i;
+ return this;
+ }
+
+ public IntegerColumnDef build() {
+ validateColumnName(columnName);
+ return new IntegerColumnDef(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/TimestampColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/TimestampColumnDef.java
new file mode 100644
index 00000000000..3593e0ac2ba
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/TimestampColumnDef.java
@@ -0,0 +1,87 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+/**
+ * Used to define TIMESTAMP columns.
+ *
+ * @deprecated implemented for compatibility with old tables, but {@link BigIntegerColumnDef}
+ * must be used for storing datetimes as bigints (no problems regarding timezone
+ * nor MySQL precision).
+ */
+@Immutable
+@Deprecated
+public class TimestampColumnDef extends AbstractColumnDef {
+
+ private TimestampColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, null);
+ }
+
+ public static Builder newTimestampColumnDefBuilder() {
+ return new Builder();
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case MsSql.ID:
+ case MySql.ID:
+ return "DATETIME";
+ case Oracle.ID:
+ return "TIMESTAMP (6)";
+ case H2.ID:
+ case PostgreSql.ID:
+ return "TIMESTAMP";
+ default:
+ throw new IllegalArgumentException("Unsupported dialect id " + dialect.getId());
+ }
+ }
+
+ public static class Builder {
+ private String columnName;
+ private boolean isNullable = true;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setIsNullable(boolean b) {
+ this.isNullable = b;
+ return this;
+ }
+
+ public TimestampColumnDef build() {
+ validateColumnName(columnName);
+ return new TimestampColumnDef(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/TinyIntColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/TinyIntColumnDef.java
new file mode 100644
index 00000000000..f6b5c9c2ace
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/TinyIntColumnDef.java
@@ -0,0 +1,82 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+/**
+ * Integer that supports at least range [0..128]. Full range depends on database vendor.
+ */
+@Immutable
+public class TinyIntColumnDef extends AbstractColumnDef {
+
+ private TinyIntColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, null);
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case PostgreSql.ID:
+ return "SMALLINT";
+ case Oracle.ID:
+ return "NUMBER(3)";
+ case MySql.ID:
+ // do not use TINYINT(1) as it's considered as booleans by connector/J.
+ return "TINYINT(2)";
+ case MsSql.ID:
+ case H2.ID:
+ return "TINYINT";
+ default:
+ throw new UnsupportedOperationException(String.format("Unknown dialect '%s'", dialect.getId()));
+ }
+ }
+
+ public static class Builder {
+ @CheckForNull
+ private String columnName;
+ private boolean isNullable = true;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public TinyIntColumnDef build() {
+ validateColumnName(columnName);
+ return new TinyIntColumnDef(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/Validations.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/Validations.java
new file mode 100644
index 00000000000..884258afc12
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/Validations.java
@@ -0,0 +1,125 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import com.google.common.base.CharMatcher;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.CharMatcher.anyOf;
+import static com.google.common.base.CharMatcher.inRange;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Objects.requireNonNull;
+
+public class Validations {
+
+ private static final int TABLE_NAME_MAX_SIZE = 25;
+ private static final int CONSTRAINT_NAME_MAX_SIZE = 30;
+ private static final int INDEX_NAME_MAX_SIZE = 30;
+
+ private static final CharMatcher DIGIT_CHAR_MATCHER = inRange('0', '9');
+ private static final CharMatcher LOWER_CASE_ASCII_LETTERS_CHAR_MATCHER = inRange('a', 'z');
+ private static final CharMatcher UNDERSCORE_CHAR_MATCHER = anyOf("_");
+
+ private Validations() {
+ // Only static stuff here
+ }
+
+ /**
+ * Ensure {@code columnName} is a valid name for a column.
+ * @throws NullPointerException if {@code columnName} is {@code null}
+ * @throws IllegalArgumentException if {@code columnName} is not valid
+ * @return the same {@code columnName}
+ * @see #checkDbIdentifier(String, String, int)
+ */
+ static String validateColumnName(@Nullable String columnName) {
+ String name = requireNonNull(columnName, "Column name cannot be null");
+ checkDbIdentifierCharacters(columnName, "Column name");
+ return name;
+ }
+
+ /**
+ * Ensure {@code tableName} is a valid name for a table.
+ * @throws NullPointerException if {@code tableName} is {@code null}
+ * @throws IllegalArgumentException if {@code tableName} is not valid
+ * @return the same {@code tableName}
+ * @see #checkDbIdentifier(String, String, int)
+ */
+ public static String validateTableName(@Nullable String tableName) {
+ requireNonNull(tableName, "Table name cannot be null");
+ checkDbIdentifier(tableName, "Table name", TABLE_NAME_MAX_SIZE);
+ return tableName;
+ }
+
+ /**
+ * Ensure {@code constraintName} is a valid name for a constraint.
+ * @throws NullPointerException if {@code constraintName} is {@code null}
+ * @throws IllegalArgumentException if {@code constraintName} is not valid
+ * @return the same {@code constraintName}
+ * @see #checkDbIdentifier(String, String, int)
+ */
+ public static String validateConstraintName(@Nullable String constraintName) {
+ requireNonNull(constraintName, "Constraint name cannot be null");
+ checkDbIdentifier(constraintName, "Constraint name", CONSTRAINT_NAME_MAX_SIZE);
+ return constraintName;
+ }
+
+ /**
+ * Ensure {@code indexName} is a valid name for an index.
+ * @throws NullPointerException if {@code indexName} is {@code null}
+ * @throws IllegalArgumentException if {@code indexName} is not valid
+ * @return the same {@code indexName}
+ * @see #checkDbIdentifier(String, String, int)
+ */
+ public static String validateIndexName(@Nullable String indexName) {
+ requireNonNull(indexName, "Index name cannot be null");
+ checkDbIdentifier(indexName, "Index name", INDEX_NAME_MAX_SIZE);
+ return indexName;
+ }
+
+ /**
+ * Ensure {@code identifier} is a valid DB identifier.
+ *
+ * @throws NullPointerException if {@code identifier} is {@code null}
+ * @throws IllegalArgumentException if {@code identifier} is empty
+ * @throws IllegalArgumentException if {@code identifier} is longer than {@code maxSize}
+ * @throws IllegalArgumentException if {@code identifier} is not lowercase
+ * @throws IllegalArgumentException if {@code identifier} contains characters others than ASCII letters, ASCII numbers or {@code _}
+ * @throws IllegalArgumentException if {@code identifier} starts with {@code _} or a number
+ */
+ static String checkDbIdentifier(@Nullable String identifier, String identifierDesc, int maxSize) {
+ String res = checkNotNull(identifier, "%s can't be null", identifierDesc);
+ checkArgument(!res.isEmpty(), "%s, can't be empty", identifierDesc);
+ checkArgument(
+ identifier.length() <= maxSize,
+ "%s length can't be more than %s", identifierDesc, maxSize);
+ checkDbIdentifierCharacters(identifier, identifierDesc);
+ return res;
+ }
+
+ private static void checkDbIdentifierCharacters(String identifier, String identifierDesc) {
+ checkArgument(
+ LOWER_CASE_ASCII_LETTERS_CHAR_MATCHER.or(DIGIT_CHAR_MATCHER).or(anyOf("_")).matchesAllOf(identifier),
+ "%s must be lower case and contain only alphanumeric chars or '_', got '%s'", identifierDesc, identifier);
+ checkArgument(
+ DIGIT_CHAR_MATCHER.or(UNDERSCORE_CHAR_MATCHER).matchesNoneOf(identifier.subSequence(0, 1)),
+ "%s must not start by a number or '_', got '%s'", identifierDesc, identifier);
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/VarcharColumnDef.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/VarcharColumnDef.java
new file mode 100644
index 00000000000..d86af4413f5
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/VarcharColumnDef.java
@@ -0,0 +1,125 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.Oracle;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+
+/**
+ * Used to define VARCHAR column
+ */
+@Immutable
+public class VarcharColumnDef extends AbstractColumnDef {
+ public static final int MAX_SIZE = 4_000;
+ /**
+ * @deprecated use {@link #UUID_SIZE} instead
+ */
+ @Deprecated
+ public static final int UUID_VARCHAR_SIZE = 50;
+ public static final int UUID_SIZE = 40;
+
+ private final int columnSize;
+ private final boolean ignoreOracleUnit;
+
+ private VarcharColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable, builder.defaultValue);
+ this.columnSize = builder.columnSize;
+ this.ignoreOracleUnit = builder.ignoreOracleUnit;
+ }
+
+ public static Builder newVarcharColumnDefBuilder() {
+ return new Builder();
+ }
+
+ public int getColumnSize() {
+ return columnSize;
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case MsSql.ID:
+ return format("NVARCHAR (%d)", columnSize);
+ case Oracle.ID:
+ return format("VARCHAR (%d%s)", columnSize, ignoreOracleUnit ? "" : " CHAR");
+ default:
+ return format("VARCHAR (%d)", columnSize);
+ }
+ }
+
+ public static class Builder {
+ @CheckForNull
+ private Integer columnSize;
+ @CheckForNull
+ private String columnName;
+ @CheckForNull
+ private String defaultValue = null;
+ private boolean isNullable = true;
+ private boolean ignoreOracleUnit = false;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setLimit(int limit) {
+ this.columnSize = limit;
+ return this;
+ }
+
+ public Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public Builder setDefaultValue(@Nullable String s) {
+ this.defaultValue = s;
+ return this;
+ }
+
+ /**
+ * In order to not depend on value of runtime variable NLS_LENGTH_SEMANTICS, unit of length
+ * is enforced to CHAR so that we're sure that type can't be BYTE.
+ * Unit is ignored for the columns created before SonarQube 6.3 (except for issues.message which
+ * has been fixed in migration 1151 of SonarQube 5.6. See SONAR-7493).
+ *
+ * @param b whether unit of length is hardcoded to CHAR.
+ */
+ public Builder setIgnoreOracleUnit(boolean b) {
+ this.ignoreOracleUnit = b;
+ return this;
+ }
+
+ public VarcharColumnDef build() {
+ validateColumnName(columnName);
+ requireNonNull(columnSize, "Limit cannot be null");
+ return new VarcharColumnDef(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/package-info.java
new file mode 100644
index 00000000000..0645c8c11d1
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/def/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.platform.db.migration.def;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java
index 68043682b38..47a73fdf125 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java
@@ -26,8 +26,8 @@ import java.util.List;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbClient;
-import org.sonar.db.version.CreateTableBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
public class MigrationHistoryTableImpl implements MigrationHistoryTable {
private static final String VERSION_COLUMN_NAME = "version";
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AddColumnsBuilder.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AddColumnsBuilder.java
new file mode 100644
index 00000000000..2317fcf8a2c
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AddColumnsBuilder.java
@@ -0,0 +1,100 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.List;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.server.platform.db.migration.def.ColumnDef;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static java.lang.String.format;
+import static org.sonar.server.platform.db.migration.def.Validations.validateTableName;
+
+/**
+ * Generate a SQL query to add multiple columns on a table
+ */
+public class AddColumnsBuilder {
+
+ private final Dialect dialect;
+ private final String tableName;
+ private List<ColumnDef> columnDefs = newArrayList();
+
+ public AddColumnsBuilder(Dialect dialect, String tableName) {
+ this.tableName = validateTableName(tableName);
+ this.dialect = dialect;
+ }
+
+ public AddColumnsBuilder addColumn(ColumnDef columnDef) {
+ columnDefs.add(columnDef);
+ return this;
+ }
+
+ public String build() {
+ if (columnDefs.isEmpty()) {
+ throw new IllegalStateException("No column has been defined");
+ }
+
+ StringBuilder sql = new StringBuilder().append("ALTER TABLE ").append(tableName).append(" ");
+ switch (dialect.getId()) {
+ case PostgreSql.ID:
+ addColumns(sql, "ADD COLUMN ");
+ break;
+ case MsSql.ID:
+ sql.append("ADD ");
+ addColumns(sql, "");
+ break;
+ default:
+ sql.append("ADD (");
+ addColumns(sql, "");
+ sql.append(")");
+ }
+ return sql.toString();
+ }
+
+ private void addColumns(StringBuilder sql, String columnPrefix) {
+ for (int i = 0; i < columnDefs.size(); i++) {
+ sql.append(columnPrefix);
+ addColumn(sql, columnDefs.get(i));
+ if (i < columnDefs.size() - 1) {
+ sql.append(", ");
+ }
+ }
+ }
+
+ private void addColumn(StringBuilder sql, ColumnDef columnDef) {
+ sql.append(columnDef.getName()).append(" ").append(columnDef.generateSqlType(dialect));
+ Object defaultValue = columnDef.getDefaultValue();
+ if (defaultValue != null) {
+ sql.append(" DEFAULT ");
+ // TODO remove duplication with CreateTableBuilder
+ if (defaultValue instanceof String) {
+ sql.append(format("'%s'", defaultValue));
+ } else if (defaultValue instanceof Boolean) {
+ sql.append((boolean) defaultValue ? dialect.getTrueSqlValue() : dialect.getFalseSqlValue());
+ } else {
+ sql.append(defaultValue);
+ }
+ }
+ sql.append(columnDef.isNullable() ? " NULL" : " NOT NULL");
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilder.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilder.java
new file mode 100644
index 00000000000..2e349cce368
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilder.java
@@ -0,0 +1,147 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.server.platform.db.migration.def.ColumnDef;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Lists.newArrayList;
+
+/**
+ * Generate SQL queries to update multiple columns of a single table.
+ *
+ * Note that this operation will not be re-entrant on:
+ * <ul>
+ * <li>Oracle 11G (may raise {@code ORA-01442: column to be modified to NOT NULL is already NOT NULL} or
+ * {@code ORA-01451: column to be modified to NULL cannot be modified to NULL})</li>
+ * </ul>
+ */
+public class AlterColumnsBuilder {
+
+ private static final String ALTER_TABLE = "ALTER TABLE ";
+ private static final String ALTER_COLUMN = "ALTER COLUMN ";
+
+ private final Dialect dialect;
+ private final String tableName;
+ private final List<ColumnDef> columnDefs = newArrayList();
+
+ public AlterColumnsBuilder(Dialect dialect, String tableName) {
+ this.dialect = dialect;
+ this.tableName = tableName;
+ }
+
+ public AlterColumnsBuilder updateColumn(ColumnDef columnDef) {
+ // limitation of Oracle, only attribute changes must be defined in ALTER.
+ checkArgument(columnDef.getDefaultValue()==null, "Default value is not supported on alter of column '%s'", columnDef.getName());
+ columnDefs.add(columnDef);
+ return this;
+ }
+
+ public List<String> build() {
+ if (columnDefs.isEmpty()) {
+ throw new IllegalStateException("No column has been defined");
+ }
+ switch (dialect.getId()) {
+ case PostgreSql.ID:
+ return createPostgresQuery();
+ case MySql.ID:
+ return createMySqlQuery();
+ case Oracle.ID:
+ return createOracleQuery();
+ default:
+ return createMsSqlAndH2Queries();
+ }
+ }
+
+ private List<String> createPostgresQuery() {
+ StringBuilder sql = new StringBuilder(ALTER_TABLE + tableName + " ");
+ for (Iterator<ColumnDef> columnDefIterator = columnDefs.iterator(); columnDefIterator.hasNext();) {
+ ColumnDef columnDef = columnDefIterator.next();
+ sql.append(ALTER_COLUMN);
+ addColumn(sql, columnDef, "TYPE ", false);
+ sql.append(", ");
+ sql.append(ALTER_COLUMN);
+ sql.append(columnDef.getName());
+ sql.append(' ').append(columnDef.isNullable() ? "DROP" : "SET").append(" NOT NULL");
+ if (columnDefIterator.hasNext()) {
+ sql.append(", ");
+ }
+ }
+ return Collections.singletonList(sql.toString());
+ }
+
+ private List<String> createMySqlQuery() {
+ StringBuilder sql = new StringBuilder(ALTER_TABLE + tableName + " ");
+ addColumns(sql, "MODIFY COLUMN ", "", true);
+ return Collections.singletonList(sql.toString());
+ }
+
+ private List<String> createOracleQuery() {
+ List<String> sqls = new ArrayList<>();
+ for (ColumnDef columnDef : columnDefs) {
+ StringBuilder sql = new StringBuilder(ALTER_TABLE + tableName + " ").append("MODIFY (");
+ addColumn(sql, columnDef, "", true);
+ sql.append(")");
+ sqls.add(sql.toString());
+ }
+ return sqls;
+ }
+
+ private List<String> createMsSqlAndH2Queries() {
+ List<String> sqls = new ArrayList<>();
+ for (ColumnDef columnDef : columnDefs) {
+ StringBuilder defaultQuery = new StringBuilder(ALTER_TABLE + tableName + " ");
+ defaultQuery.append(ALTER_COLUMN);
+ addColumn(defaultQuery, columnDef, "", true);
+ sqls.add(defaultQuery.toString());
+ }
+ return sqls;
+ }
+
+ private void addColumns(StringBuilder sql, String updateKeyword, String typePrefix, boolean addNotNullableProperty) {
+ for (Iterator<ColumnDef> columnDefIterator = columnDefs.iterator(); columnDefIterator.hasNext();) {
+ sql.append(updateKeyword);
+ addColumn(sql, columnDefIterator.next(), typePrefix, addNotNullableProperty);
+ if (columnDefIterator.hasNext()) {
+ sql.append(", ");
+ }
+ }
+ }
+
+ private void addColumn(StringBuilder sql, ColumnDef columnDef, String typePrefix, boolean addNotNullableProperty) {
+ sql.append(columnDef.getName())
+ .append(" ")
+ .append(typePrefix)
+ .append(columnDef.generateSqlType(dialect));
+ if (addNotNullableProperty) {
+ sql.append(columnDef.isNullable() ? " NULL" : " NOT NULL");
+ }
+
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateIndexBuilder.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateIndexBuilder.java
new file mode 100644
index 00000000000..426166d9f83
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateIndexBuilder.java
@@ -0,0 +1,121 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.MySql;
+import org.sonar.server.platform.db.migration.def.ColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Collections.singletonList;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.server.platform.db.migration.def.Validations.validateIndexName;
+import static org.sonar.server.platform.db.migration.def.Validations.validateTableName;
+
+public class CreateIndexBuilder {
+
+ private static final int MAX_LENGTH_ON_MYSQL = 255;
+
+ private final Dialect dialect;
+ private final List<ColumnDef> columns = new ArrayList<>();
+ private String tableName;
+ private String indexName;
+ private boolean unique = false;
+
+ public CreateIndexBuilder(Dialect dialect) {
+ this.dialect = dialect;
+ }
+
+ /**
+ * Required name of table on which index is created
+ */
+ public CreateIndexBuilder setTable(String s) {
+ this.tableName = s;
+ return this;
+ }
+
+ /**
+ * Required name of index. Name must be unique among all the tables
+ * of the schema.
+ */
+ public CreateIndexBuilder setName(String s) {
+ this.indexName = s;
+ return this;
+ }
+
+ /**
+ * By default index is NOT UNIQUE (value {@code false}).
+ */
+ public CreateIndexBuilder setUnique(boolean b) {
+ this.unique = b;
+ return this;
+ }
+
+ /**
+ * Add a column to the scope of index. Order of calls to this
+ * method is important and is kept as-is when creating the index.
+ * The attributes used from {@link ColumnDef} are the name, the type
+ * and the length (in case of VARCHAR). Other attributes are ignored.
+ */
+ public CreateIndexBuilder addColumn(ColumnDef column) {
+ columns.add(requireNonNull(column, "Column cannot be null"));
+ return this;
+ }
+
+ public List<String> build() {
+ validateTableName(tableName);
+ validateIndexName(indexName);
+ checkArgument(!columns.isEmpty(), "at least one column must be specified");
+ return singletonList(createSqlStatement());
+ }
+
+ private String createSqlStatement() {
+ StringBuilder sql = new StringBuilder("CREATE ");
+ if (unique) {
+ sql.append("UNIQUE ");
+ }
+ sql.append("INDEX ");
+ sql.append(indexName);
+ sql.append(" ON ");
+ sql.append(tableName);
+ sql.append(" (");
+ sql.append(columns.stream().map(this::columnSql).collect(Collectors.joining(", ")));
+ sql.append(")");
+ return sql.toString();
+ }
+
+ private String columnSql(ColumnDef column) {
+ String length = "";
+ // Index of varchar column is limited to 767 bytes on mysql (<= 255 UTF-8 characters)
+ // See http://jira.sonarsource.com/browse/SONAR-4137 and
+ // http://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html
+ if (dialect.getId().equals(MySql.ID) && column instanceof VarcharColumnDef) {
+ VarcharColumnDef varcharColumn = (VarcharColumnDef) column;
+ if (varcharColumn.getColumnSize() > MAX_LENGTH_ON_MYSQL) {
+ length = "(" + MAX_LENGTH_ON_MYSQL + ")";
+ }
+ }
+ return column.getName() + length;
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilder.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilder.java
new file mode 100644
index 00000000000..179cd97a489
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilder.java
@@ -0,0 +1,282 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Stream;
+import javax.annotation.CheckForNull;
+import org.sonar.core.util.stream.Collectors;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef;
+import org.sonar.server.platform.db.migration.def.ColumnDef;
+import org.sonar.server.platform.db.migration.def.IntegerColumnDef;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+import static java.util.stream.Stream.of;
+import static org.sonar.server.platform.db.migration.def.Validations.validateConstraintName;
+import static org.sonar.server.platform.db.migration.def.Validations.validateTableName;
+
+public class CreateTableBuilder {
+
+ private final Dialect dialect;
+ private final String tableName;
+ private final List<ColumnDef> columnDefs = new ArrayList<>();
+ private final List<ColumnDef> pkColumnDefs = new ArrayList<>(2);
+ private final Multimap<ColumnDef, ColumnFlag> flagsByColumn = HashMultimap.create(1, 1);
+ @CheckForNull
+ private String pkConstraintName;
+
+ public CreateTableBuilder(Dialect dialect, String tableName) {
+ this.dialect = requireNonNull(dialect, "dialect can't be null");
+ this.tableName = validateTableName(tableName);
+ }
+
+ public List<String> build() {
+ checkState(!columnDefs.isEmpty() || !pkColumnDefs.isEmpty(), "at least one column must be specified");
+
+ return Stream.concat(of(createTableStatement()), createOracleAutoIncrementStatements())
+ .collect(Collectors.toList());
+ }
+
+ public CreateTableBuilder addColumn(ColumnDef columnDef) {
+ columnDefs.add(requireNonNull(columnDef, "column def can't be null"));
+ return this;
+ }
+
+ public CreateTableBuilder addPkColumn(ColumnDef columnDef, ColumnFlag... flags) {
+ pkColumnDefs.add(requireNonNull(columnDef, "column def can't be null"));
+ addFlags(columnDef, flags);
+ return this;
+ }
+
+ private void addFlags(ColumnDef columnDef, ColumnFlag[] flags) {
+ Arrays.stream(flags)
+ .forEach(flag -> {
+ requireNonNull(flag, "flag can't be null");
+ if (flag == ColumnFlag.AUTO_INCREMENT) {
+ validateColumnDefForAutoIncrement(columnDef);
+ }
+ flagsByColumn.put(columnDef, flag);
+ });
+ }
+
+ private void validateColumnDefForAutoIncrement(ColumnDef columnDef) {
+ checkArgument("id".equals(columnDef.getName()),
+ "Auto increment column name must be id");
+ checkArgument(columnDef instanceof BigIntegerColumnDef
+ || columnDef instanceof IntegerColumnDef,
+ "Auto increment column must either be BigInteger or Integer");
+ checkArgument(!columnDef.isNullable(),
+ "Auto increment column can't be nullable");
+ checkState(pkColumnDefs.stream().filter(this::isAutoIncrement).count() == 0,
+ "There can't be more than one auto increment column");
+ }
+
+ public CreateTableBuilder withPkConstraintName(String pkConstraintName) {
+ this.pkConstraintName = validateConstraintName(pkConstraintName);
+ return this;
+ }
+
+ private String createTableStatement() {
+ StringBuilder res = new StringBuilder("CREATE TABLE ");
+ res.append(tableName);
+ res.append(" (");
+ appendPkColumns(res);
+ appendColumns(res, dialect, columnDefs);
+ appendPkConstraint(res);
+ res.append(')');
+ appendCollationClause(res, dialect);
+ return res.toString();
+ }
+
+ private void appendPkColumns(StringBuilder res) {
+ appendColumns(res, dialect, pkColumnDefs);
+ if (!pkColumnDefs.isEmpty() && !columnDefs.isEmpty()) {
+ res.append(',');
+ }
+ }
+
+ private void appendColumns(StringBuilder res, Dialect dialect, List<ColumnDef> columnDefs) {
+ if (columnDefs.isEmpty()) {
+ return;
+ }
+ Iterator<ColumnDef> columnDefIterator = columnDefs.iterator();
+ while (columnDefIterator.hasNext()) {
+ ColumnDef columnDef = columnDefIterator.next();
+ res.append(columnDef.getName());
+ res.append(' ');
+ appendDataType(res, dialect, columnDef);
+ appendDefaultValue(res, columnDef);
+ appendNullConstraint(res, columnDef);
+ appendColumnFlags(res, dialect, columnDef);
+ if (columnDefIterator.hasNext()) {
+ res.append(',');
+ }
+ }
+ }
+
+ private void appendDataType(StringBuilder res, Dialect dialect, ColumnDef columnDef) {
+ if (PostgreSql.ID.equals(dialect.getId()) && isAutoIncrement(columnDef)) {
+ if (columnDef instanceof BigIntegerColumnDef) {
+ res.append("BIGSERIAL");
+ } else if (columnDef instanceof IntegerColumnDef) {
+ res.append("SERIAL");
+ } else {
+ throw new IllegalStateException("Column with autoincrement is neither BigInteger nor Integer");
+ }
+ } else {
+ res.append(columnDef.generateSqlType(dialect));
+ }
+ }
+
+ private boolean isAutoIncrement(ColumnDef columnDef) {
+ Collection<ColumnFlag> columnFlags = this.flagsByColumn.get(columnDef);
+ return columnFlags != null && columnFlags.contains(ColumnFlag.AUTO_INCREMENT);
+ }
+
+ private static void appendNullConstraint(StringBuilder res, ColumnDef columnDef) {
+ if (columnDef.isNullable()) {
+ res.append(" NULL");
+ } else {
+ res.append(" NOT NULL");
+ }
+ }
+
+ private void appendDefaultValue(StringBuilder sql, ColumnDef columnDef) {
+ Object defaultValue = columnDef.getDefaultValue();
+ if (defaultValue != null) {
+ sql.append(" DEFAULT ");
+
+ if (defaultValue instanceof String) {
+ sql.append(format("'%s'", defaultValue));
+ } else if (defaultValue instanceof Boolean) {
+ sql.append((boolean) defaultValue ? dialect.getTrueSqlValue() : dialect.getFalseSqlValue());
+ } else {
+ sql.append(defaultValue);
+ }
+ }
+ }
+
+ private void appendColumnFlags(StringBuilder res, Dialect dialect, ColumnDef columnDef) {
+ Collection<ColumnFlag> columnFlags = this.flagsByColumn.get(columnDef);
+ if (columnFlags != null && columnFlags.contains(ColumnFlag.AUTO_INCREMENT)) {
+ switch (dialect.getId()) {
+ case Oracle.ID:
+ // no auto increment on Oracle, must use a sequence
+ break;
+ case PostgreSql.ID:
+ // no specific clause on PostgreSQL but a specific type
+ break;
+ case MsSql.ID:
+ res.append(" IDENTITY (1,1)");
+ break;
+ case MySql.ID:
+ res.append(" AUTO_INCREMENT");
+ break;
+ case H2.ID:
+ res.append(" AUTO_INCREMENT (1,1)");
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported dialect id " + dialect.getId());
+ }
+ }
+ }
+
+ private void appendPkConstraint(StringBuilder res) {
+ if (pkColumnDefs.isEmpty()) {
+ return;
+ }
+ res.append(", ");
+ res.append("CONSTRAINT ");
+ appendPkConstraintName(res);
+ res.append(" PRIMARY KEY ");
+ res.append('(');
+ appendColumnNames(res, pkColumnDefs);
+ res.append(')');
+ }
+
+ private void appendPkConstraintName(StringBuilder res) {
+ if (pkConstraintName == null) {
+ res.append("pk_").append(tableName);
+ } else {
+ res.append(pkConstraintName.toLowerCase(Locale.ENGLISH));
+ }
+ }
+
+ private static void appendColumnNames(StringBuilder res, List<ColumnDef> columnDefs) {
+ Iterator<ColumnDef> columnDefIterator = columnDefs.iterator();
+ while (columnDefIterator.hasNext()) {
+ res.append(columnDefIterator.next().getName());
+ if (columnDefIterator.hasNext()) {
+ res.append(',');
+ }
+ }
+ }
+
+ private static void appendCollationClause(StringBuilder res, Dialect dialect) {
+ if (MySql.ID.equals(dialect.getId())) {
+ res.append(" ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin");
+ }
+ }
+
+ private Stream<String> createOracleAutoIncrementStatements() {
+ if (!Oracle.ID.equals(dialect.getId())) {
+ return Stream.empty();
+ }
+ return pkColumnDefs.stream()
+ .filter(this::isAutoIncrement)
+ .flatMap(columnDef -> of(createSequenceFor(tableName), createOracleTriggerForTable(tableName)));
+ }
+
+ private static String createSequenceFor(String tableName) {
+ return "CREATE SEQUENCE " + tableName + "_seq START WITH 1 INCREMENT BY 1";
+ }
+
+ static String createOracleTriggerForTable(String tableName) {
+ return "CREATE OR REPLACE TRIGGER " + tableName + "_idt" +
+ " BEFORE INSERT ON " + tableName +
+ " FOR EACH ROW" +
+ " BEGIN" +
+ " IF :new.id IS null THEN" +
+ " SELECT " + tableName + "_seq.nextval INTO :new.id FROM dual;" +
+ " END IF;" +
+ " END;";
+ }
+
+ public enum ColumnFlag {
+ AUTO_INCREMENT
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropColumnsBuilder.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropColumnsBuilder.java
new file mode 100644
index 00000000000..99d0f69fd8e
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropColumnsBuilder.java
@@ -0,0 +1,75 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+/**
+ * Generate a SQL query to drop multiple columns from a table
+ */
+public class DropColumnsBuilder {
+
+ private final Dialect dialect;
+ private final String tableName;
+ private final String[] columns;
+
+ public DropColumnsBuilder(Dialect dialect, String tableName, String... columns) {
+ this.tableName = tableName;
+ this.dialect = dialect;
+ this.columns = columns;
+ }
+
+ public String build() {
+ StringBuilder sql = new StringBuilder().append("ALTER TABLE ").append(tableName).append(" ");
+ switch (dialect.getId()) {
+ case PostgreSql.ID:
+ case MySql.ID:
+ dropColumns(sql, "DROP COLUMN ");
+ break;
+ case MsSql.ID:
+ sql.append("DROP COLUMN ");
+ dropColumns(sql, "");
+ break;
+ case Oracle.ID:
+ sql.append("DROP (");
+ dropColumns(sql, "");
+ sql.append(")");
+ break;
+ default:
+ throw new IllegalStateException(String.format("Unsupported database '%s'", dialect.getId()));
+ }
+ return sql.toString();
+ }
+
+ private void dropColumns(StringBuilder sql, String columnPrefix) {
+ for (int i = 0; i < columns.length; i++) {
+ sql.append(columnPrefix);
+ sql.append(columns[i]);
+ if (i < columns.length - 1) {
+ sql.append(", ");
+ }
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropIndexBuilder.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropIndexBuilder.java
new file mode 100644
index 00000000000..56e9e4eb357
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropIndexBuilder.java
@@ -0,0 +1,75 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.List;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static java.util.Collections.singletonList;
+import static org.sonar.server.platform.db.migration.def.Validations.validateIndexName;
+import static org.sonar.server.platform.db.migration.def.Validations.validateTableName;
+
+public class DropIndexBuilder {
+
+ private final Dialect dialect;
+ private String tableName;
+ private String indexName;
+
+ public DropIndexBuilder(Dialect dialect) {
+ this.dialect = dialect;
+ }
+
+ public DropIndexBuilder setTable(String s) {
+ this.tableName = s;
+ return this;
+ }
+
+ public DropIndexBuilder setName(String s) {
+ this.indexName = s;
+ return this;
+ }
+
+ public List<String> build() {
+ validateTableName(tableName);
+ validateIndexName(indexName);
+ return singletonList(createSqlStatement());
+ }
+
+ private String createSqlStatement() {
+ switch (dialect.getId()) {
+ case MsSql.ID:
+ case MySql.ID:
+ return "DROP INDEX " + indexName + " ON " + tableName;
+ case Oracle.ID:
+ return "DROP INDEX " + indexName;
+ case H2.ID:
+ case PostgreSql.ID:
+ return "DROP INDEX IF EXISTS " + indexName;
+ default:
+ throw new IllegalStateException("Unsupported dialect for drop of index: " + dialect);
+ }
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropTableBuilder.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropTableBuilder.java
new file mode 100644
index 00000000000..ac736ccc446
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/DropTableBuilder.java
@@ -0,0 +1,79 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.List;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.Oracle;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.server.platform.db.migration.def.Validations.validateTableName;
+
+public class DropTableBuilder {
+
+ private final Dialect dialect;
+ private final String tableName;
+
+ public DropTableBuilder(Dialect dialect, String tableName) {
+ this.dialect = requireNonNull(dialect, "dialect can't be null");
+ this.tableName = validateTableName(tableName);
+ }
+
+ public List<String> build() {
+ if (Oracle.ID.equals(dialect.getId())) {
+ return dropOracleSequenceAndTriggerAndTableStatements();
+ }
+ return singletonList(dropTableStatement());
+ }
+
+ private String dropTableStatement() {
+ return "DROP TABLE " + tableName;
+ }
+
+ private List<String> dropOracleSequenceAndTriggerAndTableStatements() {
+ return asList(dropSequenceFor(tableName), dropTriggerFor(tableName), dropTableStatement());
+ }
+
+ private static String dropSequenceFor(String tableName) {
+ return "BEGIN\n" +
+ " EXECUTE IMMEDIATE 'DROP SEQUENCE " + tableName + "_seq';\n" +
+ "EXCEPTION\n" +
+ " WHEN OTHERS THEN\n" +
+ " IF SQLCODE != -2289 THEN\n" +
+ " RAISE;\n" +
+ " END IF;\n" +
+ "END;";
+ }
+
+ private static String dropTriggerFor(String tableName) {
+ return "BEGIN\n" +
+ " EXECUTE IMMEDIATE 'DROP TRIGGER " + tableName + "_idt';\n" +
+ "EXCEPTION\n" +
+ " WHEN OTHERS THEN\n" +
+ " IF SQLCODE != -4080 THEN\n" +
+ " RAISE;\n" +
+ " END IF;\n" +
+ "END;";
+
+ }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/RenameTableBuilder.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/RenameTableBuilder.java
new file mode 100644
index 00000000000..0e1b79cfb0a
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/RenameTableBuilder.java
@@ -0,0 +1,85 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.Arrays;
+import java.util.List;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Collections.singletonList;
+import static org.sonar.server.platform.db.migration.def.Validations.validateTableName;
+
+/**
+ * Limitation: only tables with auto-generated ID column can
+ * be renamed as the Oracle implementation assumes that
+ * the sequence and trigger related to ID column exist.
+ */
+public class RenameTableBuilder {
+
+ private final Dialect dialect;
+ private String name;
+ private String newName;
+
+ public RenameTableBuilder(Dialect dialect) {
+ this.dialect = dialect;
+ }
+
+ public RenameTableBuilder setName(String s) {
+ this.name = s;
+ return this;
+ }
+
+ public RenameTableBuilder setNewName(String s) {
+ this.newName = s;
+ return this;
+ }
+
+ public List<String> build() {
+ validateTableName(name);
+ validateTableName(newName);
+ checkArgument(!name.equals(newName), "Names must be different");
+ return createSqlStatement();
+ }
+
+ private List<String> createSqlStatement() {
+ switch (dialect.getId()) {
+ case H2.ID:
+ case MySql.ID:
+ case PostgreSql.ID:
+ return singletonList("ALTER TABLE " + name + " RENAME TO " + newName);
+ case MsSql.ID:
+ return singletonList("EXEC sp_rename '" + name + "', '" + newName + "'");
+ case Oracle.ID:
+ return Arrays.asList(
+ "DROP TRIGGER " + name + "_idt",
+ "RENAME " + name + " TO " + newName,
+ "RENAME " + name + "_seq TO " + newName + "_seq",
+ CreateTableBuilder.createOracleTriggerForTable(newName));
+ default:
+ throw new IllegalArgumentException("Unsupported dialect id " + dialect.getId());
+ }
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/package-info.java
new file mode 100644
index 00000000000..e949c01ee67
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.platform.db.migration.sql;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchema.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchema.java
index d037512bbf0..616845db87e 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchema.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchema.java
@@ -21,24 +21,24 @@ package org.sonar.server.platform.db.migration.version.v56;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.BigIntegerColumnDef;
-import org.sonar.db.version.BooleanColumnDef;
-import org.sonar.db.version.ColumnDef;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.CreateTableBuilder;
-import org.sonar.db.version.IntegerColumnDef;
-import org.sonar.db.version.TinyIntColumnDef;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef;
+import org.sonar.server.platform.db.migration.def.BooleanColumnDef;
+import org.sonar.server.platform.db.migration.def.ColumnDef;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.def.IntegerColumnDef;
+import org.sonar.server.platform.db.migration.def.TinyIntColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.BlobColumnDef.newBlobColumnDefBuilder;
-import static org.sonar.db.version.BooleanColumnDef.newBooleanColumnDefBuilder;
-import static org.sonar.db.version.ClobColumnDef.newClobColumnDefBuilder;
-import static org.sonar.db.version.CreateTableBuilder.ColumnFlag.AUTO_INCREMENT;
-import static org.sonar.db.version.DecimalColumnDef.newDecimalColumnDefBuilder;
-import static org.sonar.db.version.IntegerColumnDef.newIntegerColumnDefBuilder;
-import static org.sonar.db.version.TimestampColumnDef.newTimestampColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BlobColumnDef.newBlobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.sql.CreateTableBuilder.ColumnFlag.AUTO_INCREMENT;
+import static org.sonar.server.platform.db.migration.def.DecimalColumnDef.newDecimalColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.TimestampColumnDef.newTimestampColumnDefBuilder;
public class CreateInitialSchema extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToCeActivity.java
index c2c0f5f106c..b6046e24da7 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToCeActivity.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToCeActivity.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddAnalysisUuidColumnToCeActivity extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToEvents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToEvents.java
index 997537af395..a7ef82999a6 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToEvents.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToEvents.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddAnalysisUuidColumnToEvents extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToMeasures.java
index ba46106db69..07ba2673ad7 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddAnalysisUuidColumnToMeasures.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddAnalysisUuidColumnToMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddBColumnsToProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddBColumnsToProjects.java
index d732e1979fe..cdcf542013a 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddBColumnsToProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddBColumnsToProjects.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BooleanColumnDef.newBooleanColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddBColumnsToProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java
index 6b4cec7969a..9ac0cb41f48 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnToMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnToMeasures.java
index 50bce535743..c9ccd9787e7 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnToMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnToMeasures.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddComponentUuidColumnToMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnsToSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnsToSnapshots.java
index 3ebcbd9c5c0..800c61185ec 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnsToSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddComponentUuidColumnsToSnapshots.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddComponentUuidColumnsToSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnAnalysisUuidOfMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnAnalysisUuidOfMeasures.java
index 1650a209653..f888656d1ab 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnAnalysisUuidOfMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnAnalysisUuidOfMeasures.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.IntegerColumnDef.newIntegerColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddIndexOnAnalysisUuidOfMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnComponentUuidOfMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnComponentUuidOfMeasures.java
index 8af98e444e6..9cbd9934209 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnComponentUuidOfMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddIndexOnComponentUuidOfMeasures.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddIndexOnComponentUuidOfMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddLastUsedColumnToRulesProfiles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddLastUsedColumnToRulesProfiles.java
index 3b289a0a34f..056ff614dd4 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddLastUsedColumnToRulesProfiles.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddLastUsedColumnToRulesProfiles.java
@@ -22,10 +22,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
public class AddLastUsedColumnToRulesProfiles extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddProfileKeyToActivities.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddProfileKeyToActivities.java
index 8c4e24762f7..4518fb327ce 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddProfileKeyToActivities.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddProfileKeyToActivities.java
@@ -22,10 +22,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddProfileKeyToActivities extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUniqueIndexOnUuidOfSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUniqueIndexOnUuidOfSnapshots.java
index a90e024c317..445bdc6f5ac 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUniqueIndexOnUuidOfSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUniqueIndexOnUuidOfSnapshots.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddUniqueIndexOnUuidOfSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUserUpdatedAtToRulesProfiles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUserUpdatedAtToRulesProfiles.java
index 14d3f91f0cd..68472cc214f 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUserUpdatedAtToRulesProfiles.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUserUpdatedAtToRulesProfiles.java
@@ -22,10 +22,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
public class AddUserUpdatedAtToRulesProfiles extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnToSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnToSnapshots.java
index aa99605cc16..1f0518680ae 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnToSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnToSnapshots.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddUuidColumnToSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToProjects.java
index a19323af4a4..bbd11059d1f 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToProjects.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddUuidColumnsToProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToResourceIndex.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToResourceIndex.java
index ae003ab6569..4e03354306b 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToResourceIndex.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidColumnsToResourceIndex.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddUuidColumnsToResourceIndex extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidPathColumnToProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidPathColumnToProjects.java
index 1d127ac2931..321871d0ecf 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidPathColumnToProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/AddUuidPathColumnToProjects.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddUuidPathColumnToProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreatePermTemplatesCharacteristics.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreatePermTemplatesCharacteristics.java
index 1db6e771a26..b31fa57b24f 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreatePermTemplatesCharacteristics.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreatePermTemplatesCharacteristics.java
@@ -21,17 +21,17 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.CreateTableBuilder;
-import org.sonar.db.version.IntegerColumnDef;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.def.IntegerColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.BooleanColumnDef.newBooleanColumnDefBuilder;
-import static org.sonar.db.version.CreateTableBuilder.ColumnFlag.AUTO_INCREMENT;
-import static org.sonar.db.version.IntegerColumnDef.newIntegerColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.sql.CreateTableBuilder.ColumnFlag.AUTO_INCREMENT;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreatePermTemplatesCharacteristics extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreateTemporaryIndicesFor1211.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreateTemporaryIndicesFor1211.java
index f591285f484..ec3a5c99a03 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreateTemporaryIndicesFor1211.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/CreateTemporaryIndicesFor1211.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
public class CreateTemporaryIndicesFor1211 extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromProjects.java
index 05a0eb32bec..6e21f383aa4 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromProjects.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIdColumnsFromProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromResourceIndex.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromResourceIndex.java
index 43cec60ca59..168c4ca810d 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromResourceIndex.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromResourceIndex.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIdColumnsFromResourceIndex extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromSnapshots.java
index d53c22f93ab..024d212d4e7 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIdColumnsFromSnapshots.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIdColumnsFromSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexDuplicationsIndexSidFromDuplicationsIndex.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexDuplicationsIndexSidFromDuplicationsIndex.java
index 12db9932baf..969119dc139 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexDuplicationsIndexSidFromDuplicationsIndex.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexDuplicationsIndexSidFromDuplicationsIndex.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIndexDuplicationsIndexSidFromDuplicationsIndex extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexEventsSnapshotIdFromEvents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexEventsSnapshotIdFromEvents.java
index 4b1e0bdf177..c5b85611fa1 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexEventsSnapshotIdFromEvents.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexEventsSnapshotIdFromEvents.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIndexEventsSnapshotIdFromEvents extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexOnSnapshotIdOfMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexOnSnapshotIdOfMeasures.java
index 22ef746c73e..78c341a93bb 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexOnSnapshotIdOfMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexOnSnapshotIdOfMeasures.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIndexOnSnapshotIdOfMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsRootIdFromProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsRootIdFromProjects.java
index 647b194c752..be87d471244 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsRootIdFromProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsRootIdFromProjects.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIndexProjectsRootIdFromProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsUuidFromProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsUuidFromProjects.java
index 1f4dc0c296d..1aa43ae335c 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsUuidFromProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndexProjectsUuidFromProjects.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIndexProjectsUuidFromProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndicesOnTreeColumnsOfSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndicesOnTreeColumnsOfSnapshots.java
index 5269f796617..1ae8098acf2 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndicesOnTreeColumnsOfSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropIndicesOnTreeColumnsOfSnapshots.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropIndicesOnTreeColumnsOfSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropProjectIdColumnFromMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropProjectIdColumnFromMeasures.java
index 1b20ef3ac7b..9fe4d33b699 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropProjectIdColumnFromMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropProjectIdColumnFromMeasures.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropProjectIdColumnFromMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropRememberMeColumnsFromUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropRememberMeColumnsFromUsers.java
index da23d199f41..9fde69552cb 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropRememberMeColumnsFromUsers.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropRememberMeColumnsFromUsers.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropRememberMeColumnsFromUsers extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropResourceIndexRidFromResourceIndex.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropResourceIndexRidFromResourceIndex.java
index 35435c8a02e..17a493a75fb 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropResourceIndexRidFromResourceIndex.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropResourceIndexRidFromResourceIndex.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropResourceIndexRidFromResourceIndex extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromCeActivity.java
index 4f2c6ad65ad..edf06ba9620 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromCeActivity.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromCeActivity.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropSnapshotIdColumnFromCeActivity extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromEvents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromEvents.java
index 976100d3dbb..6a180860ad7 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromEvents.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromEvents.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropSnapshotIdColumnFromEvents extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromMeasures.java
index ca1e91b838f..8938997a313 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnFromMeasures.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropSnapshotIdColumnFromMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnsFromDuplicationsIndex.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnsFromDuplicationsIndex.java
index b4b7a20ce7a..0b525f0efc8 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnsFromDuplicationsIndex.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotIdColumnsFromDuplicationsIndex.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropSnapshotIdColumnsFromDuplicationsIndex extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotProjectIdFromSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotProjectIdFromSnapshots.java
index 782dd38425b..dc93a9cf7d8 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotProjectIdFromSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropSnapshotProjectIdFromSnapshots.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropSnapshotProjectIdFromSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTemporaryIndicesOf1210.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTemporaryIndicesOf1210.java
index 16e6151087e..aaf6b6a6ee4 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTemporaryIndicesOf1210.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTemporaryIndicesOf1210.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropTemporaryIndicesOf1210 extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTreeColumnsFromSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTreeColumnsFromSnapshots.java
index 9051c594d0b..7a614c28f0d 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTreeColumnsFromSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropTreeColumnsFromSnapshots.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class DropTreeColumnsFromSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropUnusedMeasuresColumns.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropUnusedMeasuresColumns.java
index 64de75fdb4c..78acda8aada 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropUnusedMeasuresColumns.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/DropUnusedMeasuresColumns.java
@@ -22,7 +22,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import com.google.common.annotations.VisibleForTesting;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
/**
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnEvents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnEvents.java
index 3ffc82dc788..e1ff462406e 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnEvents.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnEvents.java
@@ -21,13 +21,13 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeAnalysisUuidNotNullOnEvents extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnMeasures.java
index 63b18552c7a..c4f630861ba 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeAnalysisUuidNotNullOnMeasures.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeAnalysisUuidNotNullOnMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java
index 1604d77d52d..58245a455a4 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java
@@ -21,13 +21,13 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidColumnsNotNullOnSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidColumnsNotNullOnSnapshots.java
index aa85bcb42c3..a0b0c3527a3 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidColumnsNotNullOnSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidColumnsNotNullOnSnapshots.java
@@ -21,13 +21,13 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeComponentUuidColumnsNotNullOnSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidNotNullOnMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidNotNullOnMeasures.java
index 7a4b5422000..616560b641e 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidNotNullOnMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeComponentUuidNotNullOnMeasures.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeComponentUuidNotNullOnMeasures extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeProfileKeyNotNullOnActivities.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeProfileKeyNotNullOnActivities.java
index 19c9066588b..d6282bfff83 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeProfileKeyNotNullOnActivities.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeProfileKeyNotNullOnActivities.java
@@ -22,10 +22,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeProfileKeyNotNullOnActivities extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnNotNullOnSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnNotNullOnSnapshots.java
index b88339fe2d7..38a4f0f4ed1 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnNotNullOnSnapshots.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnNotNullOnSnapshots.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeUuidColumnNotNullOnSnapshots extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnProjects.java
index f9929ca7988..a735f578d13 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnProjects.java
@@ -21,13 +21,13 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeUuidColumnsNotNullOnProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnResourceIndex.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnResourceIndex.java
index 5954af2ab11..6ea1d60def4 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnResourceIndex.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidColumnsNotNullOnResourceIndex.java
@@ -21,13 +21,13 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeUuidColumnsNotNullOnResourceIndex extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidPathColumnNotNullOnProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidPathColumnNotNullOnProjects.java
index 412054e489e..e72488bcb84 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidPathColumnNotNullOnProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/MakeUuidPathColumnNotNullOnProjects.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeUuidPathColumnNotNullOnProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/RecreateIndexProjectsUuidFromProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/RecreateIndexProjectsUuidFromProjects.java
index 1741e273004..4f011a33027 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/RecreateIndexProjectsUuidFromProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/RecreateIndexProjectsUuidFromProjects.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class RecreateIndexProjectsUuidFromProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/TemporarilyDropIndexOfAnalysisUuidOnMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/TemporarilyDropIndexOfAnalysisUuidOnMeasures.java
index d54450e323a..1745a82aa2f 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/TemporarilyDropIndexOfAnalysisUuidOnMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v60/TemporarilyDropIndexOfAnalysisUuidOnMeasures.java
@@ -21,7 +21,7 @@ package org.sonar.server.platform.db.migration.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
/**
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddBUuidPathToProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddBUuidPathToProjects.java
index d695c123c2c..b12fb657371 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddBUuidPathToProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddBUuidPathToProjects.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddBUuidPathToProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddErrorColumnsToCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddErrorColumnsToCeActivity.java
index 51c650c9d21..79924fc2f60 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddErrorColumnsToCeActivity.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/AddErrorColumnsToCeActivity.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.ClobColumnDef.newClobColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddErrorColumnsToCeActivity extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableCeTaskInput.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableCeTaskInput.java
index 18cc2011134..aa1115d07c3 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableCeTaskInput.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableCeTaskInput.java
@@ -21,13 +21,13 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.BlobColumnDef.newBlobColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BlobColumnDef.newBlobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreateTableCeTaskInput extends DdlChange {
public CreateTableCeTaskInput(Database db) {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableInternalProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableInternalProperties.java
index 716dff4995d..9df8af78629 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableInternalProperties.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableInternalProperties.java
@@ -21,14 +21,14 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.BooleanColumnDef.newBooleanColumnDefBuilder;
-import static org.sonar.db.version.ClobColumnDef.newClobColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.MAX_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreateTableInternalProperties extends DdlChange {
public CreateTableInternalProperties(Database db) {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableProperties2.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableProperties2.java
index 9a2cf834dab..4a9d5524feb 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableProperties2.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableProperties2.java
@@ -22,18 +22,18 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import java.util.List;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.BooleanColumnDef.newBooleanColumnDefBuilder;
-import static org.sonar.db.version.ClobColumnDef.newClobColumnDefBuilder;
-import static org.sonar.db.version.CreateTableBuilder.ColumnFlag.AUTO_INCREMENT;
-import static org.sonar.db.version.IntegerColumnDef.newIntegerColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.MAX_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.sql.CreateTableBuilder.ColumnFlag.AUTO_INCREMENT;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreateTableProperties2 extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableQprofileChanges.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableQprofileChanges.java
index 6ee1a8f846a..52c7fd25627 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableQprofileChanges.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableQprofileChanges.java
@@ -22,12 +22,12 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import java.util.List;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.ClobColumnDef.newClobColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreateTableQprofileChanges extends DdlChange {
public CreateTableQprofileChanges(Database db) {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableRuleRepositories.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableRuleRepositories.java
index 77b0837eb02..912115e9c99 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableRuleRepositories.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableRuleRepositories.java
@@ -22,11 +22,11 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import java.util.List;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreateTableRuleRepositories extends DdlChange {
public CreateTableRuleRepositories(Database db) {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableScannerContext.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableScannerContext.java
index 6d298162407..e0231c16233 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableScannerContext.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/CreateTableScannerContext.java
@@ -21,13 +21,13 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.BlobColumnDef.newBlobColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BlobColumnDef.newBlobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreateTableScannerContext extends DdlChange {
public CreateTableScannerContext(Database db) {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropIsGlobalFromDashboards.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropIsGlobalFromDashboards.java
index ef5955172dd..fe2be4905d0 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropIsGlobalFromDashboards.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropIsGlobalFromDashboards.java
@@ -23,7 +23,7 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import org.sonar.db.version.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
public class DropIsGlobalFromDashboards extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableActivities.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableActivities.java
index 64ba3190dca..be601e1b83d 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableActivities.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableActivities.java
@@ -22,8 +22,8 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import org.sonar.db.version.DropIndexBuilder;
-import org.sonar.db.version.DropTableBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropTableBuilder;
public class DropTableActivities extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableProperties.java
index ae2a8163d08..c89bbee8e81 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableProperties.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/DropTableProperties.java
@@ -22,8 +22,8 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import org.sonar.db.version.DropIndexBuilder;
-import org.sonar.db.version.DropTableBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropTableBuilder;
public class DropTableProperties extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/RenameTableProperties2ToProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/RenameTableProperties2ToProperties.java
index b0185fd37ce..ee2e98c59fe 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/RenameTableProperties2ToProperties.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/RenameTableProperties2ToProperties.java
@@ -21,12 +21,12 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import org.sonar.db.version.DropIndexBuilder;
-import org.sonar.db.version.RenameTableBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.RenameTableBuilder;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class RenameTableProperties2ToProperties extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/ShrinkModuleUuidPathOfProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/ShrinkModuleUuidPathOfProjects.java
index 25e682b85f3..90798cf146f 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/ShrinkModuleUuidPathOfProjects.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v61/ShrinkModuleUuidPathOfProjects.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v61;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class ShrinkModuleUuidPathOfProjects extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddIsRootColumnOnTableUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddIsRootColumnOnTableUsers.java
index e56d2acb1fb..2d12b86ed7d 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddIsRootColumnOnTableUsers.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddIsRootColumnOnTableUsers.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
public class AddIsRootColumnOnTableUsers extends DdlChange {
public AddIsRootColumnOnTableUsers(Database db) {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroupRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroupRoles.java
index 42b07fc5736..c8a46df1150 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroupRoles.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroupRoles.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddOrganizationUuidToGroupRoles extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroups.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroups.java
index 51414df62b1..7f284972c08 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroups.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToGroups.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddOrganizationUuidToGroups extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToPermissionTemplates.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToPermissionTemplates.java
index 5cd32450367..99daaa3e609 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToPermissionTemplates.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToPermissionTemplates.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddOrganizationUuidToPermissionTemplates extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToUserRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToUserRoles.java
index 5dc1293554a..4de5aabf576 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToUserRoles.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/AddOrganizationUuidToUserRoles.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddOrganizationUuidToUserRoles extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableOrganizations.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableOrganizations.java
index 340e1915131..858e48430b5 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableOrganizations.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableOrganizations.java
@@ -21,14 +21,14 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.CreateTableBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreateTableOrganizations extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableWebhookDeliveries.java
index 2d1902d5029..85254870626 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableWebhookDeliveries.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/CreateTableWebhookDeliveries.java
@@ -21,17 +21,17 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.CreateTableBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
-import static org.sonar.db.version.BooleanColumnDef.newBooleanColumnDefBuilder;
-import static org.sonar.db.version.ClobColumnDef.newClobColumnDefBuilder;
-import static org.sonar.db.version.IntegerColumnDef.newIntegerColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class CreateTableWebhookDeliveries extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropIssueFiltersTables.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropIssueFiltersTables.java
index f09bc1908d2..517147aaaee 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropIssueFiltersTables.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropIssueFiltersTables.java
@@ -27,7 +27,7 @@ import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.Database;
import org.sonar.db.DatabaseUtils;
-import org.sonar.db.version.DropTableBuilder;
+import org.sonar.server.platform.db.migration.sql.DropTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
import static org.sonar.core.util.stream.Collectors.toList;
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropMeasureFiltersTables.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropMeasureFiltersTables.java
index d74a0d9675c..99c4ec23674 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropMeasureFiltersTables.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropMeasureFiltersTables.java
@@ -27,7 +27,7 @@ import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.Database;
import org.sonar.db.DatabaseUtils;
-import org.sonar.db.version.DropTableBuilder;
+import org.sonar.server.platform.db.migration.sql.DropTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
import static org.sonar.core.util.stream.Collectors.toList;
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropRelatedDashboardTables.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropRelatedDashboardTables.java
index 82538590a4c..511716d3d86 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropRelatedDashboardTables.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/DropRelatedDashboardTables.java
@@ -27,7 +27,7 @@ import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.Database;
import org.sonar.db.DatabaseUtils;
-import org.sonar.db.version.DropTableBuilder;
+import org.sonar.server.platform.db.migration.sql.DropTableBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
import static org.sonar.core.util.stream.Collectors.toList;
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/IncludeOrganizationUuidInUniqueIndexOfGroupRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/IncludeOrganizationUuidInUniqueIndexOfGroupRoles.java
index 5d59ad388aa..a406ff73ab7 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/IncludeOrganizationUuidInUniqueIndexOfGroupRoles.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/IncludeOrganizationUuidInUniqueIndexOfGroupRoles.java
@@ -21,12 +21,12 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.IntegerColumnDef.newIntegerColumnDefBuilder;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class IncludeOrganizationUuidInUniqueIndexOfGroupRoles extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroupRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroupRoles.java
index 980a0c27f40..715392979e6 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroupRoles.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroupRoles.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeOrganizationUuidNotNullOnGroupRoles extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroups.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroups.java
index f87396c892b..7e61a4e0986 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroups.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnGroups.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeOrganizationUuidNotNullOnGroups extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnPermissionTemplates.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnPermissionTemplates.java
index 6453cb16602..d6364521ecf 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnPermissionTemplates.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnPermissionTemplates.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeOrganizationUuidNotNullOnPermissionTemplates extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnUserRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnUserRoles.java
index c2908b377e9..3ff9590f01c 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnUserRoles.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeOrganizationUuidNotNullOnUserRoles.java
@@ -21,11 +21,11 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeOrganizationUuidNotNullOnUserRoles extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeRootColumnNotNullOnTableUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeRootColumnNotNullOnTableUsers.java
index c5463e153b1..d56b43cb3e1 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeRootColumnNotNullOnTableUsers.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v62/MakeRootColumnNotNullOnTableUsers.java
@@ -21,10 +21,10 @@ package org.sonar.server.platform.db.migration.version.v62;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
public class MakeRootColumnNotNullOnTableUsers extends DdlChange {
public MakeRootColumnNotNullOnTableUsers(Database db) {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/AddUuidToEvents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/AddUuidToEvents.java
index 9f4b53bdcf6..f0a94fddf8e 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/AddUuidToEvents.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/AddUuidToEvents.java
@@ -22,11 +22,11 @@ package org.sonar.server.platform.db.migration.version.v63;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AddColumnsBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class AddUuidToEvents extends DdlChange {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/MakeUuidNotNullOnEvents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/MakeUuidNotNullOnEvents.java
index 972c7ef9b0b..aabf4a1f775 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/MakeUuidNotNullOnEvents.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/MakeUuidNotNullOnEvents.java
@@ -21,13 +21,13 @@ package org.sonar.server.platform.db.migration.version.v63;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.AlterColumnsBuilder;
-import org.sonar.db.version.CreateIndexBuilder;
-import org.sonar.db.version.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
import org.sonar.server.platform.db.migration.step.DdlChange;
-import static org.sonar.db.version.VarcharColumnDef.UUID_SIZE;
-import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
public class MakeUuidNotNullOnEvents extends DdlChange {
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BigIntegerColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BigIntegerColumnDefTest.java
new file mode 100644
index 00000000000..2d407ab1738
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BigIntegerColumnDefTest.java
@@ -0,0 +1,91 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class BigIntegerColumnDefTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void build_string_column_def() throws Exception {
+ BigIntegerColumnDef def = new BigIntegerColumnDef.Builder()
+ .setColumnName("issues")
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.getName()).isEqualTo("issues");
+ assertThat(def.isNullable()).isTrue();
+ }
+
+ @Test
+ public void build_string_column_def_with_default_values() throws Exception {
+ BigIntegerColumnDef def = new BigIntegerColumnDef.Builder()
+ .setColumnName("issues")
+ .build();
+
+ assertThat(def.getName()).isEqualTo("issues");
+ assertThat(def.isNullable()).isTrue();
+ }
+
+ @Test
+ public void generate_sql_type() throws Exception {
+ BigIntegerColumnDef def = new BigIntegerColumnDef.Builder()
+ .setColumnName("issues")
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.generateSqlType(new H2())).isEqualTo("BIGINT");
+ assertThat(def.generateSqlType(new PostgreSql())).isEqualTo("BIGINT");
+ assertThat(def.generateSqlType(new MsSql())).isEqualTo("BIGINT");
+ assertThat(def.generateSqlType(new MySql())).isEqualTo("BIGINT");
+ assertThat(def.generateSqlType(new Oracle())).isEqualTo("NUMBER (38)");
+ }
+
+ @Test
+ public void fail_with_NPE_if_name_is_null() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new BigIntegerColumnDef.Builder()
+ .setColumnName(null);
+ }
+
+ @Test
+ public void fail_with_NPE_if_no_name() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new BigIntegerColumnDef.Builder()
+ .build();
+ }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BlobColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BlobColumnDefTest.java
new file mode 100644
index 00000000000..622678c0e1c
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BlobColumnDefTest.java
@@ -0,0 +1,113 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.server.platform.db.migration.def.BlobColumnDef.newBlobColumnDefBuilder;
+
+public class BlobColumnDefTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private BlobColumnDef underTest = newBlobColumnDefBuilder().setColumnName("a").build();
+
+ @Test
+ public void builder_setColumnName_throws_IAE_if_name_is_not_lowercase() {
+ BlobColumnDef.Builder builder = newBlobColumnDefBuilder();
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Column name must be lower case and contain only alphanumeric chars or '_', got 'T'");
+ builder.setColumnName("T");
+ }
+
+ @Test
+ public void builder_build_throws_NPE_if_no_name_was_set() {
+ BlobColumnDef.Builder builder = newBlobColumnDefBuilder();
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Column name cannot be null");
+
+ builder.build();
+ }
+
+ @Test
+ public void blobColumDef_is_nullable_by_default() {
+ assertThat(newBlobColumnDefBuilder().setColumnName("a").build().isNullable()).isTrue();
+ }
+
+ @Test
+ public void builder_setNullable_sets_nullable_field_of_BlobColumnDef() {
+ assertThat(newBlobColumnDefBuilder().setColumnName("a").setIsNullable(true).build().isNullable()).isTrue();
+ assertThat(newBlobColumnDefBuilder().setColumnName("a").setIsNullable(false).build().isNullable()).isFalse();
+ }
+
+ @Test
+ public void builder_setColumnName_sets_name_field_of_BlobColumnDef() {
+ assertThat(newBlobColumnDefBuilder().setColumnName("a").build().getName()).isEqualTo("a");
+ }
+
+ @Test
+ public void generateSqlType_for_MsSql() {
+ assertThat(underTest.generateSqlType(new MsSql())).isEqualTo("VARBINARY(MAX)");
+ }
+
+ @Test
+ public void generateSqlType_for_MySql() {
+ assertThat(underTest.generateSqlType(new MySql())).isEqualTo("LONGBLOB");
+ }
+
+ @Test
+ public void generateSqlType_for_Oracle() {
+ assertThat(underTest.generateSqlType(new Oracle())).isEqualTo("BLOB");
+ }
+
+ @Test
+ public void generateSqlType_for_H2() {
+ assertThat(underTest.generateSqlType(new H2())).isEqualTo("BLOB");
+ }
+
+ @Test
+ public void generateSqlType_for_PostgreSql() {
+ assertThat(underTest.generateSqlType(new PostgreSql())).isEqualTo("BYTEA");
+ }
+
+ @Test
+ public void generateSqlType_thows_IAE_for_unknown_dialect() {
+ Dialect dialect = mock(Dialect.class);
+ when(dialect.getId()).thenReturn("AAA");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Unsupported dialect id AAA");
+
+ underTest.generateSqlType(dialect);
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BooleanColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BooleanColumnDefTest.java
new file mode 100644
index 00000000000..6c9fcb7795f
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/BooleanColumnDefTest.java
@@ -0,0 +1,94 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+public class BooleanColumnDefTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void build_column_def() throws Exception {
+ BooleanColumnDef def = new BooleanColumnDef.Builder()
+ .setColumnName("enabled")
+ .setIsNullable(false)
+ .setDefaultValue(true)
+ .build();
+
+ assertThat(def.getName()).isEqualTo("enabled");
+ assertThat(def.isNullable()).isFalse();
+ assertThat(def.getDefaultValue()).isEqualTo(true);
+ }
+
+ @Test
+ public void build_column_def_with_only_required_attributes() throws Exception {
+ BooleanColumnDef def = new BooleanColumnDef.Builder()
+ .setColumnName("enabled")
+ .build();
+
+ assertThat(def.getName()).isEqualTo("enabled");
+ assertThat(def.isNullable()).isTrue();
+ assertThat(def.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void generate_sql_type() throws Exception {
+ BooleanColumnDef def = new BooleanColumnDef.Builder()
+ .setColumnName("enabled")
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.generateSqlType(new H2())).isEqualTo("BOOLEAN");
+ assertThat(def.generateSqlType(new PostgreSql())).isEqualTo("BOOLEAN");
+ assertThat(def.generateSqlType(new MsSql())).isEqualTo("BIT");
+ assertThat(def.generateSqlType(new MySql())).isEqualTo("TINYINT(1)");
+ assertThat(def.generateSqlType(new Oracle())).isEqualTo("NUMBER(1)");
+ }
+
+ @Test
+ public void fail_with_NPE_if_name_is_null() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new BooleanColumnDef.Builder().setColumnName(null);
+ }
+
+ @Test
+ public void fail_with_NPE_if_no_name() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new BooleanColumnDef.Builder().build();
+ }
+
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/ClobColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/ClobColumnDefTest.java
new file mode 100644
index 00000000000..6c3d1254658
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/ClobColumnDefTest.java
@@ -0,0 +1,102 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ClobColumnDefTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+ private final ClobColumnDef underTest = new ClobColumnDef.Builder()
+ .setColumnName("issues")
+ .setIsNullable(true)
+ .build();
+
+ @Test
+ public void build_string_column_def() throws Exception {
+ assertThat(underTest.getName()).isEqualTo("issues");
+ assertThat(underTest.isNullable()).isTrue();
+ assertThat(underTest.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void build_string_column_def_with_only_required_attributes() throws Exception {
+ ClobColumnDef def = new ClobColumnDef.Builder()
+ .setColumnName("issues")
+ .build();
+
+ assertThat(def.getName()).isEqualTo("issues");
+ assertThat(def.isNullable()).isTrue();
+ assertThat(def.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void generate_sql_type_on_mssql() throws Exception {
+ assertThat(underTest.generateSqlType(new MsSql())).isEqualTo("NVARCHAR (MAX)");
+ }
+
+ @Test
+ public void generate_sql_type_on_h2() throws Exception {
+ assertThat(underTest.generateSqlType(new H2())).isEqualTo("CLOB(2147483647)");
+ }
+
+ @Test
+ public void generate_sql_type_on_mysql() throws Exception {
+ assertThat(underTest.generateSqlType(new MySql())).isEqualTo("LONGTEXT");
+ }
+
+ @Test
+ public void generate_sql_type_on_oracle() throws Exception {
+ assertThat(underTest.generateSqlType(new Oracle())).isEqualTo("CLOB");
+ }
+
+ @Test
+ public void generate_sql_type_on_postgre() throws Exception {
+ assertThat(underTest.generateSqlType(new PostgreSql())).isEqualTo("TEXT");
+ }
+
+ @Test
+ public void fail_with_NPE_if_name_is_null() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new ClobColumnDef.Builder()
+ .setColumnName(null);
+ }
+
+ @Test
+ public void fail_with_NPE_if_no_name() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new ClobColumnDef.Builder()
+ .build();
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/DecimalColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/DecimalColumnDefTest.java
new file mode 100644
index 00000000000..61ca98cdc28
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/DecimalColumnDefTest.java
@@ -0,0 +1,142 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DecimalColumnDefTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void build_string_column_def() throws Exception {
+ DecimalColumnDef def = new DecimalColumnDef.Builder()
+ .setColumnName("issues")
+ .setPrecision(30)
+ .setScale(20)
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.getName()).isEqualTo("issues");
+ assertThat(def.getPrecision()).isEqualTo(30);
+ assertThat(def.getScale()).isEqualTo(20);
+ assertThat(def.isNullable()).isTrue();
+ assertThat(def.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void fail_with_NPE_if_name_is_null() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new DecimalColumnDef.Builder()
+ .setColumnName(null);
+ }
+
+ @Test
+ public void fail_with_NPE_if_no_name() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new DecimalColumnDef.Builder()
+ .build();
+ }
+
+ @Test
+ public void default_precision_is_38() throws Exception {
+ DecimalColumnDef def = new DecimalColumnDef.Builder()
+ .setColumnName("issues")
+ .setScale(20)
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.getPrecision()).isEqualTo(38);
+ }
+
+ @Test
+ public void default_precision_is_20() throws Exception {
+ DecimalColumnDef def = new DecimalColumnDef.Builder()
+ .setColumnName("issues")
+ .setPrecision(30)
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.getScale()).isEqualTo(20);
+ }
+
+ @Test
+ public void create_builder_with_only_required_attributes() throws Exception {
+ DecimalColumnDef def = new DecimalColumnDef.Builder()
+ .setColumnName("issues")
+ .build();
+
+ assertThat(def.getPrecision()).isEqualTo(38);
+ assertThat(def.getScale()).isEqualTo(20);
+ assertThat(def.isNullable()).isTrue();
+ assertThat(def.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void generate_sql_type() throws Exception {
+ DecimalColumnDef def = new DecimalColumnDef.Builder()
+ .setColumnName("issues")
+ .setPrecision(30)
+ .setScale(20)
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.generateSqlType(new H2())).isEqualTo("DOUBLE");
+ assertThat(def.generateSqlType(new PostgreSql())).isEqualTo("NUMERIC (30,20)");
+ assertThat(def.generateSqlType(new MsSql())).isEqualTo("DECIMAL (30,20)");
+ assertThat(def.generateSqlType(new MySql())).isEqualTo("DECIMAL (30,20)");
+ assertThat(def.generateSqlType(new Oracle())).isEqualTo("NUMERIC (30,20)");
+ }
+
+ @Test
+ public void fail_with_UOE_to_generate_sql_type_when_unknown_dialect() throws Exception {
+ thrown.expect(UnsupportedOperationException.class);
+ thrown.expectMessage("Unknown dialect 'unknown'");
+
+ DecimalColumnDef def = new DecimalColumnDef.Builder()
+ .setColumnName("issues")
+ .setPrecision(30)
+ .setScale(20)
+ .setIsNullable(true)
+ .build();
+
+ Dialect dialect = mock(Dialect.class);
+ when(dialect.getId()).thenReturn("unknown");
+ def.generateSqlType(dialect);
+ }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/IntegerColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/IntegerColumnDefTest.java
new file mode 100644
index 00000000000..67c281e397e
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/IntegerColumnDefTest.java
@@ -0,0 +1,124 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+
+public class IntegerColumnDefTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private IntegerColumnDef underTest = newIntegerColumnDefBuilder().setColumnName("a").build();
+
+ @Test
+ public void builder_setColumnName_throws_IAE_if_name_is_not_lowercase() {
+ IntegerColumnDef.Builder builder = newIntegerColumnDefBuilder();
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Column name must be lower case and contain only alphanumeric chars or '_', got 'T'");
+ builder.setColumnName("T");
+ }
+
+ @Test
+ public void builder_build_throws_NPE_if_no_name_was_set() {
+ IntegerColumnDef.Builder builder = newIntegerColumnDefBuilder();
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Column name cannot be null");
+
+ builder.build();
+ }
+
+ @Test
+ public void integerColumDef_is_nullable_by_default() {
+ assertThat(newIntegerColumnDefBuilder().setColumnName("a").build().isNullable()).isTrue();
+ }
+
+ @Test
+ public void builder_setNullable_sets_nullable_field_of_IntegerColumnDef() {
+ assertThat(newIntegerColumnDefBuilder().setColumnName("a").setIsNullable(true).build().isNullable()).isTrue();
+ assertThat(newIntegerColumnDefBuilder().setColumnName("a").setIsNullable(false).build().isNullable()).isFalse();
+ }
+
+ @Test
+ public void builder_setColumnName_sets_name_field_of_IntegerColumnDef() {
+ assertThat(newIntegerColumnDefBuilder().setColumnName("a").build().getName()).isEqualTo("a");
+ }
+
+ @Test
+ public void builder_setDefaultValue_sets_default_value_field_of_IntegerColumnDef() {
+ assertThat(newIntegerColumnDefBuilder().setColumnName("a").setDefaultValue(42).build().getDefaultValue()).isEqualTo(42);
+ }
+
+ @Test
+ public void default_value_is_null_by_default() {
+ assertThat(newIntegerColumnDefBuilder().setColumnName("a").build().getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void generateSqlType_for_MsSql() {
+ assertThat(underTest.generateSqlType(new MsSql())).isEqualTo("INT");
+ }
+
+ @Test
+ public void generateSqlType_for_MySql() {
+ assertThat(underTest.generateSqlType(new MySql())).isEqualTo("INTEGER");
+ }
+
+ @Test
+ public void generateSqlType_for_Oracle() {
+ assertThat(underTest.generateSqlType(new Oracle())).isEqualTo("NUMBER(38,0)");
+ }
+
+ @Test
+ public void generateSqlType_for_H2() {
+ assertThat(underTest.generateSqlType(new H2())).isEqualTo("INTEGER");
+ }
+
+ @Test
+ public void generateSqlType_for_PostgreSql() {
+ assertThat(underTest.generateSqlType(new PostgreSql())).isEqualTo("INTEGER");
+ }
+
+ @Test
+ public void generateSqlType_thows_IAE_for_unknown_dialect() {
+ Dialect dialect = mock(Dialect.class);
+ when(dialect.getId()).thenReturn("AAA");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Unsupported dialect id AAA");
+
+ underTest.generateSqlType(dialect);
+ }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/TimestampColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/TimestampColumnDefTest.java
new file mode 100644
index 00000000000..a8a7e3161cc
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/TimestampColumnDefTest.java
@@ -0,0 +1,90 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.platform.db.migration.def.TimestampColumnDef.newTimestampColumnDefBuilder;
+
+public class TimestampColumnDefTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void build_column_def() throws Exception {
+ TimestampColumnDef def = newTimestampColumnDefBuilder()
+ .setColumnName("created_at")
+ .setIsNullable(false)
+ .build();
+
+ assertThat(def.getName()).isEqualTo("created_at");
+ assertThat(def.isNullable()).isFalse();
+ assertThat(def.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void build_column_def_with_only_required_attributes() throws Exception {
+ TimestampColumnDef def = newTimestampColumnDefBuilder()
+ .setColumnName("created_at")
+ .build();
+
+ assertThat(def.getName()).isEqualTo("created_at");
+ assertThat(def.isNullable()).isTrue();
+ assertThat(def.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void generate_sql_type() throws Exception {
+ TimestampColumnDef def = newTimestampColumnDefBuilder()
+ .setColumnName("created_at")
+ .build();
+
+ assertThat(def.generateSqlType(new H2())).isEqualTo("TIMESTAMP");
+ assertThat(def.generateSqlType(new PostgreSql())).isEqualTo("TIMESTAMP");
+ assertThat(def.generateSqlType(new MsSql())).isEqualTo("DATETIME");
+ assertThat(def.generateSqlType(new MySql())).isEqualTo("DATETIME");
+ assertThat(def.generateSqlType(new Oracle())).isEqualTo("TIMESTAMP (6)");
+ }
+
+ @Test
+ public void fail_with_NPE_if_name_is_null() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ newTimestampColumnDefBuilder().setColumnName(null);
+ }
+
+ @Test
+ public void fail_with_NPE_if_no_name() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ newTimestampColumnDefBuilder().build();
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/TinyIntColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/TinyIntColumnDefTest.java
new file mode 100644
index 00000000000..1e63b3bcbe1
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/TinyIntColumnDefTest.java
@@ -0,0 +1,81 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class TinyIntColumnDefTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void build_string_column_def() throws Exception {
+ TinyIntColumnDef def = new TinyIntColumnDef.Builder()
+ .setColumnName("foo")
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.getName()).isEqualTo("foo");
+ assertThat(def.isNullable()).isTrue();
+ assertThat(def.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void generate_sql_type() throws Exception {
+ TinyIntColumnDef def = new TinyIntColumnDef.Builder()
+ .setColumnName("foo")
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.generateSqlType(new H2())).isEqualTo("TINYINT");
+ assertThat(def.generateSqlType(new PostgreSql())).isEqualTo("SMALLINT");
+ assertThat(def.generateSqlType(new MsSql())).isEqualTo("TINYINT");
+ assertThat(def.generateSqlType(new MySql())).isEqualTo("TINYINT(2)");
+ assertThat(def.generateSqlType(new Oracle())).isEqualTo("NUMBER(3)");
+ }
+
+ @Test
+ public void fail_with_UOE_to_generate_sql_type_when_unknown_dialect() throws Exception {
+ thrown.expect(UnsupportedOperationException.class);
+ thrown.expectMessage("Unknown dialect 'unknown'");
+
+ TinyIntColumnDef def = new TinyIntColumnDef.Builder()
+ .setColumnName("foo")
+ .setIsNullable(true)
+ .build();
+
+ Dialect dialect = mock(Dialect.class);
+ when(dialect.getId()).thenReturn("unknown");
+ def.generateSqlType(dialect);
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/ValidationsTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/ValidationsTest.java
new file mode 100644
index 00000000000..979b9544b7b
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/ValidationsTest.java
@@ -0,0 +1,85 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.platform.db.migration.def.Validations.validateColumnName;
+import static org.sonar.server.platform.db.migration.def.Validations.validateIndexName;
+
+public class ValidationsTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void accept_valid_table_name() throws Exception {
+ validateColumnName("date_in_ms");
+ validateColumnName("date_in_ms_1");
+ }
+
+ @Test
+ public void fail_with_NPE_if_name_is_null() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ validateColumnName(null);
+ }
+
+ @Test
+ public void fail_when_column_name_is_in_upper_case() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Column name must be lower case and contain only alphanumeric chars or '_', got 'DATE_IN_MS'");
+
+ validateColumnName("DATE_IN_MS");
+ }
+
+ @Test
+ public void fail_when_column_name_contains_invalid_character() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Column name must be lower case and contain only alphanumeric chars or '_', got 'date-in/ms'");
+
+ validateColumnName("date-in/ms");
+ }
+
+ @Test
+ public void validateIndexName_throws_IAE_when_index_name_contains_invalid_characters() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Index name must be lower case and contain only alphanumeric chars or '_', got '(not/valid)'");
+
+ validateIndexName("(not/valid)");
+ }
+
+ @Test
+ public void validateIndexName_throws_NPE_when_index_name_is_null() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Index name cannot be null");
+
+ validateIndexName(null);
+ }
+
+ @Test
+ public void validateIndexName_returns_valid_name() {
+ assertThat(validateIndexName("foo")).isEqualTo("foo");
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/VarcharColumnDefTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/VarcharColumnDefTest.java
new file mode 100644
index 00000000000..ea16e7853f4
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/def/VarcharColumnDefTest.java
@@ -0,0 +1,120 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.def;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class VarcharColumnDefTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void build_string_column_def() throws Exception {
+ VarcharColumnDef def = new VarcharColumnDef.Builder()
+ .setColumnName("issues")
+ .setLimit(10)
+ .setIsNullable(true)
+ .setDefaultValue("foo")
+ .build();
+
+ assertThat(def.getName()).isEqualTo("issues");
+ assertThat(def.getColumnSize()).isEqualTo(10);
+ assertThat(def.isNullable()).isTrue();
+ assertThat(def.getDefaultValue()).isEqualTo("foo");
+ }
+
+ @Test
+ public void build_string_column_def_with_only_required_attributes() throws Exception {
+ VarcharColumnDef def = new VarcharColumnDef.Builder()
+ .setColumnName("issues")
+ .setLimit(10)
+ .build();
+
+ assertThat(def.getName()).isEqualTo("issues");
+ assertThat(def.getColumnSize()).isEqualTo(10);
+ assertThat(def.isNullable()).isTrue();
+ assertThat(def.getDefaultValue()).isNull();
+ }
+
+ @Test
+ public void generate_sql_type() throws Exception {
+ VarcharColumnDef def = new VarcharColumnDef.Builder()
+ .setColumnName("issues")
+ .setLimit(10)
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.generateSqlType(new H2())).isEqualTo("VARCHAR (10)");
+ assertThat(def.generateSqlType(new PostgreSql())).isEqualTo("VARCHAR (10)");
+ assertThat(def.generateSqlType(new MySql())).isEqualTo("VARCHAR (10)");
+ assertThat(def.generateSqlType(new MsSql())).isEqualTo("NVARCHAR (10)");
+ assertThat(def.generateSqlType(new Oracle())).isEqualTo("VARCHAR (10 CHAR)");
+ }
+
+ @Test
+ public void generateSqlType_does_not_set_unit_on_oracle_if_legacy_mode() throws Exception {
+ VarcharColumnDef def = new VarcharColumnDef.Builder()
+ .setColumnName("issues")
+ .setLimit(10)
+ .setIsNullable(true)
+ .setIgnoreOracleUnit(true)
+ .build();
+
+ assertThat(def.generateSqlType(new Oracle())).isEqualTo("VARCHAR (10)");
+ }
+
+ @Test
+ public void fail_with_NPE_if_name_is_null() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new VarcharColumnDef.Builder()
+ .setColumnName(null);
+ }
+
+ @Test
+ public void fail_with_NPE_if_no_name() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Column name cannot be null");
+
+ new VarcharColumnDef.Builder()
+ .build();
+ }
+
+ @Test
+ public void fail_with_NPE_if_size_is_null() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Limit cannot be null");
+
+ new VarcharColumnDef.Builder()
+ .setColumnName("issues")
+ .build();
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/AddColumnsBuilderTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/AddColumnsBuilderTest.java
new file mode 100644
index 00000000000..1277520ed24
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/AddColumnsBuilderTest.java
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class AddColumnsBuilderTest {
+
+ private static final String TABLE_NAME = "issues";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void add_columns_on_h2() {
+ assertThat(createSampleBuilder(new H2()).build())
+ .isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL, col_with_default BOOLEAN DEFAULT false NOT NULL, varchar_col_with_default VARCHAR (3) DEFAULT 'foo' NOT NULL)");
+ }
+
+ @Test
+ public void add_columns_on_mysql() {
+ assertThat(createSampleBuilder(new MySql()).build())
+ .isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL, col_with_default TINYINT(1) DEFAULT false NOT NULL, varchar_col_with_default VARCHAR (3) DEFAULT 'foo' NOT NULL)");
+ }
+
+ @Test
+ public void add_columns_on_oracle() {
+ assertThat(createSampleBuilder(new Oracle()).build())
+ .isEqualTo("ALTER TABLE issues ADD (date_in_ms NUMBER (38) NULL, name VARCHAR (10 CHAR) NOT NULL, col_with_default NUMBER(1) DEFAULT 0 NOT NULL, varchar_col_with_default VARCHAR (3 CHAR) DEFAULT 'foo' NOT NULL)");
+ }
+
+ @Test
+ public void add_columns_on_postgresql() {
+ assertThat(createSampleBuilder(new PostgreSql()).build())
+ .isEqualTo("ALTER TABLE issues ADD COLUMN date_in_ms BIGINT NULL, ADD COLUMN name VARCHAR (10) NOT NULL, ADD COLUMN col_with_default BOOLEAN DEFAULT false NOT NULL, ADD COLUMN varchar_col_with_default VARCHAR (3) DEFAULT 'foo' NOT NULL");
+ }
+
+ @Test
+ public void add_columns_on_mssql() {
+ assertThat(createSampleBuilder(new MsSql()).build())
+ .isEqualTo("ALTER TABLE issues ADD date_in_ms BIGINT NULL, name NVARCHAR (10) NOT NULL, col_with_default BIT DEFAULT 0 NOT NULL, varchar_col_with_default NVARCHAR (3) DEFAULT 'foo' NOT NULL");
+ }
+
+ @Test
+ public void fail_with_ISE_if_no_column() {
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("No column has been defined");
+
+ new AddColumnsBuilder(new H2(), TABLE_NAME).build();
+ }
+
+ private AddColumnsBuilder createSampleBuilder(Dialect dialect) {
+ return new AddColumnsBuilder(dialect, TABLE_NAME)
+ .addColumn(new BigIntegerColumnDef.Builder().setColumnName("date_in_ms").setIsNullable(true).build())
+ .addColumn(new VarcharColumnDef.Builder().setColumnName("name").setLimit(10).setIsNullable(false).build())
+
+ // columns with default values
+ .addColumn(newBooleanColumnDefBuilder().setColumnName("col_with_default").setDefaultValue(false).setIsNullable(false).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("varchar_col_with_default").setLimit(3).setDefaultValue("foo").setIsNullable(false).build());
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilderTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilderTest.java
new file mode 100644
index 00000000000..207d7312744
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilderTest.java
@@ -0,0 +1,166 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.server.platform.db.migration.def.BooleanColumnDef;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.DecimalColumnDef.newDecimalColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class AlterColumnsBuilderTest {
+
+ private static final String TABLE_NAME = "issues";
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void update_columns_on_h2() {
+ assertThat(createSampleBuilder(new H2()).build())
+ .containsOnly(
+ "ALTER TABLE issues ALTER COLUMN value DOUBLE NULL",
+ "ALTER TABLE issues ALTER COLUMN name VARCHAR (10) NULL");
+ }
+
+ @Test
+ public void update_not_nullable_column_on_h2() {
+ assertThat(createNotNullableBuilder(new H2()).build())
+ .containsOnly("ALTER TABLE issues ALTER COLUMN name VARCHAR (10) NOT NULL");
+ }
+
+ @Test
+ public void update_columns_on_mssql() {
+ assertThat(createSampleBuilder(new MsSql()).build())
+ .containsOnly(
+ "ALTER TABLE issues ALTER COLUMN value DECIMAL (30,20) NULL",
+ "ALTER TABLE issues ALTER COLUMN name NVARCHAR (10) NULL");
+ }
+
+ @Test
+ public void update_not_nullable_column_on_mssql() {
+ assertThat(createNotNullableBuilder(new MsSql()).build())
+ .containsOnly("ALTER TABLE issues ALTER COLUMN name NVARCHAR (10) NOT NULL");
+ }
+
+ @Test
+ public void update_columns_on_postgres() {
+ assertThat(createSampleBuilder(new PostgreSql()).build())
+ .containsOnly("ALTER TABLE issues " +
+ "ALTER COLUMN value TYPE NUMERIC (30,20), ALTER COLUMN value DROP NOT NULL, " +
+ "ALTER COLUMN name TYPE VARCHAR (10), ALTER COLUMN name DROP NOT NULL");
+ }
+
+ @Test
+ public void update_not_nullable_column_on_postgres() {
+ assertThat(createNotNullableBuilder(new PostgreSql()).build())
+ .containsOnly("ALTER TABLE issues ALTER COLUMN name TYPE VARCHAR (10), ALTER COLUMN name SET NOT NULL");
+ }
+
+ @Test
+ public void update_columns_on_mysql() {
+ assertThat(createSampleBuilder(new MySql()).build())
+ .containsOnly("ALTER TABLE issues MODIFY COLUMN value DECIMAL (30,20) NULL, MODIFY COLUMN name VARCHAR (10) NULL");
+ }
+
+ @Test
+ public void update_not_nullable_column_on_mysql() {
+ assertThat(createNotNullableBuilder(new MySql()).build())
+ .containsOnly("ALTER TABLE issues MODIFY COLUMN name VARCHAR (10) NOT NULL");
+ }
+
+ @Test
+ public void update_columns_on_oracle() {
+ assertThat(createSampleBuilder(new Oracle()).build())
+ .containsOnly(
+ "ALTER TABLE issues MODIFY (value NUMERIC (30,20) NULL)",
+ "ALTER TABLE issues MODIFY (name VARCHAR (10 CHAR) NULL)");
+ }
+
+ @Test
+ public void update_not_nullable_column_on_oracle() {
+ assertThat(createNotNullableBuilder(new Oracle()).build())
+ .containsOnly("ALTER TABLE issues MODIFY (name VARCHAR (10 CHAR) NOT NULL)");
+ }
+
+ @Test
+ public void fail_with_ISE_if_no_column() {
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("No column has been defined");
+
+ new AlterColumnsBuilder(new H2(), TABLE_NAME).build();
+ }
+
+ /**
+ * As we want DEFAULT value to be removed from all tables, it is supported
+ * only on creation of tables and columns, not on alter.
+ */
+ @Test
+ public void updateColumn_throws_IAE_if_default_value_is_defined() {
+ BooleanColumnDef column = newBooleanColumnDefBuilder()
+ .setColumnName("enabled")
+ .setIsNullable(false)
+ .setDefaultValue(false)
+ .build();
+ AlterColumnsBuilder alterColumnsBuilder = new AlterColumnsBuilder(new H2(), TABLE_NAME);
+
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Default value is not supported on alter of column 'enabled'");
+
+ alterColumnsBuilder.updateColumn(column);
+ }
+
+ private AlterColumnsBuilder createSampleBuilder(Dialect dialect) {
+ return new AlterColumnsBuilder(dialect, TABLE_NAME)
+ .updateColumn(
+ newDecimalColumnDefBuilder()
+ .setColumnName("value")
+ .setPrecision(30)
+ .setScale(20)
+ .setIsNullable(true)
+ .build())
+ .updateColumn(
+ newVarcharColumnDefBuilder()
+ .setColumnName("name")
+ .setLimit(10)
+ .setIsNullable(true)
+ .build());
+ }
+
+ private AlterColumnsBuilder createNotNullableBuilder(Dialect dialect) {
+ return new AlterColumnsBuilder(dialect, TABLE_NAME)
+ .updateColumn(
+ newVarcharColumnDefBuilder()
+ .setColumnName("name")
+ .setLimit(10)
+ .setIsNullable(false)
+ .build());
+ }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateIndexBuilderTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateIndexBuilderTest.java
new file mode 100644
index 00000000000..3a675629686
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateIndexBuilderTest.java
@@ -0,0 +1,163 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class CreateIndexBuilderTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void create_index_on_single_column() {
+ verifySql(new CreateIndexBuilder(new H2())
+ .setTable("issues")
+ .setName("issues_key")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("kee").setLimit(10).build()),
+ "CREATE INDEX issues_key ON issues (kee)");
+ }
+
+ @Test
+ public void create_unique_index_on_single_column() {
+ verifySql(new CreateIndexBuilder(new H2())
+ .setTable("issues")
+ .setName("issues_key")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("kee").setLimit(10).build())
+ .setUnique(true),
+ "CREATE UNIQUE INDEX issues_key ON issues (kee)");
+ }
+
+ @Test
+ public void create_index_on_multiple_columns() {
+ verifySql(new CreateIndexBuilder(new H2())
+ .setTable("rules")
+ .setName("rules_key")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("repository").setLimit(10).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_key").setLimit(50).build()),
+ "CREATE INDEX rules_key ON rules (repository, rule_key)");
+ }
+
+ @Test
+ public void create_unique_index_on_multiple_columns() {
+ verifySql(new CreateIndexBuilder(new H2())
+ .setTable("rules")
+ .setName("rules_key")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("repository").setLimit(10).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_key").setLimit(50).build())
+ .setUnique(true),
+ "CREATE UNIQUE INDEX rules_key ON rules (repository, rule_key)");
+ }
+
+ @Test
+ public void index_length_is_not_specified_on_big_varchar_columns_if_not_mysql() {
+ Arrays.<Dialect>asList(new H2(), new MsSql(), new PostgreSql(), new Oracle())
+ .forEach(dialect -> verifySql(new CreateIndexBuilder(dialect)
+ .setTable("issues")
+ .setName("issues_key")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("kee").setLimit(4000).build()),
+ "CREATE INDEX issues_key ON issues (kee)"));
+ }
+
+ @Test
+ public void index_length_is_limited_to_255_on_big_varchar_columns_if_mysql() {
+ verifySql(new CreateIndexBuilder(new MySql())
+ .setTable("issues")
+ .setName("issues_key")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("kee").setLimit(4000).build()),
+ "CREATE INDEX issues_key ON issues (kee(255))");
+ }
+
+ @Test
+ public void throw_NPE_if_table_is_missing() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Table name cannot be null");
+
+ new CreateIndexBuilder(new H2())
+ .setName("issues_key")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("kee").setLimit(10).build())
+ .build();
+ }
+
+ @Test
+ public void throw_NPE_if_index_name_is_missing() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Index name cannot be null");
+
+ new CreateIndexBuilder(new H2())
+ .setTable("issues")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("kee").setLimit(10).build())
+ .build();
+ }
+
+ @Test
+ public void throw_IAE_if_columns_are_missing() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("at least one column must be specified");
+
+ new CreateIndexBuilder(new H2())
+ .setTable("issues")
+ .setName("issues_key")
+ .build();
+ }
+
+ @Test
+ public void throw_IAE_if_table_name_is_not_valid() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Table name must be lower case and contain only alphanumeric chars or '_', got '(not valid)'");
+
+ new CreateIndexBuilder(new H2())
+ .setTable("(not valid)")
+ .setName("issues_key")
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("kee").setLimit(10).build())
+ .build();
+ }
+
+ @Test
+ public void throw_NPE_when_adding_null_column() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Column cannot be null");
+
+ new CreateIndexBuilder(new H2())
+ .setTable("issues")
+ .setName("issues_key")
+ .addColumn(null)
+ .build();
+ }
+
+ private static void verifySql(CreateIndexBuilder builder, String expectedSql) {
+ List<String> actual = builder.build();
+ assertThat(actual).containsExactly(expectedSql);
+ }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilderDbTesterTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilderDbTesterTest.java
new file mode 100644
index 00000000000..ba20ebb3987
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilderDbTesterTest.java
@@ -0,0 +1,134 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.Map;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.server.platform.db.migration.def.TinyIntColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BlobColumnDef.newBlobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.DecimalColumnDef.newDecimalColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.sql.CreateTableBuilder.ColumnFlag.AUTO_INCREMENT;
+
+public class CreateTableBuilderDbTesterTest {
+ @ClassRule
+ public static final DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+ private Dialect dialect = dbTester.getDbClient().getDatabase().getDialect();
+ private static int tableNameGenerator = 0;
+
+ @Test
+ public void create_no_primary_key_table() {
+ newCreateTableBuilder()
+ .addColumn(newBooleanColumnDefBuilder().setColumnName("bool_col_1").build())
+ .addColumn(newBooleanColumnDefBuilder().setColumnName("bool_col_2").setIsNullable(false).build())
+ .addColumn(newIntegerColumnDefBuilder().setColumnName("i_col_1").build())
+ .addColumn(newIntegerColumnDefBuilder().setColumnName("i_col_2").setIsNullable(false).build())
+ .addColumn(newBigIntegerColumnDefBuilder().setColumnName("bi_col_1").build())
+ .addColumn(newBigIntegerColumnDefBuilder().setColumnName("bi_col_2").setIsNullable(false).build())
+ .addColumn(newClobColumnDefBuilder().setColumnName("clob_col_1").build())
+ .addColumn(newClobColumnDefBuilder().setColumnName("clob_col_2").setIsNullable(false).build())
+ .addColumn(newDecimalColumnDefBuilder().setColumnName("dec_col_1").build())
+ .addColumn(newDecimalColumnDefBuilder().setColumnName("dec_col_2").setIsNullable(false).build())
+ .addColumn(new TinyIntColumnDef.Builder().setColumnName("tiny_col_1").build())
+ .addColumn(new TinyIntColumnDef.Builder().setColumnName("tiny_col_2").setIsNullable(false).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("varchar_col_1").setLimit(40).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("varchar_col_2").setLimit(40).setIsNullable(false).build())
+ .addColumn(newBlobColumnDefBuilder().setColumnName("blob_col_1").build())
+ .addColumn(newBlobColumnDefBuilder().setColumnName("blob_col_2").setIsNullable(false).build())
+ .build()
+ .forEach(dbTester::executeDdl);
+ }
+
+ @Test
+ public void create_single_column_primary_key_table() {
+ newCreateTableBuilder()
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col_1").setIsNullable(false).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("varchar_col_2").setLimit(40).setIsNullable(false).build())
+ .build()
+ .forEach(dbTester::executeDdl);
+ }
+
+ @Test
+ public void create_multi_column_primary_key_table() {
+ newCreateTableBuilder()
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col_1").setIsNullable(false).build())
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col_2").setIsNullable(false).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("varchar_col_2").setLimit(40).setIsNullable(false).build())
+ .build()
+ .forEach(dbTester::executeDdl);
+ }
+
+ @Test
+ public void create_autoincrement_notnullable_integer_primary_key_table() {
+ String tableName = createTableName();
+ new CreateTableBuilder(dialect, tableName)
+ .addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .addColumn(valColumnDef())
+ .build()
+ .forEach(dbTester::executeDdl);
+
+ verifyAutoIncrementIsWorking(tableName);
+ }
+
+ @Test
+ public void create_autoincrement_notnullable_biginteger_primary_key_table() {
+ String tableName = createTableName();
+ new CreateTableBuilder(dialect, tableName)
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .addColumn(valColumnDef())
+ .build()
+ .forEach(dbTester::executeDdl);
+
+ verifyAutoIncrementIsWorking(tableName);
+ }
+
+ private static VarcharColumnDef valColumnDef() {
+ return newVarcharColumnDefBuilder().setColumnName("val").setLimit(10).setIsNullable(false).build();
+ }
+
+ private void verifyAutoIncrementIsWorking(String tableName) {
+ dbTester.executeInsert(tableName, "val", "toto");
+ dbTester.commit();
+
+ Map<String, Object> row = dbTester.selectFirst("select id as \"id\", val as \"val\" from " + tableName);
+ assertThat(row.get("id")).isNotNull();
+ assertThat(row.get("val")).isEqualTo("toto");
+ }
+
+ private CreateTableBuilder newCreateTableBuilder() {
+ return new CreateTableBuilder(dialect, createTableName());
+ }
+
+ private static String createTableName() {
+ return "table_" + tableNameGenerator++;
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilderTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilderTest.java
new file mode 100644
index 00000000000..1c84ff2e9d5
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilderTest.java
@@ -0,0 +1,582 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.server.platform.db.migration.def.ColumnDef;
+import org.sonar.server.platform.db.migration.def.TinyIntColumnDef;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+import static org.mockito.Mockito.mock;
+import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BlobColumnDef.newBlobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.DecimalColumnDef.newDecimalColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.sql.CreateTableBuilder.ColumnFlag.AUTO_INCREMENT;
+
+@RunWith(DataProviderRunner.class)
+public class CreateTableBuilderTest {
+ private static final H2 H2 = new H2();
+ private static final Oracle ORACLE = new Oracle();
+ private static final PostgreSql POSTGRESQL = new PostgreSql();
+ private static final MsSql MS_SQL = new MsSql();
+ private static final MySql MY_SQL = new MySql();
+ private static final Dialect[] ALL_DIALECTS = {H2, MY_SQL, MS_SQL, POSTGRESQL, ORACLE};
+ private static final String TABLE_NAME = "table_42";
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private CreateTableBuilder underTest = new CreateTableBuilder(mock(Dialect.class), TABLE_NAME);
+
+ @Test
+ public void constructor_fails_with_NPE_if_dialect_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("dialect can't be null");
+
+ new CreateTableBuilder(null, TABLE_NAME);
+ }
+
+ @Test
+ public void constructor_fails_with_NPE_if_tablename_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Table name cannot be null");
+
+ new CreateTableBuilder(mock(Dialect.class), null);
+ }
+
+ @Test
+ public void constructor_throws_IAE_if_table_name_is_not_lowercase() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Table name must be lower case and contain only alphanumeric chars or '_', got 'Tooo");
+
+ new CreateTableBuilder(mock(Dialect.class), "Tooo");
+ }
+
+ @Test
+ public void constructor_throws_IAE_if_table_name_is_26_chars_long() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Table name length can't be more than 25");
+
+ new CreateTableBuilder(mock(Dialect.class), "abcdefghijklmnopqrstuvwxyz");
+ }
+
+ @Test
+ public void constructor_does_not_fail_if_table_name_is_25_chars_long() {
+ new CreateTableBuilder(mock(Dialect.class), "abcdefghijklmnopqrstuvwxy");
+ }
+
+ @Test
+ public void constructor_does_not_fail_if_table_name_contains_ascii_letters() {
+ new CreateTableBuilder(mock(Dialect.class), "abcdefghijklmnopqrstuvwxy");
+ new CreateTableBuilder(mock(Dialect.class), "z");
+ }
+
+ @Test
+ public void constructor_throws_IAE_if_table_name_starts_with_underscore() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Table name must not start by a number or '_', got '_a'");
+
+ new CreateTableBuilder(mock(Dialect.class), "_a");
+ }
+
+ @Test
+ @UseDataProvider("digitCharsDataProvider")
+ public void constructor_throws_IAE_if_table_name_starts_with_number(char number) {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Table name must not start by a number or '_', got '" + number + "a'");
+
+ new CreateTableBuilder(mock(Dialect.class), number + "a");
+ }
+
+ @DataProvider
+ public static Object[][] digitCharsDataProvider() {
+ return new Object[][] {
+ {'0'},
+ {'1'},
+ {'2'},
+ {'3'},
+ {'4'},
+ {'5'},
+ {'6'},
+ {'7'},
+ {'8'},
+ {'9'},
+ };
+ }
+
+ @Test
+ public void constructor_does_not_fail_if_table_name_contains_underscore_or_numbers() {
+ new CreateTableBuilder(mock(Dialect.class), "a1234567890");
+ new CreateTableBuilder(mock(Dialect.class), "a_");
+ }
+
+ @Test
+ public void build_throws_ISE_if_no_column_has_been_set() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("at least one column must be specified");
+
+ underTest.build();
+ }
+
+ @Test
+ public void addColumn_throws_NPE_if_ColumnDef_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("column def can't be null");
+
+ underTest.addColumn(null);
+ }
+
+ @Test
+ public void addPkColumn_throws_NPE_if_ColumnDef_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("column def can't be null");
+
+ underTest.addPkColumn(null);
+ }
+
+ @Test
+ public void addPkColumn_throws_IAE_when_AUTO_INCREMENT_flag_is_provided_with_column_name_other_than_id() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Auto increment column name must be id");
+
+ underTest.addPkColumn(newIntegerColumnDefBuilder().setColumnName("toto").build(), AUTO_INCREMENT);
+ }
+
+ @Test
+ public void addPkColumn_throws_ISE_when_adding_multiple_autoincrement_columns() {
+ underTest.addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT);
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("There can't be more than one auto increment column");
+
+ underTest.addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT);
+ }
+
+ @Test
+ public void addPkColumn_throws_IAE_when_AUTO_INCREMENT_flag_is_provided_with_def_other_than_Integer_and_BigInteger() {
+ ColumnDef[] columnDefs = {
+ newBooleanColumnDefBuilder().setColumnName("id").build(),
+ newClobColumnDefBuilder().setColumnName("id").build(),
+ newDecimalColumnDefBuilder().setColumnName("id").build(),
+ new TinyIntColumnDef.Builder().setColumnName("id").build(),
+ newVarcharColumnDefBuilder().setColumnName("id").setLimit(40).build(),
+ newBlobColumnDefBuilder().setColumnName("id").build()
+ };
+ Arrays.stream(columnDefs)
+ .forEach(columnDef -> {
+ try {
+ underTest.addPkColumn(columnDef, AUTO_INCREMENT);
+ fail("A IllegalArgumentException should have been raised");
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Auto increment column must either be BigInteger or Integer");
+ }
+ });
+ }
+
+ @Test
+ public void addPkColumn_throws_IAE_when_AUTO_INCREMENT_flag_is_provided_and_column_is_nullable() {
+ ColumnDef[] columnDefs = {
+ newIntegerColumnDefBuilder().setColumnName("id").build(),
+ newBigIntegerColumnDefBuilder().setColumnName("id").build()
+ };
+ Arrays.stream(columnDefs)
+ .forEach(columnDef -> {
+ try {
+ underTest.addPkColumn(columnDef, AUTO_INCREMENT);
+ fail("A IllegalArgumentException should have been raised");
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Auto increment column can't be nullable");
+ }
+ });
+ }
+
+ @Test
+ public void build_sets_type_SERIAL_for_autoincrement_integer_pk_column_on_Postgresql() {
+ List<String> stmts = new CreateTableBuilder(POSTGRESQL, TABLE_NAME)
+ .addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .build();
+ assertThat(stmts).hasSize(1);
+ assertThat(stmts.iterator().next())
+ .isEqualTo(
+ "CREATE TABLE table_42 (id SERIAL NOT NULL, CONSTRAINT pk_table_42 PRIMARY KEY (id))");
+ }
+
+ @Test
+ public void build_sets_type_BIGSERIAL_for_autoincrement_biginteger_pk_column_on_Postgresql() {
+ List<String> stmts = new CreateTableBuilder(POSTGRESQL, TABLE_NAME)
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .build();
+ assertThat(stmts).hasSize(1);
+ assertThat(stmts.iterator().next())
+ .isEqualTo(
+ "CREATE TABLE table_42 (id BIGSERIAL NOT NULL, CONSTRAINT pk_table_42 PRIMARY KEY (id))");
+ }
+
+ @Test
+ public void build_generates_a_create_trigger_statement_when_an_autoincrement_pk_column_is_specified_and_on_Oracle() {
+ List<String> stmts = new CreateTableBuilder(ORACLE, TABLE_NAME)
+ .addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .build();
+ assertThat(stmts).hasSize(3);
+ assertThat(stmts.get(0))
+ .isEqualTo("CREATE TABLE table_42 (id NUMBER(38,0) NOT NULL, CONSTRAINT pk_table_42 PRIMARY KEY (id))");
+ assertThat(stmts.get(1))
+ .isEqualTo("CREATE SEQUENCE table_42_seq START WITH 1 INCREMENT BY 1");
+ assertThat(stmts.get(2))
+ .isEqualTo("CREATE OR REPLACE TRIGGER table_42_idt" +
+ " BEFORE INSERT ON table_42" +
+ " FOR EACH ROW" +
+ " BEGIN" +
+ " IF :new.id IS null THEN" +
+ " SELECT table_42_seq.nextval INTO :new.id FROM dual;" +
+ " END IF;" +
+ " END;");
+ }
+
+ @Test
+ public void build_adds_IDENTITY_clause_on_MsSql() {
+ List<String> stmts = new CreateTableBuilder(MS_SQL, TABLE_NAME)
+ .addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .build();
+ assertThat(stmts).hasSize(1);
+ assertThat(stmts.iterator().next())
+ .isEqualTo(
+ "CREATE TABLE table_42 (id INT NOT NULL IDENTITY (1,1), CONSTRAINT pk_table_42 PRIMARY KEY (id))");
+ }
+
+ @Test
+ public void build_adds_AUTO_INCREMENT_clause_on_H2() {
+ List<String> stmts = new CreateTableBuilder(H2, TABLE_NAME)
+ .addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .build();
+ assertThat(stmts).hasSize(1);
+ assertThat(stmts.iterator().next())
+ .isEqualTo(
+ "CREATE TABLE table_42 (id INTEGER NOT NULL AUTO_INCREMENT (1,1), CONSTRAINT pk_table_42 PRIMARY KEY (id))");
+ }
+
+ @Test
+ public void build_adds_AUTO_INCREMENT_clause_on_MySql() {
+ List<String> stmts = new CreateTableBuilder(MY_SQL, TABLE_NAME)
+ .addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .build();
+ assertThat(stmts).hasSize(1);
+ assertThat(stmts.iterator().next())
+ .startsWith("CREATE TABLE table_42 (id INTEGER NOT NULL AUTO_INCREMENT, CONSTRAINT pk_table_42 PRIMARY KEY (id))");
+ }
+
+ @Test
+ public void builds_adds_hardcoded_collation_clause_on_MySql() {
+ List<String> stmts = new CreateTableBuilder(MY_SQL, TABLE_NAME)
+ .addPkColumn(newIntegerColumnDefBuilder().setColumnName("id").setIsNullable(false).build(), AUTO_INCREMENT)
+ .build();
+ assertThat(stmts).hasSize(1);
+ assertThat(stmts.iterator().next())
+ .endsWith(" ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin");
+
+ }
+
+ @Test
+ public void withPkConstraintName_throws_NPE_if_name_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Constraint name cannot be null");
+
+ underTest.withPkConstraintName(null);
+ }
+
+ @Test
+ public void withPkConstraintName_throws_IAE_if_name_is_not_lowercase() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Constraint name must be lower case and contain only alphanumeric chars or '_', got 'Too'");
+
+ underTest.withPkConstraintName("Too");
+ }
+
+ @Test
+ public void withPkConstraintName_throws_IAE_if_name_is_more_than_30_char_long() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Constraint name length can't be more than 30");
+
+ underTest.withPkConstraintName("abcdefghijklmnopqrstuvwxyzabcdf");
+ }
+
+ @Test
+ public void withPkConstraintName_throws_IAE_if_name_starts_with_underscore() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Constraint name must not start by a number or '_', got '_a'");
+
+ underTest.withPkConstraintName("_a");
+ }
+
+ @Test
+ @UseDataProvider("digitCharsDataProvider")
+ public void withPkConstraintName_throws_IAE_if_name_starts_with_number(char number) {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Constraint name must not start by a number or '_', got '" + number + "a'");
+
+ underTest.withPkConstraintName(number + "a");
+ }
+
+ @Test
+ public void withPkConstraintName_does_not_fail_if_name_is_30_char_long() {
+ underTest.withPkConstraintName("abcdefghijklmnopqrstuvwxyzabcd");
+ }
+
+ @Test
+ public void withPkConstraintName_does_not_fail_if_name_contains_ascii_letters() {
+ underTest.withPkConstraintName("abcdefghijklmnopqrstuvwxyz");
+ }
+
+ @Test
+ public void withPkConstraintName_does_not_fail_if_name_contains_underscore() {
+ underTest.withPkConstraintName("a_");
+ }
+
+ @Test
+ public void withPkConstraintName_does_not_fail_if_name_contains_numbers() {
+ underTest.withPkConstraintName("a0123456789");
+ }
+
+ @Test
+ public void build_adds_NULL_when_column_is_nullable_for_all_DBs() {
+ Arrays.stream(ALL_DIALECTS)
+ .forEach(dialect -> {
+ List<String> stmts = new CreateTableBuilder(dialect, TABLE_NAME)
+ .addColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col").build())
+ .build();
+ assertThat(stmts).hasSize(1);
+
+ assertThat(stmts.iterator().next())
+ .startsWith("CREATE TABLE " + TABLE_NAME + " (" +
+ "bg_col " +
+ bigIntSqlType(dialect) + " NULL" +
+ ")");
+ });
+ }
+
+ @Test
+ public void build_adds_NOT_NULL_when_column_is_not_nullable_for_all_DBs() {
+ Arrays.stream(ALL_DIALECTS)
+ .forEach(dialect -> {
+ List<String> stmts = new CreateTableBuilder(dialect, TABLE_NAME)
+ .addColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col").setIsNullable(false).build())
+ .build();
+ assertThat(stmts).hasSize(1);
+
+ assertThat(stmts.iterator().next())
+ .startsWith("CREATE TABLE " + TABLE_NAME + " (" +
+ "bg_col " +
+ bigIntSqlType(dialect) +
+ " NOT NULL" +
+ ")");
+ });
+ }
+
+ @Test
+ public void build_of_single_column_table() {
+ List<String> stmts = new CreateTableBuilder(H2, TABLE_NAME)
+ .addColumn(newBooleanColumnDefBuilder().setColumnName("bool_col_1").build())
+ .build();
+ assertThat(stmts).hasSize(1);
+
+ assertThat(stmts.iterator().next()).isEqualTo("CREATE TABLE table_42 (bool_col_1 BOOLEAN NULL)");
+ }
+
+ @Test
+ public void build_table_with_pk() {
+ List<String> stmts = new CreateTableBuilder(H2, TABLE_NAME)
+ .addPkColumn(newBooleanColumnDefBuilder().setColumnName("bool_col").build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("varchar_col").setLimit(40).build())
+ .build();
+ assertThat(stmts).hasSize(1);
+
+ assertThat(stmts.iterator().next())
+ .isEqualTo("CREATE TABLE " + TABLE_NAME + " (" +
+ "bool_col BOOLEAN NULL," +
+ "varchar_col VARCHAR (40) NULL," +
+ " CONSTRAINT pk_" + TABLE_NAME + " PRIMARY KEY (bool_col)" +
+ ")");
+
+ }
+
+ @Test
+ public void build_adds_PRIMARY_KEY_constraint_on_single_column_with_name_computed_from_tablename() {
+ Arrays.asList(ALL_DIALECTS)
+ .forEach(dialect -> {
+ List<String> stmts = new CreateTableBuilder(dialect, TABLE_NAME)
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col").setIsNullable(false).build())
+ .build();
+ assertThat(stmts).hasSize(1);
+
+ assertThat(stmts.iterator().next())
+ .startsWith("CREATE TABLE " + TABLE_NAME + " (" +
+ "bg_col " + bigIntSqlType(dialect) + " NOT NULL," +
+ " CONSTRAINT pk_" + TABLE_NAME + " PRIMARY KEY (bg_col)" +
+ ")");
+ });
+ }
+
+ @Test
+ public void build_adds_PRIMARY_KEY_constraint_on_single_column_with_lower_case_of_specified_name() {
+ Arrays.asList(ALL_DIALECTS)
+ .forEach(dialect -> {
+ List<String> stmts = new CreateTableBuilder(dialect, TABLE_NAME)
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col").setIsNullable(false).build())
+ .withPkConstraintName("my_pk")
+ .build();
+ assertThat(stmts).hasSize(1);
+
+ assertThat(stmts.iterator().next())
+ .startsWith("CREATE TABLE " + TABLE_NAME + " (" +
+ "bg_col " +
+ bigIntSqlType(dialect) +
+ " NOT NULL," +
+ " CONSTRAINT my_pk PRIMARY KEY (bg_col)" +
+ ")");
+ });
+ }
+
+ @Test
+ public void build_adds_PRIMARY_KEY_constraint_on_multiple_columns_with_name_computed_from_tablename() {
+ Arrays.asList(ALL_DIALECTS)
+ .forEach(dialect -> {
+ List<String> stmts = new CreateTableBuilder(dialect, TABLE_NAME)
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col_1").setIsNullable(false).build())
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col_2").setIsNullable(false).build())
+ .build();
+ assertThat(stmts).hasSize(1);
+
+ assertThat(stmts.iterator().next())
+ .startsWith("CREATE TABLE " + TABLE_NAME + " (" +
+ "bg_col_1 " + bigIntSqlType(dialect) + " NOT NULL," +
+ "bg_col_2 " + bigIntSqlType(dialect) + " NOT NULL," +
+ " CONSTRAINT pk_" + TABLE_NAME + " PRIMARY KEY (bg_col_1,bg_col_2)" +
+ ")");
+ });
+ }
+
+ @Test
+ public void build_adds_PRIMARY_KEY_constraint_on_multiple_columns_with_lower_case_of_specified_name() {
+ Arrays.asList(ALL_DIALECTS)
+ .forEach(dialect -> {
+ List<String> stmts = new CreateTableBuilder(dialect, TABLE_NAME)
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col_1").setIsNullable(false).build())
+ .addPkColumn(newBigIntegerColumnDefBuilder().setColumnName("bg_col_2").setIsNullable(false).build())
+ .withPkConstraintName("my_pk")
+ .build();
+ assertThat(stmts).hasSize(1);
+
+ assertThat(stmts.iterator().next())
+ .startsWith("CREATE TABLE " + TABLE_NAME + " (" +
+ "bg_col_1 " + bigIntSqlType(dialect) + " NOT NULL," +
+ "bg_col_2 " + bigIntSqlType(dialect) + " NOT NULL," +
+ " CONSTRAINT my_pk PRIMARY KEY (bg_col_1,bg_col_2)" +
+ ")");
+ });
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_varchar_column_on_H2() {
+ verifyDefaultClauseOnVarcharColumn(H2, "CREATE TABLE table_42 (status VARCHAR (1) DEFAULT 'P' NOT NULL)");
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_varchar_column_on_MSSQL() {
+ verifyDefaultClauseOnVarcharColumn(MS_SQL, "CREATE TABLE table_42 (status NVARCHAR (1) DEFAULT 'P' NOT NULL)");
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_varchar_column_on_MySQL() {
+ verifyDefaultClauseOnVarcharColumn(MY_SQL, "CREATE TABLE table_42 (status VARCHAR (1) DEFAULT 'P' NOT NULL) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin");
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_varchar_column_on_Oracle() {
+ verifyDefaultClauseOnVarcharColumn(ORACLE, "CREATE TABLE table_42 (status VARCHAR (1 CHAR) DEFAULT 'P' NOT NULL)");
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_varchar_column_on_PostgreSQL() {
+ verifyDefaultClauseOnVarcharColumn(POSTGRESQL, "CREATE TABLE table_42 (status VARCHAR (1) DEFAULT 'P' NOT NULL)");
+ }
+
+ private static void verifyDefaultClauseOnVarcharColumn(Dialect dialect, String expectedSql) {
+ List<String> stmts = new CreateTableBuilder(dialect, TABLE_NAME)
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("status").setLimit(1).setIsNullable(false).setDefaultValue("P").build())
+ .build();
+ assertThat(stmts).containsExactly(expectedSql);
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_boolean_column_on_H2() {
+ verifyDefaultClauseOnBooleanColumn(H2, "CREATE TABLE table_42 (enabled BOOLEAN DEFAULT true NOT NULL)");
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_boolean_column_on_MSSQL() {
+ verifyDefaultClauseOnBooleanColumn(MS_SQL, "CREATE TABLE table_42 (enabled BIT DEFAULT 1 NOT NULL)");
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_boolean_column_on_MySQL() {
+ verifyDefaultClauseOnBooleanColumn(MY_SQL, "CREATE TABLE table_42 (enabled TINYINT(1) DEFAULT true NOT NULL) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin");
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_boolean_column_on_Oracle() {
+ verifyDefaultClauseOnBooleanColumn(ORACLE, "CREATE TABLE table_42 (enabled NUMBER(1) DEFAULT 1 NOT NULL)");
+ }
+
+ @Test
+ public void build_adds_DEFAULT_clause_on_boolean_column_on_PostgreSQL() {
+ verifyDefaultClauseOnBooleanColumn(POSTGRESQL, "CREATE TABLE table_42 (enabled BOOLEAN DEFAULT true NOT NULL)");
+ }
+
+ private static void verifyDefaultClauseOnBooleanColumn(Dialect dialect, String expectedSql) {
+ List<String> stmts = new CreateTableBuilder(dialect, TABLE_NAME)
+ .addColumn(newBooleanColumnDefBuilder().setColumnName("enabled").setIsNullable(false).setDefaultValue(true).build())
+ .build();
+ assertThat(stmts).containsExactly(expectedSql);
+ }
+
+ private static String bigIntSqlType(Dialect dialect) {
+ return Oracle.ID.equals(dialect.getId()) ? "NUMBER (38)" : "BIGINT";
+ }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropColumnsBuilderTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropColumnsBuilderTest.java
new file mode 100644
index 00000000000..9b73c16113c
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropColumnsBuilderTest.java
@@ -0,0 +1,63 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import org.junit.Test;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DropColumnsBuilderTest {
+
+ @Test
+ public void drop_columns_on_mysql() {
+ assertThat(new DropColumnsBuilder(new MySql(), "issues", "date_in_ms", "name")
+ .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, DROP COLUMN name");
+ }
+
+ @Test
+ public void drop_columns_on_oracle() {
+ assertThat(new DropColumnsBuilder(new Oracle(), "issues", "date_in_ms", "name")
+ .build()).isEqualTo("ALTER TABLE issues DROP (date_in_ms, name)");
+ }
+
+ @Test
+ public void drop_columns_on_postgresql() {
+ assertThat(new DropColumnsBuilder(new PostgreSql(), "issues", "date_in_ms", "name")
+ .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, DROP COLUMN name");
+ }
+
+ @Test
+ public void drop_columns_on_mssql() {
+ assertThat(new DropColumnsBuilder(new MsSql(), "issues", "date_in_ms", "name")
+ .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, name");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void fail_to_drop_columns_on_h2() {
+ new DropColumnsBuilder(new H2(), "issues", "date_in_ms", "name")
+ .build();
+ }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropIndexBuilderTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropIndexBuilderTest.java
new file mode 100644
index 00000000000..5958a74cbca
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropIndexBuilderTest.java
@@ -0,0 +1,98 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DropIndexBuilderTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void drop_index_in_table() {
+ verifySql(new H2(), "DROP INDEX IF EXISTS issues_key");
+ verifySql(new MsSql(), "DROP INDEX issues_key ON issues");
+ verifySql(new MySql(), "DROP INDEX issues_key ON issues");
+ verifySql(new Oracle(), "DROP INDEX issues_key");
+ verifySql(new PostgreSql(), "DROP INDEX IF EXISTS issues_key");
+ }
+
+ private static void verifySql(Dialect dialect, String expectedSql) {
+ List<String> actual = new DropIndexBuilder(dialect)
+ .setTable("issues")
+ .setName("issues_key")
+ .build();
+ assertThat(actual).containsExactly(expectedSql);
+ }
+
+ @Test
+ public void throw_NPE_if_table_name_is_missing() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Table name cannot be null");
+
+ new DropIndexBuilder(new H2())
+ .setName("issues_key")
+ .build();
+ }
+
+ @Test
+ public void throw_IAE_if_table_name_is_not_valid() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Table name must be lower case and contain only alphanumeric chars or '_', got '(not valid)'");
+
+ new DropIndexBuilder(new H2())
+ .setTable("(not valid)")
+ .setName("issues_key")
+ .build();
+ }
+
+ @Test
+ public void throw_NPE_if_index_name_is_missing() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Index name cannot be null");
+
+ new DropIndexBuilder(new H2())
+ .setTable("issues")
+ .build();
+ }
+
+ @Test
+ public void throw_IAE_if_index_name_is_not_valid() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Index name must be lower case and contain only alphanumeric chars or '_', got '(not valid)'");
+
+ new DropIndexBuilder(new H2())
+ .setTable("issues")
+ .setName("(not valid)")
+ .build();
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropTableBuilderTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropTableBuilderTest.java
new file mode 100644
index 00000000000..6c2e3140656
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/DropTableBuilderTest.java
@@ -0,0 +1,97 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.platform.db.migration.sql;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DropTableBuilderTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void drop_tables_on_mysql() {
+ assertThat(new DropTableBuilder(new MySql(), "issues")
+ .build()).containsOnly("DROP TABLE issues");
+ }
+
+ @Test
+ public void drop_tables_on_postgresql() {
+ assertThat(new DropTableBuilder(new PostgreSql(), "issues")
+ .build()).containsOnly("DROP TABLE issues");
+ }
+
+ @Test
+ public void drop_tables_on_mssql() {
+ assertThat(new DropTableBuilder(new MsSql(), "issues")
+ .build()).containsOnly("DROP TABLE issues");
+ }
+
+ @Test
+ public void drop_tables_on_h2() {
+ assertThat(new DropTableBuilder(new H2(), "issues")
+ .build()).containsOnly("DROP TABLE issues");
+ }
+
+ @Test
+ public void drop_columns_on_oracle() {
+ assertThat(new DropTableBuilder(new Oracle(), "issues")
+ .build()).containsExactly(
+ "BEGIN\n" +
+ " EXECUTE IMMEDIATE 'DROP SEQUENCE issues_seq';\n" +
+ "EXCEPTION\n" +
+ " WHEN OTHERS THEN\n" +
+ " IF SQLCODE != -2289 THEN\n" +
+ " RAISE;\n" +
+ " END IF;\n" +
+ "END;",
+ "BEGIN\n" +
+ " EXECUTE IMMEDIATE 'DROP TRIGGER issues_idt';\n" +
+ "EXCEPTION\n" +
+ " WHEN OTHERS THEN\n" +
+ " IF SQLCODE != -4080 THEN\n" +
+ " RAISE;\n" +
+ " END IF;\n" +
+ "END;",
+ "DROP TABLE issues");
+ }
+
+ @Test
+ public void fail_when_dialect_is_null() throws Exception {
+ expectedException.expect(NullPointerException.class);
+ new DropTableBuilder(null, "issues");
+ }
+
+ @Test
+ public void fail_when_table_is_null() throws Exception {
+ expectedException.expect(NullPointerException.class);
+ new DropTableBuilder(new PostgreSql(), null);
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/RenameTableBuilderTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/RenameTableBuilderTest.java
new file mode 100644
index 00000000000..ba3bf266518
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/sql/RenameTableBuilderTest.java
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.sql;
+
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RenameTableBuilderTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void rename_table_on_h2() {
+ verifySql(new H2(), "ALTER TABLE foo RENAME TO bar");
+ }
+
+ @Test
+ public void rename_table_on_mssql() {
+ verifySql(new MsSql(), "EXEC sp_rename 'foo', 'bar'");
+ }
+
+ @Test
+ public void rename_table_on_mysql() {
+ verifySql(new MySql(), "ALTER TABLE foo RENAME TO bar");
+ }
+
+ @Test
+ public void rename_table_on_oracle() {
+ verifySql(new Oracle(),
+ "DROP TRIGGER foo_idt",
+ "RENAME foo TO bar",
+ "RENAME foo_seq TO bar_seq",
+ "CREATE OR REPLACE TRIGGER bar_idt BEFORE INSERT ON bar FOR EACH ROW BEGIN IF :new.id IS null THEN SELECT bar_seq.nextval INTO :new.id FROM dual; END IF; END;");
+ }
+
+ @Test
+ public void rename_table_on_postgresql() {
+ verifySql(new PostgreSql(), "ALTER TABLE foo RENAME TO bar");
+ }
+
+ @Test
+ public void throw_IAE_if_name_is_not_valid() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Table name must be lower case and contain only alphanumeric chars or '_', got '(not valid)'");
+
+ new RenameTableBuilder(new H2()).setName("(not valid)").build();
+ }
+
+ @Test
+ public void throw_IAE_if_new_name_is_not_valid() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Table name must be lower case and contain only alphanumeric chars or '_', got '(not valid)'");
+
+ new RenameTableBuilder(new H2()).setName("foo").setNewName("(not valid)").build();
+ }
+
+ private static void verifySql(Dialect dialect, String... expectedSql) {
+ List<String> actual = new RenameTableBuilder(dialect)
+ .setName("foo")
+ .setNewName("bar")
+ .build();
+ assertThat(actual).containsExactly(expectedSql);
+ }
+}