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
@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 {
*/
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",
"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",
"project_links",
"project_measures",
"project_qprofiles",
+ "project_branches",
"properties",
"qprofile_changes",
"quality_gates",
"users",
"user_roles",
"user_tokens",
- "webhook_deliveries");
+ "webhook_deliveries")));
private SqTables() {
// prevents instantiation
"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,
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,
"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");
*/
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;
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;
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,
UserPermissionDao.class,
UserTokenDao.class,
WebhookDeliveryDao.class)
- .build();
+ );
@Override
protected void configureModule() {
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;
Class<?>[] mappers = {
ActiveRuleMapper.class,
AuthorizationMapper.class,
+ BranchMapper.class,
CeActivityMapper.class,
CeQueueMapper.class,
CeScannerContextMapper.class,
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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
+}
*/
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;
return this;
}
+ /**
+ * Use {@link #projectUuid()}, {@link #moduleUuid()} or {@link #moduleUuidPath()}
+ */
+ @Deprecated
public String getRootUuid() {
return rootUuid;
}
return this;
}
+ @Nullable
+ public String getMainBranchProjectUuid() {
+ return mainBranchProjectUuid;
+ }
+
+ public ComponentDto setMainBranchProjectUuid(@Nullable String s) {
+ this.mainBranchProjectUuid = s;
+ return this;
+ }
+
public boolean isEnabled() {
return enabled;
}
.append("moduleUuid", moduleUuid)
.append("moduleUuidPath", moduleUuidPath)
.append("rootUuid", rootUuid)
+ .append("mainBranchProjectUuid", mainBranchProjectUuid)
.append("copyComponentUuid", copyComponentUuid)
.append("developerUuid", developerUuid)
.append("path", path)
--- /dev/null
+<?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>
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},
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);
}
}
.setRootUuid(moduleOrProject.uuid())
.setModuleUuid(moduleOrProject.uuid())
.setModuleUuidPath(moduleOrProject.moduleUuidPath())
+ .setMainBranchProjectUuid(moduleOrProject.getMainBranchProjectUuid())
.setCreatedAt(new Date())
.setEnabled(true)
.setPrivate(moduleOrProject.isPrivate());
"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,
project_uuid="A"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
description="[null]"
private="[false]"
tags="[null]"
project_uuid="A"
module_uuid="[null]"
module_uuid_path=".A."
+ main_branch_project_uuid="[null]"
scope="PRJ"
qualifier="BRC"
long_name="Struts Core"
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"
project_uuid="A"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
description="[null]"
private="[false]"
tags="[null]"
project_uuid="A"
module_uuid="[null]"
module_uuid_path=".A."
+ main_branch_project_uuid="[null]"
scope="PRJ"
qualifier="BRC"
long_name="Struts Core"
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"
project_uuid="A"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
description="[null]"
private="[false]"
tags="[null]"
project_uuid="A"
module_uuid="[null]"
module_uuid_path=".A."
+ main_branch_project_uuid="[null]"
scope="PRJ"
qualifier="BRC"
long_name="Struts Core"
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"
project_uuid="A"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
description="[null]"
private="[false]"
tags="[null]"
project_uuid="A"
module_uuid="[null]"
module_uuid_path=".A."
+ main_branch_project_uuid="[null]"
scope="PRJ"
qualifier="BRC"
long_name="Struts Core"
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="."
+ main_branch_project_uuid="[null]"
description="[null]"
private="[false]"
tags="[null]"
project_uuid="A"
module_uuid="[null]"
module_uuid_path=".A."
+ main_branch_project_uuid="[null]"
scope="PRJ"
qualifier="BRC"
long_name="Struts Core"
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="."
+ main_branch_project_uuid="[null]"
description="[null]"
private="[false]"
tags="[null]"
project_uuid="A"
module_uuid="[null]"
module_uuid_path=".A."
+ main_branch_project_uuid="[null]"
scope="PRJ"
qualifier="BRC"
long_name="Struts Core"
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"
project_uuid="ABCD"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
scope="PRJ"
qualifier="TRK"
kee="old key"
project_uuid="ABCD"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
scope="PRJ"
qualifier="TRK"
kee="old key"
project_uuid="P1"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="PRJ"
project_uuid="P1"
module_uuid="P1"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="DIR"
project_uuid="P1"
module_uuid="P1"
module_uuid_path=".P1."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="FIL"
project_uuid="P1"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="PRJ"
project_uuid="P1"
module_uuid="P1"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="DIR"
project_uuid="P1"
module_uuid="P1"
module_uuid_path=".P1."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="FIL"
project_uuid="ABCD"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="PRJ"
project_uuid="ABCD"
module_uuid="ABCD"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="DIR"
project_uuid="ABCD"
module_uuid="ABCD"
module_uuid_path=".ABCD."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="FIL"
project_uuid="ABCD"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="PRJ"
project_uuid="ABCD"
module_uuid="ABCD"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="DIR"
project_uuid="ABCD"
module_uuid="ABCD"
module_uuid_path=".ABCD."
+ main_branch_project_uuid="[null]"
created_at="[null]"
long_name="[null]"
scope="FIL"
project_uuid="P1"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
enabled="[true]"
created_at="[null]"
long_name="[null]"
project_uuid="P1"
module_uuid="[null]"
module_uuid_path="."
+ main_branch_project_uuid="[null]"
enabled="[true]"
created_at="[null]"
long_name="[null]"
--- /dev/null
+/*
+ * 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());
+ }
+}
--- /dev/null
+/*
+ * 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());
+ }
+}
--- /dev/null
+/*
+ * 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()
+ );
+ }
+}
.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)
+ ;
}
}
--- /dev/null
+/*
+ * 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();
+ }
+
+}
import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber;
public class DbVersion66Test {
+
private DbVersion66 underTest = new DbVersion66();
@Test
@Test
public void verify_migration_count() {
- verifyMigrationCount(underTest, 6);
+ verifyMigrationCount(underTest, 9);
}
+
}
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;
+++ /dev/null
-/*
- * 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();
-
-}
+++ /dev/null
-/*
- * 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;
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
*/
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.
*/
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);
}
public class TreeRootHolderImpl implements MutableTreeRootHolder {
@CheckForNull
private Map<Integer, Component> componentsByRef;
- @CheckForNull
- private Map<String, Component> componentsByKey;
private Component root;
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();
- }
}
+++ /dev/null
-/*
- * 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();
- }
-
-}
*/
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
*/
// Persist data
PersistComponentsStep.class,
PersistAnalysisStep.class,
- PersistDevelopersStep.class,
PersistMeasuresStep.class,
PersistIssuesStep.class,
PersistProjectLinksStep.class,
PublishTaskResultStep.class);
- private final TaskContainer taskContainer;
-
public ReportComputationSteps(TaskContainer taskContainer) {
super(taskContainer);
- this.taskContainer = taskContainer;
}
/**
*/
@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;
}
}
}
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());
}
}
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() {
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));
- }
}
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();
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");
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);
- }
}
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;
.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
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();
+++ /dev/null
-/*
- * 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();
- }
-}
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");
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");
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");
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());
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());
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());
assertThat(file.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
assertThat(file.projectUuid()).isEqualTo(project.uuid());
assertThat(file.getRootUuid()).isEqualTo(module.uuid());
+ assertThat(file.getMainBranchProjectUuid()).isNull();
}
@Test
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() {
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);
}
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);
}
.setNew(true)
.setRuleKey(RuleKey.of("squid", "AvoidCycle"))
- .setProjectKey("struts")
+ .setProjectUuid("ABCD")
+ .setComponentUuid("BCDE")
.setLine(5000)
.setEffort(Duration.create(10L))
.setResolution("OPEN")
.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");
.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");
.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
}
/**
- * Can be null on Views or Devs
+ * Can be null on Views
*/
@Override
@CheckForNull