]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9616 decrease coupling with component keys
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Mon, 11 Sep 2017 09:42:40 +0000 (11:42 +0200)
committerJanos Gyerik <janos.gyerik@sonarsource.com>
Tue, 12 Sep 2017 08:52:52 +0000 (10:52 +0200)
56 files changed:
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
server/sonar-ce/src/test/java/org/sonar/ce/monitoring/CeDatabaseMBeanImplTest.java
server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java
server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl
server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java
server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDto.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchKeyType.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchType.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java
server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml [new file with mode: 0644]
server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentTesting.java
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentDaoWithDuplicatedKeysTest/schema.sql
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shared.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldBulkUpdateKey-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldBulkUpdateKeyOnOnlyOneSubmodule-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ComponentKeyUpdaterDaoTest/shouldUpdateKey-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ResourceDaoTest/update_authorization_date-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/component/ResourceDaoTest/update_authorization_date.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/close_issues_clean_index_and_files_sources_of_specified_components-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/close_issues_clean_index_and_files_sources_of_specified_components.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/shouldDeleteHistoricalDataOfDirectoriesAndFiles-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/shouldDeleteHistoricalDataOfDirectoriesAndFiles.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/shouldPurgeProject-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/shouldPurgeProject.xml
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/AddBranchColumnToProjectsTable.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/AddIndexOnProjectBranchesKey.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranches.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranchesTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66Test.java
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranchesTest/empty.sql [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/component/NewComponent.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/developer/PersistDevelopersDelegate.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/developer/package-info.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ComponentFunctions.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/TreeRootHolder.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/TreeRootHolderImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistDevelopersStep.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java
server/sonar-server/src/main/java/org/sonar/server/issue/ServerIssueStorage.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ComponentFunctionsTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/TreeRootHolderImplTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/TreeRootHolderRule.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulatorTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistDevelopersStepTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ServerIssueStorageTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java

index 782514d6502e42aa9c0284c8042d3a5b33458410..a562760d4bbbdb603260a38f4b9eea9ebfa5c7c5 100644 (file)
@@ -146,7 +146,7 @@ public class ComputeEngineContainerImplTest {
       assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize(
         COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION
           + 25 // level 1
-          + 48 // content of DaoModule
+          + 49 // content of DaoModule
           + 3 // content of EsSearchModule
           + 61 // content of CorePropertyDefinitions
           + 1 // StopFlagContainer
index 6015641203593528f591f1964328b7e1101b5e60..63a0e03f083ff40e1f9e0ce4d93209c833806bce 100644 (file)
@@ -37,7 +37,7 @@ public class CeDatabaseMBeanImplTest {
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
-  CeDatabaseMBeanImpl underTest = new CeDatabaseMBeanImpl(dbTester.getDbClient());
+  private CeDatabaseMBeanImpl underTest = new CeDatabaseMBeanImpl(dbTester.getDbClient());
 
   @Test
   public void register_and_unregister() throws Exception {
index 2f6d77bcb05144010bc1b2c66a50e0565fa67144..c92eb1734e0b4c7062bc2ed39429c50edf832ea6 100644 (file)
  */
 package org.sonar.db.version;
 
-import com.google.common.collect.ImmutableSet;
+import java.util.HashSet;
 import java.util.Set;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableSet;
+
 public final class SqTables {
   /**
    * These tables are still involved in DB migrations, so potentially
    * incorrect collation must be fixed so that joins with other
    * tables are possible.
    */
-  public static final Set<String> OLD_DROPPED_TABLES = ImmutableSet.of(
+  public static final Set<String> OLD_DROPPED_TABLES = unmodifiableSet(new HashSet<>(asList(
     "active_dashboards",
     "activities",
     "dashboards",
@@ -38,14 +41,14 @@ public final class SqTables {
     "measure_filter_favourites",
     "resource_index",
     "widgets",
-    "widget_properties");
+    "widget_properties")));
 
   /**
    * List of all the tables.
    * This list is hardcoded because we didn't succeed in using java.sql.DatabaseMetaData#getTables() in the same way
    * for all the supported databases, particularly due to Oracle results.
    */
-  public static final Set<String> TABLES = ImmutableSet.of(
+  public static final Set<String> TABLES = unmodifiableSet(new HashSet<>(asList(
     "active_rules",
     "active_rule_parameters",
     "ce_activity",
@@ -80,6 +83,7 @@ public final class SqTables {
     "project_links",
     "project_measures",
     "project_qprofiles",
+    "project_branches",
     "properties",
     "qprofile_changes",
     "quality_gates",
@@ -94,7 +98,7 @@ public final class SqTables {
     "users",
     "user_roles",
     "user_tokens",
-    "webhook_deliveries");
+    "webhook_deliveries")));
 
   private SqTables() {
     // prevents instantiation
index 55bc327fb2aa51a77ed52228bc6c6e5500ff4d89..7f5d672442757aff64eec62235b3fd5584438f13 100644 (file)
@@ -306,6 +306,7 @@ CREATE TABLE "PROJECTS" (
   "PROJECT_UUID" VARCHAR(50) NOT NULL,
   "MODULE_UUID" VARCHAR(50),
   "MODULE_UUID_PATH" VARCHAR(1500),
+  "MAIN_BRANCH_PROJECT_UUID" VARCHAR(50),
   "NAME" VARCHAR(2000),
   "DESCRIPTION" VARCHAR(2000),
   "PRIVATE" BOOLEAN NOT NULL,
@@ -670,6 +671,7 @@ CREATE UNIQUE INDEX "PK_WEBHOOK_DELIVERIES" ON "WEBHOOK_DELIVERIES" ("UUID");
 CREATE INDEX "COMPONENT_UUID" ON "WEBHOOK_DELIVERIES" ("COMPONENT_UUID");
 CREATE INDEX "CE_TASK_UUID" ON "WEBHOOK_DELIVERIES" ("CE_TASK_UUID");
 
+
 CREATE TABLE "ES_QUEUE" (
   "UUID" VARCHAR(40) NOT NULL PRIMARY KEY,
   "DOC_TYPE" VARCHAR(40) NOT NULL,
@@ -690,3 +692,16 @@ CREATE TABLE "PLUGINS" (
   "UPDATED_AT" BIGINT NOT NULL
 );
 CREATE UNIQUE INDEX "PLUGINS_KEY" ON "PLUGINS" ("KEE");
+
+CREATE TABLE "PROJECT_BRANCHES" (
+  "UUID" VARCHAR(50) NOT NULL PRIMARY KEY,
+  "PROJECT_UUID" VARCHAR(50) NOT NULL,
+  "KEE_TYPE" VARCHAR(6) NOT NULL,
+  "KEE" VARCHAR(255) NOT NULL,
+  "BRANCH_TYPE" VARCHAR(5),
+  "MERGE_BRANCH_UUID" VARCHAR(50),
+  "PULL_REQUEST_TITLE" VARCHAR(4000),
+  "CREATED_AT" BIGINT NOT NULL
+);
+CREATE UNIQUE INDEX "PK_PROJECT_BRANCHES" ON "PROJECT_BRANCHES" ("UUID");
+CREATE UNIQUE INDEX "PROJECT_BRANCHES_KEE" ON "PROJECT_BRANCHES" ("PROJECT_UUID", "KEE_TYPE", "KEE");
index 44b741739d7faeb37402471dcce93528923d8c0c..d791dbbff31f32a3c8a1485c2683821e661ba584 100644 (file)
@@ -19,7 +19,8 @@
  */
 package org.sonar.db;
 
-import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import org.sonar.core.platform.Module;
 import org.sonar.db.ce.CeActivityDao;
@@ -27,6 +28,7 @@ import org.sonar.db.ce.CeQueueDao;
 import org.sonar.db.ce.CeScannerContextDao;
 import org.sonar.db.ce.CeTaskCharacteristicDao;
 import org.sonar.db.ce.CeTaskInputDao;
+import org.sonar.db.component.BranchDao;
 import org.sonar.db.component.ComponentDao;
 import org.sonar.db.component.ComponentKeyUpdaterDao;
 import org.sonar.db.component.ComponentLinkDao;
@@ -72,12 +74,13 @@ import org.sonar.db.user.UserTokenDao;
 import org.sonar.db.webhook.WebhookDeliveryDao;
 
 public class DaoModule extends Module {
-  private static final List<Class<? extends Dao>> classes = ImmutableList.<Class<? extends Dao>>builder().add(
+  private static final List<Class<? extends Dao>> classes = Collections.unmodifiableList(Arrays.asList(
     // =====================================================================
     // for readability and easier merge, keep list ordered alphabetically
     // =====================================================================
     ActiveRuleDao.class,
     AuthorizationDao.class,
+    BranchDao.class,
     CeActivityDao.class,
     CeQueueDao.class,
     CeScannerContextDao.class,
@@ -124,7 +127,7 @@ public class DaoModule extends Module {
     UserPermissionDao.class,
     UserTokenDao.class,
     WebhookDeliveryDao.class)
-    .build();
+  );
 
   @Override
   protected void configureModule() {
index ee23994014bc6349c690717e665a7a21d5fe676e..6e7db16ec98836ee2e37320f6dcbf6b3f08e0571 100644 (file)
@@ -35,6 +35,7 @@ import org.sonar.db.ce.CeScannerContextMapper;
 import org.sonar.db.ce.CeTaskCharacteristicDto;
 import org.sonar.db.ce.CeTaskCharacteristicMapper;
 import org.sonar.db.ce.CeTaskInputMapper;
+import org.sonar.db.component.BranchMapper;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentDtoWithSnapshotId;
 import org.sonar.db.component.ComponentKeyUpdaterMapper;
@@ -190,6 +191,7 @@ public class MyBatis implements Startable {
     Class<?>[] mappers = {
       ActiveRuleMapper.class,
       AuthorizationMapper.class,
+      BranchMapper.class,
       CeActivityMapper.class,
       CeQueueMapper.class,
       CeScannerContextMapper.class,
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java
new file mode 100644 (file)
index 0000000..126dda1
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.component;
+
+import org.sonar.api.utils.System2;
+import org.sonar.db.Dao;
+import org.sonar.db.DbSession;
+
+public class BranchDao implements Dao {
+
+  private final System2 system2;
+
+  public BranchDao(System2 system2) {
+    this.system2 = system2;
+  }
+
+  public void insert(DbSession dbSession, BranchDto dto) {
+    mapper(dbSession).insert(dto, system2.now());
+  }
+
+  private static BranchMapper mapper(DbSession dbSession) {
+    return dbSession.getMapper(BranchMapper.class);
+  }
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDto.java
new file mode 100644 (file)
index 0000000..7192a6d
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.component;
+
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class BranchDto {
+
+  /**
+   * Value of {@link #kee} when the name of main branch is not known.
+   * Used only if {@link #keeType} is {@link BranchKeyType#BRANCH}.
+   * It does not conflict with names of real branches because the character ':'
+   * is not accepted.
+   */
+  public static final String DEFAULT_KEY_OF_MAIN_BRANCH = ":main:";
+
+  /**
+   * Branch UUID is the projects.uuid that reference projects, branches or pull requests
+   * (projects.qualifier="TRK").
+   * Not null.
+   * Important - the table project_branches does NOT have its own UUIDs for the time being.
+   * All values must exist in projects.uuid.
+   */
+  private String uuid;
+
+  /**
+   * UUID of the project that represents the main branch.
+   * On main branches, projectUuid equals uuid.
+   * Not null.
+   */
+  private String projectUuid;
+
+  /**
+   * Not null.
+   */
+  private BranchKeyType keeType;
+
+  /**
+   * If {@link #keeType} is {@link BranchKeyType#BRANCH}, then name of branch, for example
+   * "feature/foo". Can be {@link #DEFAULT_KEY_OF_MAIN_BRANCH} is the name is not known.
+   *
+   * If {@link #keeType} is {@link BranchKeyType#PR}, then id of the pull request, for
+   * example "1204".
+   */
+  private String kee;
+
+  /**
+   * Value is mandatory when {@link #keeType} is {@link BranchKeyType#BRANCH}.
+   * Otherwise it is null.
+   */
+  @Nullable
+  private BranchType branchType;
+
+  /**
+   * UUID of the branch:
+   * - in which the short-lived branch or pull request will be merged into
+   * - that is the base of long-lived branch.
+   *
+   * Can be null if information is not known.
+   */
+  @Nullable
+  private String mergeBranchUuid;
+
+  /**
+   * Optional title of pull requests
+   */
+  @Nullable
+  private String pullRequestTitle;
+
+  public String getUuid() {
+    return uuid;
+  }
+
+  public void setUuid(String s) {
+    this.uuid = s;
+  }
+
+  public String getProjectUuid() {
+    return projectUuid;
+  }
+
+  public void setProjectUuid(String s) {
+    this.projectUuid = s;
+  }
+
+  public BranchKeyType getKeeType() {
+    return keeType;
+  }
+
+  public void setKeeType(BranchKeyType t) {
+    this.keeType = t;
+  }
+
+  public String getKee() {
+    return kee;
+  }
+
+  public void setKee(String s) {
+    checkArgument(s.length() <= 255, "Maximum length of branch name or pull request id is 255: %s", s);
+    this.kee = s;
+  }
+
+  @Nullable
+  public BranchType getBranchType() {
+    return branchType;
+  }
+
+  public void setBranchType(@Nullable BranchType b) {
+    this.branchType = b;
+  }
+
+  @Nullable
+  public String getMergeBranchUuid() {
+    return mergeBranchUuid;
+  }
+
+  public void setMergeBranchUuid(@Nullable String s) {
+    this.mergeBranchUuid = s;
+  }
+
+  @Nullable
+  public String getPullRequestTitle() {
+    return pullRequestTitle;
+  }
+
+  public void setPullRequestTitle(@Nullable String s) {
+    checkArgument(s == null || s.length() <= 4000, "Maximum length of pull request title is 4000: %s", s);
+    this.pullRequestTitle = s;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("BranchDto{");
+    sb.append("uuid='").append(uuid).append('\'');
+    sb.append(", mergeBranchUuid='").append(mergeBranchUuid).append('\'');
+    sb.append(", pullRequestTitle='").append(pullRequestTitle).append('\'');
+    sb.append('}');
+    return sb.toString();
+  }
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchKeyType.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchKeyType.java
new file mode 100644 (file)
index 0000000..cc6ca0a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.component;
+
+/**
+ * Supported values in column project_branches.kee_type
+ */
+public enum BranchKeyType {
+  /**
+   * Branch, whatever long or short, main or not.
+   */
+  BRANCH,
+
+  /**
+   * Pull request
+   */
+  PR
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java
new file mode 100644 (file)
index 0000000..505381a
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.component;
+
+import org.apache.ibatis.annotations.Param;
+
+public interface BranchMapper {
+
+  void insert(@Param("dto") BranchDto dto, @Param("now") long now);
+
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchType.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchType.java
new file mode 100644 (file)
index 0000000..6ade009
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.component;
+
+public enum BranchType {
+
+  /**
+   * Long-lived branch
+   */
+  LONG,
+
+  /**
+   * Short-lived branch
+   */
+  SHORT
+}
index 42338f71817ec36287932c26a2580a84312598be..58a6fe02ed7edee034f8d999f904b09937f16570 100644 (file)
@@ -106,6 +106,26 @@ public class ComponentDto {
    */
   private String rootUuid;
 
+  /**
+   * On non-main branches only, {@link #uuid} of the main branch that represents
+   * the project ({@link #qualifier}="TRK").
+   * It is propagated to all the components of the branch.
+   *
+   * Value is null on the main-branch components and on other kinds of components
+   * (applications, portfolios).
+   *
+   * Value must be used for loading settings, checking permissions, running webhooks,
+   * selecting Quality profiles/gates and any other project-related operations.
+   *
+   * Example:
+   * - project P : kee=P, uuid=U1, qualifier=TRK, project_uuid=U1, main_branch_project_uuid=NULL
+   * - file F of project P : kee=P:F, uuid=U2, qualifier=FIL, project_uuid=U1, main_branch_project_uuid=NULL
+   * - branch B of project P : kee=P:BRANCH:B, uuid=U3, qualifier=TRK, project_uuid=U3, main_branch_project_uuid=U1
+   * - file F in branch B of project P : kee=P:F:BRANCH:B, uuid=U4, qualifier=FIL, project_uuid=U3, main_branch_project_uuid=U1
+   */
+  @Nullable
+  private String mainBranchProjectUuid;
+
   private String moduleUuid;
   private String moduleUuidPath;
   private String copyComponentUuid;
@@ -317,6 +337,10 @@ public class ComponentDto {
     return this;
   }
 
+  /**
+   * Use {@link #projectUuid()}, {@link #moduleUuid()} or {@link #moduleUuidPath()}
+   */
+  @Deprecated
   public String getRootUuid() {
     return rootUuid;
   }
@@ -326,6 +350,16 @@ public class ComponentDto {
     return this;
   }
 
+  @Nullable
+  public String getMainBranchProjectUuid() {
+    return mainBranchProjectUuid;
+  }
+
+  public ComponentDto setMainBranchProjectUuid(@Nullable String s) {
+    this.mainBranchProjectUuid = s;
+    return this;
+  }
+
   public boolean isEnabled() {
     return enabled;
   }
@@ -430,6 +464,7 @@ public class ComponentDto {
       .append("moduleUuid", moduleUuid)
       .append("moduleUuidPath", moduleUuidPath)
       .append("rootUuid", rootUuid)
+      .append("mainBranchProjectUuid", mainBranchProjectUuid)
       .append("copyComponentUuid", copyComponentUuid)
       .append("developerUuid", developerUuid)
       .append("path", path)
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml
new file mode 100644 (file)
index 0000000..e05ac53
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
+<mapper namespace="org.sonar.db.component.BranchMapper">
+
+  <sql id="columns">
+    pb.uuid as uuid,
+    pb.project_uuid as projectUuid,
+    pb.kee_type as keeType,
+    pb.kee as kee,
+    pb.branch_type as branchType,
+    pb.merge_branch_uuid as mergeBranchUuid,
+    pb.pull_request_title as pullRequestTitle
+  </sql>
+
+  <insert id="insert" parameterType="map" useGeneratedKeys="false">
+    insert into project_branches (
+      uuid,
+      project_uuid,
+      kee_type,
+      kee,
+      branch_type,
+      merge_branch_uuid,
+      pull_request_title,
+      created_at
+    ) values (
+      #{dto.uuid, jdbcType=VARCHAR},
+      #{dto.projectUuid, jdbcType=VARCHAR},
+      #{dto.keeType, jdbcType=VARCHAR},
+      #{dto.kee, jdbcType=VARCHAR},
+      #{dto.branchType, jdbcType=VARCHAR},
+      #{dto.mergeBranchUuid, jdbcType=VARCHAR},
+      #{dto.pullRequestTitle, jdbcType=VARCHAR},
+      #{now, jdbcType=BIGINT}
+    )
+  </insert>
+
+</mapper>
index 2f738fc26d2950cf44c0fba0d7de3f7e84dc808d..eb3249b44f8f744922d16c1b4eaa64c41a0f22ca 100644 (file)
@@ -10,6 +10,7 @@
     p.project_uuid as projectUuid,
     p.module_uuid as moduleUuid,
     p.module_uuid_path as moduleUuidPath,
+    p.main_branch_project_uuid as mainBranchProjectUuid,
     p.kee as kee,
     p.deprecated_kee as deprecatedKey,
     p.name as name,
 
   <insert id="insert" parameterType="Component" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
     INSERT INTO projects (
-    organization_uuid,
-    kee,
-    deprecated_kee,
-    uuid,
-    uuid_path,
-    project_uuid,
-    module_uuid,
-    module_uuid_path,
-    name,
-    long_name,
-    qualifier,
-    scope,
-    language,
-    description,
-    private,
-    tags,
-    root_uuid,
-    path,
-    copy_component_uuid,
-    developer_uuid,
-    enabled,
-    created_at,
-    b_changed,
-    b_copy_component_uuid,
-    b_description,
-    b_enabled,
-    b_language,
-    b_long_name,
-    b_module_uuid,
-    b_module_uuid_path,
-    b_name,
-    b_path,
-    b_qualifier
+      organization_uuid,
+      kee,
+      deprecated_kee,
+      uuid,
+      uuid_path,
+      project_uuid,
+      module_uuid,
+      module_uuid_path,
+      main_branch_project_uuid,
+      name,
+      long_name,
+      qualifier,
+      scope,
+      language,
+      description,
+      private,
+      tags,
+      root_uuid,
+      path,
+      copy_component_uuid,
+      developer_uuid,
+      enabled,
+      created_at,
+      b_changed,
+      b_copy_component_uuid,
+      b_description,
+      b_enabled,
+      b_language,
+      b_long_name,
+      b_module_uuid,
+      b_module_uuid_path,
+      b_name,
+      b_path,
+      b_qualifier
     )
     VALUES (
     #{organizationUuid,jdbcType=VARCHAR},
     #{projectUuid,jdbcType=VARCHAR},
     #{moduleUuid,jdbcType=VARCHAR},
     #{moduleUuidPath,jdbcType=VARCHAR},
+    #{mainBranchProjectUuid, jdbcType=VARCHAR},
     #{name,jdbcType=VARCHAR},
     #{longName,jdbcType=VARCHAR},
     #{qualifier,jdbcType=VARCHAR},
index 0fb6690bd2104ccd945eff77694581ac7d1f90eb..9d7a3d2786afac70a41107d263e93f289119c652 100644 (file)
@@ -29,6 +29,6 @@ public class DaoModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new DaoModule().configure(container);
-    assertThat(container.size()).isEqualTo(2 + 48);
+    assertThat(container.size()).isEqualTo(2 + 49);
   }
 }
index 98c6f8f339e4f3a7c77680e3833d5b1c0c161565..88cb1226657f550bf12fe962a93a29355855d56f 100644 (file)
@@ -188,6 +188,7 @@ public class ComponentTesting {
       .setRootUuid(moduleOrProject.uuid())
       .setModuleUuid(moduleOrProject.uuid())
       .setModuleUuidPath(moduleOrProject.moduleUuidPath())
+      .setMainBranchProjectUuid(moduleOrProject.getMainBranchProjectUuid())
       .setCreatedAt(new Date())
       .setEnabled(true)
       .setPrivate(moduleOrProject.isPrivate());
index cc547e89452d8b3ddf59ba4a832ea8946756a061..831672702774748118ae30c9bdcb48292d260f83 100644 (file)
@@ -24,6 +24,7 @@ CREATE TABLE "PROJECTS" (
   "PROJECT_UUID" VARCHAR(50),
   "MODULE_UUID" VARCHAR(50),
   "MODULE_UUID_PATH" VARCHAR(1500),
+  "MAIN_BRANCH_PROJECT_UUID" VARCHAR(50),
   "NAME" VARCHAR(2000),
   "DESCRIPTION" VARCHAR(2000),
   "PRIVATE" BOOLEAN NOT NULL,
index 0b62345e122f761346e2e8d20ad9616c92d74ecb..e5fd3a6e3b3ee4d7d166fc733ef95ee2bec524d6 100644 (file)
@@ -13,6 +13,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
@@ -49,6 +50,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".A."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts Core"
@@ -89,6 +91,7 @@
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts UI"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".H."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Foo Struts Core"
index 2896545423c03214f084f956f9f71c04f452b78e..d39f1be9a44ffb4c5dc5009f739595789f048391 100644 (file)
@@ -13,6 +13,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
@@ -51,6 +52,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".A."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts Core"
@@ -93,6 +95,7 @@
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts UI"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".H."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Foo Struts Core"
index c337ea840b86d67dc151dfba970d466b7ee7d06d..db2a64524f8e92a5da81b2aee7c2c6bad2e080c1 100644 (file)
@@ -13,6 +13,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
@@ -51,6 +52,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".A."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts Core"
@@ -93,6 +95,7 @@
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts UI"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".H."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Foo Struts Core"
index 168060a9d15cf2ffd314975a1231bcfc5dda7014..673a5ecf35cb9ef38baaf423522fa20161ea0fff 100644 (file)
@@ -13,6 +13,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
@@ -51,6 +52,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".A."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts Core"
@@ -91,6 +93,7 @@
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts UI"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
index 2628761a8cdf9c9e15d18a5ac28fb456bd5dcc9a..3615da19411581940a1749b2aedb508fbbdb4bb7 100644 (file)
@@ -13,6 +13,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
@@ -49,6 +50,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".A."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts Core"
@@ -88,6 +90,7 @@
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts UI"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
index fb96c3a2b2b926cdf198aed935b17121c1e85e13..d7407379270332bc6c895be0ab002c995b2f75ef 100644 (file)
@@ -13,6 +13,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
@@ -53,6 +54,7 @@
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".A."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts Core"
@@ -93,6 +95,7 @@
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="B"
             module_uuid_path=".A.B."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Struts UI"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="E"
             module_uuid="[null]"
             module_uuid_path=".E."
+            main_branch_project_uuid="[null]"
             description="[null]"
             private="[false]"
             tags="[null]"
             project_uuid="A"
             module_uuid="[null]"
             module_uuid_path=".H."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="BRC"
             long_name="Foo Struts Core"
index 6381dbc4ab5373542ce42b32c3fd337ca5fa1192..1c3e6e59276e73201b1bc797d54b7109d5bf9d26 100644 (file)
@@ -8,6 +8,7 @@
             project_uuid="ABCD"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="TRK"
             kee="old key"
index 6381dbc4ab5373542ce42b32c3fd337ca5fa1192..1c3e6e59276e73201b1bc797d54b7109d5bf9d26 100644 (file)
@@ -8,6 +8,7 @@
             project_uuid="ABCD"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             scope="PRJ"
             qualifier="TRK"
             kee="old key"
index 5515cd38ea452896569b790e6a1eccb630982dfa..00ee6f678a89073dc84d63296da50c078fbe8dee 100644 (file)
@@ -15,6 +15,7 @@ What has been changed :
             project_uuid="P1"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="PRJ"
@@ -53,6 +54,7 @@ What has been changed :
             project_uuid="P1"
             module_uuid="P1"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="DIR"
@@ -91,6 +93,7 @@ What has been changed :
             project_uuid="P1"
             module_uuid="P1"
             module_uuid_path=".P1."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="FIL"
index 43d7229f269756d4a606fbc188e089e635779c77..4e7905239dfbcdc30511d5d8d8d9b6a8cf1e5c00 100644 (file)
@@ -7,6 +7,7 @@
             project_uuid="P1"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="PRJ"
@@ -44,6 +45,7 @@
             project_uuid="P1"
             module_uuid="P1"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="DIR"
@@ -81,6 +83,7 @@
             project_uuid="P1"
             module_uuid="P1"
             module_uuid_path=".P1."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="FIL"
index 73c511a1b7403b6a7b188f5686604606fcfea9b5..e32aeb548d0a7c85fa5964bd05db9e71fdc0cba8 100644 (file)
@@ -13,6 +13,7 @@ What has been changed : purge_status=1 on snapshot 4 (PRJ) and snapshots 5 and 6
             project_uuid="ABCD"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="PRJ"
@@ -52,6 +53,7 @@ What has been changed : purge_status=1 on snapshot 4 (PRJ) and snapshots 5 and 6
             project_uuid="ABCD"
             module_uuid="ABCD"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="DIR"
@@ -91,6 +93,7 @@ What has been changed : purge_status=1 on snapshot 4 (PRJ) and snapshots 5 and 6
             project_uuid="ABCD"
             module_uuid="ABCD"
             module_uuid_path=".ABCD."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="FIL"
index 4abc4eefd7372b1ea301ba6a9a693667188fbdde..eef613afa84bd5c79663a323f64a0a176f220946 100644 (file)
@@ -7,6 +7,7 @@
             project_uuid="ABCD"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="PRJ"
@@ -44,6 +45,7 @@
             project_uuid="ABCD"
             module_uuid="ABCD"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="DIR"
@@ -81,6 +83,7 @@
             project_uuid="ABCD"
             module_uuid="ABCD"
             module_uuid_path=".ABCD."
+            main_branch_project_uuid="[null]"
             created_at="[null]"
             long_name="[null]"
             scope="FIL"
index e8178d60f1cbfd564d2dab8deede5ba3edc7f337..0ce2b40b57e9461a0236a53504be0e249db0526a 100644 (file)
@@ -7,6 +7,7 @@
             project_uuid="P1"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             enabled="[true]"
             created_at="[null]"
             long_name="[null]"
index 2c48394a5bc4ab7953dc829e3acdc3e0f3a9634e..69fb0fd3418bdc2f5c0b0b65442b79f2b64d59d6 100644 (file)
@@ -7,6 +7,7 @@
             project_uuid="P1"
             module_uuid="[null]"
             module_uuid_path="."
+            main_branch_project_uuid="[null]"
             enabled="[true]"
             created_at="[null]"
             long_name="[null]"
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/AddBranchColumnToProjectsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/AddBranchColumnToProjectsTable.java
new file mode 100644 (file)
index 0000000..713f7da
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.platform.db.migration.version.v66;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class AddBranchColumnToProjectsTable extends DdlChange {
+
+  public AddBranchColumnToProjectsTable(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AddColumnsBuilder(getDialect(), "projects")
+      .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+        .setColumnName("main_branch_project_uuid")
+        .setLimit(50)
+        .setIsNullable(true)
+        .build())
+      .build());
+  }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/AddIndexOnProjectBranchesKey.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/AddIndexOnProjectBranchesKey.java
new file mode 100644 (file)
index 0000000..81eee9c
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v66;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class AddIndexOnProjectBranchesKey extends DdlChange {
+  public AddIndexOnProjectBranchesKey(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(
+      new CreateIndexBuilder(getDialect())
+        .setTable("project_branches")
+        .setName("project_branches_kee")
+        .setUnique(true)
+        .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+          .setColumnName("project_uuid")
+          .setIsNullable(false)
+          .setLimit(50)
+          .build())
+        .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+          .setColumnName("kee_type")
+          .setIsNullable(false)
+          .setLimit(6)
+          .build())
+        .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+          .setColumnName("kee")
+          .setIsNullable(false)
+          .setLimit(255)
+          .build())
+        .build());
+  }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranches.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranches.java
new file mode 100644 (file)
index 0000000..f7884a0
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v66;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class CreateTableProjectBranches extends DdlChange {
+
+  private static final String TABLE_NAME = "project_branches";
+
+  public CreateTableProjectBranches(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new CreateTableBuilder(getDialect(), TABLE_NAME)
+      .addPkColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+        .setColumnName("uuid")
+        .setIsNullable(false)
+        .setLimit(50)
+        .build())
+      .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+        .setColumnName("project_uuid")
+        .setIsNullable(false)
+        .setLimit(50)
+        .build())
+      .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+        .setColumnName("kee_type")
+        .setIsNullable(false)
+        .setLimit(6)
+        .build())
+      .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+        .setColumnName("kee")
+        .setIsNullable(false)
+        .setLimit(255)
+        .build())
+      .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+        .setColumnName("branch_type")
+        .setIsNullable(true)
+        .setLimit(5)
+        .build())
+      .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+        .setColumnName("merge_branch_uuid")
+        .setIsNullable(true)
+        .setLimit(50)
+        .build())
+      .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+        .setColumnName("pull_request_title")
+        .setIsNullable(true)
+        .setLimit(4000)
+        .build())
+      .addColumn(BigIntegerColumnDef.newBigIntegerColumnDefBuilder()
+        .setColumnName("created_at")
+        .setIsNullable(false)
+        .build())
+      .build()
+    );
+  }
+}
index 1880ebc31d63c9b98c976019e21bde78a0f2ea6e..f0cf40b9f7078c620ed3edba699ee27ccfb80500 100644 (file)
@@ -32,6 +32,10 @@ public class DbVersion66 implements DbVersion {
       .add(1802, "Delete leak settings on views", DeleteLeakSettingsOnViews.class)
       .add(1803, "Fix empty USERS.EXTERNAL_IDENTITY and USERS.EXTERNAL_IDENTITY_PROVIDER", FixEmptyIdentityProviderInUsers.class)
       .add(1804, "Add rules.plugin_key", AddPluginKeyToRules.class)
-      .add(1805, "Create table plugins", CreateTablePlugins.class);
+      .add(1805, "Create table plugins", CreateTablePlugins.class)
+      .add(1806, "Create table project_branches", CreateTableProjectBranches.class)
+      .add(1807, "Add on project_branches key", AddIndexOnProjectBranchesKey.class)
+      .add(1808, "Add branch column to projects table", AddBranchColumnToProjectsTable.class)
+    ;
   }
 }
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranchesTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranchesTest.java
new file mode 100644 (file)
index 0000000..a960ef0
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.platform.db.migration.version.v66;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.CoreDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CreateTableProjectBranchesTest {
+  private static final String TABLE = "project_branches";
+
+  @Rule
+  public final CoreDbTester db = CoreDbTester.createForSchema(CreateTableProjectBranchesTest.class, "empty.sql");
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private CreateTableProjectBranches underTest = new CreateTableProjectBranches(db.database());
+
+  @Test
+  public void creates_table_on_empty_db() throws SQLException {
+    underTest.execute();
+
+    assertThat(db.countRowsOfTable(TABLE)).isEqualTo(0);
+
+    db.assertColumnDefinition(TABLE, "uuid", Types.VARCHAR, 50, false);
+    db.assertColumnDefinition(TABLE, "project_uuid", Types.VARCHAR, 50, false);
+    db.assertColumnDefinition(TABLE, "kee_type", Types.VARCHAR, 6, false);
+    db.assertColumnDefinition(TABLE, "kee", Types.VARCHAR, 255, false);
+    db.assertColumnDefinition(TABLE, "branch_type", Types.VARCHAR, 5, true);
+    db.assertColumnDefinition(TABLE, "merge_branch_uuid", Types.VARCHAR, 50, true);
+    db.assertColumnDefinition(TABLE, "pull_request_title", Types.VARCHAR, 4000, true);
+    db.assertColumnDefinition(TABLE, "created_at", Types.BIGINT, null, false);
+    db.assertPrimaryKey(TABLE, "pk_" + TABLE, "uuid");
+  }
+
+  @Test
+  public void migration_is_not_reentrant() throws SQLException {
+    underTest.execute();
+
+    expectedException.expect(IllegalStateException.class);
+
+    underTest.execute();
+  }
+
+}
index bce2e551bc19b346ac8d8a66b911a1d07a84f400..c52a3550b87a950a76d3dc18fa59bd9e72e3fdfb 100644 (file)
@@ -26,6 +26,7 @@ import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.
 import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber;
 
 public class DbVersion66Test {
+
   private DbVersion66 underTest = new DbVersion66();
 
   @Test
@@ -35,6 +36,7 @@ public class DbVersion66Test {
 
   @Test
   public void verify_migration_count() {
-    verifyMigrationCount(underTest, 6);
+    verifyMigrationCount(underTest, 9);
   }
+
 }
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranchesTest/empty.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v66/CreateTableProjectBranchesTest/empty.sql
new file mode 100644 (file)
index 0000000..e69de29
index 01b359c686aeb315c5172a57d1adca598938e47d..578a22d81e83126a01af4f799fd4a5d4dc9a13a2 100644 (file)
@@ -79,8 +79,8 @@ public class NewComponent {
   public static class Builder {
     private String organizationUuid;
     private String key;
-    private String branch;
     private String qualifier = PROJECT;
+    private String branch;
     private String name;
     private boolean isPrivate = false;
 
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/developer/PersistDevelopersDelegate.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/developer/PersistDevelopersDelegate.java
deleted file mode 100644 (file)
index cc6fe7c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation.task.projectanalysis.api.developer;
-
-import org.sonar.server.computation.task.step.ComputationStep;
-
-/**
- * This interface is used to delegate the persistence of developers to the Developer Cockpit plugin
- */
-public interface PersistDevelopersDelegate {
-
-  /**
-   * The delegate's implementation of {@link ComputationStep#execute()}.
-   */
-  void execute();
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/developer/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/developer/package-info.java
deleted file mode 100644 (file)
index 1b89497..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.server.computation.task.projectanalysis.api.developer;
-
-import javax.annotation.ParametersAreNonnullByDefault;
index 20dbe60069dbde36848e48d82b84e9e4ddc096f7..42820f5735fa831993d324e2a53d806fe481010c 100644 (file)
@@ -32,20 +32,6 @@ public final class ComponentFunctions {
     return ToReportRef.INSTANCE;
   }
 
-  public static Function<Component, String> toKey() {
-    return ToKey.INSTANCE;
-  }
-
-  private enum ToKey implements Function<Component, String> {
-    INSTANCE;
-
-    @Override
-    @Nonnull
-    public String apply(@Nonnull Component input) {
-      return input.getKey();
-    }
-  }
-
   private enum ToReportRef implements Function<Component, Integer> {
     INSTANCE;
     @Override
index 030dc2604a9899cd7f7e362bd039708581ead2d3..3ef387a802a498f4e8d307b99af5dde2cd740cda 100644 (file)
@@ -19,6 +19,9 @@
  */
 package org.sonar.server.computation.task.projectanalysis.component;
 
+/**
+ * The tree of components defined in the scanner report.
+ */
 public interface TreeRootHolder {
   /**
    * The root of the tree of Component representing the component in the current ScannerReport.
@@ -35,20 +38,4 @@ public interface TreeRootHolder {
    */
   Component getComponentByRef(int ref);
 
-  /**
-   * Retrieves the component with the specified key in the {@link Component} tree in the holder.
-   *
-   * @throws NullPointerException if {@code key} is {@code null}
-   * @throws IllegalStateException if the holder is empty (ie. there is not root  yet)
-   * @throws IllegalArgumentException if there is no {@link Component} with the specified key in the tree
-   */
-  Component getComponentByKey(String key);
-
-  /**
-   * Checks whether the {@link Component} with the specified key exists in the tree.
-   * 
-   * @throws NullPointerException if {@code key} is {@code null}
-   * @throws IllegalStateException if the holder is empty (ie. there is not root  yet)
-   */
-  boolean hasComponentWithKey(String key);
 }
index 208a3d2062a2588cb92ddbfad5e0dd712c640c20..ea12670158bccadd4fe92964ed98877d9b6191b7 100644 (file)
@@ -34,8 +34,6 @@ import static org.sonar.server.computation.task.projectanalysis.component.Compon
 public class TreeRootHolderImpl implements MutableTreeRootHolder {
   @CheckForNull
   private Map<Integer, Component> componentsByRef;
-  @CheckForNull
-  private Map<String, Component> componentsByKey;
 
   private Component root;
 
@@ -77,46 +75,7 @@ public class TreeRootHolderImpl implements MutableTreeRootHolder {
     this.componentsByRef = builder.build();
   }
 
-  @Override
-  public Component getComponentByKey(String key) {
-    checkKeyArgument(key);
-    checkInitialized();
-    ensureComponentByKeyIsPopulated();
-    Component component = componentsByKey.get(key);
-    checkArgument(component != null, "Component with key '%s' can't be found", key);
-    return component;
-  }
-
-  @Override
-  public boolean hasComponentWithKey(String key) {
-    checkKeyArgument(key);
-    checkInitialized();
-    ensureComponentByKeyIsPopulated();
-
-    return componentsByKey.containsKey(key);
-  }
-
   private void checkInitialized() {
     checkState(this.root != null, "Holder has not been initialized yet");
   }
-
-  private static void checkKeyArgument(String key) {
-    requireNonNull(key, "key can not be null");
-  }
-
-  private void ensureComponentByKeyIsPopulated() {
-    if (componentsByKey != null) {
-      return;
-    }
-
-    final ImmutableMap.Builder<String, Component> builder = ImmutableMap.builder();
-    new DepthTraversalTypeAwareCrawler(
-      new TypeAwareVisitorAdapter(CrawlerDepthLimit.LEAVES, POST_ORDER) {
-        @Override
-        public void visitAny(Component component) {
-          builder.put(component.getKey(), component);
-        }
-      }).visit(this.root);
-    this.componentsByKey = builder.build();
-  }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistDevelopersStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistDevelopersStep.java
deleted file mode 100644 (file)
index e2e1edd..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation.task.projectanalysis.step;
-
-import org.sonar.server.computation.task.projectanalysis.api.developer.PersistDevelopersDelegate;
-import org.sonar.server.computation.task.step.ComputationStep;
-
-/**
- * Persist developers, should only be execute when the Dev Cockpit plugin is installed.
- */
-public class PersistDevelopersStep implements ComputationStep {
-
-  private final PersistDevelopersDelegate persistDevelopersDelegate;
-
-  public PersistDevelopersStep(PersistDevelopersDelegate persistDevelopersDelegate) {
-    this.persistDevelopersDelegate = persistDevelopersDelegate;
-  }
-
-  @Override
-  public String getDescription() {
-    return "Persist developers";
-  }
-
-  @Override
-  public void execute() {
-    persistDevelopersDelegate.execute();
-  }
-
-}
index 8bb92dad38d2737840030e1cc1580dc2030ef9f4..02a4df5f3dadbc3b664b856c8b41e0a531be691a 100644 (file)
  */
 package org.sonar.server.computation.task.projectanalysis.step;
 
-import com.google.common.base.Predicate;
 import java.util.Arrays;
 import java.util.List;
-import javax.annotation.Nonnull;
-import org.picocontainer.ComponentAdapter;
 import org.sonar.server.computation.task.container.TaskContainer;
-import org.sonar.server.computation.task.projectanalysis.api.developer.PersistDevelopersDelegate;
 import org.sonar.server.computation.task.projectanalysis.filemove.FileMoveDetectionStep;
 import org.sonar.server.computation.task.step.ComputationStep;
 
-import static com.google.common.collect.FluentIterable.from;
-
 /**
  * Ordered list of steps classes and instances to be executed for batch processing
  */
@@ -92,7 +86,6 @@ public class ReportComputationSteps extends AbstractComputationSteps {
     // Persist data
     PersistComponentsStep.class,
     PersistAnalysisStep.class,
-    PersistDevelopersStep.class,
     PersistMeasuresStep.class,
     PersistIssuesStep.class,
     PersistProjectLinksStep.class,
@@ -111,11 +104,8 @@ public class ReportComputationSteps extends AbstractComputationSteps {
 
     PublishTaskResultStep.class);
 
-  private final TaskContainer taskContainer;
-
   public ReportComputationSteps(TaskContainer taskContainer) {
     super(taskContainer);
-    this.taskContainer = taskContainer;
   }
 
   /**
@@ -124,27 +114,7 @@ public class ReportComputationSteps extends AbstractComputationSteps {
    */
   @Override
   public List<Class<? extends ComputationStep>> orderedStepClasses() {
-    return from(STEPS)
-      .filter(new AllowPersistDevelopersStepIfDevCockpitPluginInstalled(taskContainer))
-      .toList();
-  }
-
-  private static class AllowPersistDevelopersStepIfDevCockpitPluginInstalled implements Predicate<Class<? extends ComputationStep>> {
-    private final boolean devCockpitIsInstalled;
-
-    private AllowPersistDevelopersStepIfDevCockpitPluginInstalled(TaskContainer taskContainer) {
-      this.devCockpitIsInstalled = isDevCockpitInstalled(taskContainer);
-    }
-
-    private static boolean isDevCockpitInstalled(TaskContainer taskContainer) {
-      List<ComponentAdapter<PersistDevelopersDelegate>> componentAdapters = taskContainer.getPicoContainer().getComponentAdapters(PersistDevelopersDelegate.class);
-      return !componentAdapters.isEmpty();
-    }
-
-    @Override
-    public boolean apply(@Nonnull Class<? extends ComputationStep> input) {
-      return devCockpitIsInstalled || !input.equals(PersistDevelopersStep.class);
-    }
+    return STEPS;
   }
 
 }
index 74ca0c4448fed316a333514d6ff5995c63b29a32..c3b1a5996141a67f2155d610376e6af306ae3f37 100644 (file)
@@ -67,10 +67,10 @@ public class ServerIssueStorage extends IssueStorage {
   }
 
   protected ComponentDto component(DbSession session, DefaultIssue issue) {
-    return getDbClient().componentDao().selectOrFailByKey(session, issue.componentKey());
+    return getDbClient().componentDao().selectOrFailByUuid(session, issue.componentUuid());
   }
 
   protected ComponentDto project(DbSession session, DefaultIssue issue) {
-    return getDbClient().componentDao().selectOrFailByKey(session, issue.projectKey());
+    return getDbClient().componentDao().selectOrFailByUuid(session, issue.projectUuid());
   }
 }
index 0257869aef62c8d09c88dc773f6aea215bdd3244..992f8deaaf184591102750d4ec694e4ca5c32b31 100644 (file)
@@ -23,17 +23,13 @@ import java.util.Random;
 import org.junit.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.MODULE;
 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
-import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.SUBVIEW;
 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.VIEW;
-import static org.sonar.server.computation.task.projectanalysis.component.ComponentFunctions.toKey;
 import static org.sonar.server.computation.task.projectanalysis.component.ComponentFunctions.toReportRef;
 
 public class ComponentFunctionsTest {
 
   public static final int SOME_INT = new Random().nextInt();
-  public static final String SOME_KEY = "some key";
 
   @Test(expected = NullPointerException.class)
   public void toReportRef_throws_NPE_if_Component_is_null() {
@@ -49,15 +45,4 @@ public class ComponentFunctionsTest {
   public void toReportRef_returns_the_ref_of_the_Component() {
     assertThat(toReportRef().apply(ReportComponent.builder(PROJECT, SOME_INT).build())).isEqualTo(SOME_INT);
   }
-
-  @Test(expected = NullPointerException.class)
-  public void toKey_if_Component_is_null() {
-    toKey().apply(null);
-  }
-
-  @Test
-  public void toKey_returns_the_key_of_the_Component() {
-    assertThat(toKey().apply(ReportComponent.builder(MODULE, -63).setKey(SOME_KEY).build())).isEqualTo(SOME_KEY);
-    assertThat(toKey().apply(ViewsComponent.builder(SUBVIEW, SOME_INT).build())).isEqualTo(String.valueOf(SOME_INT));
-  }
 }
index 0582e5e9e7a2041a3a10ec81ec4e298b1619df19..f9d16b0e15771a0f0a3940545b17df6597e89976 100644 (file)
@@ -36,20 +36,20 @@ public class TreeRootHolderImplTest {
 
   private static final ReportComponent SOME_REPORT_COMPONENT_TREE = ReportComponent.builder(PROJECT, 1)
     .addChildren(
-        ReportComponent.builder(MODULE, 2)
-            .addChildren(ReportComponent.builder(DIRECTORY, 3)
-                .addChildren(
-                    ReportComponent.builder(FILE, 4).build()
-                )
-                .build())
-            .build()
+      ReportComponent.builder(MODULE, 2)
+        .addChildren(ReportComponent.builder(DIRECTORY, 3)
+          .addChildren(
+            ReportComponent.builder(FILE, 4).build()
+          )
+          .build())
+        .build()
     )
     .build();
   private static final ViewsComponent SOME_VIEWS_COMPONENT_TREE = ViewsComponent.builder(VIEW, 1)
     .addChildren(
-        ViewsComponent.builder(VIEW, 2)
-            .addChildren(ViewsComponent.builder(PROJECT_VIEW, 3).build())
-            .build()
+      ViewsComponent.builder(VIEW, 2)
+        .addChildren(ViewsComponent.builder(PROJECT_VIEW, 3).build())
+        .build()
     )
     .build();
 
@@ -119,84 +119,12 @@ public class TreeRootHolderImplTest {
     underTest.getComponentByRef(1);
   }
 
-  @Test
-  public void getComponentByKey_throws_NPE_if_key_is_null() {
-    expectedException.expect(NullPointerException.class);
-    expectedException.expectMessage("key can not be null");
-
-    underTest.getComponentByKey(null);
-  }
-
-  @Test
-  public void getComponentByKey_throws_ISE_if_root_has_not_been_set() {
-    expectNotInitialized_ISE();
-
-    underTest.getComponentByKey("key");
-  }
-
-  @Test
-  public void getComponentByKey_returns_any_report_component_in_the_tree() {
-    underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
-
-    for (int i = 1; i <= 4; i++) {
-      String key = "key_" + i;
-      assertThat(underTest.getComponentByKey(key).getKey()).isEqualTo(key);
-    }
-  }
-
-  @Test
-  public void getComponentByKey_returns_any_views_component_in_the_tree() {
-    underTest.setRoot(SOME_VIEWS_COMPONENT_TREE);
-
-    for (int i = 1; i <= 3; i++) {
-      String key = String.valueOf(i);
-      assertThat(underTest.getComponentByKey(key).getKey()).isEqualTo(key);
-    }
-  }
-
   @Test
   public void verify_setRoot_getRoot() {
     underTest.setRoot(DUMB_PROJECT);
     assertThat(underTest.getRoot()).isSameAs(DUMB_PROJECT);
   }
 
-  @Test
-  public void hasComponentWithKey_throws_NPE_if_key_is_null() {
-    expectedException.expect(NullPointerException.class);
-    expectedException.expectMessage("key can not be null");
-
-    underTest.hasComponentWithKey(null);
-  }
-
-  @Test
-  public void hasComponentWithKey_throws_ISE_if_root_has_not_been_set() {
-    expectNotInitialized_ISE();
-
-    underTest.hasComponentWithKey("key");
-  }
-
-  @Test
-  public void hasComponentWithKey_returns_true_for_any_report_component_in_the_tree() {
-    underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
-
-    for (int i = 1; i <= 4; i++) {
-      String key = "key_" + i;
-      assertThat(underTest.hasComponentWithKey(key)).isTrue();
-    }
-    assertThat(underTest.hasComponentWithKey("toto")).isFalse();
-  }
-
-  @Test
-  public void hasComponentWithKey_returns_true_for_any_views_component_in_the_tree() {
-    underTest.setRoot(SOME_VIEWS_COMPONENT_TREE);
-
-    for (int i = 1; i <= 3; i++) {
-      String key = String.valueOf(i);
-      assertThat(underTest.hasComponentWithKey(key)).isTrue();
-    }
-    assertThat(underTest.hasComponentWithKey("toto")).isFalse();
-  }
-
   private void expectNotInitialized_ISE() {
     expectedException.expect(IllegalStateException.class);
     expectedException.expectMessage("Holder has not been initialized yet");
index 117593f229284abc55dceb08ad8150b7cff07182..ea4ed8a60980123b980ae858877a5d8e0b5ad624 100644 (file)
@@ -44,14 +44,4 @@ public class TreeRootHolderRule extends ExternalResource implements TreeRootHold
   public Component getComponentByRef(int ref) {
     return delegate.getComponentByRef(ref);
   }
-
-  @Override
-  public Component getComponentByKey(String key) {
-    return delegate.getComponentByKey(key);
-  }
-
-  @Override
-  public boolean hasComponentWithKey(String key) {
-    return delegate.hasComponentWithKey(key);
-  }
 }
index 0d5bd5ba2f97ddfb5cafd59bdb345e3ef031f9b1..4fbe85c0476cbf8b8c9ae936e8d4bb1f146ec15d 100644 (file)
@@ -37,7 +37,6 @@ import org.sonar.plugin.ce.ReportAnalysisComponentProvider;
 import org.sonar.server.computation.task.container.TaskContainer;
 import org.sonar.server.computation.task.step.StepsExplorer;
 import org.sonar.server.computation.task.projectanalysis.step.PersistComponentsStep;
-import org.sonar.server.computation.task.projectanalysis.step.PersistDevelopersStep;
 import org.sonar.server.computation.task.step.ComputationStep;
 
 import static com.google.common.base.Predicates.notNull;
@@ -84,8 +83,7 @@ public class ProjectAnalysisTaskContainerPopulatorTest {
       .transform(StepsExplorer.toCanonicalName())
       .toSet();
 
-    // PersistDevelopersStep is the only step that is not in the report container (it's only added when Dev Cockpit plugin is installed)
-    assertThat(difference(StepsExplorer.retrieveStepPackageStepsCanonicalNames(PROJECTANALYSIS_STEP_PACKAGE), computationStepClassNames)).containsOnly(PersistDevelopersStep.class.getCanonicalName());
+    assertThat(difference(StepsExplorer.retrieveStepPackageStepsCanonicalNames(PROJECTANALYSIS_STEP_PACKAGE), computationStepClassNames)).isEmpty();
   }
 
   @Test
@@ -97,15 +95,6 @@ public class ProjectAnalysisTaskContainerPopulatorTest {
     assertThat(container.added).contains(PersistComponentsStep.class);
   }
 
-  @Test
-  public void PersistDevelopersStep_is_not_added_to_the_container_when_DevCockpitBridge_is_null() {
-    underTest = new ProjectAnalysisTaskContainerPopulator(task, null);
-    AddedObjectsRecorderTaskContainer container = new AddedObjectsRecorderTaskContainer();
-    underTest.populateContainer(container);
-
-    assertThat(container.added).doesNotContain(PersistDevelopersStep.class);
-  }
-
   @Test
   public void Components_of_ReportAnalysisComponentProvider_are_added_to_the_container() {
     Object object = new Object();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistDevelopersStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistDevelopersStepTest.java
deleted file mode 100644 (file)
index 427ae95..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation.task.projectanalysis.step;
-
-import org.junit.Test;
-import org.sonar.server.computation.task.projectanalysis.api.developer.PersistDevelopersDelegate;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class PersistDevelopersStepTest {
-
-  PersistDevelopersDelegate persistDevelopersDelegate = mock(PersistDevelopersDelegate.class);
-
-  PersistDevelopersStep underTest = new PersistDevelopersStep(persistDevelopersDelegate);
-
-  @Test
-  public void execute_calls_delegate_execute() throws Exception {
-    underTest.execute();
-
-    verify(persistDevelopersDelegate).execute();
-  }
-}
index 94a5e8e273bd93e7101d341a708d2787fbf204a7..5c823ab234d2baf326a024e214172047841ff9f7 100644 (file)
@@ -130,6 +130,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(moduleDto.getUuidPath()).isEqualTo(projectDto.getUuidPath() + projectDto.uuid() + UUID_PATH_SEPARATOR);
     assertThat(moduleDto.moduleUuid()).isEqualTo(projectDto.uuid());
     assertThat(moduleDto.moduleUuidPath()).isEqualTo(projectDto.moduleUuidPath() + moduleDto.uuid() + ".");
+    assertThat(moduleDto.getMainBranchProjectUuid()).isNull();
     assertThat(moduleDto.projectUuid()).isEqualTo(projectDto.uuid());
     assertThat(moduleDto.qualifier()).isEqualTo("BRC");
     assertThat(moduleDto.scope()).isEqualTo("PRJ");
@@ -145,6 +146,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(directoryDto.getUuidPath()).isEqualTo(moduleDto.getUuidPath() + moduleDto.uuid() + UUID_PATH_SEPARATOR);
     assertThat(directoryDto.moduleUuid()).isEqualTo(moduleDto.uuid());
     assertThat(directoryDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
+    assertThat(directoryDto.getMainBranchProjectUuid()).isNull();
     assertThat(directoryDto.projectUuid()).isEqualTo(projectDto.uuid());
     assertThat(directoryDto.qualifier()).isEqualTo("DIR");
     assertThat(directoryDto.scope()).isEqualTo("DIR");
@@ -161,6 +163,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(fileDto.getUuidPath()).isEqualTo(directoryDto.getUuidPath() + directoryDto.uuid() + UUID_PATH_SEPARATOR);
     assertThat(fileDto.moduleUuid()).isEqualTo(moduleDto.uuid());
     assertThat(fileDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
+    assertThat(fileDto.getMainBranchProjectUuid()).isNull();
     assertThat(fileDto.projectUuid()).isEqualTo(projectDto.uuid());
     assertThat(fileDto.qualifier()).isEqualTo("FIL");
     assertThat(fileDto.scope()).isEqualTo("FIL");
@@ -255,6 +258,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(projectReloaded.getId()).isEqualTo(project.getId());
     assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
     assertThat(projectReloaded.getUuidPath()).isEqualTo(UUID_PATH_OF_ROOT);
+    assertThat(projectReloaded.getMainBranchProjectUuid()).isNull();
 
     ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get();
     assertThat(moduleReloaded.getId()).isEqualTo(module.getId());
@@ -264,6 +268,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(moduleReloaded.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
     assertThat(moduleReloaded.projectUuid()).isEqualTo(module.projectUuid());
     assertThat(moduleReloaded.getRootUuid()).isEqualTo(module.getRootUuid());
+    assertThat(moduleReloaded.getMainBranchProjectUuid()).isNull();
 
     ComponentDto directory = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get();
     assertThat(directory.getUuidPath()).isEqualTo(directory.getUuidPath());
@@ -271,6 +276,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(directory.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
     assertThat(directory.projectUuid()).isEqualTo(project.uuid());
     assertThat(directory.getRootUuid()).isEqualTo(module.uuid());
+    assertThat(directory.getMainBranchProjectUuid()).isNull();
 
     ComponentDto file = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
     assertThat(file.getUuidPath()).isEqualTo(file.getUuidPath());
@@ -278,6 +284,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(file.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
     assertThat(file.projectUuid()).isEqualTo(project.uuid());
     assertThat(file.getRootUuid()).isEqualTo(module.uuid());
+    assertThat(file.getMainBranchProjectUuid()).isNull();
   }
 
   @Test
index d763f025932019fc78abb0abd3400acc19af2f2d..722705fef7e1b81b5bc6a70df7fb32902e75b11c 100644 (file)
@@ -44,14 +44,14 @@ import static org.mockito.Mockito.when;
 
 public class ServerIssueStorageTest {
 
-  System2 system2 = mock(System2.class);
+  private System2 system2 = mock(System2.class);
 
   @org.junit.Rule
   public DbTester dbTester = DbTester.create(system2);
 
-  DbClient dbClient = dbTester.getDbClient();
+  private DbClient dbClient = dbTester.getDbClient();
 
-  ServerIssueStorage storage = new ServerIssueStorage(system2, new FakeRuleFinder(), dbClient, mock(IssueIndexer.class));
+  private ServerIssueStorage underTest = new ServerIssueStorage(system2, new FakeRuleFinder(), dbClient, mock(IssueIndexer.class));
 
   @Before
   public void setupDbClient() {
@@ -62,7 +62,7 @@ public class ServerIssueStorageTest {
   public void load_component_id_from_db() {
     dbTester.prepareDbUnit(getClass(), "load_component_id_from_db.xml");
 
-    long componentId = storage.component(dbTester.getSession(), new DefaultIssue().setComponentKey("struts:Action")).getId();
+    long componentId = underTest.component(dbTester.getSession(), new DefaultIssue().setComponentUuid("BCDE")).getId();
 
     assertThat(componentId).isEqualTo(100);
   }
@@ -71,7 +71,7 @@ public class ServerIssueStorageTest {
   public void load_project_id_from_db() {
     dbTester.prepareDbUnit(getClass(), "load_project_id_from_db.xml");
 
-    long projectId = storage.project(dbTester.getSession(), new DefaultIssue().setProjectKey("struts")).getId();
+    long projectId = underTest.project(dbTester.getSession(), new DefaultIssue().setProjectUuid("ABCD")).getId();
 
     assertThat(projectId).isEqualTo(1);
   }
@@ -91,7 +91,8 @@ public class ServerIssueStorageTest {
       .setNew(true)
 
       .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
-      .setProjectKey("struts")
+      .setProjectUuid("ABCD")
+      .setComponentUuid("BCDE")
       .setLine(5000)
       .setEffort(Duration.create(10L))
       .setResolution("OPEN")
@@ -101,11 +102,9 @@ public class ServerIssueStorageTest {
       .addComment(comment)
       .setCreationDate(date)
       .setUpdateDate(date)
-      .setCloseDate(date)
-
-      .setComponentKey("struts:Action");
+      .setCloseDate(date);
 
-    storage.save(issue);
+    underTest.save(issue);
 
     dbTester.assertDbUnit(getClass(), "should_insert_new_issues-result.xml",
       new String[] {"id", "created_at", "updated_at", "issue_change_creation_date"}, "issues", "issue_changes");
@@ -150,7 +149,7 @@ public class ServerIssueStorageTest {
       .setComponentKey("struts:Action")
       .setProjectKey("struts");
 
-    storage.save(issue);
+    underTest.save(issue);
 
     dbTester.assertDbUnit(getClass(), "should_update_issues-result.xml",
       new String[] {"id", "created_at", "updated_at", "issue_change_creation_date"}, "issues", "issue_changes");
index d8e17c542f8719d58eb30a7a3990a2fde16c81d4..742c38385f45f2418f2e901e900b1d1d88ff0bf7 100644 (file)
@@ -104,8 +104,8 @@ public class CreateActionTest {
       .extracting(Project::getKey, Project::getName, Project::getQualifier, Project::getVisibility)
       .containsOnly(DEFAULT_PROJECT_KEY, DEFAULT_PROJECT_NAME, "TRK", "public");
     assertThat(db.getDbClient().componentDao().selectByKey(db.getSession(), DEFAULT_PROJECT_KEY).get())
-      .extracting(ComponentDto::getDbKey, ComponentDto::name, ComponentDto::qualifier, ComponentDto::scope, ComponentDto::isPrivate)
-      .containsOnly(DEFAULT_PROJECT_KEY, DEFAULT_PROJECT_NAME, "TRK", "PRJ", false);
+      .extracting(ComponentDto::getDbKey, ComponentDto::name, ComponentDto::qualifier, ComponentDto::scope, ComponentDto::isPrivate, ComponentDto::getMainBranchProjectUuid)
+      .containsOnly(DEFAULT_PROJECT_KEY, DEFAULT_PROJECT_NAME, "TRK", "PRJ", false, null);
   }
 
   @Test
index 83905f1533afa77471c488681799436ec4138d70..e397f7dfe7d3131187a4dfd44dfbbfd3a245e661 100644 (file)
@@ -179,7 +179,7 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
   }
 
   /**
-   * Can be null on Views or Devs
+   * Can be null on Views
    */
   @Override
   @CheckForNull