From ff98ac39bf0bfab4ef22db1e5cb2e85a91a4103e Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Tue, 17 Apr 2018 19:50:42 +0200 Subject: [PATCH] SONAR-10594 add RuleRepositoryDao#deleteIfKeyNotIn() --- .../org/sonar/db/rule/RuleRepositoryDao.java | 8 ++++ .../sonar/db/rule/RuleRepositoryMapper.java | 3 ++ .../sonar/db/rule/RuleRepositoryMapper.xml | 7 ++++ .../sonar/db/rule/RuleRepositoryDaoTest.java | 40 +++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryDao.java index 42aaceec67f..61b06e6ab3f 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryDao.java @@ -23,8 +23,11 @@ import java.util.Collection; import java.util.List; import org.sonar.api.utils.System2; import org.sonar.db.Dao; +import org.sonar.db.DatabaseUtils; import org.sonar.db.DbSession; +import static com.google.common.base.Preconditions.checkArgument; + public class RuleRepositoryDao implements Dao { private final System2 system2; @@ -71,4 +74,9 @@ public class RuleRepositoryDao implements Dao { } } } + + public void deleteIfKeyNotIn(DbSession dbSession, Collection keys) { + checkArgument(keys.size() < DatabaseUtils.PARTITION_SIZE_FOR_ORACLE, "too many rule repositories: %s", keys.size()); + dbSession.getMapper(RuleRepositoryMapper.class).deleteIfKeyNotIn(keys); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryMapper.java index d08a407e12e..a33adbcf3a0 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryMapper.java @@ -19,6 +19,7 @@ */ package org.sonar.db.rule; +import java.util.Collection; import java.util.List; import javax.annotation.CheckForNull; import org.apache.ibatis.annotations.Param; @@ -37,4 +38,6 @@ public interface RuleRepositoryMapper { void insert(@Param("repository") RuleRepositoryDto repository, @Param("now") long now); int update(@Param("repository") RuleRepositoryDto repository); + + void deleteIfKeyNotIn(@Param("keys") Collection keys); } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleRepositoryMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleRepositoryMapper.xml index 59941de82d2..d15ddce28dc 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleRepositoryMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleRepositoryMapper.xml @@ -41,4 +41,11 @@ where kee = #{repository.kee, jdbcType=VARCHAR} + + + delete from rule_repositories + + where kee not in #{key,jdbcType=VARCHAR} + + diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleRepositoryDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleRepositoryDaoTest.java index ede67de1dc3..8c711fa1a7a 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleRepositoryDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleRepositoryDaoTest.java @@ -19,21 +19,29 @@ */ package org.sonar.db.rule; +import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.sonar.api.utils.System2; import org.sonar.api.utils.internal.AlwaysIncreasingSystem2; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; public class RuleRepositoryDaoTest { private System2 system2 = new AlwaysIncreasingSystem2(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); @Rule public DbTester dbTester = DbTester.create(system2); @@ -81,6 +89,38 @@ public class RuleRepositoryDaoTest { .isLessThan(selectCreatedAtByKey(dbTester.getSession(), repo3.getKey())); } + @Test + public void deleteIfKeyNotIn() { + RuleRepositoryDto repo1 = new RuleRepositoryDto("findbugs", "java", "Findbugs"); + RuleRepositoryDto repo2 = new RuleRepositoryDto("sonarjava", "java", "SonarJava"); + RuleRepositoryDto repo3 = new RuleRepositoryDto("sonarcobol", "cobol", "SonarCobol"); + underTest.insertOrUpdate(dbTester.getSession(), asList(repo1, repo2, repo3)); + + underTest.deleteIfKeyNotIn(dbTester.getSession(), Arrays.asList(repo2.getKey(), "unknown")); + assertThat(underTest.selectAll(dbTester.getSession())) + .extracting(RuleRepositoryDto::getKey) + .containsExactly(repo2.getKey()); + } + + @Test + public void deleteIfKeyNotIn_truncates_table_if_keys_are_empty() { + RuleRepositoryDto repo1 = new RuleRepositoryDto("findbugs", "java", "Findbugs"); + RuleRepositoryDto repo2 = new RuleRepositoryDto("sonarjava", "java", "SonarJava"); + underTest.insertOrUpdate(dbTester.getSession(), asList(repo1, repo2)); + + underTest.deleteIfKeyNotIn(dbTester.getSession(), emptyList()); + + assertThat(underTest.selectAll(dbTester.getSession())).isEmpty(); + } + + @Test + public void deleteIfKeyNotIn_fails_if_more_than_1000_keys() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("too many rule repositories: 1100"); + + Collection keys = IntStream.range(0, 1_100).mapToObj(index -> "repo" + index).collect(Collectors.toSet()); + underTest.deleteIfKeyNotIn(dbTester.getSession(), keys); + } @Test public void test_insert_and_selectAll() { -- 2.39.5