--- /dev/null
+package org.sonar.db.issue;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AnticipatedTransitionDaoIT {
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+
+ private final AnticipatedTransitionDao underTest = db.getDbClient().anticipatedTransitionDao();
+
+ @Test
+ public void select_anticipated_transition() {
+ final String projectUuid = "project147852";
+ String atUuid = "uuid_123456";
+ AnticipatedTransitionDto transition = new AnticipatedTransitionDto(
+ atUuid,
+ projectUuid,
+ "userUuid",
+ "transition",
+ "status",
+ "comment",
+ 1,
+ "message",
+ "lineHash",
+ "ruleKey");
+
+ // insert one
+ underTest.insert(db.getSession(), transition);
+
+ // select all
+ var anticipatedTransitionDtos = underTest.selectByProjectUuid(db.getSession(), projectUuid);
+ assertThat(anticipatedTransitionDtos).hasSize(1);
+ assertThat(anticipatedTransitionDtos.get(0))
+ .extracting("uuid").isEqualTo(atUuid);
+
+ // delete one
+ underTest.delete(db.getSession(), atUuid);
+
+ // select all
+ var anticipatedTransitionDtosDeleted = underTest.selectByProjectUuid(db.getSession(), projectUuid);
+ assertThat(anticipatedTransitionDtosDeleted).isEmpty();
+ }
+}
import org.sonar.db.es.EsQueueDao;
import org.sonar.db.event.EventComponentChangeDao;
import org.sonar.db.event.EventDao;
+import org.sonar.db.issue.AnticipatedTransitionDao;
import org.sonar.db.issue.IssueChangeDao;
import org.sonar.db.issue.IssueDao;
import org.sonar.db.measure.LiveMeasureDao;
// =====================================================================
ActiveRuleDao.class,
AnalysisPropertiesDao.class,
+ AnticipatedTransitionDao.class,
AuthorizationDao.class,
ApplicationProjectsDao.class,
AuditDao.class,
import org.sonar.db.es.EsQueueDao;
import org.sonar.db.event.EventComponentChangeDao;
import org.sonar.db.event.EventDao;
+import org.sonar.db.issue.AnticipatedTransitionDao;
import org.sonar.db.issue.IssueChangeDao;
import org.sonar.db.issue.IssueDao;
import org.sonar.db.measure.LiveMeasureDao;
private final ScimUserDao scimUserDao;
private final ScimGroupDao scimGroupDao;
private final EntityDao entityDao;
+ private final AnticipatedTransitionDao anticipatedTransitionDao;
private final ReportScheduleDao reportScheduleDao;
private final ReportSubscriptionDao reportSubscriptionDao;
entityDao = getDao(map, EntityDao.class);
reportScheduleDao = getDao(map, ReportScheduleDao.class);
reportSubscriptionDao = getDao(map, ReportSubscriptionDao.class);
+ anticipatedTransitionDao = getDao(map, AnticipatedTransitionDao.class);
}
public DbSession openSession(boolean batch) {
return entityDao;
}
- public ReportScheduleDao reportScheduleDao(){
+ public ReportScheduleDao reportScheduleDao() {
return reportScheduleDao;
}
public ReportSubscriptionDao reportSubscriptionDao() {
return reportSubscriptionDao;
}
+
+ public AnticipatedTransitionDao anticipatedTransitionDao() {
+ return anticipatedTransitionDao;
+ }
}
import org.sonar.db.event.EventComponentChangeMapper;
import org.sonar.db.event.EventDto;
import org.sonar.db.event.EventMapper;
+import org.sonar.db.issue.AnticipatedTransitionDto;
+import org.sonar.db.issue.AnticipatedTransitionMapper;
import org.sonar.db.issue.IssueChangeDto;
import org.sonar.db.issue.IssueChangeMapper;
import org.sonar.db.issue.IssueDto;
confBuilder.loadAlias("ActiveRule", ActiveRuleDto.class);
confBuilder.loadAlias("ActiveRuleParam", ActiveRuleParamDto.class);
confBuilder.loadAlias("ApplicationProject", ApplicationProjectDto.class);
+ confBuilder.loadAlias("AnticipatedTransition", AnticipatedTransitionDto.class);
confBuilder.loadAlias("CeTaskCharacteristic", CeTaskCharacteristicDto.class);
confBuilder.loadAlias("Component", ComponentDto.class);
confBuilder.loadAlias("DuplicationUnit", DuplicationUnitDto.class);
AlmPatMapper.class,
AlmSettingMapper.class,
AnalysisPropertiesMapper.class,
+ AnticipatedTransitionMapper.class,
ApplicationProjectsMapper.class,
AuditMapper.class,
AuthorizationMapper.class,
--- /dev/null
+package org.sonar.db.issue;
+
+import java.util.List;
+import org.sonar.db.Dao;
+import org.sonar.db.DbSession;
+
+public class AnticipatedTransitionDao implements Dao {
+
+ public void insert(DbSession session, AnticipatedTransitionDto transition) {
+ mapper(session).insert(transition);
+ }
+
+ public void delete(DbSession session, String uuid) {
+ mapper(session).delete(uuid);
+ }
+
+ public List<AnticipatedTransitionDto> selectByProjectUuid(DbSession session, String projectUuid) {
+ return mapper(session).selectByProjectUuid(projectUuid);
+ }
+
+ private static AnticipatedTransitionMapper mapper(DbSession session) {
+ return session.getMapper(AnticipatedTransitionMapper.class);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.issue;
+
+import javax.annotation.Nullable;
+
+public class AnticipatedTransitionDto {
+ private String uuid;
+ private String projectUuid;
+ private String userUuid;
+ private String transition;
+ private String status;
+ private String comment;
+ private Integer line;
+ private String message;
+ private String lineHash;
+ private String ruleKey;
+ // TODO: private String filePath
+ // TODO: private Instant createdAt
+
+
+ public AnticipatedTransitionDto(
+ String uuid,
+ String projectUuid,
+ String userUuid,
+ String transition,
+ String status,
+ @Nullable String comment,
+ @Nullable Integer line,
+ @Nullable String message,
+ @Nullable String lineHash,
+ String ruleKey) {
+ this.uuid = uuid;
+ this.projectUuid = projectUuid;
+ this.userUuid = userUuid;
+ this.transition = transition;
+ this.status = status;
+ this.comment = comment;
+ this.line = line;
+ this.message = message;
+ this.lineHash = lineHash;
+ this.ruleKey = ruleKey;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getProjectUuid() {
+ return projectUuid;
+ }
+
+ public void setProjectUuid(String projectUuid) {
+ this.projectUuid = projectUuid;
+ }
+
+ public String getUserUuid() {
+ return userUuid;
+ }
+
+ public void setUserUuid(String userUuid) {
+ this.userUuid = userUuid;
+ }
+
+ public String getTransition() {
+ return transition;
+ }
+
+ public void setTransition(String transition) {
+ this.transition = transition;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public Integer getLine() {
+ return line;
+ }
+
+ public void setLine(Integer line) {
+ this.line = line;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getLineHash() {
+ return lineHash;
+ }
+
+ public void setLineHash(String lineHash) {
+ this.lineHash = lineHash;
+ }
+
+ public String getRuleKey() {
+ return ruleKey;
+ }
+
+ public void setRuleKey(String ruleKey) {
+ this.ruleKey = ruleKey;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.issue;
+
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface AnticipatedTransitionMapper {
+ void insert(AnticipatedTransitionDto anticipatedTransitionDto);
+
+ void delete(@Param("uuid") String uuid);
+
+ List<AnticipatedTransitionDto> selectByProjectUuid(@Param("projectUuid") String projectUuid);
+}
--- /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.issue.AnticipatedTransitionMapper">
+
+ <sql id="anticipatedTransitionsColumns">
+ at.uuid as uuid,
+ at.project_uuid as projectUuid,
+ at.user_uuid as userUuid,
+ at.transition as transition,
+ at.status as status,
+ at.transition_comment as "comment",
+ at.line as line,
+ at.message as message,
+ at.line_hash as lineHash,
+ at.rule_key as ruleKey
+ </sql>
+
+ <insert id="insert" useGeneratedKeys="false" parameterType="AnticipatedTransition">
+ INSERT INTO anticipated_transitions (uuid, project_uuid, user_uuid, transition, status,
+ transition_comment, line, message, line_hash, rule_key)
+ VALUES (#{uuid,jdbcType=VARCHAR}, #{projectUuid,jdbcType=VARCHAR}, #{userUuid,jdbcType=VARCHAR},
+ #{transition,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{comment,jdbcType=VARCHAR},
+ #{line,jdbcType=INTEGER}, #{message,jdbcType=VARCHAR}, #{lineHash,jdbcType=VARCHAR}, #{ruleKey,jdbcType=VARCHAR})
+ </insert>
+
+ <delete id="delete" parameterType="string">
+ delete from anticipated_transitions where uuid=#{uuid}
+ </delete>
+
+ <select id="selectByProjectUuid" parameterType="string" resultType="AnticipatedTransition">
+ select
+ <include refid="anticipatedTransitionsColumns"/>
+ from anticipated_transitions at
+ where at.project_uuid=#{projectUuid,jdbcType=VARCHAR}
+ </select>
+</mapper>
ALTER TABLE "ANALYSIS_PROPERTIES" ADD CONSTRAINT "PK_ANALYSIS_PROPERTIES" PRIMARY KEY("UUID");
CREATE INDEX "ANALYSIS_PROPERTIES_ANALYSIS" ON "ANALYSIS_PROPERTIES"("ANALYSIS_UUID" NULLS FIRST);
+CREATE TABLE "ANTICIPATED_TRANSITIONS"(
+ "UUID" CHARACTER VARYING(40) NOT NULL,
+ "PROJECT_UUID" CHARACTER VARYING(40) NOT NULL,
+ "USER_UUID" CHARACTER VARYING(255) NOT NULL,
+ "TRANSITION" CHARACTER VARYING(20) NOT NULL,
+ "STATUS" CHARACTER VARYING(20) NOT NULL,
+ "TRANSITION_COMMENT" CHARACTER VARYING(4000),
+ "LINE" INTEGER,
+ "MESSAGE" CHARACTER VARYING(4000),
+ "LINE_HASH" CHARACTER VARYING(255),
+ "RULE_KEY" CHARACTER VARYING(200) NOT NULL
+);
+ALTER TABLE "ANTICIPATED_TRANSITIONS" ADD CONSTRAINT "PK_ANTICIPATED_TRANSITIONS" PRIMARY KEY("UUID");
+
CREATE TABLE "APP_BRANCH_PROJECT_BRANCH"(
"UUID" CHARACTER VARYING(40) NOT NULL,
"APPLICATION_UUID" CHARACTER VARYING(40) NOT NULL,
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v102;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.step.CreateTableChange;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.USER_UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class CreateAnticipatedTransitionsTable extends CreateTableChange {
+ static final String ANTICIPATED_TRANSITIONS_TABLE_NAME = "anticipated_transitions";
+
+ public CreateAnticipatedTransitionsTable(Database db) {
+ super(db, ANTICIPATED_TRANSITIONS_TABLE_NAME);
+ }
+
+ @Override
+ public void execute(DdlChange.Context context, String tableName) throws SQLException {
+ context.execute(new CreateTableBuilder(getDialect(), tableName)
+ .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("project_uuid").setIsNullable(false).setLimit(UUID_SIZE).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("user_uuid").setIsNullable(false).setLimit(USER_UUID_SIZE).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("transition").setIsNullable(false).setLimit(20).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("status").setIsNullable(false).setLimit(20).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("transition_comment").setLimit(MAX_SIZE).build())
+ .addColumn(newIntegerColumnDefBuilder().setColumnName("line").build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("message").setLimit(MAX_SIZE).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("line_hash").setLimit(255).build())
+ .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_key").setIsNullable(false).setLimit(200).build())
+ .build());
+ }
+}
.add(10_2_027, "Populate column 'created_at_temp' in 'components' table", PopulateCreatedAtTempInComponents.class)
.add(10_2_028, "Drop column 'created_at' in 'components' table", DropCreatedAtInComponents.class)
.add(10_2_029, "Rename column 'created_at_temp' to 'created_at' in 'components' table", RenameCreatedAtTempInComponents.class)
- ;
+
+ .add(10_2_030, "Create table 'anticipated_transitions'", CreateAnticipatedTransitionsTable.class);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v102;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.USER_UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.version.v102.CreateAnticipatedTransitionsTable.ANTICIPATED_TRANSITIONS_TABLE_NAME;
+
+public class CreateAnticipatedTransitionsTableTest {
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createEmpty();
+
+ private final DdlChange createAnticipatedTransitionsTable = new CreateAnticipatedTransitionsTable(db.database());
+
+ @Test
+ public void migration_should_create_a_table() throws SQLException {
+ db.assertTableDoesNotExist(ANTICIPATED_TRANSITIONS_TABLE_NAME);
+
+ createAnticipatedTransitionsTable.execute();
+
+ db.assertTableExists(ANTICIPATED_TRANSITIONS_TABLE_NAME);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "uuid", Types.VARCHAR, UUID_SIZE, false);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "project_uuid", Types.VARCHAR, UUID_SIZE, false);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "user_uuid", Types.VARCHAR, USER_UUID_SIZE, false);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "transition", Types.VARCHAR, 20, false);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "status", Types.VARCHAR, 20, false);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "transition_comment", Types.VARCHAR, MAX_SIZE, true);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "line", Types.INTEGER, 11, true);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "message", Types.VARCHAR, MAX_SIZE, true);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "line_hash", Types.VARCHAR, 255, true);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "rule_key", Types.VARCHAR, 200, false);
+ db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "file_path", Types.VARCHAR, 1500, false);
+ db.assertPrimaryKey(ANTICIPATED_TRANSITIONS_TABLE_NAME, "pk_anticipated_transitions", "uuid");
+ }
+
+ @Test
+ public void migration_should_be_reentrant() throws SQLException {
+ db.assertTableDoesNotExist(ANTICIPATED_TRANSITIONS_TABLE_NAME);
+
+ createAnticipatedTransitionsTable.execute();
+ // re-entrant
+ createAnticipatedTransitionsTable.execute();
+
+ db.assertTableExists(ANTICIPATED_TRANSITIONS_TABLE_NAME);
+ }
+}