diff options
Diffstat (limited to 'server/sonar-db-dao')
4 files changed, 100 insertions, 3 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java index 402e09abe5f..d7e24c7aa54 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java @@ -19,7 +19,6 @@ */ package org.sonar.db.component; -import com.google.common.annotations.VisibleForTesting; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -150,8 +149,7 @@ public class BranchDao implements Dao { return mapper(dbSession).updateMeasuresMigrated(branchUuid, measuresMigrated, now); } - @VisibleForTesting - boolean isMeasuresMigrated(DbSession dbSession, String uuid) { + public boolean isMeasuresMigrated(DbSession dbSession, String uuid) { return mapper(dbSession).isMeasuresMigrated(uuid); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/JsonMeasureDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/JsonMeasureDao.java index 49b9aa77b8b..d760cd38862 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/JsonMeasureDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/JsonMeasureDao.java @@ -37,10 +37,32 @@ public class JsonMeasureDao implements Dao { return mapper(dbSession).insert(dto, system2.now()); } + /** + * Update a measure. The measure json value will be overwritten. + */ public int update(DbSession dbSession, JsonMeasureDto dto) { return mapper(dbSession).update(dto, system2.now()); } + /** + * Unlike {@link #update(DbSession, JsonMeasureDto)}, this method will not overwrite the entire json value, + * but will update the measures inside the json. + */ + public int insertOrUpdate(DbSession dbSession, JsonMeasureDto dto) { + long now = system2.now(); + Optional<JsonMeasureDto> existingMeasureOpt = selectByComponentUuid(dbSession, dto.getComponentUuid()); + if (existingMeasureOpt.isPresent()) { + JsonMeasureDto existingDto = existingMeasureOpt.get(); + existingDto.getMetricValues().putAll(dto.getMetricValues()); + dto.getMetricValues().putAll(existingDto.getMetricValues()); + dto.computeJsonValueHash(); + return mapper(dbSession).update(dto, now); + } else { + dto.computeJsonValueHash(); + return mapper(dbSession).insert(dto, now); + } + } + public Optional<JsonMeasureDto> selectByComponentUuid(DbSession dbSession, String componentUuid) { return Optional.ofNullable(mapper(dbSession).selectByComponentUuid(componentUuid)); } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/BranchDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/BranchDaoTest.java index f11f90f271c..5c374541c90 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/BranchDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/BranchDaoTest.java @@ -712,6 +712,29 @@ public class BranchDaoTest { assertThat(underTest.isMeasuresMigrated(dbSession, uuid2)).isFalse(); } + @Test + public void isMeasuresMigrated() throws SQLException { + createMeasuresMigratedColumn(); + + // master branch with flag set to false + ComponentDto project = db.components().insertPrivateProject(); + // branches & PRs + ComponentDto branch1 = db.components().insertProjectBranch(project, b -> b.setBranchType(BRANCH)); + ComponentDto branch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); + ComponentDto branch3 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST)); + ComponentDto branch4 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST)); + + db.getDbClient().branchDao().updateMeasuresMigrated(dbSession, branch1.branchUuid(), true); + db.getDbClient().branchDao().updateMeasuresMigrated(dbSession, branch2.branchUuid(), false); + db.getDbClient().branchDao().updateMeasuresMigrated(dbSession, branch3.branchUuid(), true); + + assertThat(underTest.isMeasuresMigrated(dbSession, project.uuid())).isFalse(); + assertThat(underTest.isMeasuresMigrated(dbSession, branch1.uuid())).isTrue(); + assertThat(underTest.isMeasuresMigrated(dbSession, branch2.uuid())).isFalse(); + assertThat(underTest.isMeasuresMigrated(dbSession, branch3.uuid())).isTrue(); + assertThat(underTest.isMeasuresMigrated(dbSession, branch4.uuid())).isFalse(); + } + private void createMeasuresMigratedColumn() throws SQLException { AddMeasuresMigratedColumnToProjectBranchesTable migration = new AddMeasuresMigratedColumnToProjectBranchesTable(db.getDbClient().getDatabase()); migration.execute(); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/JsonMeasureDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/JsonMeasureDaoTest.java index f0b6d913c6b..3841aeeef9b 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/JsonMeasureDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/JsonMeasureDaoTest.java @@ -30,6 +30,7 @@ import org.sonar.server.platform.db.migration.adhoc.CreateIndexOnPortfoliosMeasu import org.sonar.server.platform.db.migration.adhoc.CreateIndexOnProjectBranchesMeasuresMigrated; import org.sonar.server.platform.db.migration.adhoc.CreateMeasuresTable; +import static java.util.Map.entry; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.db.measure.MeasureTesting.newJsonMeasure; @@ -73,6 +74,59 @@ public class JsonMeasureDaoTest { } @Test + public void insertOrUpdate_inserts_or_updates_measure() { + // insert + JsonMeasureDto dto = newJsonMeasure(); + int count = underTest.insertOrUpdate(db.getSession(), dto); + assertThat(count).isEqualTo(1); + verifyTableSize(1); + verifyPersisted(dto); + + // update + String key = dto.getMetricValues().keySet().stream().findFirst().orElseThrow(); + dto.addValue(key, 10d); + count = underTest.insertOrUpdate(db.getSession(), dto); + assertThat(count).isEqualTo(1); + verifyTableSize(1); + verifyPersisted(dto); + } + + @Test + public void insertOrUpdate_merges_measures() { + // insert + Double value2 = 10d; + JsonMeasureDto dto = newJsonMeasure(); + dto.getMetricValues().clear(); + dto.addValue("key1", 11d) + .addValue("key2", value2); + int count = underTest.insert(db.getSession(), dto); + verifyPersisted(dto); + verifyTableSize(1); + assertThat(count).isEqualTo(1); + + // update key1 value, remove key2 (must not disappear from DB) and add key3 + Double value1 = 12d; + Double value3 = 13d; + dto.addValue("key1", value1) + .addValue("key3", value3) + .getMetricValues().remove("key2"); + count = underTest.insertOrUpdate(db.getSession(), dto); + assertThat(count).isEqualTo(1); + verifyTableSize(1); + + assertThat(underTest.selectByComponentUuid(db.getSession(), dto.getComponentUuid())) + .hasValueSatisfying(selected -> { + assertThat(selected.getComponentUuid()).isEqualTo(dto.getComponentUuid()); + assertThat(selected.getBranchUuid()).isEqualTo(dto.getBranchUuid()); + assertThat(selected.getMetricValues()).contains( + entry("key1", value1), + entry("key2", value2), + entry("key3", value3)); + assertThat(selected.getJsonValueHash()).isEqualTo(dto.computeJsonValueHash()); + }); + } + + @Test public void select_measure() { JsonMeasureDto measure1 = newJsonMeasure(); JsonMeasureDto measure2 = newJsonMeasure(); |