aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java113
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest.java171
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml18
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml10
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_projects.xml82
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml10
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml18
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_technical_projects-result.xml19
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_technical_projects.xml19
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql55
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/705_populate_projects_uuid_columns.rb32
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java3
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Component.java121
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Migration50Mapper.java74
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/package-info.java24
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/persistence/migration/v50/Migration50Mapper.xml7
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql1
-rw-r--r--sonar-core/src/test/java/org/sonar/core/persistence/migration/v50/ComponentTest.java37
20 files changed, 817 insertions, 3 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java
index f5ef2c46688..f81424d5c6b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java
@@ -29,6 +29,7 @@ import org.sonar.server.db.migrations.v45.AddMissingCustomRuleParametersMigratio
import org.sonar.server.db.migrations.v45.AddMissingRuleParameterDefaultValuesMigration;
import org.sonar.server.db.migrations.v45.DeleteMeasuresOnDeletedProfilesMigration;
import org.sonar.server.db.migrations.v50.InsertProjectsAuthorizationUpdatedAtMigration;
+import org.sonar.server.db.migrations.v50.PopulateProjectsUuidColumnsMigration;
import java.util.List;
@@ -63,7 +64,8 @@ public interface DatabaseMigrations {
AddMissingCustomRuleParametersMigration.class,
// 5.0
- InsertProjectsAuthorizationUpdatedAtMigration.class
+ InsertProjectsAuthorizationUpdatedAtMigration.class,
+ PopulateProjectsUuidColumnsMigration.class
);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java
new file mode 100644
index 00000000000..222bd793fa9
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java
@@ -0,0 +1,113 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.
+ */
+
+package org.sonar.server.db.migrations.v50;
+
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import org.sonar.api.resources.Scopes;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.migration.v50.Component;
+import org.sonar.core.persistence.migration.v50.Migration50Mapper;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.db.migrations.DatabaseMigration;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import static com.google.common.collect.Maps.newHashMap;
+
+/**
+ * Used in the Active Record Migration 705
+ *
+ * @since 5.0
+ */
+public class PopulateProjectsUuidColumnsMigration implements DatabaseMigration {
+
+ private final DbClient db;
+
+ public PopulateProjectsUuidColumnsMigration(DbClient db) {
+ this.db = db;
+ }
+
+ @Override
+ public void execute() {
+ DbSession session = db.openSession(true);
+ try {
+ Migration50Mapper mapper = session.getMapper(Migration50Mapper.class);
+
+ for (Component project : mapper.selectEnabledRootTrkProjects()) {
+ Map<Long, String> uuidByComponentId = newHashMap();
+ Map<Long, Component> componentsBySnapshotId = newHashMap();
+
+ List<Component> components = mapper.selectComponentChildrenForProjects(project.getId());
+ components.add(project);
+ for (Component component : components) {
+ componentsBySnapshotId.put(component.getSnapshotId(), component);
+
+ component.setUuid(getOrCreateUuid(component.getId(), uuidByComponentId));
+ component.setProjectUuid(getOrCreateUuid(project.getId(), uuidByComponentId));
+ }
+
+ for (Component component : components) {
+ String snapshotPath = component.getSnapshotPath();
+ StringBuilder moduleUuidPath = new StringBuilder();
+ Component lastModule = null;
+ if (!Strings.isNullOrEmpty(snapshotPath)) {
+ for (String s : Splitter.on(".").omitEmptyStrings().split(snapshotPath)) {
+ Long snapshotId = Long.valueOf(s);
+ Component currentComponent = componentsBySnapshotId.get(snapshotId);
+ if (currentComponent.getScope().equals(Scopes.PROJECT)) {
+ lastModule = currentComponent;
+ moduleUuidPath.append(currentComponent.getUuid()).append(".");
+ }
+ }
+ }
+ if (moduleUuidPath.length() > 0) {
+ component.setModuleUuidPath(moduleUuidPath.toString());
+ }
+
+ // Module UUID should contains direct module of a component, but it should be null on the first module
+ if (lastModule != null && !lastModule.getId().equals(project.getId())) {
+ component.setModuleUuid(getOrCreateUuid(lastModule.getId(), uuidByComponentId));
+ }
+
+ mapper.updateComponentUuids(component);
+ }
+ }
+
+ session.commit();
+ } finally {
+ session.close();
+ }
+ }
+
+ private static String getOrCreateUuid(Long componentId, Map<Long, String> uuidByComponentId) {
+ String uuid = uuidByComponentId.get(componentId);
+ if (uuid == null) {
+ String newUuid = UUID.randomUUID().toString();
+ uuidByComponentId.put(componentId, newUuid);
+ return newUuid;
+ }
+ return uuid;
+ }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest.java b/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest.java
new file mode 100644
index 00000000000..9c1fcdb67b5
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest.java
@@ -0,0 +1,171 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.
+ */
+
+package org.sonar.server.db.migrations.v50;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.TestDatabase;
+import org.sonar.core.persistence.migration.v50.Component;
+import org.sonar.core.persistence.migration.v50.Migration50Mapper;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.db.migrations.DatabaseMigration;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class PopulateProjectsUuidColumnsMigrationTest {
+
+ @ClassRule
+ public static TestDatabase db = new TestDatabase().schema(PopulateProjectsUuidColumnsMigrationTest.class, "schema.sql");
+
+ DbSession session;
+
+ DbClient dbClient;
+
+ Migration50Mapper mapper;
+
+ DatabaseMigration migration;
+
+ @Before
+ public void setUp() throws Exception {
+ db.executeUpdateSql("truncate table projects");
+ db.executeUpdateSql("truncate table snapshots");
+ dbClient = new DbClient(db.database(), db.myBatis());
+ session = dbClient.openSession(false);
+ mapper = session.getMapper(Migration50Mapper.class);
+ migration = new PopulateProjectsUuidColumnsMigration(dbClient);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ session.close();
+ }
+
+ @Test
+ public void migrate_projects() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_projects.xml");
+
+ migration.execute();
+ session.commit();
+
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isNull();
+
+ Component module = mapper.selectComponentByKey("org.struts:struts-core");
+ assertThat(module.getUuid()).isNotNull();
+ assertThat(module.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(module.getModuleUuid()).isNull();
+ assertThat(module.getModuleUuidPath()).isEqualTo(root.getUuid() + ".");
+
+ Component subModule = mapper.selectComponentByKey("org.struts:struts-db");
+ assertThat(subModule.getUuid()).isNotNull();
+ assertThat(subModule.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(subModule.getModuleUuid()).isEqualTo(module.getUuid());
+ assertThat(subModule.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid() + ".");
+
+ Component directory = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts");
+ assertThat(directory.getUuid()).isNotNull();
+ assertThat(directory.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(directory.getModuleUuid()).isEqualTo(subModule.getUuid());
+ assertThat(directory.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid() + "." + subModule.getUuid() + ".");
+
+ Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java");
+ assertThat(file.getUuid()).isNotNull();
+ assertThat(file.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(file.getModuleUuid()).isEqualTo(subModule.getUuid());
+ assertThat(file.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid() + "." + subModule.getUuid() + ".");
+
+ // Verify that each generated uuid is unique
+ assertThat(ImmutableSet.of(root.getUuid(), module.getUuid(), subModule.getUuid(), directory.getUuid(), file.getUuid())).hasSize(5);
+ }
+
+ @Test
+ public void migrate_provisioned_project() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_provisioned_project.xml");
+
+ migration.execute();
+ session.commit();
+
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isNull();
+ }
+
+ @Test
+ public void migrate_library() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_library.xml");
+
+ migration.execute();
+ session.commit();
+
+ Component root = mapper.selectComponentByKey("org.hamcrest:hamcrest-library");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isNull();
+ }
+
+ @Test
+ public void not_migrate_view() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_view.xml");
+
+ migration.execute();
+ session.commit();
+
+ Component root = mapper.selectComponentByKey("view");
+ assertThat(root.getUuid()).isNull();
+ assertThat(root.getProjectUuid()).isNull();
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isNull();
+ }
+
+ @Test
+ public void not_migrate_developer() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_developer.xml");
+
+ migration.execute();
+ session.commit();
+
+ Component root = mapper.selectComponentByKey("DEV:developer@company.net");
+ assertThat(root.getUuid()).isNull();
+ assertThat(root.getProjectUuid()).isNull();
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isNull();
+ }
+
+ @Test
+ public void not_migrate_technical_projects() throws Exception {
+ db.prepareDbUnit(getClass(), "not_migrate_technical_projects.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "not_migrate_technical_projects.xml");
+ }
+
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml
new file mode 100644
index 00000000000..9d518e84c76
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml
@@ -0,0 +1,18 @@
+<dataset>
+
+ <!-- developer -->
+ <projects id="1" kee="DEV:developer@company.net" name="developer@company.net" long_name="Developer" scope="PRJ" qualifier="DEV" root_id="[null]" description="[null]"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="[null]"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="DEV" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml
new file mode 100644
index 00000000000..4740588290e
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml
@@ -0,0 +1,10 @@
+<dataset>
+
+ <!-- library -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="LIB" kee="org.hamcrest:hamcrest-library" name="org.hamcrest:hamcrest-library"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="[null]" long_name="org.hamcrest:hamcrest-library"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
+ created_at="2014-06-18" authorization_updated_at="2014-06-18" />
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_projects.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_projects.xml
new file mode 100644
index 00000000000..14ba41f91d4
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_projects.xml
@@ -0,0 +1,82 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
+ created_at="2014-06-18" authorization_updated_at="2014-06-18" />
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" created_at="2014-06-18" authorization_updated_at="[null]" />
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+ <!-- sub module -->
+ <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" created_at="2014-06-18" authorization_updated_at="[null]" />
+ <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2."/>
+
+ <!-- directory -->
+ <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="src/org/struts" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" created_at="2014-06-18" authorization_updated_at="[null]" />
+ <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3."/>
+
+ <!-- file -->
+ <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="RequestContext.java" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" created_at="2014-06-18" authorization_updated_at="[null]" />
+
+ <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3.4."/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml
new file mode 100644
index 00000000000..a38323d7a19
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml
@@ -0,0 +1,10 @@
+<dataset>
+
+ <!-- provisioned project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
+ created_at="2014-06-18" authorization_updated_at="2014-06-18" />
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml
new file mode 100644
index 00000000000..79021a863b9
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml
@@ -0,0 +1,18 @@
+<dataset>
+
+ <!-- view -->
+ <projects id="1" kee="view" name="View" long_name="View" scope="PRJ" qualifier="VW" root_id="[null]" description="[null]"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="[null]"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="VW" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_technical_projects-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_technical_projects-result.xml
new file mode 100644
index 00000000000..302f21763a1
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_technical_projects-result.xml
@@ -0,0 +1,19 @@
+<dataset>
+
+ <!-- technical project -->
+ <projects id="1" root_id="[null]" scope="FIL" qualifier="TRK" kee="OS_PLUGINSorg.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="10" person_id="[null]" path="[null]" deprecated_kee="[null]"
+ created_at="2014-06-18" authorization_updated_at="2014-06-18" />
+ <snapshots id="1" project_id="1" parent_snapshot_id="10" root_project_id="1" root_snapshot_id="10"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="1" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="10."/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_technical_projects.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_technical_projects.xml
new file mode 100644
index 00000000000..302f21763a1
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_technical_projects.xml
@@ -0,0 +1,19 @@
+<dataset>
+
+ <!-- technical project -->
+ <projects id="1" root_id="[null]" scope="FIL" qualifier="TRK" kee="OS_PLUGINSorg.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="10" person_id="[null]" path="[null]" deprecated_kee="[null]"
+ created_at="2014-06-18" authorization_updated_at="2014-06-18" />
+ <snapshots id="1" project_id="1" parent_snapshot_id="10" root_project_id="1" root_snapshot_id="10"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="1" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="10."/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql
new file mode 100644
index 00000000000..22b95030079
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql
@@ -0,0 +1,55 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "SNAPSHOTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "CREATED_AT" TIMESTAMP,
+ "BUILD_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER NOT NULL,
+ "PARENT_SNAPSHOT_ID" INTEGER,
+ "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
+ "PURGE_STATUS" INTEGER,
+ "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "ROOT_SNAPSHOT_ID" INTEGER,
+ "VERSION" VARCHAR(500),
+ "PATH" VARCHAR(500),
+ "DEPTH" INTEGER,
+ "ROOT_PROJECT_ID" INTEGER,
+ "PERIOD1_MODE" VARCHAR(100),
+ "PERIOD1_PARAM" VARCHAR(100),
+ "PERIOD1_DATE" TIMESTAMP,
+ "PERIOD2_MODE" VARCHAR(100),
+ "PERIOD2_PARAM" VARCHAR(100),
+ "PERIOD2_DATE" TIMESTAMP,
+ "PERIOD3_MODE" VARCHAR(100),
+ "PERIOD3_PARAM" VARCHAR(100),
+ "PERIOD3_DATE" TIMESTAMP,
+ "PERIOD4_MODE" VARCHAR(100),
+ "PERIOD4_PARAM" VARCHAR(100),
+ "PERIOD4_DATE" TIMESTAMP,
+ "PERIOD5_MODE" VARCHAR(100),
+ "PERIOD5_PARAM" VARCHAR(100),
+ "PERIOD5_DATE" TIMESTAMP
+);
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/705_populate_projects_uuid_columns.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/705_populate_projects_uuid_columns.rb
new file mode 100644
index 00000000000..a08d370720b
--- /dev/null
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/705_populate_projects_uuid_columns.rb
@@ -0,0 +1,32 @@
+#
+# SonarQube, open source software quality management tool.
+# Copyright (C) 2008-2014 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.
+#
+
+#
+# SonarQube 5.0
+# SONAR-5753
+#
+class PopulateProjectsUuidColumns < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.server.db.migrations.v50.PopulateProjectsUuidColumnsMigration')
+ end
+
+end
+
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
index b3abd5d623e..de50ab9b538 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
@@ -33,7 +33,7 @@ import java.util.List;
*/
public class DatabaseVersion implements BatchComponent, ServerComponent {
- public static final int LAST_VERSION = 704;
+ public static final int LAST_VERSION = 705;
/**
* List of all the tables.
* This list is hardcoded because we didn't succeed in using java.sql.DatabaseMetaData#getTables() in the same way
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
index 6f9ebbe4461..fba96a99c1b 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
@@ -58,6 +58,7 @@ import org.sonar.core.notification.db.NotificationQueueMapper;
import org.sonar.core.permission.*;
import org.sonar.core.persistence.migration.v44.Migration44Mapper;
import org.sonar.core.persistence.migration.v45.Migration45Mapper;
+import org.sonar.core.persistence.migration.v50.Migration50Mapper;
import org.sonar.core.properties.PropertiesMapper;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.purge.PurgeMapper;
@@ -180,7 +181,7 @@ public class MyBatis implements BatchComponent, ServerComponent {
MeasureMapper.class, MetricMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, SnapshotMapper.class,
ProjectQgateAssociationMapper.class,
AnalysisReportMapper.class,
- Migration45Mapper.class
+ Migration45Mapper.class, Migration50Mapper.class
};
loadMappers(conf, mappers);
configureLogback(mappers);
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Component.java b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Component.java
new file mode 100644
index 00000000000..b16a9d1e651
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Component.java
@@ -0,0 +1,121 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.
+ */
+
+package org.sonar.core.persistence.migration.v50;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class Component {
+
+ private Long id;
+ private Long projectId;
+ private Long snapshotId;
+ private String snapshotPath;
+ private String scope;
+
+ private String uuid;
+ private String projectUuid;
+ private String moduleUuid;
+ private String moduleUuidPath;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ /**
+ * Can be null on provisioned projects or library
+ */
+ @CheckForNull
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(@Nullable Long projectId) {
+ this.projectId = projectId;
+ }
+
+ /**
+ * Can be null on provisioned projects or library
+ */
+ @CheckForNull
+ public Long getSnapshotId() {
+ return snapshotId;
+ }
+
+ public void setSnapshotId(@Nullable Long snapshotId) {
+ this.snapshotId = snapshotId;
+ }
+
+ @CheckForNull
+ public String getSnapshotPath() {
+ return snapshotPath;
+ }
+
+ public void setSnapshotPath(@Nullable String snapshotPath) {
+ this.snapshotPath = snapshotPath;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getProjectUuid() {
+ return projectUuid;
+ }
+
+ public void setProjectUuid(String projectUuid) {
+ this.projectUuid = projectUuid;
+ }
+
+ @CheckForNull
+ public String getModuleUuid() {
+ return moduleUuid;
+ }
+
+ public void setModuleUuid(@Nullable String moduleUuid) {
+ this.moduleUuid = moduleUuid;
+ }
+
+ @CheckForNull
+ public String getModuleUuidPath() {
+ return moduleUuidPath;
+ }
+
+ public void setModuleUuidPath(@Nullable String moduleUuidPath) {
+ this.moduleUuidPath = moduleUuidPath;
+ }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Migration50Mapper.java b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Migration50Mapper.java
new file mode 100644
index 00000000000..72e3f492250
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Migration50Mapper.java
@@ -0,0 +1,74 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.
+ */
+
+package org.sonar.core.persistence.migration.v50;
+
+import org.apache.ibatis.annotations.*;
+import org.apache.ibatis.mapping.ResultSetType;
+import org.apache.ibatis.mapping.StatementType;
+
+import java.util.List;
+
+public interface Migration50Mapper {
+
+ @Select("SELECT " +
+ " p.id AS \"id\", " +
+ " s.root_project_id AS \"projectId\", " +
+ " s.id AS \"snapshotId\", " +
+ " s.path AS \"snapshotPath\", " +
+ " p.scope AS \"scope\" " +
+ "FROM projects p " +
+ " LEFT OUTER JOIN snapshots s ON s.project_id = p.id AND s.islast = ${_true} " +
+ " WHERE p.scope = 'PRJ' AND p.qualifier <> 'VW' AND p.qualifier <> 'DEV' AND p.root_id IS NULL AND p.enabled=${_true}")
+ @Result(javaType = Component.class)
+ @Options(statementType = StatementType.PREPARED, resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 200)
+ List<Component> selectEnabledRootTrkProjects();
+
+ @Select("SELECT " +
+ " p.id AS \"id\", " +
+ " s.root_project_id AS \"projectId\", " +
+ " s.id AS \"snapshotId\", " +
+ " s.path AS \"snapshotPath\", " +
+ " p.scope AS \"scope\" " +
+ "FROM projects root " +
+ " INNER JOIN snapshots root_snapshot ON root_snapshot.project_id = root.id AND root_snapshot.islast = ${_true} " +
+ " INNER JOIN snapshots s ON s.root_snapshot_id = root_snapshot.id AND s.islast = ${_true} " +
+ " INNER JOIN projects p ON p.id = s.project_id" +
+ " WHERE root.id = #{id}")
+ @Result(javaType = Component.class)
+ List<Component> selectComponentChildrenForProjects(@Param("id") Long projectId);
+
+ @Select("SELECT " +
+ " p.id AS \"id\", " +
+ " p.uuid AS \"uuid\", " +
+ " p.project_uuid AS \"projectUuid\", " +
+ " p.module_uuid AS \"moduleUuid\", " +
+ " p.module_uuid_path AS \"moduleUuidPath\" " +
+ "FROM projects p " +
+ " WHERE p.kee = #{key}")
+ @Result(javaType = Component.class)
+ Component selectComponentByKey(@Param("key") String key);
+
+ @Update("UPDATE projects " +
+ " SET uuid=#{uuid}, project_uuid=#{projectUuid}, module_uuid=#{moduleUuid}, module_uuid_path=#{moduleUuidPath} " +
+ " WHERE id=#{id}")
+ void updateComponentUuids(Component component);
+
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/package-info.java b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/package-info.java
new file mode 100644
index 00000000000..af7d784eb29
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.core.persistence.migration.v50;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/migration/v50/Migration50Mapper.xml b/sonar-core/src/main/resources/org/sonar/core/persistence/migration/v50/Migration50Mapper.xml
new file mode 100644
index 00000000000..1db97943867
--- /dev/null
+++ b/sonar-core/src/main/resources/org/sonar/core/persistence/migration/v50/Migration50Mapper.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="org.sonar.core.persistence.migration.v50.Migration50Mapper">
+
+</mapper>
+
diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
index b039308d5bb..6bd7b5bd800 100644
--- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
+++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
@@ -263,6 +263,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('701');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('702');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('703');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('704');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('705');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/migration/v50/ComponentTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/migration/v50/ComponentTest.java
new file mode 100644
index 00000000000..cea162271a0
--- /dev/null
+++ b/sonar-core/src/test/java/org/sonar/core/persistence/migration/v50/ComponentTest.java
@@ -0,0 +1,37 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.
+ */
+
+package org.sonar.core.persistence.migration.v50;
+
+import org.junit.Test;
+
+import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+
+public class ComponentTest {
+
+ @Test
+ public void test_bean() throws Exception {
+ assertThat(Component.class, allOf(
+ hasValidGettersAndSetters()));
+ }
+
+}