]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7778 add DUPLICATIONS_INDEX.COMPONENT_UUID
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 20 Jun 2016 13:37:36 +0000 (15:37 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 21 Jun 2016 10:08:41 +0000 (12:08 +0200)
20 files changed:
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1235_add_component_uuid_to_duplications_index.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1236_populate_component_uuid_of_duplications_index.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1237_delete_orphan_duplications_index_rows_without_component.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1238_make_component_uuid_not_null_on_duplications_index.rb [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java
sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java
sonar-db/src/main/java/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndex.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v60/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndex.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndex.java [new file with mode: 0644]
sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql
sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java
sonar-db/src/test/java/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndexTest.java [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/version/v60/AddComponentUuidColumnToMeasuresTest.java
sonar-db/src/test/java/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndexTest.java [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndexTest.java [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndexTest/duplications_index_5.6.sql [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndexTest/in_progress_duplications_index.sql [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndexTest/in_progress_measures_with_snapshots.sql [new file with mode: 0644]

diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1235_add_component_uuid_to_duplications_index.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1235_add_component_uuid_to_duplications_index.rb
new file mode 100644 (file)
index 0000000..0631d12
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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 6.0
+#
+class AddComponentUuidToDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.AddComponentUuidColumnToDuplicationsIndex')
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1236_populate_component_uuid_of_duplications_index.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1236_populate_component_uuid_of_duplications_index.rb
new file mode 100644 (file)
index 0000000..28a53ab
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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 6.0
+#
+class PopulateComponentUuidOfDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.PopulateComponentUuidOfDuplicationsIndex')
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1237_delete_orphan_duplications_index_rows_without_component.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1237_delete_orphan_duplications_index_rows_without_component.rb
new file mode 100644 (file)
index 0000000..1d78fcb
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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 6.0
+#
+class DeleteOrphanDuplicationsIndexRowsWithoutComponent < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.DeleteOrphanDuplicationsIndexRowsWithoutComponent')
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1238_make_component_uuid_not_null_on_duplications_index.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1238_make_component_uuid_not_null_on_duplications_index.rb
new file mode 100644 (file)
index 0000000..a9c235b
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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 6.0
+#
+class MakeComponentUuidNotNullOnDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.MakeComponentUuidNotNullOnDuplicationsIndex')
+  end
+end
index 75602eba9b3a608a71b131d43fd56fd6359a85fe..7164ed2f1e4bd4214cf6b90f7cd7cbb148bf09de 100644 (file)
@@ -30,7 +30,7 @@ import org.sonar.db.MyBatis;
 
 public class DatabaseVersion {
 
-  public static final int LAST_VERSION = 1_234;
+  public static final int LAST_VERSION = 1_238;
 
   /**
    * The minimum supported version which can be upgraded. Lower
index b1018fe89b31ad4e4866722d6b304905b1ab1007..cc29007d6b7ec0d001242b1da28423f83c5699e6 100644 (file)
@@ -84,6 +84,7 @@ import org.sonar.db.version.v55.FeedRulesTypes;
 import org.sonar.db.version.v56.FixLengthOfIssuesMessageOnOracle;
 import org.sonar.db.version.v56.FixTypeOfRuleTypeOnMysql;
 import org.sonar.db.version.v60.AddAnalysisUuidColumnToCeActivity;
+import org.sonar.db.version.v60.AddComponentUuidColumnToDuplicationsIndex;
 import org.sonar.db.version.v60.AddComponentUuidColumnToMeasures;
 import org.sonar.db.version.v60.AddComponentUuidColumnsToSnapshots;
 import org.sonar.db.version.v60.AddUuidColumnToSnapshots;
@@ -92,6 +93,7 @@ import org.sonar.db.version.v60.AddUuidColumnsToResourceIndex;
 import org.sonar.db.version.v60.CleanOrphanRowsInProjects;
 import org.sonar.db.version.v60.CleanOrphanRowsInResourceIndex;
 import org.sonar.db.version.v60.CleanOrphanRowsInSnapshots;
+import org.sonar.db.version.v60.DeleteOrphanDuplicationsIndexRowsWithoutComponent;
 import org.sonar.db.version.v60.DeleteOrphanMeasuresWithoutComponent;
 import org.sonar.db.version.v60.DropIdColumnsFromProjects;
 import org.sonar.db.version.v60.DropIdColumnsFromResourceIndex;
@@ -101,12 +103,14 @@ import org.sonar.db.version.v60.DropRememberMeColumnsFromUsers;
 import org.sonar.db.version.v60.DropSnapshotIdColumnFromCeActivity;
 import org.sonar.db.version.v60.DropUnusedMeasuresColumns;
 import org.sonar.db.version.v60.MakeComponentUuidColumnsNotNullOnSnapshots;
+import org.sonar.db.version.v60.MakeComponentUuidNotNullOnDuplicationsIndex;
 import org.sonar.db.version.v60.MakeComponentUuidNotNullOnMeasures;
 import org.sonar.db.version.v60.MakeUuidColumnNotNullOnSnapshots;
 import org.sonar.db.version.v60.MakeUuidColumnsNotNullOnProjects;
 import org.sonar.db.version.v60.MakeUuidColumnsNotNullOnResourceIndex;
 import org.sonar.db.version.v60.PopulateAnalysisUuidColumnOnCeActivity;
 import org.sonar.db.version.v60.PopulateComponentUuidColumnsOfSnapshots;
+import org.sonar.db.version.v60.PopulateComponentUuidOfDuplicationsIndex;
 import org.sonar.db.version.v60.PopulateComponentUuidOfMeasures;
 import org.sonar.db.version.v60.PopulateUuidColumnOnSnapshots;
 import org.sonar.db.version.v60.PopulateUuidColumnsOfProjects;
@@ -227,7 +231,12 @@ public class MigrationStepModule extends Module {
       // CE_ACTIVITY.ANALYSIS_UUID
       AddAnalysisUuidColumnToCeActivity.class,
       PopulateAnalysisUuidColumnOnCeActivity.class,
-      DropSnapshotIdColumnFromCeActivity.class
-    );
+      DropSnapshotIdColumnFromCeActivity.class,
+
+      // UUID columns of DUPLICATION_INDEX
+      AddComponentUuidColumnToDuplicationsIndex.class,
+      PopulateComponentUuidOfDuplicationsIndex.class,
+      DeleteOrphanDuplicationsIndexRowsWithoutComponent.class,
+      MakeComponentUuidNotNullOnDuplicationsIndex.class);
   }
 }
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndex.java b/sonar-db/src/main/java/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndex.java
new file mode 100644 (file)
index 0000000..62c3b75
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.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;
+
+public class AddComponentUuidColumnToDuplicationsIndex extends DdlChange {
+
+  private static final String TABLE_PUBLICATIONS_INDEX = "duplications_index";
+
+  public AddComponentUuidColumnToDuplicationsIndex(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AddColumnsBuilder(getDatabase().getDialect(), TABLE_PUBLICATIONS_INDEX)
+      .addColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+      .build());
+  }
+
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java b/sonar-db/src/main/java/org/sonar/db/version/v60/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java
new file mode 100644 (file)
index 0000000..b04cf1b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.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 {
+
+  public DeleteOrphanDuplicationsIndexRowsWithoutComponent(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("SELECT id from duplications_index where component_uuid is null");
+    massUpdate.update("DELETE from duplications_index WHERE id=?");
+    massUpdate.rowPluralName("resources_index entries");
+    massUpdate.execute((row, update) -> {
+      update.setLong(1, row.getLong(1));
+      return true;
+    });
+  }
+
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndex.java b/sonar-db/src/main/java/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndex.java
new file mode 100644 (file)
index 0000000..6198db9
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.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;
+
+public class MakeComponentUuidNotNullOnDuplicationsIndex extends DdlChange {
+
+  private static final String TABLE_DUPLICATIONS_INDEX = "duplications_index";
+
+  public MakeComponentUuidNotNullOnDuplicationsIndex(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AlterColumnsBuilder(getDatabase().getDialect(), TABLE_DUPLICATIONS_INDEX)
+      .updateColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(false).build())
+      .build());
+  }
+
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndex.java b/sonar-db/src/main/java/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndex.java
new file mode 100644 (file)
index 0000000..a5f433d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.BaseDataChange;
+import org.sonar.db.version.MassUpdate;
+import org.sonar.db.version.Select;
+import org.sonar.db.version.SqlStatement;
+
+public class PopulateComponentUuidOfDuplicationsIndex extends BaseDataChange {
+
+  public PopulateComponentUuidOfDuplicationsIndex(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("select distinct di.snapshot_id, s.component_uuid from duplications_index di" +
+      " inner join snapshots s on s.id=di.snapshot_id" +
+      " where di.component_uuid is null");
+    massUpdate.update("UPDATE duplications_index SET component_uuid=? WHERE snapshot_id=? and component_uuid is null");
+    massUpdate.rowPluralName("component uuid of duplications_index entries");
+    massUpdate.execute(PopulateComponentUuidOfDuplicationsIndex::handle);
+  }
+
+  public static boolean handle(Select.Row row, SqlStatement update) throws SQLException {
+    long snapshotId = row.getLong(1);
+    String componentUuid = row.getString(2);
+
+    update.setString(1, componentUuid);
+    update.setLong(2, snapshotId);
+
+    return true;
+  }
+
+}
index af6597ae6732b2ef8a36b56b77e92266d4061682..531951a2b326accf03082c370d7151079254a8f5 100644 (file)
@@ -441,6 +441,10 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1231');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1232');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1233');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1234');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1235');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1236');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1237');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1238');
 
 INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, USER_LOCAL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', true, 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482');
 ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
index 0a762dd2fb65dadbc9a5d4688c92f87c43515eea..dbb4112b21f46038b5a7e2c5e2655d872e68ca4e 100644 (file)
@@ -187,6 +187,7 @@ CREATE TABLE "DUPLICATIONS_INDEX" (
   "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
   "PROJECT_SNAPSHOT_ID" INTEGER NOT NULL,
   "SNAPSHOT_ID" INTEGER NOT NULL,
+  "COMPONENT_UUID" VARCHAR(50) NOT NULL,
   "HASH" VARCHAR(50) NOT NULL,
   "INDEX_IN_FILE" INTEGER NOT NULL,
   "START_LINE" INTEGER NOT NULL,
index 152848d750a59c7f20df1f3abdc4571acc2fc15c..bb8902738914b5b44c2576506745e55eaff8fee3 100644 (file)
@@ -29,6 +29,6 @@ public class MigrationStepModuleTest {
   public void verify_count_of_added_MigrationStep_types() {
     ComponentContainer container = new ComponentContainer();
     new MigrationStepModule().configure(container);
-    assertThat(container.size()).isEqualTo(93);
+    assertThat(container.size()).isEqualTo(97);
   }
 }
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndexTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndexTest.java
new file mode 100644 (file)
index 0000000..4ba3a65
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import static java.lang.String.valueOf;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+public class AddComponentUuidColumnToDuplicationsIndexTest {
+
+  private static final String TABLE = "duplications_index";
+
+  @Rule
+  public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddComponentUuidColumnToDuplicationsIndexTest.class,
+    "duplications_index_5.6.sql");
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private AddComponentUuidColumnToDuplicationsIndex underTest = new AddComponentUuidColumnToDuplicationsIndex(db.database());
+
+  @Test
+  public void migration_adds_column_to_empty_table() throws SQLException {
+    underTest.execute();
+
+    verifyAddedColumns();
+  }
+
+  @Test
+  public void migration_adds_column_to_populated_table() throws SQLException {
+    for (int i = 0; i < 9; i++) {
+      db.executeInsert(
+        TABLE,
+        "ID", valueOf(i),
+        "PROJECT_SNAPSHOT_ID", valueOf(10 + i),
+        "SNAPSHOT_ID", valueOf(20 + i),
+        "HASH", "some_hash_" + i,
+        "INDEX_IN_FILE", "2",
+        "START_LINE", "3",
+        "END_LINE", "4");
+    }
+    db.commit();
+
+    underTest.execute();
+
+    verifyAddedColumns();
+  }
+
+  @Test
+  public void migration_is_not_reentrant() throws SQLException {
+    underTest.execute();
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Fail to execute ");
+    underTest.execute();
+  }
+
+  private void verifyAddedColumns() {
+    db.assertColumnDefinition(TABLE, "component_uuid", Types.VARCHAR, 50, true);
+  }
+
+}
index 414c2d9d11e7e5e95472b69b8fe6dbf3e618acb8..5bbef109dd1eb3f5adc5d20098b7bcbde3f5dfa6 100644 (file)
@@ -33,7 +33,6 @@ public class AddComponentUuidColumnToMeasuresTest {
 
   @Rule
   public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddComponentUuidColumnToMeasuresTest.class, "project_measures_5.6.sql");
-
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndexTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndexTest.java
new file mode 100644 (file)
index 0000000..ec32c46
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MakeComponentUuidNotNullOnDuplicationsIndexTest {
+
+  @Rule
+  public DbTester db = DbTester.createForSchema(System2.INSTANCE, MakeComponentUuidNotNullOnDuplicationsIndexTest.class,
+    "in_progress_duplications_index.sql");
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private MakeComponentUuidNotNullOnDuplicationsIndex underTest = new MakeComponentUuidNotNullOnDuplicationsIndex(db.database());
+
+  @Test
+  public void migration_sets_uuid_columns_not_nullable_on_empty_table() throws SQLException {
+    underTest.execute();
+
+    verifyColumnDefinitions();
+  }
+
+  @Test
+  public void migration_sets_uuid_columns_not_nullable_on_populated_table() throws SQLException {
+    insertDuplicationIndex(1L, true);
+    insertDuplicationIndex(2L, true);
+
+    underTest.execute();
+
+    verifyColumnDefinitions();
+    assertThat(idsOfRowsInDuplicationsIndex()).containsOnly(1L, 2L);
+  }
+
+  @Test
+  public void migration_fails_if_some_uuid_columns_are_null() throws SQLException {
+    insertDuplicationIndex(1L, false);
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Fail to execute");
+
+    underTest.execute();
+  }
+
+  private void verifyColumnDefinitions() {
+    db.assertColumnDefinition("duplications_index", "component_uuid", Types.VARCHAR, 50, false);
+  }
+
+  private List<Long> idsOfRowsInDuplicationsIndex() {
+    return db.select("select ID from duplications_index").stream().map(map -> (Long) map.get("ID")).collect(Collectors.toList());
+  }
+
+  private void insertDuplicationIndex(long id, boolean hasComponentUuid) {
+    db.executeInsert(
+      "duplications_index",
+      "ID", valueOf(id),
+      "PROJECT_SNAPSHOT_ID", valueOf(10 + id),
+      "SNAPSHOT_ID", valueOf(20 + id),
+      "COMPONENT_UUID", hasComponentUuid ? valueOf(30 + id) : null,
+      "HASH", "some_hash_" + id,
+      "INDEX_IN_FILE", "2",
+      "START_LINE", "3",
+      "END_LINE", "4");
+  }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndexTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndexTest.java
new file mode 100644 (file)
index 0000000..acd4a75
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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.v60;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PopulateComponentUuidOfDuplicationsIndexTest {
+
+  @Rule
+  public DbTester db = DbTester.createForSchema(System2.INSTANCE, PopulateComponentUuidOfDuplicationsIndexTest.class,
+    "in_progress_measures_with_snapshots.sql");
+
+  private PopulateComponentUuidOfDuplicationsIndex underTest = new PopulateComponentUuidOfDuplicationsIndex(db.database());
+
+  @Test
+  public void migration_has_no_effect_on_empty_tables() throws SQLException {
+    underTest.execute();
+
+    assertThat(db.countRowsOfTable("duplications_index")).isEqualTo(0);
+    assertThat(db.countRowsOfTable("snapshots")).isEqualTo(0);
+  }
+
+  @Test
+  public void migration_updates_component_uuid_with_values_from_table_snapshots_when_they_exist() throws SQLException {
+    String uuid1 = insertSnapshot(40);
+    insertSnapshot(50);
+    String uuid3 = insertSnapshot(60);
+    insertSnapshot(70);
+
+    insertDuplicationIndex(1, 40);
+    insertDuplicationIndex(2, 40);
+    insertDuplicationIndex(3, 40);
+    insertDuplicationIndex(4, 60);
+    insertDuplicationIndex(5, 90); // 90 does not exist
+    insertDuplicationIndex(6, 100); // 100 does not exist
+    db.commit();
+
+    underTest.execute();
+
+    verifyDuplicationsIndex(1, 40, uuid1);
+    verifyDuplicationsIndex(2, 40, uuid1);
+    verifyDuplicationsIndex(3, 40, uuid1);
+    verifyDuplicationsIndex(4, 60, uuid3);
+    verifyDuplicationsIndex(5, 90, null);
+    verifyDuplicationsIndex(6, 100, null);
+  }
+
+  @Test
+  public void migration_is_reentrant() throws SQLException {
+    String uuid1 = insertSnapshot(40);
+    insertSnapshot(50);
+    insertDuplicationIndex(1, 40);
+
+    underTest.execute();
+    verifyDuplicationsIndex(1, 40, uuid1);
+
+    underTest.execute();
+    verifyDuplicationsIndex(1, 40, uuid1);
+
+  }
+
+  private void verifyDuplicationsIndex(long id, long snapshotId, @Nullable String componentUuid) {
+    List<Map<String, Object>> rows = db.select("select SNAPSHOT_ID, COMPONENT_UUID from duplications_index where ID=" + id);
+    assertThat(rows).hasSize(1);
+    Map<String, Object> row = rows.get(0);
+    assertThat(row.get("SNAPSHOT_ID")).isEqualTo(snapshotId);
+    assertThat(row.get("COMPONENT_UUID")).isEqualTo(componentUuid);
+  }
+
+  private String insertSnapshot(long id) {
+    String uuid = "uuid_" + id;
+    db.executeInsert(
+      "snapshots",
+      "id", valueOf(id),
+      "component_uuid", uuid,
+      "root_component_uuid", valueOf(id + 100));
+    return uuid;
+  }
+
+  private void insertDuplicationIndex(long id, long snapshotId) {
+    db.executeInsert(
+      "duplications_index",
+      "ID", valueOf(id),
+      "PROJECT_SNAPSHOT_ID", valueOf(10 + id),
+      "SNAPSHOT_ID", valueOf(snapshotId),
+      "HASH", "some_hash_" + id,
+      "INDEX_IN_FILE", "2",
+      "START_LINE", "3",
+      "END_LINE", "4");
+  }
+
+}
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndexTest/duplications_index_5.6.sql b/sonar-db/src/test/resources/org/sonar/db/version/v60/AddComponentUuidColumnToDuplicationsIndexTest/duplications_index_5.6.sql
new file mode 100644 (file)
index 0000000..6ac3885
--- /dev/null
@@ -0,0 +1,9 @@
+CREATE TABLE "DUPLICATIONS_INDEX" (
+  "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "PROJECT_SNAPSHOT_ID" INTEGER NOT NULL,
+  "SNAPSHOT_ID" INTEGER NOT NULL,
+  "HASH" VARCHAR(50) NOT NULL,
+  "INDEX_IN_FILE" INTEGER NOT NULL,
+  "START_LINE" INTEGER NOT NULL,
+  "END_LINE" INTEGER NOT NULL
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndexTest/in_progress_duplications_index.sql b/sonar-db/src/test/resources/org/sonar/db/version/v60/MakeComponentUuidNotNullOnDuplicationsIndexTest/in_progress_duplications_index.sql
new file mode 100644 (file)
index 0000000..df0cc07
--- /dev/null
@@ -0,0 +1,10 @@
+CREATE TABLE "DUPLICATIONS_INDEX" (
+  "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "PROJECT_SNAPSHOT_ID" INTEGER NOT NULL,
+  "SNAPSHOT_ID" INTEGER NOT NULL,
+  "COMPONENT_UUID" VARCHAR(50),
+  "HASH" VARCHAR(50) NOT NULL,
+  "INDEX_IN_FILE" INTEGER NOT NULL,
+  "START_LINE" INTEGER NOT NULL,
+  "END_LINE" INTEGER NOT NULL
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndexTest/in_progress_measures_with_snapshots.sql b/sonar-db/src/test/resources/org/sonar/db/version/v60/PopulateComponentUuidOfDuplicationsIndexTest/in_progress_measures_with_snapshots.sql
new file mode 100644 (file)
index 0000000..94a2041
--- /dev/null
@@ -0,0 +1,43 @@
+CREATE TABLE "DUPLICATIONS_INDEX" (
+  "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "PROJECT_SNAPSHOT_ID" INTEGER NOT NULL,
+  "SNAPSHOT_ID" INTEGER NOT NULL,
+  "COMPONENT_UUID" VARCHAR(50),
+  "HASH" VARCHAR(50) NOT NULL,
+  "INDEX_IN_FILE" INTEGER NOT NULL,
+  "START_LINE" INTEGER NOT NULL,
+  "END_LINE" INTEGER NOT NULL
+);
+
+CREATE TABLE "SNAPSHOTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "CREATED_AT" BIGINT,
+  "BUILD_DATE" BIGINT,
+  "COMPONENT_UUID" VARCHAR(50) 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_COMPONENT_UUID" VARCHAR(50) NOT NULL,
+  "PERIOD1_MODE" VARCHAR(100),
+  "PERIOD1_PARAM" VARCHAR(100),
+  "PERIOD1_DATE" BIGINT,
+  "PERIOD2_MODE" VARCHAR(100),
+  "PERIOD2_PARAM" VARCHAR(100),
+  "PERIOD2_DATE" BIGINT,
+  "PERIOD3_MODE" VARCHAR(100),
+  "PERIOD3_PARAM" VARCHAR(100),
+  "PERIOD3_DATE" BIGINT,
+  "PERIOD4_MODE" VARCHAR(100),
+  "PERIOD4_PARAM" VARCHAR(100),
+  "PERIOD4_DATE" BIGINT,
+  "PERIOD5_MODE" VARCHAR(100),
+  "PERIOD5_PARAM" VARCHAR(100),
+  "PERIOD5_DATE" BIGINT
+);