aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DbVersionModule.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchema.java (renamed from sonar-db/src/main/java/org/sonar/db/version/v56/CreateInitialSchema.java)4
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/DbVersion56.java (renamed from sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java)18
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchema.java (renamed from sonar-db/src/main/java/org/sonar/db/version/v56/PopulateInitialSchema.java)6
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/package-info.java (renamed from sonar-db/src/main/java/org/sonar/db/version/v56/package-info.java)2
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/DbVersionModuleTest.java2
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchemaTest.java (renamed from sonar-db/src/test/java/org/sonar/db/version/v56/CreateInitialSchemaTest.java)2
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/DbVersion56Test.java (renamed from sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java)27
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchemaTest.java (renamed from sonar-db/src/test/java/org/sonar/db/version/v56/PopulateInitialSchemaTest.java)2
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchemaTest/empty.sql (renamed from sonar-db/src/test/resources/org/sonar/db/version/v56/CreateInitialSchemaTest/empty.sql)0
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchemaTest/v56.sql (renamed from sonar-db/src/test/resources/org/sonar/db/version/v56/PopulateInitialSchemaTest/v56.sql)0
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java28
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/DatabaseMigratorTest.java35
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddAnalysisUuidColumnToDuplicationsIndex.java3
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddComponentUuidColumnToDuplicationsIndex.java3
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java3
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/MakeComponentUuidNotNullOnDuplicationsIndex.java3
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java3
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java3
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb155
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/001_create_initial_schema.rb24
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/002_populate_initial_schema.rb24
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/README.txt55
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/lib/database_version.rb3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/version/BaseDataChange.java65
-rw-r--r--sonar-db/src/main/java/org/sonar/db/version/DdlChange.java122
-rw-r--r--sonar-db/src/main/java/org/sonar/db/version/MigrationStep.java32
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java479
30 files changed, 56 insertions, 1062 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DbVersionModule.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DbVersionModule.java
index 4fdb281ddbb..0de137980aa 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DbVersionModule.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DbVersionModule.java
@@ -20,6 +20,7 @@
package org.sonar.server.platform.db.migration.version;
import org.sonar.core.platform.Module;
+import org.sonar.server.platform.db.migration.version.v56.DbVersion56;
import org.sonar.server.platform.db.migration.version.v561.DbVersion561;
import org.sonar.server.platform.db.migration.version.v60.DbVersion60;
import org.sonar.server.platform.db.migration.version.v61.DbVersion61;
@@ -30,6 +31,7 @@ public class DbVersionModule extends Module {
@Override
protected void configureModule() {
add(
+ DbVersion56.class,
DbVersion561.class,
DbVersion60.class,
DbVersion61.class,
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v56/CreateInitialSchema.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchema.java
index 91007e90792..d037512bbf0 100644
--- a/sonar-db/src/main/java/org/sonar/db/version/v56/CreateInitialSchema.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchema.java
@@ -17,7 +17,7 @@
* 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.db.version.v56;
+package org.sonar.server.platform.db.migration.version.v56;
import java.sql.SQLException;
import org.sonar.db.Database;
@@ -26,10 +26,10 @@ 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.DdlChange;
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.step.DdlChange;
import static org.sonar.db.version.BigIntegerColumnDef.newBigIntegerColumnDefBuilder;
import static org.sonar.db.version.BlobColumnDef.newBlobColumnDefBuilder;
diff --git a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/DbVersion56.java
index 6e7ec450d6e..c8295486b0d 100644
--- a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/DbVersion56.java
@@ -17,18 +17,16 @@
* 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.db.version;
+package org.sonar.server.platform.db.migration.version.v56;
-import org.sonar.core.platform.Module;
-import org.sonar.db.version.v56.CreateInitialSchema;
-import org.sonar.db.version.v56.PopulateInitialSchema;
+import org.sonar.server.platform.db.migration.step.MigrationStepRegistry;
+import org.sonar.server.platform.db.migration.version.DbVersion;
-public class MigrationStepModule extends Module {
+public class DbVersion56 implements DbVersion {
@Override
- protected void configureModule() {
- add(
- // 5.6
- CreateInitialSchema.class,
- PopulateInitialSchema.class);
+ public void addSteps(MigrationStepRegistry registry) {
+ registry
+ .add(1, "Create initial schema", CreateInitialSchema.class)
+ .add(2, "Populate initial schema", PopulateInitialSchema.class);
}
}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v56/PopulateInitialSchema.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchema.java
index 491db800cbb..ef48be58073 100644
--- a/sonar-db/src/main/java/org/sonar/db/version/v56/PopulateInitialSchema.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchema.java
@@ -17,15 +17,15 @@
* 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.db.version.v56;
+package org.sonar.server.platform.db.migration.version.v56;
import java.sql.SQLException;
import java.util.Date;
import org.sonar.api.utils.System2;
import org.sonar.db.Database;
-import org.sonar.db.version.BaseDataChange;
+import org.sonar.server.platform.db.migration.step.DataChange;
-public class PopulateInitialSchema extends BaseDataChange {
+public class PopulateInitialSchema extends DataChange {
private static final String ADMINS_GROUP = "sonar-administrators";
private static final String USERS_GROUP = "sonar-users";
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v56/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/package-info.java
index c3a55a0eb13..832de3c3198 100644
--- a/sonar-db/src/main/java/org/sonar/db/version/v56/package-info.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v56/package-info.java
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
-package org.sonar.db.version.v56;
+package org.sonar.server.platform.db.migration.version.v56;
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/DbVersionModuleTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/DbVersionModuleTest.java
index 6f9226ab604..8a2b5a42cc9 100644
--- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/DbVersionModuleTest.java
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/DbVersionModuleTest.java
@@ -36,7 +36,7 @@ public class DbVersionModuleTest {
underTest.configure(container);
assertThat(container.getPicoContainer().getComponentAdapters())
- .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 5);
+ .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 6);
}
}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v56/CreateInitialSchemaTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchemaTest.java
index d92d451c1e8..61a39f3dae5 100644
--- a/sonar-db/src/test/java/org/sonar/db/version/v56/CreateInitialSchemaTest.java
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchemaTest.java
@@ -17,7 +17,7 @@
* 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.db.version.v56;
+package org.sonar.server.platform.db.migration.version.v56;
import java.sql.Connection;
import java.sql.ResultSet;
diff --git a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/DbVersion56Test.java
index 60bf767ed9c..d62347556e6 100644
--- a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/DbVersion56Test.java
@@ -17,18 +17,31 @@
* 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.db.version;
+package org.sonar.server.platform.db.migration.version.v56;
import org.junit.Test;
-import org.sonar.core.platform.ComponentContainer;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationCount;
+import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber;
+
+public class DbVersion56Test {
+ private DbVersion56 underTest = new DbVersion56();
-public class MigrationStepModuleTest {
@Test
- public void verify_count_of_added_MigrationStep_types() {
- ComponentContainer container = new ComponentContainer();
- new MigrationStepModule().configure(container);
- assertThat(container.size()).isEqualTo(4);
+ public void verify_no_support_component() {
+ assertThat(underTest.getSupportComponents()).isEmpty();
}
+
+ @Test
+ public void migrationNumber_starts_at_1153() {
+ verifyMinimumMigrationNumber(underTest, 1);
+ }
+
+ @Test
+ public void verify_migration_count() {
+ verifyMigrationCount(underTest, 2);
+ }
+
+
}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v56/PopulateInitialSchemaTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchemaTest.java
index 3f3699edcc8..5d167c53e49 100644
--- a/sonar-db/src/test/java/org/sonar/db/version/v56/PopulateInitialSchemaTest.java
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchemaTest.java
@@ -17,7 +17,7 @@
* 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.db.version.v56;
+package org.sonar.server.platform.db.migration.version.v56;
import java.sql.SQLException;
import java.util.List;
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v56/CreateInitialSchemaTest/empty.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchemaTest/empty.sql
index e69de29bb2d..e69de29bb2d 100644
--- a/sonar-db/src/test/resources/org/sonar/db/version/v56/CreateInitialSchemaTest/empty.sql
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v56/CreateInitialSchemaTest/empty.sql
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v56/PopulateInitialSchemaTest/v56.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchemaTest/v56.sql
index d0c61c969ac..d0c61c969ac 100644
--- a/sonar-db/src/test/resources/org/sonar/db/version/v56/PopulateInitialSchemaTest/v56.sql
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v56/PopulateInitialSchemaTest/v56.sql
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java
index 1435468e39a..1746941c190 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java
@@ -29,7 +29,6 @@ import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.DbClient;
import org.sonar.db.DdlUtils;
-import org.sonar.db.version.MigrationStep;
import org.sonar.server.plugins.ServerPluginRepository;
/**
@@ -42,16 +41,13 @@ import org.sonar.server.plugins.ServerPluginRepository;
public class DatabaseMigrator implements Startable {
private final DbClient dbClient;
- private final MigrationStep[] migrations;
private final ServerUpgradeStatus serverUpgradeStatus;
/**
* ServerPluginRepository is used to ensure H2 schema creation is done only after copy of bundle plugins have been done
*/
- public DatabaseMigrator(DbClient dbClient, MigrationStep[] migrations, ServerUpgradeStatus serverUpgradeStatus,
- ServerPluginRepository unused) {
+ public DatabaseMigrator(DbClient dbClient, ServerUpgradeStatus serverUpgradeStatus, ServerPluginRepository unused) {
this.dbClient = dbClient;
- this.migrations = migrations;
this.serverUpgradeStatus = serverUpgradeStatus;
}
@@ -89,28 +85,6 @@ public class DatabaseMigrator implements Startable {
return false;
}
- public void executeMigration(String className) {
- MigrationStep migration = getMigration(className);
- try {
- migration.execute();
-
- } catch (Exception e) {
- // duplication between log and exception because webapp does not correctly log initial stacktrace
- String msg = "Fail to execute database migration: " + className;
- Loggers.get(getClass()).error(msg, e);
- throw new IllegalStateException(msg, e);
- }
- }
-
- private MigrationStep getMigration(String className) {
- for (MigrationStep migration : migrations) {
- if (migration.getClass().getName().equals(className)) {
- return migration;
- }
- }
- throw new IllegalArgumentException("Database migration not found: " + className);
- }
-
@VisibleForTesting
protected void createSchema(Connection connection, String dialectId) {
DdlUtils.createSchema(connection, dialectId, false);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
index 9e9f2e95479..65b92653ff3 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
@@ -25,7 +25,6 @@ import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.core.platform.PluginClassloaderFactory;
import org.sonar.core.platform.PluginLoader;
import org.sonar.db.charset.DatabaseCharsetChecker;
-import org.sonar.db.version.MigrationStepModule;
import org.sonar.server.platform.DefaultServerUpgradeStatus;
import org.sonar.server.platform.StartupMetadataProvider;
import org.sonar.server.platform.db.CheckDatabaseCharsetAtStartup;
@@ -75,9 +74,7 @@ public class PlatformLevel2 extends PlatformLevel {
add(DatabaseMigrationStateImpl.class,
DatabaseMigrationExecutorServiceImpl.class);
// Ruby DB Migration
- add(
- DatabaseMigrator.class,
- MigrationStepModule.class);
+ add(DatabaseMigrator.class);
addIfStartupLeader(
DatabaseCharsetChecker.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
index aa5f0f6f694..9aa211f5fbc 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
@@ -55,13 +55,12 @@ import org.sonar.server.authentication.IdentityProviderRepository;
import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.platform.PersistentSettings;
import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.db.migrations.DatabaseMigrator;
import org.sonar.server.platform.db.migration.DatabaseMigrationState;
import org.sonar.server.platform.ws.UpgradesAction;
import org.sonar.server.user.NewUserNotifier;
import static com.google.common.collect.Lists.newArrayList;
-import static org.sonar.server.platform.db.migration.DatabaseMigrationState.*;
+import static org.sonar.server.platform.db.migration.DatabaseMigrationState.Status;
public final class JRubyFacade {
@@ -153,9 +152,8 @@ public final class JRubyFacade {
return get(Database.class);
}
- // Only used by Java migration
- public DatabaseMigrator databaseMigrator() {
- return get(DatabaseMigrator.class);
+ public boolean isDbUptodate() {
+ return getContainer().getComponentByType(DatabaseVersion.class).getStatus() == DatabaseVersion.Status.UP_TO_DATE;
}
/* PROFILES CONSOLE : RULES AND METRIC THRESHOLDS */
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/DatabaseMigratorTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/DatabaseMigratorTest.java
index 6fca4c37125..a3bac3ac496 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/DatabaseMigratorTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/DatabaseMigratorTest.java
@@ -31,7 +31,6 @@ import org.sonar.db.DbSession;
import org.sonar.db.dialect.Dialect;
import org.sonar.db.dialect.H2;
import org.sonar.db.dialect.MySql;
-import org.sonar.db.version.MigrationStep;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyBoolean;
@@ -45,14 +44,13 @@ public class DatabaseMigratorTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
- DbClient dbClient = mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS);
- MigrationStep[] migrations = new MigrationStep[] {new FakeMigrationStep()};
- ServerUpgradeStatus serverUpgradeStatus = mock(ServerUpgradeStatus.class);
- DatabaseMigrator migrator;
+ private DbClient dbClient = mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS);
+ private ServerUpgradeStatus serverUpgradeStatus = mock(ServerUpgradeStatus.class);
+ private DatabaseMigrator migrator;
@Before
public void setUp() {
- migrator = new DatabaseMigrator(dbClient, migrations, serverUpgradeStatus, null);
+ migrator = new DatabaseMigrator(dbClient, serverUpgradeStatus, null);
}
@Test
@@ -64,21 +62,6 @@ public class DatabaseMigratorTest {
}
@Test
- public void fail_if_execute_unknown_migration() {
- thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Database migration not found: org.xxx.UnknownMigration");
-
- migrator.executeMigration("org.xxx.UnknownMigration");
- }
-
- @Test
- public void execute_migration() {
- assertThat(FakeMigrationStep.executed).isFalse();
- migrator.executeMigration(FakeMigrationStep.class.getName());
- assertThat(FakeMigrationStep.executed).isTrue();
- }
-
- @Test
public void should_create_schema_on_h2() {
Dialect supportedDialect = new H2();
when(dbClient.getDatabase().getDialect()).thenReturn(supportedDialect);
@@ -88,7 +71,7 @@ public class DatabaseMigratorTest {
when(dbClient.openSession(false)).thenReturn(session);
when(serverUpgradeStatus.isFreshInstall()).thenReturn(true);
- DatabaseMigrator databaseMigrator = new DatabaseMigrator(dbClient, migrations, serverUpgradeStatus, null) {
+ DatabaseMigrator databaseMigrator = new DatabaseMigrator(dbClient, serverUpgradeStatus, null) {
@Override
protected void createSchema(Connection connection, String dialectId) {
}
@@ -97,12 +80,4 @@ public class DatabaseMigratorTest {
assertThat(databaseMigrator.createDatabase()).isTrue();
}
- public static class FakeMigrationStep implements MigrationStep {
- static boolean executed = false;
-
- @Override
- public void execute() {
- executed = true;
- }
- }
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddAnalysisUuidColumnToDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddAnalysisUuidColumnToDuplicationsIndex.java
index 04f86a0ed14..557449e68c2 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddAnalysisUuidColumnToDuplicationsIndex.java
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddAnalysisUuidColumnToDuplicationsIndex.java
@@ -22,7 +22,6 @@ package org.sonar.db.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.db.version.AddColumnsBuilder;
-import org.sonar.db.version.DdlChange;
import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
@@ -42,4 +41,4 @@ public class AddAnalysisUuidColumnToDuplicationsIndex extends DdlChange {
.build());
}
-} \ No newline at end of file
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddComponentUuidColumnToDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddComponentUuidColumnToDuplicationsIndex.java
index a25cf2cc376..8612d57b378 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddComponentUuidColumnToDuplicationsIndex.java
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/AddComponentUuidColumnToDuplicationsIndex.java
@@ -22,7 +22,6 @@ package org.sonar.db.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.db.version.AddColumnsBuilder;
-import org.sonar.db.version.DdlChange;
import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
@@ -43,4 +42,4 @@ public class AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex extends Dd
.build());
}
-} \ No newline at end of file
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java
index 763dd89a98a..0a05c5194b3 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java
@@ -21,7 +21,6 @@ package org.sonar.db.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
-import org.sonar.db.version.BaseDataChange;
import org.sonar.db.version.MassUpdate;
public class DeleteOrphanDuplicationsIndexRowsWithoutComponent extends BaseDataChange {
@@ -42,4 +41,4 @@ public class DeleteOrphanDuplicationsIndexRowsWithoutComponent extends BaseDataC
});
}
-} \ No newline at end of file
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/MakeComponentUuidNotNullOnDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/MakeComponentUuidNotNullOnDuplicationsIndex.java
index 6233d86fb40..8ced13cac4d 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/MakeComponentUuidNotNullOnDuplicationsIndex.java
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1/MakeComponentUuidNotNullOnDuplicationsIndex.java
@@ -22,7 +22,6 @@ package org.sonar.db.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.db.version.AlterColumnsBuilder;
-import org.sonar.db.version.DdlChange;
import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
@@ -42,4 +41,4 @@ public class MakeComponentUuidNotNullOnDuplicationsIndex extends DdlChange {
.build());
}
-} \ No newline at end of file
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java
index 8e9280fa5ec..8cc16f323a9 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java
@@ -22,7 +22,6 @@ package org.sonar.db.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.db.version.AddColumnsBuilder;
-import org.sonar.db.version.DdlChange;
import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
@@ -42,4 +41,4 @@ public class AddComponentUuidColumnToDuplicationsIndex extends DdlChange {
.build());
}
-} \ No newline at end of file
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java
index e365b126bfd..9e522216532 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java
@@ -22,7 +22,6 @@ package org.sonar.db.version.v60;
import java.sql.SQLException;
import org.sonar.db.Database;
import org.sonar.db.version.AlterColumnsBuilder;
-import org.sonar.db.version.DdlChange;
import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
@@ -43,4 +42,4 @@ public class MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex extends
.build());
}
-} \ No newline at end of file
+}
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb b/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb
index 3c375e4607b..00f28b34ec3 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb
@@ -100,164 +100,9 @@ Rails::Initializer.run do |config|
# Prevent appearance of ANSI style escape sequences in logs
config.active_record.colorize_logging = false
- # Use SQL instead of Active Record's schema dumper when creating the test database.
- # This is necessary if your schema can't be completely dumped by the schema dumper,
- # like if you have constraints or database-specific column types
- # config.active_record.schema_format = :sql
-
- # Activate observers that should always be running
- # Please note that observers generated using script/generate observer need to have an _observer suffix
- # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
end
-class ActiveRecord::Migration
- def self.dialect
- ActiveRecord::Base.configurations[ENV['RAILS_ENV']]['dialect']
- end
-
- def self.column_exists?(table_name, column_name)
- columns(table_name).any?{ |c| c.name == column_name.to_s }
- end
-
- def self.add_index(table_name, column_name, options = {})
- # ActiveRecord can generate index names longer than 30 characters, but that's
- # not supported by Oracle, the "Enterprise" database.
- # For this reason we force to set name of indexes.
- raise ArgumentError, 'Missing index name' unless options[:name]
-
- unless index_exists?(table_name, column_name, :name => options[:name])
- super(table_name, column_name, options)
- end
- end
-
- def self.remove_column(table_name, column_name)
- if column_exists?(table_name, column_name)
- super(table_name, column_name)
- end
- end
-
- def self.add_column(table_name, column_name, type, options = {})
- unless column_exists?(table_name, column_name)
- super(table_name, column_name, type, options)
- end
- end
-
- def self.add_varchar_index(table_name, column_name, options = {})
- if dialect()=='mysql' && !options[: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
- options[:length]=255
- end
- add_index table_name, column_name, options
- end
-
- def self.execute_java_migration(classname)
- Java::OrgSonarServerUi::JRubyFacade.getInstance().databaseMigrator().executeMigration(classname)
- end
-
- def self.alter_to_big_primary_key(tablename)
- case dialect()
- when "postgre"
- execute "ALTER TABLE #{tablename} ALTER COLUMN id TYPE bigint"
- when "mysql"
- execute "ALTER TABLE #{tablename} CHANGE id id BIGINT AUTO_INCREMENT"
- when "h2"
- # not needed?
- when "oracle"
- # do nothing, oracle integer are big enough
- when "sqlserver"
- constraint=select_one "select name from sysobjects where parent_obj = (select id from sysobjects where name = '#{tablename}')"
- execute "ALTER TABLE #{tablename} DROP CONSTRAINT #{constraint["name"]}"
- execute "ALTER TABLE #{tablename} ALTER COLUMN id bigint"
- execute "ALTER TABLE #{tablename} ADD PRIMARY KEY(id)"
- end
- end
-
- def self.alter_to_big_integer(tablename, columnname, indexname=nil)
- case dialect()
- when "sqlserver"
- execute "DROP INDEX #{indexname} on #{tablename}" if indexname
- change_column(tablename, columnname, :big_integer, :null => true)
- execute "CREATE INDEX #{indexname} on #{tablename}(#{columnname})" if indexname
- else
- change_column(tablename, columnname, :big_integer, :null => true)
- end
- end
-
- def self.add_primary_key(tablename, columnname)
- if dialect()=="mysql"
- execute "ALTER TABLE `#{tablename}` ADD PRIMARY KEY (`#{columnname}`)"
- else
- execute "ALTER TABLE #{tablename} ADD CONSTRAINT pk_#{tablename} PRIMARY KEY (#{columnname})"
- end
- end
-
- # SONAR-4178
- def self.create_table(table_name, options = {})
- # Oracle constraint (see names of triggers and indices)
- raise ArgumentError, "Table name is too long: #{table_name}" if table_name.to_s.length>25
-
- super(table_name, options)
- create_id_trigger(table_name) if dialect()=='oracle' && options[:id] != false
- end
-
- def drop_table(table_name, options = {})
- super(table_name, options)
- drop_id_trigger(table_name) if dialect()=='oracle'
- end
-
- def self.rename_table(old_table_name, new_table_name, options = {})
- drop_id_trigger(old_table_name) if dialect()=='oracle' && options[:id] != false
- super(old_table_name, new_table_name)
- create_id_trigger(new_table_name) if dialect()=='oracle' && options[:id] != false
- end
-
- def self.create_id_trigger(table)
- execute_ddl("create trigger for table #{table}",
-
- %{CREATE OR REPLACE TRIGGER #{table}_idt
- BEFORE INSERT ON #{table}
- FOR EACH ROW
- BEGIN
- IF :new.id IS null THEN
- SELECT #{table}_seq.nextval INTO :new.id FROM dual;
- END IF;
- END;})
- end
-
- def self.drop_id_trigger(table)
- drop_trigger("#{table}_idt")
- end
-
- def self.drop_trigger(trigger_name)
- execute_ddl("drop trigger #{trigger_name}", "DROP TRIGGER #{trigger_name}")
- end
-
- def self.write(text="")
- # See migration.rb, the method write directly calls "puts"
- Java::OrgSlf4j::LoggerFactory::getLogger('DbMigration').info(text) if verbose
- end
-
- def self.drop_index_quietly(table, index)
- begin
- remove_index table, :name => index
- rescue
- #ignore
- end
- end
-
-
- private
-
- def self.execute_ddl(message, ddl)
- say_with_time(message) do
- ActiveRecord::Base.connection.execute(ddl)
- end
- end
-end
-
# patch for SONAR-1182. GWT does not support ISO8601 dates that end with 'Z'
# http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/i18n/client/DateTimeFormat.html
module ActiveSupport
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/001_create_initial_schema.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/001_create_initial_schema.rb
deleted file mode 100644
index 049022bd018..00000000000
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/001_create_initial_schema.rb
+++ /dev/null
@@ -1,24 +0,0 @@
- #
- # SonarQube, open source software quality management tool.
- # Copyright (C) 2008-2016 SonarSource
- # mailto:contact AT sonarsource DOT com
- #
- # SonarQube 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.
- #
- # SonarQube 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.
- #
-class CreateInitialSchema < ActiveRecord::Migration
- def self.up
- execute_java_migration('org.sonar.db.version.v56.CreateInitialSchema')
- end
-end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/002_populate_initial_schema.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/002_populate_initial_schema.rb
deleted file mode 100644
index 3687c57fe3d..00000000000
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/002_populate_initial_schema.rb
+++ /dev/null
@@ -1,24 +0,0 @@
- #
- # SonarQube, open source software quality management tool.
- # Copyright (C) 2008-2016 SonarSource
- # mailto:contact AT sonarsource DOT com
- #
- # SonarQube 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.
- #
- # SonarQube 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.
- #
-class PopulateInitialSchema < ActiveRecord::Migration
- def self.up
- execute_java_migration('org.sonar.db.version.v56.PopulateInitialSchema')
- end
-end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/README.txt b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/README.txt
deleted file mode 100644
index 3cd43b6e984..00000000000
--- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/README.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-HOW TO ADD A MIGRATION
-
-* Jump some versions when adding the first Ruby on Rails migration of a new sonar version. For example if sonar 2.10 is 193, then sonar 2.11 should start at 200.
-* Complete the DDL files for H2 :
- + sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
- + sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql :
- - add "INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('<THE MIGRATION ID>')"
-* Update the migration id defined in org.sonar.db.version.DatabaseVersion
-* If a table is added or removed, then edit org.sonar.db.version.DatabaseVersion#TABLES
-* Changes in bulk must be handled using Java migrations based on org.sonar.db.version.MassUpdate :
- + Create the class for the Java migration in package org.sonar.db.version.vXYZ, where XYZ is the version of SQ without dots
- + Add the class to org.sonar.db.version.MigrationStepModule
- + Create a Ruby migration which calls execute_java_migration('org.sonar.db.version.vXYZ.MyMigration')
- + Simple, "one to one" migrations that only need to be split by 1000 can rely on class org.sonar.db.version.BaseDataChange
-
-
-RECOMMENDATIONS
-
-* Prefer to add nullable columns to avoid problems during migration, EXCEPT for booleans. For booleans:
-
- * columns must be NON-nullable but default value (false) must NOT be set in database. It allows to fully define the model programmatically.
- * column names must be chosen so that the default value is actually false.
- * E.g.: rule_failures.switched_off
-
-* Always create an index with a name : add_index "action_plans", "project_id", :name => "action_plans_project_id"
- Note that this name is limited to 30 characters because of Oracle constraint.
-
-* Silently ignore failures when adding an index that has already been created by users. It can occur when the index
- is not created in the same migration script than the table.
-
- begin
- add_index "action_plans", "project_id", :name => "action_plans_project_id"
- rescue
- # ignore
- end
-
-* Use faux models when touching rows (SELECT/INSERT/UPDATE/DELETE). See http://guides.rubyonrails.org/migrations.html#using-models-in-your-migrations
- for more details. Note that associations must not be used.
- IMPORTANT : do not use faux models for user models (User, Group, UserRole, GroupRole) because of required associations and password encryption.
-
-
- class MyMigration < ActiveRecord::Migration
- # This is the faux model. It only maps columns. No functional methods.
- class Metric < ActiveRecord::Base
- end
-
- def self.up
- # it’s a good idea to call reset_column_information to refresh the ActiveRecord cache for the model prior to
- # updating data in the database
- Metric.reset_column_information
- Metric.find(:all) do |m|
- m.save
- end
- end
- end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/lib/database_version.rb b/server/sonar-web/src/main/webapp/WEB-INF/lib/database_version.rb
index 52f032d0441..9656163835a 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/lib/database_version.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/lib/database_version.rb
@@ -53,7 +53,7 @@ class DatabaseVersion
def self.uptodate?
unless $uptodate
- $uptodate = (current_version>=target_version)
+ $uptodate = Java::OrgSonarServerUi::JRubyFacade.getInstance().isDbUptodate()
end
$uptodate
end
@@ -63,7 +63,6 @@ class DatabaseVersion
end
def self.upgrade_and_start
- ActiveRecord::Migrator.migrate(migrations_path)
Java::OrgSonarServerPlatform::Platform.getInstance().upgradeDb()
Java::OrgSonarServerPlatform::Platform.getInstance().doStart()
load_java_web_services
diff --git a/sonar-db/src/main/java/org/sonar/db/version/BaseDataChange.java b/sonar-db/src/main/java/org/sonar/db/version/BaseDataChange.java
deleted file mode 100644
index ae82b4d2f89..00000000000
--- a/sonar-db/src/main/java/org/sonar/db/version/BaseDataChange.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.db.version;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import org.apache.commons.dbutils.DbUtils;
-import org.sonar.db.Database;
-
-public abstract class BaseDataChange implements DataChange, MigrationStep {
-
- private final Database db;
-
- public BaseDataChange(Database db) {
- this.db = db;
- }
-
- @Override
- public final void execute() throws SQLException {
- Connection readConnection = null;
- Connection writeConnection = null;
- try {
- readConnection = openConnection();
-
- writeConnection = db.getDataSource().getConnection();
- writeConnection.setAutoCommit(false);
- Context context = new Context(db, readConnection, writeConnection);
- execute(context);
-
- } finally {
- DbUtils.closeQuietly(readConnection);
- DbUtils.closeQuietly(writeConnection);
- }
- }
-
- /**
- * Do not forget to close it !
- */
- protected Connection openConnection() throws SQLException {
- Connection connection = db.getDataSource().getConnection();
- connection.setAutoCommit(false);
- if (connection.getMetaData().supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED)) {
- connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
- }
- return connection;
- }
-
-}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/DdlChange.java b/sonar-db/src/main/java/org/sonar/db/version/DdlChange.java
deleted file mode 100644
index ffab3bb9fc5..00000000000
--- a/sonar-db/src/main/java/org/sonar/db/version/DdlChange.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.db.version;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.List;
-import java.util.regex.Pattern;
-import org.apache.commons.dbutils.DbUtils;
-import org.sonar.db.Database;
-import org.sonar.db.dialect.Dialect;
-
-import static java.lang.String.format;
-import static java.util.Arrays.asList;
-
-public abstract class DdlChange implements MigrationStep {
-
- private final Database db;
-
- public DdlChange(Database db) {
- this.db = db;
- }
-
- @Override
- public final void execute() throws SQLException {
- Connection writeConnection = null;
- try {
- writeConnection = db.getDataSource().getConnection();
- writeConnection.setAutoCommit(false);
- Context context = new Context(writeConnection);
- execute(context);
-
- } finally {
- DbUtils.closeQuietly(writeConnection);
- }
- }
-
- public abstract void execute(Context context) throws SQLException;
-
- protected Database getDatabase() {
- return db;
- }
-
- protected Dialect getDialect() {
- return db.getDialect();
- }
-
- public static class Context {
- private static final int ERROR_HANDLING_THRESHOLD = 10;
- // the tricky regexp is required to match "NULL" but not "NOT NULL"
- private final Pattern nullPattern = Pattern.compile("\\h?(?<!NOT )NULL");
- private final Pattern notNullPattern = Pattern.compile("\\h?NOT NULL");
- private final Connection writeConnection;
-
- public Context(Connection writeConnection) {
- this.writeConnection = writeConnection;
- }
-
- public void execute(String sql) throws SQLException {
- execute(sql, sql, 0);
- }
-
- public void execute(String original, String sql, int errorCount) throws SQLException {
- try (Statement stmt = writeConnection.createStatement()) {
- stmt.execute(sql);
- writeConnection.commit();
- } catch (SQLException e) {
- if (errorCount < ERROR_HANDLING_THRESHOLD) {
- String message = e.getMessage();
- if (message.contains("ORA-01451")) {
- String newSql = nullPattern.matcher(sql).replaceFirst("");
- execute(original, newSql, errorCount + 1);
- return;
- } else if (message.contains("ORA-01442")) {
- String newSql = notNullPattern.matcher(sql).replaceFirst("");
- execute(original, newSql, errorCount + 1);
- return;
- }
- }
- throw new IllegalStateException(messageForIseOf(original, sql, errorCount), e);
- } catch (Exception e) {
- throw new IllegalStateException(messageForIseOf(original, sql, errorCount), e);
- }
- }
-
- private static String messageForIseOf(String original, String sql, int errorCount) {
- if (!original.equals(sql) || errorCount > 0) {
- return format("Fail to execute %s %n (caught %s error, original was %s)", sql, errorCount, original);
- } else {
- return format("Fail to execute %s", sql);
- }
- }
-
- public void execute(String... sqls) throws SQLException {
- execute(asList(sqls));
- }
-
- public void execute(List<String> sqls) throws SQLException {
- for (String sql : sqls) {
- execute(sql);
- }
- }
- }
-}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/MigrationStep.java b/sonar-db/src/main/java/org/sonar/db/version/MigrationStep.java
deleted file mode 100644
index 6a50bc05795..00000000000
--- a/sonar-db/src/main/java/org/sonar/db/version/MigrationStep.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.db.version;
-
-import java.sql.SQLException;
-
-/**
- * Java alternative of ActiveRecord::Migration. Do not forget to declare implementation classes in {@link MigrationStepModule}
- * @since 3.7
- */
-public interface MigrationStep {
-
- void execute() throws SQLException;
-
-}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java b/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java
deleted file mode 100644
index 329f54955e2..00000000000
--- a/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * 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.db.version;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.utils.System2;
-import org.sonar.db.BatchSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.version.Select.Row;
-import org.sonar.db.version.Select.RowReader;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-
-
-public class BaseDataChangeTest {
-
- @Rule
- public DbTester db = DbTester.createForSchema(System2.INSTANCE, BaseDataChangeTest.class, "schema.sql");
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Before
- public void setUp() {
- db.executeUpdateSql("truncate table persons");
- }
-
- @Test
- public void query() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- final AtomicBoolean executed = new AtomicBoolean(false);
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- assertThat(context.prepareSelect("select id from persons order by id desc").list(Select.LONG_READER))
- .containsExactly(3L, 2L, 1L);
- assertThat(context.prepareSelect("select id from persons where id=?").setLong(1, 2L).get(Select.LONG_READER))
- .isEqualTo(2L);
- assertThat(context.prepareSelect("select id from persons where id=?").setLong(1, 12345L).get(Select.LONG_READER))
- .isNull();
- executed.set(true);
- }
- }.execute();
- assertThat(executed.get()).isTrue();
- }
-
- @Test
- public void read_column_types() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- final List<Object[]> persons = new ArrayList<>();
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- persons.addAll(context
- .prepareSelect("select id,login,age,enabled,updated_at,coeff from persons where id=2")
- .list(new UserReader()));
- }
- }.execute();
- assertThat(persons).hasSize(1);
- assertThat(persons.get(0)[0]).isEqualTo(2L);
- assertThat(persons.get(0)[1]).isEqualTo("emmerik");
- assertThat(persons.get(0)[2]).isEqualTo(14);
- assertThat(persons.get(0)[3]).isEqualTo(true);
- assertThat(persons.get(0)[4]).isNotNull();
- assertThat(persons.get(0)[5]).isEqualTo(5.2);
- }
-
- @Test
- public void parameterized_query() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- final List<Long> ids = new ArrayList<>();
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- ids.addAll(context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(Select.LONG_READER));
- }
- }.execute();
- assertThat(ids).containsOnly(2L, 3L);
- }
-
- @Test
- public void display_current_row_details_if_error_during_get() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Error during processing of row: [id=2]");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).get(new RowReader<Long>() {
- @Override
- public Long read(Row row) throws SQLException {
- throw new IllegalStateException("Unexpected error");
- }
- });
- }
- }.execute();
-
- }
-
- @Test
- public void display_current_row_details_if_error_during_list() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Error during processing of row: [id=2]");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(new RowReader<Long>() {
- @Override
- public Long read(Row row) throws SQLException {
- throw new IllegalStateException("Unexpected error");
- }
- });
- }
- }.execute();
-
- }
-
- @Test
- public void bad_parameterized_query() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- final List<Long> ids = new ArrayList<>();
- BaseDataChange change = new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- // parameter value is not set
- ids.addAll(context.prepareSelect("select id from persons where id>=?").list(Select.LONG_READER));
- }
- };
-
- thrown.expect(SQLException.class);
-
- change.execute();
- }
-
- @Test
- public void scroll() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- final List<Long> ids = new ArrayList<>();
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- context.prepareSelect("select id from persons order by id desc").scroll(new Select.RowHandler() {
- @Override
- public void handle(Select.Row row) throws SQLException {
- ids.add(row.getNullableLong(1));
- }
- });
- }
- }.execute();
- assertThat(ids).containsExactly(3L, 2L, 1L);
- }
-
- @Test
- public void insert() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)")
- .setLong(1, 10L)
- .setString(2, "kurt")
- .setInt(3, 27)
- .setBoolean(4, true)
- .setDouble(5, 2.2)
- .execute().commit().close();
- }
- }.execute();
-
- db.assertDbUnit(getClass(), "insert-result.xml", "persons");
- }
-
- @Test
- public void batch_insert() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- Upsert upsert = context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)");
- upsert
- .setLong(1, 10L)
- .setString(2, "kurt")
- .setInt(3, 27)
- .setBoolean(4, true)
- .setDouble(5, 2.2)
- .addBatch();
- upsert
- .setLong(1, 11L)
- .setString(2, "courtney")
- .setInt(3, 25)
- .setBoolean(4, false)
- .setDouble(5, 2.3)
- .addBatch();
- upsert.execute().commit().close();
- }
- }.execute();
-
- db.assertDbUnit(getClass(), "batch-insert-result.xml", "persons");
- }
-
- @Test
- public void update_null() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- Upsert upsert = context.prepareUpsert("update persons set login=?,age=?,enabled=?, updated_at=?, coeff=? where id=?");
- upsert
- .setString(1, null)
- .setInt(2, null)
- .setBoolean(3, null)
- .setDate(4, null)
- .setDouble(5, null)
- .setLong(6, 2L)
- .execute()
- .commit()
- .close();
- }
- }.execute();
-
- db.assertDbUnit(getClass(), "update-null-result.xml", "persons");
- }
-
- @Test
- public void mass_batch_insert() throws Exception {
- db.executeUpdateSql("truncate table persons");
-
- final int count = BatchSession.MAX_BATCH_SIZE + 10;
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- Upsert upsert = context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)");
- for (int i = 0; i < count; i++) {
- upsert
- .setLong(1, 10L + i)
- .setString(2, "login" + i)
- .setInt(3, 10 + i)
- .setBoolean(4, true)
- .setDouble(4, i + 0.5)
- .addBatch();
- }
- upsert.execute().commit().close();
-
- }
- }.execute();
-
- assertThat(db.countRowsOfTable("persons")).isEqualTo(count);
- }
-
- @Test
- public void scroll_and_update() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- final Upsert upsert = context.prepareUpsert("update persons set login=?, age=? where id=?");
- context.prepareSelect("select id from persons").scroll(new Select.RowHandler() {
- @Override
- public void handle(Select.Row row) throws SQLException {
- long id = row.getNullableLong(1);
- upsert.setString(1, "login" + id).setInt(2, 10 + (int) id).setLong(3, id);
- upsert.execute();
- }
- });
- upsert.commit().close();
- }
- }.execute();
-
- db.assertDbUnit(getClass(), "scroll-and-update-result.xml", "persons");
- }
-
- @Test
- public void display_current_row_details_if_error_during_scroll() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Error during processing of row: [id=1]");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- final Upsert upsert = context.prepareUpsert("update persons set login=?, age=? where id=?");
- context.prepareSelect("select id from persons").scroll(new Select.RowHandler() {
- @Override
- public void handle(Select.Row row) throws SQLException {
- throw new IllegalStateException("Unexpected error");
- }
- });
- upsert.commit().close();
- }
- }.execute();
- }
-
- @Test
- public void mass_update() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- MassUpdate massUpdate = context.prepareMassUpdate();
- massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
- massUpdate.update("update persons set login=?, age=? where id=?");
- massUpdate.execute(new MassUpdate.Handler() {
- @Override
- public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
- long id = row.getNullableLong(1);
- update
- .setString(1, "login" + id)
- .setInt(2, 10 + (int) id)
- .setLong(3, id);
- return true;
- }
- });
- }
- }.execute();
-
- db.assertDbUnit(getClass(), "mass-update-result.xml", "persons");
- }
-
- @Test
- public void display_current_row_details_if_error_during_mass_update() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Error during processing of row: [id=2]");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- MassUpdate massUpdate = context.prepareMassUpdate();
- massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
- massUpdate.update("update persons set login=?, age=? where id=?");
- massUpdate.execute(new MassUpdate.Handler() {
- @Override
- public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
- throw new IllegalStateException("Unexpected error");
- }
- });
- }
- }.execute();
- }
-
- @Test
- public void mass_update_nothing() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- MassUpdate massUpdate = context.prepareMassUpdate();
- massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
- massUpdate.update("update persons set login=?, age=? where id=?");
- massUpdate.execute(new MassUpdate.Handler() {
- @Override
- public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
- return false;
- }
- });
- }
- }.execute();
-
- db.assertDbUnit(getClass(), "persons.xml", "persons");
- }
-
- @Test
- public void bad_mass_update() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- BaseDataChange change = new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- MassUpdate massUpdate = context.prepareMassUpdate();
- massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
- // update is not set
- massUpdate.execute(new MassUpdate.Handler() {
- @Override
- public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
- return false;
- }
- });
- }
- };
- try {
- change.execute();
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessage("SELECT or UPDATE requests are not defined");
- }
- }
-
- @Test
- public void read_not_null_fields() throws Exception {
- db.prepareDbUnit(getClass(), "persons.xml");
-
- final List<Object[]> persons = new ArrayList<>();
- new BaseDataChange(db.database()) {
- @Override
- public void execute(Context context) throws SQLException {
- persons.addAll(context
- .prepareSelect("select id,login,age,enabled,updated_at,coeff from persons where id=2")
- .list(new Select.RowReader<Object[]>() {
- @Override
- public Object[] read(Select.Row row) throws SQLException {
- return new Object[] {
- // id, login, age, enabled
- row.getLong(1),
- row.getString(2),
- row.getInt(3),
- row.getBoolean(4),
- row.getDate(5),
- row.getDouble(6),
- };
- }
- }));
- }
- }.execute();
- assertThat(persons).hasSize(1);
- assertThat(persons.get(0)[0]).isEqualTo(2L);
- assertThat(persons.get(0)[1]).isEqualTo("emmerik");
- assertThat(persons.get(0)[2]).isEqualTo(14);
- assertThat(persons.get(0)[3]).isEqualTo(true);
- assertThat(persons.get(0)[4]).isNotNull();
- assertThat(persons.get(0)[5]).isEqualTo(5.2);
- }
-
- static class UserReader implements Select.RowReader<Object[]> {
- @Override
- public Object[] read(Select.Row row) throws SQLException {
- return new Object[] {
- // id, login, age, enabled
- row.getNullableLong(1),
- row.getNullableString(2),
- row.getNullableInt(3),
- row.getNullableBoolean(4),
- row.getNullableDate(5),
- row.getNullableDouble(6),
- };
- }
- }
-}