"UUID" VARCHAR(40) NOT NULL,
"TASK_TYPE" VARCHAR(15) NOT NULL,
"COMPONENT_UUID" VARCHAR(40) NULL,
+ "MAIN_COMPONENT_UUID" VARCHAR(40) NULL,
"TMP_COMPONENT_UUID" VARCHAR(40) NULL,
"TMP_MAIN_COMPONENT_UUID" VARCHAR(40) NULL,
"STATUS" VARCHAR(15) NOT NULL,
"UPDATED_AT" BIGINT NOT NULL
);
CREATE UNIQUE INDEX "CE_QUEUE_UUID" ON "CE_QUEUE" ("UUID");
-CREATE INDEX "CE_QUEUE_COMPONENT_UUID" ON "CE_QUEUE" ("COMPONENT_UUID");
+CREATE INDEX "CE_QUEUE_COMPONENT" ON "CE_QUEUE" ("COMPONENT_UUID");
+CREATE INDEX "CE_QUEUE_MAIN_COMPONENT" ON "CE_QUEUE" ("MAIN_COMPONENT_UUID");
CREATE INDEX "CE_QUEUE_TMP_CPNT_UUID" ON "CE_QUEUE" ("TMP_COMPONENT_UUID");
CREATE INDEX "CE_QUEUE_TMP_MAIN_CPNT_UUID" ON "CE_QUEUE" ("TMP_MAIN_COMPONENT_UUID");
CREATE INDEX "CE_QUEUE_STATUS" ON "CE_QUEUE" ("STATUS");
"UUID" VARCHAR(40) NOT NULL,
"TASK_TYPE" VARCHAR(15) NOT NULL,
"COMPONENT_UUID" VARCHAR(40) NULL,
+ "MAIN_COMPONENT_UUID" VARCHAR(40) NULL,
"TMP_COMPONENT_UUID" VARCHAR(40) NULL,
"TMP_MAIN_COMPONENT_UUID" VARCHAR(40) NULL,
"ANALYSIS_UUID" VARCHAR(50) NULL,
"STATUS" VARCHAR(15) NOT NULL,
"IS_LAST" BOOLEAN,
"IS_LAST_KEY" VARCHAR(55),
+ "MAIN_IS_LAST" BOOLEAN,
+ "MAIN_IS_LAST_KEY" VARCHAR(55),
"TMP_IS_LAST" BOOLEAN,
"TMP_IS_LAST_KEY" VARCHAR(55),
"TMP_MAIN_IS_LAST" BOOLEAN,
"ERROR_TYPE" VARCHAR(20)
);
CREATE UNIQUE INDEX "CE_ACTIVITY_UUID" ON "CE_ACTIVITY" ("UUID");
+CREATE INDEX "CE_ACTIVITY_COMPONENT" ON "CE_ACTIVITY" ("COMPONENT_UUID");
+CREATE INDEX "CE_ACTIVITY_MAIN_COMPONENT" ON "CE_ACTIVITY" ("COMPONENT_UUID");
CREATE INDEX "CE_ACTIVITY_COMPONENT_UUID" ON "CE_ACTIVITY" ("COMPONENT_UUID");
CREATE INDEX "CE_ACTIVITY_TMP_CPNT_UUID" ON "CE_ACTIVITY" ("TMP_COMPONENT_UUID");
-CREATE INDEX "CE_ACTIVITY_TMP_MAIN_CPNT_UUID" ON "CE_ACTIVITY" ("TMP_MAIN_COMPONENT_UUID");
-CREATE INDEX "CE_ACTIVITY_ISLASTKEY" ON "CE_ACTIVITY" ("IS_LAST_KEY");
-CREATE INDEX "CE_ACTIVITY_ISLAST_STATUS" ON "CE_ACTIVITY" ("IS_LAST", "STATUS");
+CREATE INDEX "CE_ACTIVITY_ISLAST_KEY" ON "CE_ACTIVITY" ("IS_LAST_KEY");
+CREATE INDEX "CE_ACTIVITY_ISLAST" ON "CE_ACTIVITY" ("IS_LAST", "STATUS");
+CREATE INDEX "CE_ACTIVITY_MAIN_ISLAST_KEY" ON "CE_ACTIVITY" ("MAIN_IS_LAST_KEY");
+CREATE INDEX "CE_ACTIVITY_MAIN_ISLAST" ON "CE_ACTIVITY" ("MAIN_IS_LAST", "STATUS");
CREATE INDEX "CE_ACTIVITY_T_ISLAST_KEY" ON "CE_ACTIVITY" ("TMP_IS_LAST_KEY");
CREATE INDEX "CE_ACTIVITY_T_ISLAST" ON "CE_ACTIVITY" ("TMP_IS_LAST", "STATUS");
CREATE INDEX "CE_ACTIVITY_T_MAIN_ISLAST_KEY" ON "CE_ACTIVITY" ("TMP_MAIN_IS_LAST_KEY");
CeActivityMapper ceActivityMapper = mapper(dbSession);
if (isLast) {
- ceActivityMapper.clearIsLast(dto.getIsLastKey(), dto.getMainIsLastKey(), dto.getUpdatedAt());
+ ceActivityMapper.clearIsLast(dto.getIsLastKey(), dto.getUpdatedAt());
+ ceActivityMapper.clearMainIsLast(dto.getMainIsLastKey(), dto.getUpdatedAt());
}
ceActivityMapper.insert(dto);
}
void insert(CeActivityDto dto);
- void clearIsLast(@Param("isLastKey") String isLastKey, @Param("mainIsLastKey") String mainIsLastKey, @Param("updatedAt") long updatedAt);
+ void clearIsLast(@Param("isLastKey") String isLastKey, @Param("updatedAt") long updatedAt);
+
+ void clearMainIsLast(@Param("mainIsLastKey") String mainIsLastKey, @Param("updatedAt") long updatedAt);
void deleteByUuids(@Param("uuids") List<String> uuids);
}
ca.id,
ca.uuid,
ca.task_type as taskType,
- ca.tmp_component_uuid as componentUuid,
- ca.tmp_main_component_uuid as mainComponentUuid,
+ ca.component_uuid as componentUuid,
+ ca.main_component_uuid as mainComponentUuid,
ca.analysis_uuid as analysisUuid,
ca.status as status,
ca.submitter_uuid as submitterUuid,
ca.executed_at as executedAt,
ca.created_at as createdAt,
ca.updated_at as updatedAt,
- ca.tmp_is_last as isLast,
- ca.tmp_is_last_key as isLastKey,
- ca.tmp_main_is_last as mainIsLast,
- ca.tmp_main_is_last_key as mainIsLastKey,
+ ca.is_last as isLast,
+ ca.is_last_key as isLastKey,
+ ca.main_is_last as mainIsLast,
+ ca.main_is_last_key as mainIsLastKey,
ca.execution_time_ms as executionTimeMs,
ca.error_message as errorMessage,
ca.error_type as errorType,
left outer join ce_scanner_context csc on csc.task_uuid = ca.uuid
<where>
<if test="query.onlyCurrents">
- and ca.tmp_main_is_last=${_true}
+ and ca.main_is_last=${_true}
</if>
<if test="query.mainComponentUuids != null and query.mainComponentUuids.size()>0">
- and ca.tmp_main_component_uuid in
+ and ca.main_component_uuid in
<foreach collection="query.mainComponentUuids" open="(" close=")" item="cUuid" separator=",">
#{cUuid,jdbcType=VARCHAR}
</foreach>
from
ce_activity
where
- tmp_main_is_last=${_true}
+ main_is_last=${_true}
and status=#{status,jdbcType=VARCHAR}
<if test="mainComponentUuid!=null">
- and tmp_main_component_uuid=#{mainComponentUuid,jdbcType=VARCHAR}
+ and main_component_uuid=#{mainComponentUuid,jdbcType=VARCHAR}
</if>
</select>
<insert id="insert" parameterType="org.sonar.db.ce.CeActivityDto" useGeneratedKeys="false">
insert into ce_activity (
uuid,
+ component_uuid,
+ main_component_uuid,
tmp_component_uuid,
tmp_main_component_uuid,
analysis_uuid,
status,
task_type,
+ is_last,
+ is_last_key,
+ main_is_last,
+ main_is_last_key,
tmp_is_last,
tmp_is_last_key,
tmp_main_is_last,
#{uuid,jdbcType=VARCHAR},
#{componentUuid,jdbcType=VARCHAR},
#{mainComponentUuid,jdbcType=VARCHAR},
+ #{componentUuid,jdbcType=VARCHAR},
+ #{mainComponentUuid,jdbcType=VARCHAR},
#{analysisUuid,jdbcType=VARCHAR},
#{status,jdbcType=VARCHAR},
#{taskType,jdbcType=VARCHAR},
#{isLastKey,jdbcType=VARCHAR},
#{mainIsLast,jdbcType=BOOLEAN},
#{mainIsLastKey,jdbcType=VARCHAR},
+ #{isLast,jdbcType=BOOLEAN},
+ #{isLastKey,jdbcType=VARCHAR},
+ #{mainIsLast,jdbcType=BOOLEAN},
+ #{mainIsLastKey,jdbcType=VARCHAR},
#{submitterUuid,jdbcType=VARCHAR},
#{submittedAt,jdbcType=BIGINT},
#{workerUuid,jdbcType=VARCHAR},
<update id="clearIsLast" parameterType="map">
update ce_activity set
+ is_last=${_false},
+ updated_at=#{updatedAt,jdbcType=BIGINT}
+ where
+ is_last=${_true}
+ and is_last_key=#{isLastKey,jdbcType=VARCHAR}
+ </update>
+
+ <update id="clearMainIsLast" parameterType="map">
+ update ce_activity set
+ main_is_last=${_false},
tmp_is_last=${_false},
tmp_main_is_last=${_false},
updated_at=#{updatedAt,jdbcType=BIGINT}
where
- (tmp_is_last=${_true} and tmp_is_last_key=#{isLastKey,jdbcType=VARCHAR})
- or
- (tmp_main_is_last=${_true} and tmp_main_is_last_key=#{mainIsLastKey,jdbcType=VARCHAR})
+ main_is_last=${_true}
+ and main_is_last_key=#{mainIsLastKey,jdbcType=VARCHAR}
</update>
<delete id="deleteByUuids" parameterType="string">
<sql id="columns">
cq.uuid,
cq.task_type as taskType,
- cq.tmp_component_uuid as componentUuid,
- cq.tmp_main_component_uuid as mainComponentUuid,
+ cq.component_uuid as componentUuid,
+ cq.main_component_uuid as mainComponentUuid,
cq.status as status,
cq.submitter_uuid as submitterUuid,
cq.worker_uuid as workerUuid,
where
status=#{status,jdbcType=VARCHAR}
<if test="mainComponentUuid!=null">
- and tmp_main_component_uuid=#{mainComponentUuid,jdbcType=VARCHAR}
+ and main_component_uuid=#{mainComponentUuid,jdbcType=VARCHAR}
</if>
</select>
<select id="countByStatusAndMainComponentUuids" resultType="org.sonar.db.ce.QueueCount">
select
- tmp_main_component_uuid as mainComponentUuid,
+ main_component_uuid as mainComponentUuid,
count(1) as total
from
ce_queue
where
status=#{status,jdbcType=VARCHAR}
- and tmp_main_component_uuid in
+ and main_component_uuid in
<foreach collection="mainComponentUuids" open="(" close=")" item="mainComponentUuid" separator=",">
#{mainComponentUuid,jdbcType=VARCHAR}
</foreach>
- group by tmp_main_component_uuid
+ group by main_component_uuid
</select>
<select id="countAll" resultType="int">
from
ce_queue cq
where
- cq.tmp_main_component_uuid=#{mainComponentUuid,jdbcType=VARCHAR}
+ cq.main_component_uuid=#{mainComponentUuid,jdbcType=VARCHAR}
<include refid="orderByDateAndId"/>
</select>
ce_queue cq
<where>
<if test="query.mainComponentUuids != null and query.mainComponentUuids.size()>0">
- and cq.tmp_main_component_uuid in
+ and cq.main_component_uuid in
<foreach collection="query.mainComponentUuids" open="(" close=")" item="mainComponentUuid" separator=",">
#{mainComponentUuid,jdbcType=VARCHAR}
</foreach>
from
ce_queue cq2
where
- cq.tmp_main_component_uuid=cq2.tmp_main_component_uuid
+ cq.main_component_uuid=cq2.main_component_uuid
and cq2.status <> 'PENDING'
)
</sql>
(
uuid,
task_type,
+ component_uuid,
+ main_component_uuid,
tmp_component_uuid,
tmp_main_component_uuid,
status,
#{taskType,jdbcType=VARCHAR},
#{componentUuid,jdbcType=VARCHAR},
#{mainComponentUuid,jdbcType=VARCHAR},
+ #{componentUuid,jdbcType=VARCHAR},
+ #{mainComponentUuid,jdbcType=VARCHAR},
#{status,jdbcType=VARCHAR},
#{submitterUuid,jdbcType=VARCHAR},
0,
<delete id="deleteCeScannerContextOfCeActivityByProjectUuid">
delete from ce_scanner_context
where
- task_uuid in (select uuid from ce_activity where tmp_main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
+ task_uuid in (select uuid from ce_activity where main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
</delete>
<delete id="deleteCeTaskCharacteristicsOfCeActivityByProjectUuid">
delete from ce_task_characteristics
where
- task_uuid in (select uuid from ce_activity where tmp_main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
+ task_uuid in (select uuid from ce_activity where main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
</delete>
<delete id="deleteCeTaskInputOfCeActivityByProjectUuid">
delete from ce_task_input
where
- task_uuid in (select uuid from ce_activity where tmp_main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
+ task_uuid in (select uuid from ce_activity where main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
</delete>
<delete id="deleteCeActivityByProjectUuid">
- delete from ce_activity where tmp_main_component_uuid=#{projectUuid,jdbcType=VARCHAR}
+ delete from ce_activity where main_component_uuid=#{projectUuid,jdbcType=VARCHAR}
</delete>
<delete id="deleteCeScannerContextOfCeQueueByProjectUuid">
delete from ce_scanner_context
where
- task_uuid in (select uuid from ce_queue where tmp_main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
+ task_uuid in (select uuid from ce_queue where main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
</delete>
<delete id="deleteCeTaskCharacteristicsOfCeQueueByProjectUuid">
delete from ce_task_characteristics
where
- task_uuid in (select uuid from ce_queue where tmp_main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
+ task_uuid in (select uuid from ce_queue where main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
</delete>
<delete id="deleteCeTaskInputOfCeQueueByProjectUuid">
delete from ce_task_input
where
- task_uuid in (select uuid from ce_queue where tmp_main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
+ task_uuid in (select uuid from ce_queue where main_component_uuid=#{projectUuid,jdbcType=VARCHAR})
</delete>
<delete id="deleteCeQueueByProjectUuid">
- delete from ce_queue where tmp_main_component_uuid=#{projectUuid,jdbcType=VARCHAR}
+ delete from ce_queue where main_component_uuid=#{projectUuid,jdbcType=VARCHAR}
</delete>
<delete id="deleteWebhooksByProjectUuid">
import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.assertj.core.api.AbstractListAssert;
+import org.assertj.core.api.ObjectAssert;
+import org.assertj.core.groups.Tuple;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.sonar.api.utils.internal.TestSystem2;
import org.sonar.core.util.CloseableIterator;
+import org.sonar.core.util.UuidFactoryFast;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import static java.util.Collections.singletonList;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
import static org.sonar.db.Pagination.forPage;
+import static org.sonar.db.ce.CeActivityDto.Status.CANCELED;
import static org.sonar.db.ce.CeActivityDto.Status.FAILED;
import static org.sonar.db.ce.CeActivityDto.Status.SUCCESS;
import static org.sonar.db.ce.CeQueueDto.Status.PENDING;
import static org.sonar.db.ce.CeQueueTesting.makeInProgress;
import static org.sonar.db.ce.CeTaskTypes.REPORT;
+@RunWith(DataProviderRunner.class)
public class CeActivityDaoTest {
private static final String MAINCOMPONENT_1 = randomAlphabetic(12);
assertThat(dto.isHasScannerContext()).isFalse();
}
+ @Test
+ @UseDataProvider("notCanceledStatus")
+ public void insert_resets_is_last_and_main_is_last_fields_based_on_component_and_main_component(CeActivityDto.Status status) {
+ String project1 = randomAlphabetic(5);
+ String branch11 = randomAlphabetic(6);
+ String project2 = randomAlphabetic(8);
+ String branch21 = randomAlphabetic(9);
+ String type = randomAlphabetic(10);
+
+ String task1Project1 = insertAndCommit(newUuid(), type, project1, project1, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(true, true));
+
+ String task2Project1 = insertAndCommit(newUuid(), type, project1, project1, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, true));
+
+ String task1Branch11 = insertAndCommit(newUuid(), type, branch11, project1, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(true, true));
+
+ String task2Branch11 = insertAndCommit(newUuid(), type, branch11, project1, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, true));
+
+ String task1Project2 = insertAndCommit(newUuid(), type, project2, project2, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, true));
+
+ String task2Project2 = insertAndCommit(newUuid(), type, project2, project2, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project2).containsOnly(tuple(true, true));
+
+ String task1Branch21 = insertAndCommit(newUuid(), type, branch21, project2, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project2).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch21).containsOnly(tuple(true, true));
+
+ String task3project1 = insertAndCommit(newUuid(), type, project1, project1, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task2Project2).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch21).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(task3project1).containsOnly(tuple(true, true));
+ }
+
+ @Test
+ @UseDataProvider("notCanceledStatus")
+ public void insert_resets_is_last_and_main_is_last_fields_based_on_type(CeActivityDto.Status status) {
+ String type1 = randomAlphabetic(10);
+ String type2 = randomAlphabetic(11);
+ String project = randomAlphabetic(5);
+ String branch = randomAlphabetic(6);
+
+ String type1Project1 = insertAndCommit(newUuid(), type1, project, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
+
+ String type2Project1 = insertAndCommit(newUuid(), type2, project, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(true, true));
+
+ String type2Project2 = insertAndCommit(newUuid(), type2, project, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type2Project2).containsOnly(tuple(true, true));
+
+ String type1Branch1 = insertAndCommit(newUuid(), type1, branch, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type2Project2).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type1Branch1).containsOnly(tuple(true, true));
+
+ String type2Branch1 = insertAndCommit(newUuid(), type2, branch, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type2Project2).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(type1Branch1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type2Branch1).containsOnly(tuple(true, true));
+
+ String type2Branch2 = insertAndCommit(newUuid(), type2, branch, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type2Project2).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(type1Branch1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type2Branch1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type2Branch2).containsOnly(tuple(true, true));
+ }
+
+ @Test
+ @UseDataProvider("notCanceledStatus")
+ public void insert_resets_is_last_and_main_is_last_fields_based_on_component_or_not(CeActivityDto.Status status) {
+ String project = randomAlphabetic(5);
+ String type1 = randomAlphabetic(11);
+ String type2 = randomAlphabetic(11);
+
+ String type1Project1 = insertAndCommit(newUuid(), type1, project, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
+
+ String type1NoProject1 = insertAndCommit(newUuid(), type1, null, null, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(true, true));
+
+ String type1NoProject2 = insertAndCommit(newUuid(), type1, null, null, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject2).containsOnly(tuple(true, true));
+
+ String type2NoProject1 = insertAndCommit(newUuid(), type2, null, null, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject2).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type2NoProject1).containsOnly(tuple(true, true));
+
+ String type2NoProject2 = insertAndCommit(newUuid(), type2, null, null, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject2).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type2NoProject1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type2NoProject2).containsOnly(tuple(true, true));
+
+ String type1Project2 = insertAndCommit(newUuid(), type1, project, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type1NoProject2).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type2NoProject1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(type2NoProject2).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(type1Project2).containsOnly(tuple(true, true));
+ }
+
+ @Test
+ @UseDataProvider("notCanceledStatus")
+ public void insert_does_not_resets_is_last_and_main_is_last_fields_if_status_is_CANCELED(CeActivityDto.Status status) {
+ String project = randomAlphabetic(5);
+ String branch = randomAlphabetic(6);
+ String type = randomAlphabetic(10);
+
+ String task1Project1 = insertAndCommit(newUuid(), type, project, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(true, true));
+
+ String task1Project2 = insertAndCommit(newUuid(), type, project, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, true));
+
+ String task1Project3 = insertAndCommit(newUuid(), type, project, project, CANCELED).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(task1Project3).containsOnly(tuple(false, false));
+
+ String task1Branch1 = insertAndCommit(newUuid(), type, branch, project, status).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Project3).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch1).containsOnly(tuple(true, true));
+
+ String task1Branch2 = insertAndCommit(newUuid(), type, branch, project, CANCELED).getUuid();
+ assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Project3).containsOnly(tuple(false, false));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch1).containsOnly(tuple(true, true));
+ assertIsLastAndMainIsLastFieldsOf(task1Branch2).containsOnly(tuple(false, false));
+ }
+
+ @DataProvider
+ public static Object[][] notCanceledStatus() {
+ return Arrays.stream(CeActivityDto.Status.values())
+ .filter(t -> t != CANCELED)
+ .map(t -> new Object[] {t})
+ .toArray(Object[][]::new);
+ }
+
+ private AbstractListAssert<?, List<? extends Tuple>, Tuple, ObjectAssert<Tuple>> assertIsLastAndMainIsLastFieldsOf(String taskUuid) {
+ return assertThat(db.select("select is_last as \"IS_LAST\", main_is_last as \"MAIN_IS_LAST\" from ce_activity where uuid='" + taskUuid + "'"))
+ .extracting(t -> (Boolean) t.get("IS_LAST"), t -> (Boolean) t.get("MAIN_IS_LAST"));
+ }
+
@Test
public void test_insert_of_errorMessage_of_1_000_chars() {
CeActivityDto dto = createActivityDto("TASK_1", REPORT, COMPONENT_1, MAINCOMPONENT_1, CeActivityDto.Status.FAILED)
return insert(uuid, type, mainComponentUuid, mainComponentUuid, status);
}
- private CeActivityDto insert(String uuid, String type, String componentUuid, @Nullable String mainComponentUuid, CeActivityDto.Status status) {
+ private CeActivityDto insertAndCommit(String uuid, String type, @Nullable String componentUuid, @Nullable String mainComponentUuid, CeActivityDto.Status status) {
+ CeActivityDto res = insert(uuid, type, componentUuid, mainComponentUuid, status);
+ db.commit();
+ return res;
+ }
+
+ private CeActivityDto insert(String uuid, String type, @Nullable String componentUuid, @Nullable String mainComponentUuid, CeActivityDto.Status status) {
CeActivityDto dto = createActivityDto(uuid, type, componentUuid, mainComponentUuid, status);
underTest.insert(db.getSession(), dto);
return dto;
return input.getUuid();
}
}
+
+ private static String newUuid() {
+ return UuidFactoryFast.getInstance().create();
+ }
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+import org.sonar.server.platform.db.migration.def.BooleanColumnDef;
+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.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+@SupportsBlueGreen
+public class AddLastKeyColumnsToCeActivity extends DdlChange {
+ private static final String TABLE_NAME = "ce_activity";
+ private static final int TASK_TYPE_COLUMN_SIZE = 15;
+ private static final BooleanColumnDef COLUMN_IS_LAST = newBooleanColumnDefBuilder()
+ .setColumnName("is_last")
+ .setIsNullable(true)
+ .build();
+ private static final VarcharColumnDef COLUMN_IS_LAST_KEY = newVarcharColumnDefBuilder()
+ .setColumnName("is_last_key")
+ .setLimit(UUID_SIZE + TASK_TYPE_COLUMN_SIZE)
+ .setIsNullable(true)
+ .build();
+ private static final BooleanColumnDef COLUMN_MAIN_IS_LAST = newBooleanColumnDefBuilder()
+ .setColumnName("main_is_last")
+ .setIsNullable(true)
+ .build();
+ private static final VarcharColumnDef COLUMN_MAIN_IS_LAST_KEY = newVarcharColumnDefBuilder()
+ .setColumnName("main_is_last_key")
+ .setLimit(UUID_SIZE + TASK_TYPE_COLUMN_SIZE)
+ .setIsNullable(true)
+ .build();
+ private static final VarcharColumnDef COLUMN_STATUS = newVarcharColumnDefBuilder()
+ .setColumnName("status")
+ .setLimit(15)
+ .setIsNullable(false)
+ .build();
+
+ public AddLastKeyColumnsToCeActivity(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ // drop existing column with wrong values
+ context.execute(new DropIndexBuilder(getDialect())
+ .setTable(TABLE_NAME)
+ .setName("ce_activity_islastkey")
+ .build());
+ context.execute(new DropIndexBuilder(getDialect())
+ .setTable(TABLE_NAME)
+ .setName("ce_activity_islast_status")
+ .build());
+ context.execute(new DropColumnsBuilder(getDialect(), TABLE_NAME, COLUMN_IS_LAST.getName(), COLUMN_IS_LAST_KEY.getName())
+ .build());
+
+
+ context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME)
+ .addColumn(COLUMN_IS_LAST)
+ .addColumn(COLUMN_IS_LAST_KEY)
+ .addColumn(COLUMN_MAIN_IS_LAST)
+ .addColumn(COLUMN_MAIN_IS_LAST_KEY)
+ .build());
+
+ // create indexes
+ context.execute(new CreateIndexBuilder(getDialect())
+ .setTable(TABLE_NAME)
+ .setName(TABLE_NAME + "_islast_key")
+ .addColumn(COLUMN_IS_LAST_KEY)
+ .setUnique(false)
+ .build());
+ context.execute(new CreateIndexBuilder(getDialect())
+ .setTable(TABLE_NAME)
+ .setName(TABLE_NAME + "_islast")
+ .addColumn(COLUMN_IS_LAST)
+ .addColumn(COLUMN_STATUS)
+ .setUnique(false)
+ .build());
+ context.execute(new CreateIndexBuilder(getDialect())
+ .setTable(TABLE_NAME)
+ .setName(TABLE_NAME + "_main_islast_key")
+ .addColumn(COLUMN_MAIN_IS_LAST_KEY)
+ .setUnique(false)
+ .build());
+ context.execute(new CreateIndexBuilder(getDialect())
+ .setTable(TABLE_NAME)
+ .setName(TABLE_NAME + "_main_islast")
+ .addColumn(COLUMN_MAIN_IS_LAST)
+ .addColumn(COLUMN_STATUS)
+ .setUnique(false)
+ .build());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+
+@SupportsBlueGreen
+public class AddMainComponentUuidColumnsToCeActivity extends AddMainComponentUuidColumnsToCeTable {
+
+ public AddMainComponentUuidColumnsToCeActivity(Database db) {
+ super(db, "ce_activity");
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+
+@SupportsBlueGreen
+public class AddMainComponentUuidColumnsToCeQueue extends AddMainComponentUuidColumnsToCeTable {
+
+ public AddMainComponentUuidColumnsToCeQueue(Database db) {
+ super(db, "ce_queue");
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+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.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public abstract class AddMainComponentUuidColumnsToCeTable extends DdlChange {
+ private static final VarcharColumnDef COLUMN_COMPONENT_UUID = newVarcharColumnDefBuilder()
+ .setColumnName("component_uuid")
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .setIsNullable(true)
+ .build();
+ private static final VarcharColumnDef COLUMN_MAIN_COMPONENT_UUID = newVarcharColumnDefBuilder()
+ .setColumnName("main_component_uuid")
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .setIsNullable(true)
+ .build();
+ private final String tableName;
+
+ AddMainComponentUuidColumnsToCeTable(Database db, String tableName) {
+ super(db);
+ this.tableName = tableName;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ // drop existing column with wrong values
+ context.execute(new DropIndexBuilder(getDialect())
+ .setTable(tableName)
+ .setName(tableName + "_component_uuid")
+ .build());
+ context.execute(new DropColumnsBuilder(getDialect(), tableName, COLUMN_COMPONENT_UUID.getName())
+ .build());
+
+ // add new columns
+ context.execute(new AddColumnsBuilder(getDialect(), tableName)
+ .addColumn(COLUMN_COMPONENT_UUID)
+ .addColumn(COLUMN_MAIN_COMPONENT_UUID)
+ .build());
+
+ // create indexes
+ context.execute(new CreateIndexBuilder(getDialect())
+ .setTable(tableName)
+ .setName(tableName + "_component")
+ .addColumn(COLUMN_COMPONENT_UUID)
+ .setUnique(false)
+ .build());
+ context.execute(new CreateIndexBuilder(getDialect())
+ .setTable(tableName)
+ .setName(tableName + "_main_component")
+ .addColumn(COLUMN_MAIN_COMPONENT_UUID)
+ .setUnique(false)
+ .build());
+ }
+}
.add(2309, "Add CE_ACTIVITY.MAIN_LAST_KEY 1/6", AddTmpLastKeyColumnsToCeActivity.class)
.add(2310, "Populate CE_ACTIVITY.MAIN_LAST_KEY 2/6", PopulateTmpLastKeyColumnsToCeActivity.class)
.add(2311, "Populate CE_ACTIVITY.MAIN_LAST_KEY 3/6", MakeCeActivityLastKeyColumnsNullable.class)
+ .add(2312, "Add CE_QUEUE.MAIN_COMPONENT_UUID 3/5", AddMainComponentUuidColumnsToCeQueue.class)
+ .add(2313, "Add CE_ACTIVITY.MAIN_COMPONENT_UUID 3/5", AddMainComponentUuidColumnsToCeActivity.class)
+ .add(2314, "Add CE_ACTIVITY.MAIN_LAST_KEY 3/6", AddLastKeyColumnsToCeActivity.class)
+ .add(2315, "Populate CE_QUEUE.MAIN_COMPONENT_UUID 4/5", PopulateMainComponentUuidColumnsToCeQueue.class)
+ .add(2316, "Populate CE_ACTIVITY.MAIN_COMPONENT_UUID 4/5", PopulateMainComponentUuidColumnsToCeActivity.class)
+ .add(2317, "Populate CE_ACTIVITY.MAIN_LAST_KEY 4/6", PopulateLastKeyColumnsToCeActivity.class)
;
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import java.sql.SQLException;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+import org.sonar.server.platform.db.migration.step.Select;
+import org.sonar.server.platform.db.migration.step.SqlStatement;
+
+@SupportsBlueGreen
+public class PopulateLastKeyColumnsToCeActivity extends DataChange {
+ private static final String TABLE_NAME = "ce_activity";
+
+ private final Configuration configuration;
+
+ public PopulateLastKeyColumnsToCeActivity(Database db, Configuration configuration) {
+ super(db);
+ this.configuration = configuration;
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+ if (configuration.getBoolean("sonar.sonarcloud.enabled").orElse(false)) {
+ // data migration will be done in background so that interruption of service
+ // is reduced during upgrade
+ return;
+ }
+
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("select" +
+ " ca.uuid, ca.tmp_is_last, ca.tmp_is_last_key, ca.tmp_main_is_last, ca.tmp_main_is_last_key" +
+ " from ce_activity ca" +
+ " where" +
+ " ca.is_last is null" +
+ " or ca.is_last_key is null" +
+ " or ca.main_is_last is null" +
+ " or ca.main_is_last_key is null");
+ massUpdate.rowPluralName("rows of " + TABLE_NAME);
+ massUpdate.update("update " + TABLE_NAME + " set is_last=?, is_last_key=?, main_is_last=?, main_is_last_key=? where uuid=?");
+ massUpdate.execute(PopulateLastKeyColumnsToCeActivity::handleUpdate);
+ }
+
+ private static boolean handleUpdate(Select.Row row, SqlStatement update) throws SQLException {
+ String uuid = row.getString(1);
+ boolean isLast = row.getBoolean(2);
+ String isLastKey = row.getString(3);
+ boolean mainIsLast = row.getBoolean(2);
+ String mainIsLastKey = row.getString(3);
+
+ update.setBoolean(1, isLast);
+ update.setString(2, isLastKey);
+ update.setBoolean(3, mainIsLast);
+ update.setString(4, mainIsLastKey);
+ update.setString(5, uuid);
+
+ return true;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import java.sql.SQLException;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+
+@SupportsBlueGreen
+public class PopulateMainComponentUuidColumnsToCeActivity extends PopulateMainComponentUuidColumnsToCeTable {
+ private final Configuration configuration;
+
+ public PopulateMainComponentUuidColumnsToCeActivity(Database db, Configuration configuration) {
+ super(db, "ce_activity");
+ this.configuration = configuration;
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+ if (configuration.getBoolean("sonar.sonarcloud.enabled").orElse(false)) {
+ // data migration will be done in background so that interruption of service
+ // is reduced during upgrade
+ return;
+ }
+
+ super.execute(context);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+
+@SupportsBlueGreen
+public class PopulateMainComponentUuidColumnsToCeQueue extends PopulateMainComponentUuidColumnsToCeTable {
+
+ public PopulateMainComponentUuidColumnsToCeQueue(Database db) {
+ super(db, "ce_queue");
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+import org.sonar.server.platform.db.migration.step.Select;
+import org.sonar.server.platform.db.migration.step.SqlStatement;
+
+public abstract class PopulateMainComponentUuidColumnsToCeTable extends DataChange {
+ protected final String tableName;
+
+ PopulateMainComponentUuidColumnsToCeTable(Database db, String tableName) {
+ super(db);
+ this.tableName = tableName;
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("select" +
+ " c.uuid, c.tmp_component_uuid, c.tmp_main_component_uuid" +
+ " from " + tableName + " c" +
+ " where" +
+ " c.tmp_component_uuid is not null" +
+ " and (c.component_uuid is null or c.main_component_uuid is null)");
+ massUpdate.rowPluralName("tasks with component");
+ massUpdate.update("update " + tableName + " set component_uuid=?, main_component_uuid=? where uuid=?");
+ massUpdate.execute(PopulateMainComponentUuidColumnsToCeTable::handleUpdate);
+ }
+
+ private static boolean handleUpdate(Select.Row row, SqlStatement update) throws SQLException {
+ String uuid = row.getString(1);
+ String componentUuuid = row.getString(2);
+ String mainComponentUuuid = row.getString(3);
+
+ update.setString(1, componentUuuid);
+ update.setString(2, mainComponentUuuid);
+ update.setString(3, uuid);
+
+ return true;
+ }
+}
@Test
public void verify_migration_count() {
- verifyMigrationCount(underTest, 12);
+ verifyMigrationCount(underTest, 18);
}
}
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.DbClient;
-import org.sonar.server.platform.db.migration.version.v74.PopulateTmpColumnsToCeActivity;
-import org.sonar.server.platform.db.migration.version.v74.PopulateTmpColumnsToCeQueue;
-import org.sonar.server.platform.db.migration.version.v74.PopulateTmpLastKeyColumnsToCeActivity;
+import org.sonar.server.platform.db.migration.version.v74.PopulateLastKeyColumnsToCeActivity;
+import org.sonar.server.platform.db.migration.version.v74.PopulateMainComponentUuidColumnsToCeActivity;
+import org.sonar.server.platform.db.migration.version.v74.PopulateMainComponentUuidColumnsToCeQueue;
import org.sonar.server.user.UserSession;
public class MigrateDataAction implements SystemWsAction {
userSession.isSystemAdministrator();
Configuration emptyConfiguration = new MapSettings().asConfig();
- new PopulateTmpColumnsToCeQueue(dbClient.getDatabase()).execute();
- new PopulateTmpColumnsToCeActivity(dbClient.getDatabase(), emptyConfiguration).execute();
- new PopulateTmpLastKeyColumnsToCeActivity(dbClient.getDatabase(), emptyConfiguration).execute();
+ new PopulateMainComponentUuidColumnsToCeQueue(dbClient.getDatabase()).execute();
+ new PopulateMainComponentUuidColumnsToCeActivity(dbClient.getDatabase(), emptyConfiguration).execute();
+ new PopulateLastKeyColumnsToCeActivity(dbClient.getDatabase(), emptyConfiguration).execute();
LOG.info("done");
response.noContent();