]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7690 add EVENTS.ANALYSIS_UUID in place of SNAPSHOT_ID
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 22 Jun 2016 06:54:56 +0000 (08:54 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 27 Jun 2016 09:06:48 +0000 (11:06 +0200)
27 files changed:
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1248_add_analysis_uuid_column_to_events.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1249_populate_analysis_uuid_on_events.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1250_clean_events_without_analysis_uuid.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1251_clean_events_without_snapshot_id.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1252_make_analysis_uuid_not_null_on_events.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1253_drop_index_events_snapshot_id_from_events.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1254_drop_snapshot_id_column_from_events.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/AddAnalysisUuidColumnToEvents.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuid.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v60/CleanEventsWithoutSnapshotId.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromEvents.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v60/MakeAnalysisUuidNotNullOnEvents.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v60/PopulateAnalysisUuidOnEvents.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/AddAnalysisUuidColumnToEventsTest.java [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuidTest.java [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/version/v60/CleanEventsWithoutSnapshotIdTest.java [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromEventsTest.java [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/version/v60/PopulateAnalysisUuidOnEventsTest.java [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/version/v60/AddAnalysisUuidColumnToEventsTest/events_before_6-0.sql [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuidTest/in_progress_events.sql [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/version/v60/CleanEventsWithoutSnapshotIdTest/in_progress_events.sql [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/version/v60/PopulateAnalysisUuidOnEventsTest/in_progress_events_with_snapshots.sql [new file with mode: 0644]

diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1248_add_analysis_uuid_column_to_events.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1248_add_analysis_uuid_column_to_events.rb
new file mode 100644 (file)
index 0000000..509dd58
--- /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 AddAnalysisUuidColumnToEvents < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.AddAnalysisUuidColumnToEvents')
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1249_populate_analysis_uuid_on_events.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1249_populate_analysis_uuid_on_events.rb
new file mode 100644 (file)
index 0000000..de52900
--- /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 PopulateAnalysisUuidOnEvents < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.PopulateAnalysisUuidOnEvents')
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1250_clean_events_without_analysis_uuid.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1250_clean_events_without_analysis_uuid.rb
new file mode 100644 (file)
index 0000000..28dd37d
--- /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 CleanEventsWithoutAnalysisUuid < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.CleanEventsWithoutAnalysisUuid')
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1251_clean_events_without_snapshot_id.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1251_clean_events_without_snapshot_id.rb
new file mode 100644 (file)
index 0000000..77c28f9
--- /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 CleanEventsWithoutSnapshotId < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.CleanEventsWithoutSnapshotId')
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1252_make_analysis_uuid_not_null_on_events.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1252_make_analysis_uuid_not_null_on_events.rb
new file mode 100644 (file)
index 0000000..f044551
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# 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 MakeAnalysisUuidNotNullOnEvents < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.MakeAnalysisUuidNotNullOnEvents')
+
+    add_index :events, :analysis_uuid, :name => 'events_analysis'
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1253_drop_index_events_snapshot_id_from_events.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1253_drop_index_events_snapshot_id_from_events.rb
new file mode 100644 (file)
index 0000000..7784185
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# 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 DropIndexEventsSnapshotIdFromEvents < ActiveRecord::Migration
+
+  def self.up
+    begin
+      remove_index :events, :name => 'events_snapshot_id'
+    rescue
+      #ignore
+    end
+  end
+end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1254_drop_snapshot_id_column_from_events.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1254_drop_snapshot_id_column_from_events.rb
new file mode 100644 (file)
index 0000000..019ed97
--- /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 DropSnapshotIdColumnFromEvents < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.DropSnapshotIdColumnFromEvents')
+  end
+end
index 9e699e2d1b98f6d5cbfb6378c2a80397cd8768e4..91a8b88a9c7679b1e6b4879a1a475a8984a8913b 100644 (file)
@@ -30,7 +30,7 @@ import org.sonar.db.MyBatis;
 
 public class DatabaseVersion {
 
-  public static final int LAST_VERSION = 1_247;
+  public static final int LAST_VERSION = 1_254;
 
   /**
    * The minimum supported version which can be upgraded. Lower
index df052f0228d4f05b4a03620dc694ed5730238dfe..6e4314e9e167d22adb299ba757d2eba602412269 100644 (file)
@@ -85,6 +85,7 @@ 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.AddAnalysisUuidColumnToDuplicationsIndex;
+import org.sonar.db.version.v60.AddAnalysisUuidColumnToEvents;
 import org.sonar.db.version.v60.AddComponentUuidColumnToDuplicationsIndex;
 import org.sonar.db.version.v60.AddComponentUuidColumnToMeasures;
 import org.sonar.db.version.v60.AddComponentUuidColumnsToSnapshots;
@@ -92,6 +93,8 @@ import org.sonar.db.version.v60.AddLastUsedColumnToRulesProfiles;
 import org.sonar.db.version.v60.AddUuidColumnToSnapshots;
 import org.sonar.db.version.v60.AddUuidColumnsToProjects;
 import org.sonar.db.version.v60.AddUuidColumnsToResourceIndex;
+import org.sonar.db.version.v60.CleanEventsWithoutAnalysisUuid;
+import org.sonar.db.version.v60.CleanEventsWithoutSnapshotId;
 import org.sonar.db.version.v60.CleanOrphanRowsInProjects;
 import org.sonar.db.version.v60.CleanOrphanRowsInResourceIndex;
 import org.sonar.db.version.v60.CleanOrphanRowsInSnapshots;
@@ -104,9 +107,11 @@ import org.sonar.db.version.v60.DropIdColumnsFromSnapshots;
 import org.sonar.db.version.v60.DropProjectIdColumnFromMeasures;
 import org.sonar.db.version.v60.DropRememberMeColumnsFromUsers;
 import org.sonar.db.version.v60.DropSnapshotIdColumnFromCeActivity;
+import org.sonar.db.version.v60.DropSnapshotIdColumnFromEvents;
 import org.sonar.db.version.v60.DropSnapshotIdColumnsFromDuplicationsIndex;
 import org.sonar.db.version.v60.DropUnusedMeasuresColumns;
 import org.sonar.db.version.v60.MakeAnalysisUuidNotNullOnDuplicationsIndex;
+import org.sonar.db.version.v60.MakeAnalysisUuidNotNullOnEvents;
 import org.sonar.db.version.v60.MakeComponentUuidColumnsNotNullOnSnapshots;
 import org.sonar.db.version.v60.MakeComponentUuidNotNullOnDuplicationsIndex;
 import org.sonar.db.version.v60.MakeComponentUuidNotNullOnMeasures;
@@ -115,6 +120,7 @@ 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.PopulateAnalysisUuidOfDuplicationsIndex;
+import org.sonar.db.version.v60.PopulateAnalysisUuidOnEvents;
 import org.sonar.db.version.v60.PopulateComponentUuidColumnsOfSnapshots;
 import org.sonar.db.version.v60.PopulateComponentUuidOfDuplicationsIndex;
 import org.sonar.db.version.v60.PopulateComponentUuidOfMeasures;
@@ -253,6 +259,14 @@ public class MigrationStepModule extends Module {
       PopulateAnalysisUuidOfDuplicationsIndex.class,
       DeleteOrphanDuplicationsIndexRowsWithoutAnalysis.class,
       MakeAnalysisUuidNotNullOnDuplicationsIndex.class,
-      DropSnapshotIdColumnsFromDuplicationsIndex.class);
+      DropSnapshotIdColumnsFromDuplicationsIndex.class,
+
+      // EVENTS.ANALYSIS_UUID
+      AddAnalysisUuidColumnToEvents.class,
+      PopulateAnalysisUuidOnEvents.class,
+      CleanEventsWithoutAnalysisUuid.class,
+      CleanEventsWithoutSnapshotId.class,
+      MakeAnalysisUuidNotNullOnEvents.class,
+      DropSnapshotIdColumnFromEvents.class);
   }
 }
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/AddAnalysisUuidColumnToEvents.java b/sonar-db/src/main/java/org/sonar/db/version/v60/AddAnalysisUuidColumnToEvents.java
new file mode 100644 (file)
index 0000000..c9e3903
--- /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 AddAnalysisUuidColumnToEvents extends DdlChange {
+
+  private static final String TABLE_EVENTS = "events";
+
+  public AddAnalysisUuidColumnToEvents(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AddColumnsBuilder(getDatabase().getDialect(), TABLE_EVENTS)
+      .addColumn(newVarcharColumnDefBuilder().setColumnName("analysis_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+      .build());
+  }
+
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuid.java b/sonar-db/src/main/java/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuid.java
new file mode 100644 (file)
index 0000000..2d01453
--- /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 CleanEventsWithoutAnalysisUuid extends BaseDataChange {
+
+  public CleanEventsWithoutAnalysisUuid(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("SELECT distinct snapshot_id from events e where e.snapshot_id is not null and e.analysis_uuid is null");
+    massUpdate.update("DELETE from events WHERE snapshot_id=?");
+    massUpdate.rowPluralName("no analysis uuid events");
+    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/CleanEventsWithoutSnapshotId.java b/sonar-db/src/main/java/org/sonar/db/version/v60/CleanEventsWithoutSnapshotId.java
new file mode 100644 (file)
index 0000000..90a86b1
--- /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 CleanEventsWithoutSnapshotId extends BaseDataChange {
+
+  public CleanEventsWithoutSnapshotId(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("SELECT e.id from events e where e.snapshot_id is null");
+    massUpdate.update("DELETE from events WHERE id=?");
+    massUpdate.rowPluralName("no snapshot id events");
+    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/DropSnapshotIdColumnFromEvents.java b/sonar-db/src/main/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromEvents.java
new file mode 100644 (file)
index 0000000..d92d51a
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.DdlChange;
+import org.sonar.db.version.DropColumnsBuilder;
+
+public class DropSnapshotIdColumnFromEvents extends DdlChange {
+
+  private static final String TABLE_EVENTS = "events";
+
+  public DropSnapshotIdColumnFromEvents(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new DropColumnsBuilder(getDatabase().getDialect(), TABLE_EVENTS, "snapshot_id").build());
+  }
+
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/MakeAnalysisUuidNotNullOnEvents.java b/sonar-db/src/main/java/org/sonar/db/version/v60/MakeAnalysisUuidNotNullOnEvents.java
new file mode 100644 (file)
index 0000000..97f82f3
--- /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 MakeAnalysisUuidNotNullOnEvents extends DdlChange {
+
+  private static final String TABLE_EVENTS = "events";
+
+  public MakeAnalysisUuidNotNullOnEvents(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AlterColumnsBuilder(getDatabase().getDialect(), TABLE_EVENTS)
+      .updateColumn(newVarcharColumnDefBuilder().setColumnName("analysis_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(false).build())
+      .build());
+  }
+
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v60/PopulateAnalysisUuidOnEvents.java b/sonar-db/src/main/java/org/sonar/db/version/v60/PopulateAnalysisUuidOnEvents.java
new file mode 100644 (file)
index 0000000..49e970b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 PopulateAnalysisUuidOnEvents extends BaseDataChange {
+
+  public PopulateAnalysisUuidOnEvents(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("SELECT distinct e.snapshot_id, s.uuid from events e" +
+      " inner join snapshots s on s.id=e.snapshot_id and s.scope = 'PRJ' and s.qualifier in ('TRK', 'DEV', 'VW')" +
+      " where e.snapshot_id is not null and e.analysis_uuid is null");
+    massUpdate.update("UPDATE events SET analysis_uuid=? WHERE snapshot_id=? and analysis_uuid is null");
+    massUpdate.rowPluralName("analysis uuid of root component events");
+    massUpdate.execute(this::handle);
+  }
+
+  private boolean handle(Select.Row row, SqlStatement update) throws SQLException {
+    long snapshotId = row.getLong(1);
+    String snapshotUuid = row.getString(2);
+
+    update.setString(1, snapshotUuid);
+    update.setLong(2, snapshotId);
+
+    return true;
+  }
+}
index 9c370a1c52df6014f3f2958a3d8026dd359cbd66..5fb4ad24c2f71fce4dc3f028418a5f0d806c9eb8 100644 (file)
@@ -454,6 +454,13 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1244');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1245');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1246');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1247');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1248');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1249');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1250');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1251');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1252');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1253');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1254');
 
 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 6ae2e93429fefe79fea0540215e024276dd22ae5..c94c26a17fa7f1cd5657de006e37d15c8e2d0b2e 100644 (file)
@@ -140,8 +140,8 @@ CREATE TABLE "WIDGET_PROPERTIES" (
 CREATE TABLE "EVENTS" (
   "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
   "NAME" VARCHAR(400),
+  "ANALYSIS_UUID" VARCHAR(50) NOT NULL,
   "COMPONENT_UUID" VARCHAR(50),
-  "SNAPSHOT_ID" INTEGER,
   "CATEGORY" VARCHAR(50),
   "EVENT_DATE" BIGINT NOT NULL,
   "CREATED_AT" BIGINT NOT NULL,
@@ -565,7 +565,7 @@ CREATE INDEX "MEASURES_COMPONENT_UUID" ON "PROJECT_MEASURES" ("COMPONENT_UUID");
 
 CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS" ("NAME");
 
-CREATE INDEX "EVENTS_SNAPSHOT_ID" ON "EVENTS" ("SNAPSHOT_ID");
+CREATE INDEX "EVENTS_ANALYSIS" ON "EVENTS" ("ANALYSIS_UUID");
 
 CREATE INDEX "EVENTS_COMPONENT_UUID" ON "EVENTS" ("COMPONENT_UUID");
 
index aef48b2d99b4d840b260e9b571c6a59d8546fdcf..be2e9aab82319ae28ddb1bba9fad9e52a2b2c746 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(104);
+    assertThat(container.size()).isEqualTo(110);
   }
 }
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/AddAnalysisUuidColumnToEventsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/AddAnalysisUuidColumnToEventsTest.java
new file mode 100644 (file)
index 0000000..a5b8b46
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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 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;
+
+public class AddAnalysisUuidColumnToEventsTest {
+
+  private static final String TABLE_EVENTS = "events";
+
+  @Rule
+  public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddAnalysisUuidColumnToEventsTest.class, "events_before_6-0.sql");
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private AddAnalysisUuidColumnToEvents underTest = new AddAnalysisUuidColumnToEvents(db.database());
+
+  @Test
+  public void migration_adds_columns_to_empty_table() throws SQLException {
+    underTest.execute();
+
+    verifyAddedColumns();
+  }
+
+  @Test
+  public void migration_adds_columns_to_populated_table() throws SQLException {
+    for (int i = 0; i < 9; i++) {
+      db.executeInsert(
+          TABLE_EVENTS,
+          "NAME", valueOf(i),
+          "EVENT_DATE", valueOf(1 + 100),
+          "CREATED_AT", valueOf(1 + 300));
+    }
+    db.commit();
+
+    underTest.execute();
+
+    verifyAddedColumns();
+  }
+
+  private void verifyAddedColumns() {
+    db.assertColumnDefinition(TABLE_EVENTS, "analysis_uuid", Types.VARCHAR, 50, true);
+  }
+
+  @Test
+  public void migration_is_not_reentrant() throws SQLException {
+    underTest.execute();
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Fail to execute ");
+    underTest.execute();
+  }
+
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuidTest.java
new file mode 100644 (file)
index 0000000..095d824
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.stream.Collectors;
+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 CleanEventsWithoutAnalysisUuidTest {
+
+  private static final String TABLE_EVENTS = "events";
+
+  @Rule
+  public DbTester db = DbTester.createForSchema(System2.INSTANCE, CleanEventsWithoutAnalysisUuidTest.class,
+    "in_progress_events.sql");
+
+  private CleanEventsWithoutAnalysisUuid underTest = new CleanEventsWithoutAnalysisUuid(db.database());
+
+  @Test
+  public void migration_has_no_effect_on_empty_table() throws SQLException {
+    underTest.execute();
+
+    assertThat(db.countRowsOfTable(TABLE_EVENTS)).isEqualTo(0);
+  }
+
+  @Test
+  public void migration_deletes_any_row_with_a_null_uuid() throws SQLException {
+    insertEvent(1, true, true);
+    insertEvent(2, false, true);
+    insertEvent(3, false, false);
+    insertEvent(4, true, true);
+    db.commit();
+
+    underTest.execute();
+
+    assertThat(idsOfRowsInResourceIndex()).containsOnly(1L, 3L, 4L);
+  }
+
+  @Test
+  public void migration_is_reentrant() throws SQLException {
+    insertEvent(1, true, true);
+    insertEvent(2, false, true);
+
+    underTest.execute();
+
+    assertThat(idsOfRowsInResourceIndex()).containsOnly(1L);
+
+    underTest.execute();
+
+    assertThat(idsOfRowsInResourceIndex()).containsOnly(1L);
+  }
+
+  private List<Long> idsOfRowsInResourceIndex() {
+    return db.select("select ID from events").stream().map(map -> (Long) map.get("ID")).collect(Collectors.toList());
+  }
+
+  private void insertEvent(long id, boolean hasAnalysisUuid, boolean hasSnapshotId) {
+    db.executeInsert(
+      TABLE_EVENTS,
+      "ID", valueOf(id),
+      "NAME", "name_" + id,
+      "ANALYSIS_UUID", hasAnalysisUuid ? "uuid_" + id : null,
+      "SNAPSHOT_ID", hasSnapshotId ? valueOf(id + 100) : null,
+      "EVENT_DATE", valueOf(1 + 100),
+      "CREATED_AT", valueOf(1 + 300));
+  }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/CleanEventsWithoutSnapshotIdTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/CleanEventsWithoutSnapshotIdTest.java
new file mode 100644 (file)
index 0000000..00d26e9
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.db.version.v60;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.stream.Collectors;
+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 CleanEventsWithoutSnapshotIdTest {
+
+  private static final String TABLE_EVENTS = "events";
+
+  @Rule
+  public DbTester db = DbTester.createForSchema(System2.INSTANCE, CleanEventsWithoutSnapshotIdTest.class,
+      "in_progress_events.sql");
+
+  private CleanEventsWithoutSnapshotId underTest = new CleanEventsWithoutSnapshotId(db.database());
+
+  @Test
+  public void migration_has_no_effect_on_empty_table() throws SQLException {
+    underTest.execute();
+
+    assertThat(db.countRowsOfTable(TABLE_EVENTS)).isEqualTo(0);
+  }
+
+  @Test
+  public void migration_deletes_any_row_with_a_null_uuid() throws SQLException {
+    insertEvent(1, true);
+    insertEvent(2, false);
+    insertEvent(3, false);
+    insertEvent(4, true);
+    db.commit();
+
+    underTest.execute();
+
+    assertThat(idsOfRowsInResourceIndex()).containsOnly(1L, 4L);
+  }
+
+  @Test
+  public void migration_is_reentrant() throws SQLException {
+    insertEvent(1, true);
+    insertEvent(2, false);
+
+    underTest.execute();
+
+    assertThat(idsOfRowsInResourceIndex()).containsOnly(1L);
+
+    underTest.execute();
+
+    assertThat(idsOfRowsInResourceIndex()).containsOnly(1L);
+  }
+
+  private List<Long> idsOfRowsInResourceIndex() {
+    return db.select("select ID from events").stream().map(map -> (Long) map.get("ID")).collect(Collectors.toList());
+  }
+
+  private void insertEvent(long id, boolean hasSnapshotId) {
+    db.executeInsert(
+        TABLE_EVENTS,
+        "ID", valueOf(id),
+        "NAME", "name_" + id,
+        "SNAPSHOT_ID", hasSnapshotId ? valueOf(id + 100) : null,
+        "EVENT_DATE", valueOf(1 + 100),
+        "CREATED_AT", valueOf(1 + 300));
+  }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromEventsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/DropSnapshotIdColumnFromEventsTest.java
new file mode 100644 (file)
index 0000000..6905738
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.junit.Test;
+import org.sonar.db.Database;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.db.version.DdlChange;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class DropSnapshotIdColumnFromEventsTest {
+
+  private Database database = mock(Database.class);
+  private DropSnapshotIdColumnFromEvents underTest = new DropSnapshotIdColumnFromEvents(database);
+
+  @Test
+  public void verify_generated_sql_on_postgresql() throws SQLException {
+    when(database.getDialect()).thenReturn(new PostgreSql());
+
+    DdlChange.Context context = mock(DdlChange.Context.class);
+    underTest.execute(context);
+
+    verify(context).execute("ALTER TABLE events DROP COLUMN snapshot_id");
+  }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v60/PopulateAnalysisUuidOnEventsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v60/PopulateAnalysisUuidOnEventsTest.java
new file mode 100644 (file)
index 0000000..bfd66e6
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * 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.Map;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+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 PopulateAnalysisUuidOnEventsTest {
+
+  private static final String TABLE_EVENTS = "events";
+  private static final String TABLE_SNAPSHOTS = "snapshots";
+
+  @Rule
+  public DbTester db = DbTester.createForSchema(System2.INSTANCE, PopulateAnalysisUuidOnEventsTest.class,
+    "in_progress_events_with_snapshots.sql");
+
+  private PopulateAnalysisUuidOnEvents underTest = new PopulateAnalysisUuidOnEvents(db.database());
+
+  @Test
+  public void migration_has_no_effect_on_empty_tables() throws SQLException {
+    underTest.execute();
+
+    assertThat(db.countRowsOfTable(TABLE_EVENTS)).isEqualTo(0);
+  }
+
+  @Test
+  public void migration_populates_uuids_of_root_components_only() throws SQLException {
+    insertSnapshot(1, "U1", Scopes.PROJECT, Qualifiers.PROJECT);
+    insertSnapshot(2, "U2", Scopes.PROJECT, Qualifiers.MODULE);
+    insertSnapshot(3, "U3", Scopes.DIRECTORY, Qualifiers.DIRECTORY);
+    insertSnapshot(4, "U4", Scopes.FILE, Qualifiers.FILE);
+    insertSnapshot(5, "U5", Scopes.FILE, Qualifiers.UNIT_TEST_FILE);
+    insertSnapshot(6, "U6", Scopes.PROJECT, Qualifiers.VIEW);
+    insertSnapshot(7, "U7", Scopes.PROJECT, Qualifiers.SUBVIEW);
+    insertSnapshot(8, "U8", Scopes.FILE, Qualifiers.PROJECT);
+    insertSnapshot(9, "U9", Scopes.PROJECT, "DEV");
+    insertSnapshot(10, "U10", Scopes.PROJECT, "DEV_PRJ");
+    insertSnapshot(11, "U11", "FOO", "BAR");
+    insertEvent(21, null);
+    insertEvent(22, 1L);
+    insertEvent(23, 2L);
+    insertEvent(24, 3L);
+    insertEvent(25, 4L);
+    insertEvent(26, 5L);
+    insertEvent(27, 6L);
+    insertEvent(28, 7L);
+    insertEvent(29, 8L);
+    insertEvent(210, 9L);
+    insertEvent(211, 10L);
+    insertEvent(212, 11L);
+    db.commit();
+
+    underTest.execute();
+
+    verifyAnalysisUuid(21, null);
+    verifyAnalysisUuid(22, "U1");
+    verifyAnalysisUuid(23, null);
+    verifyAnalysisUuid(24, null);
+    verifyAnalysisUuid(25, null);
+    verifyAnalysisUuid(26, null);
+    verifyAnalysisUuid(27, "U6");
+    verifyAnalysisUuid(28, null);
+    verifyAnalysisUuid(29, null);
+    verifyAnalysisUuid(210, "U9");
+    verifyAnalysisUuid(212, null);
+    verifyAnalysisUuid(211, null);
+  }
+
+  @Test
+  public void migration_is_reentrant() throws SQLException {
+    insertSnapshot(1, "U1", Scopes.PROJECT, Qualifiers.PROJECT);
+    insertEvent(1, null);
+    insertEvent(2, 1L);
+
+    underTest.execute();
+    verifyAnalysisUuid(1, null);
+    verifyAnalysisUuid(2, "U1");
+
+    underTest.execute();
+    verifyAnalysisUuid(1, null);
+    verifyAnalysisUuid(2, "U1");
+  }
+
+  private void verifyAnalysisUuid(int eventId, @Nullable String expectedAnalysisUuid) {
+    Map<String, Object> rows = db.selectFirst("select analysis_uuid as \"analysisUuid\" from events where id=" + eventId);
+    assertThat(rows.get("analysisUuid")).isEqualTo(expectedAnalysisUuid);
+  }
+
+  private String insertSnapshot(long id, String uuid, String scope, String qualifier) {
+    db.executeInsert(
+      TABLE_SNAPSHOTS,
+      "ID", valueOf(id),
+      "UUID", uuid,
+      "COMPONENT_UUID", valueOf(id + 10),
+      "ROOT_COMPONENT_UUID", valueOf(id + 100),
+      "SCOPE", scope,
+      "QUALIFIER", qualifier);
+    return uuid;
+  }
+
+  private void insertEvent(long id, @Nullable Long snapshotId) {
+    db.executeInsert(
+      TABLE_EVENTS,
+      "ID", valueOf(id),
+      "NAME", "name_" + id,
+      "SNAPSHOT_ID", snapshotId == null ? null : valueOf(snapshotId),
+      "EVENT_DATE", valueOf(1 + 100),
+      "CREATED_AT", valueOf(1 + 300));
+  }
+
+}
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v60/AddAnalysisUuidColumnToEventsTest/events_before_6-0.sql b/sonar-db/src/test/resources/org/sonar/db/version/v60/AddAnalysisUuidColumnToEventsTest/events_before_6-0.sql
new file mode 100644 (file)
index 0000000..e0c04fc
--- /dev/null
@@ -0,0 +1,12 @@
+
+CREATE TABLE "EVENTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "NAME" VARCHAR(400),
+  "COMPONENT_UUID" VARCHAR(50),
+  "SNAPSHOT_ID" INTEGER,
+  "CATEGORY" VARCHAR(50),
+  "EVENT_DATE" BIGINT NOT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "DESCRIPTION" VARCHAR(4000),
+  "EVENT_DATA"  VARCHAR(4000)
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuidTest/in_progress_events.sql b/sonar-db/src/test/resources/org/sonar/db/version/v60/CleanEventsWithoutAnalysisUuidTest/in_progress_events.sql
new file mode 100644 (file)
index 0000000..6f84d3b
--- /dev/null
@@ -0,0 +1,15 @@
+
+CREATE TABLE "EVENTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "NAME" VARCHAR(400),
+  "ANALYSIS_UUID" VARCHAR(50),
+  "COMPONENT_UUID" VARCHAR(50),
+  "SNAPSHOT_ID" INTEGER,
+  "CATEGORY" VARCHAR(50),
+  "EVENT_DATE" BIGINT NOT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "DESCRIPTION" VARCHAR(4000),
+  "EVENT_DATA"  VARCHAR(4000)
+);
+
+
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v60/CleanEventsWithoutSnapshotIdTest/in_progress_events.sql b/sonar-db/src/test/resources/org/sonar/db/version/v60/CleanEventsWithoutSnapshotIdTest/in_progress_events.sql
new file mode 100644 (file)
index 0000000..6f84d3b
--- /dev/null
@@ -0,0 +1,15 @@
+
+CREATE TABLE "EVENTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "NAME" VARCHAR(400),
+  "ANALYSIS_UUID" VARCHAR(50),
+  "COMPONENT_UUID" VARCHAR(50),
+  "SNAPSHOT_ID" INTEGER,
+  "CATEGORY" VARCHAR(50),
+  "EVENT_DATE" BIGINT NOT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "DESCRIPTION" VARCHAR(4000),
+  "EVENT_DATA"  VARCHAR(4000)
+);
+
+
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v60/PopulateAnalysisUuidOnEventsTest/in_progress_events_with_snapshots.sql b/sonar-db/src/test/resources/org/sonar/db/version/v60/PopulateAnalysisUuidOnEventsTest/in_progress_events_with_snapshots.sql
new file mode 100644 (file)
index 0000000..3b66dd2
--- /dev/null
@@ -0,0 +1,48 @@
+
+CREATE TABLE "EVENTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "NAME" VARCHAR(400),
+  "ANALYSIS_UUID" VARCHAR(50),
+  "COMPONENT_UUID" VARCHAR(50),
+  "SNAPSHOT_ID" INTEGER,
+  "CATEGORY" VARCHAR(50),
+  "EVENT_DATE" BIGINT NOT NULL,
+  "CREATED_AT" BIGINT NOT NULL,
+  "DESCRIPTION" VARCHAR(4000),
+  "EVENT_DATA"  VARCHAR(4000)
+);
+
+CREATE TABLE "SNAPSHOTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(50) NOT NULL,
+  "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
+);
+