@@ -21,6 +21,7 @@ package org.sonar.db.rule; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import java.util.Set; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.Dao; | |||
import org.sonar.db.DatabaseUtils; | |||
@@ -44,6 +45,10 @@ public class RuleRepositoryDao implements Dao { | |||
return dbSession.getMapper(RuleRepositoryMapper.class).selectAll(); | |||
} | |||
public Set<String> selectAllKeys(DbSession dbSession) { | |||
return dbSession.getMapper(RuleRepositoryMapper.class).selectAllKeys(); | |||
} | |||
/** | |||
* @return a non-null list ordered by key (as implemented by database, order may | |||
* depend on case sensitivity) | |||
@@ -52,14 +57,18 @@ public class RuleRepositoryDao implements Dao { | |||
return dbSession.getMapper(RuleRepositoryMapper.class).selectByLanguage(language); | |||
} | |||
public void insertOrUpdate(DbSession dbSession, Collection<RuleRepositoryDto> dtos) { | |||
public void insert(DbSession dbSession, Collection<RuleRepositoryDto> dtos) { | |||
RuleRepositoryMapper mapper = dbSession.getMapper(RuleRepositoryMapper.class); | |||
long now = system2.now(); | |||
for (RuleRepositoryDto dto : dtos) { | |||
int updated = mapper.update(dto); | |||
if (updated == 0) { | |||
mapper.insert(dto, now); | |||
} | |||
mapper.insert(dto, now); | |||
} | |||
} | |||
public void update(DbSession dbSession, Collection<RuleRepositoryDto> dtos) { | |||
RuleRepositoryMapper mapper = dbSession.getMapper(RuleRepositoryMapper.class); | |||
for (RuleRepositoryDto dto : dtos) { | |||
mapper.update(dto); | |||
} | |||
} | |||
@@ -21,6 +21,7 @@ package org.sonar.db.rule; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import java.util.Set; | |||
import javax.annotation.CheckForNull; | |||
import org.apache.ibatis.annotations.Param; | |||
@@ -28,6 +29,8 @@ public interface RuleRepositoryMapper { | |||
List<RuleRepositoryDto> selectAll(); | |||
Set<String> selectAllKeys(); | |||
List<RuleRepositoryDto> selectByLanguage(@Param("language") String language); | |||
@CheckForNull | |||
@@ -35,7 +38,7 @@ public interface RuleRepositoryMapper { | |||
void insert(@Param("repository") RuleRepositoryDto repository, @Param("now") long now); | |||
int update(@Param("repository") RuleRepositoryDto repository); | |||
void update(@Param("repository") RuleRepositoryDto repository); | |||
void deleteIfKeyNotIn(@Param("keys") Collection<String> keys); | |||
} |
@@ -13,6 +13,11 @@ | |||
order by kee | |||
</select> | |||
<select id="selectAllKeys" resultType="String"> | |||
select kee | |||
from rule_repositories | |||
</select> | |||
<select id="selectByLanguage" parameterType="String" resultType="org.sonar.db.rule.RuleRepositoryDto"> | |||
select <include refid="sqlColumns"/> | |||
from rule_repositories |
@@ -48,11 +48,11 @@ public class RuleRepositoryDaoTest { | |||
private RuleRepositoryDao underTest = new RuleRepositoryDao(system2); | |||
@Test | |||
public void insertOrUpdate_insert_rows_that_do_not_exist() { | |||
public void insert_insert_rows_that_do_not_exist() { | |||
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.insert(dbTester.getSession(), asList(repo1, repo2, repo3)); | |||
List<RuleRepositoryDto> rows = underTest.selectAll(dbTester.getSession()); | |||
assertThat(rows).hasSize(3); | |||
@@ -67,15 +67,16 @@ public class RuleRepositoryDaoTest { | |||
} | |||
@Test | |||
public void insertOrUpdate_update_rows_that_exist() { | |||
public void update_update_rows_that_exist() { | |||
RuleRepositoryDto repo1 = new RuleRepositoryDto("findbugs", "java", "Findbugs"); | |||
RuleRepositoryDto repo2 = new RuleRepositoryDto("sonarjava", "java", "SonarJava"); | |||
underTest.insertOrUpdate(dbTester.getSession(), asList(repo1, repo2)); | |||
underTest.insert(dbTester.getSession(), asList(repo1, repo2)); | |||
// update sonarjava, insert sonarcobol | |||
RuleRepositoryDto repo2bis = new RuleRepositoryDto("sonarjava", "java", "SonarJava"); | |||
RuleRepositoryDto repo3 = new RuleRepositoryDto("sonarcobol", "cobol", "SonarCobol"); | |||
underTest.insertOrUpdate(dbTester.getSession(), asList(repo2bis, repo3)); | |||
underTest.update(dbTester.getSession(), asList(repo2bis)); | |||
underTest.insert(dbTester.getSession(), asList(repo3)); | |||
List<RuleRepositoryDto> rows = underTest.selectAll(dbTester.getSession()); | |||
assertThat(rows).hasSize(3); | |||
@@ -94,7 +95,7 @@ public class RuleRepositoryDaoTest { | |||
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.insert(dbTester.getSession(), asList(repo1, repo2, repo3)); | |||
underTest.deleteIfKeyNotIn(dbTester.getSession(), Arrays.asList(repo2.getKey(), "unknown")); | |||
assertThat(underTest.selectAll(dbTester.getSession())) | |||
@@ -106,7 +107,7 @@ public class RuleRepositoryDaoTest { | |||
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.insert(dbTester.getSession(), asList(repo1, repo2)); | |||
underTest.deleteIfKeyNotIn(dbTester.getSession(), emptyList()); | |||
@@ -128,18 +129,29 @@ public class RuleRepositoryDaoTest { | |||
RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugs"); | |||
RuleRepositoryDto dto2 = new RuleRepositoryDto("squid", "java", "Java"); | |||
RuleRepositoryDto dto3 = new RuleRepositoryDto("cobol-lint", "cobol", "Cobol Lint"); | |||
underTest.insertOrUpdate(dbSession, asList(dto1, dto2, dto3)); | |||
underTest.insert(dbSession, asList(dto1, dto2, dto3)); | |||
assertThat(underTest.selectByLanguage(dbSession, "java")).extracting(RuleRepositoryDto::getKey) | |||
// ordered by key | |||
.containsExactly("findbugs", "squid"); | |||
} | |||
@Test | |||
public void selectAllKeys() { | |||
DbSession dbSession = dbTester.getSession(); | |||
RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugs"); | |||
RuleRepositoryDto dto2 = new RuleRepositoryDto("squid", "java", "Java"); | |||
RuleRepositoryDto dto3 = new RuleRepositoryDto("cobol-lint", "cobol", "Cobol Lint"); | |||
underTest.insert(dbSession, asList(dto1, dto2, dto3)); | |||
assertThat(underTest.selectAllKeys(dbSession)).containsOnly("findbugs", "squid", "cobol-lint"); | |||
} | |||
@Test | |||
public void selectByLanguage_returns_empty_list_if_no_results() { | |||
DbSession dbSession = dbTester.getSession(); | |||
RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugs"); | |||
underTest.insertOrUpdate(dbSession, asList(dto1)); | |||
underTest.insert(dbSession, asList(dto1)); | |||
assertThat(underTest.selectByLanguage(dbSession, "missing")).isEmpty(); | |||
} |
@@ -311,11 +311,15 @@ public class RegisterRules implements Startable { | |||
} | |||
private void persistRepositories(DbSession dbSession, List<RulesDefinition.Repository> repositories) { | |||
List<RuleRepositoryDto> dtos = repositories.stream() | |||
List<String> keys = repositories.stream().map(RulesDefinition.Repository::key).collect(toList(repositories.size())); | |||
Set<String> existingKeys = dbClient.ruleRepositoryDao().selectAllKeys(dbSession); | |||
Map<Boolean, List<RuleRepositoryDto>> dtos = repositories.stream() | |||
.map(r -> new RuleRepositoryDto(r.key(), r.language(), r.name())) | |||
.collect(toList(repositories.size())); | |||
List<String> keys = dtos.stream().map(RuleRepositoryDto::getKey).collect(toList(repositories.size())); | |||
dbClient.ruleRepositoryDao().insertOrUpdate(dbSession, dtos); | |||
.collect(Collectors.groupingBy(i -> existingKeys.contains(i.getKey()))); | |||
dbClient.ruleRepositoryDao().update(dbSession, dtos.getOrDefault(true, emptyList())); | |||
dbClient.ruleRepositoryDao().insert(dbSession, dtos.getOrDefault(false, emptyList())); | |||
dbClient.ruleRepositoryDao().deleteIfKeyNotIn(dbSession, keys); | |||
dbSession.commit(); | |||
} |
@@ -302,7 +302,7 @@ public class RegisterRulesTest { | |||
public void delete_repositories_that_have_been_uninstalled() { | |||
RuleRepositoryDto repository = new RuleRepositoryDto("findbugs", "java", "Findbugs"); | |||
DbSession dbSession = db.getSession(); | |||
db.getDbClient().ruleRepositoryDao().insertOrUpdate(dbSession, singletonList(repository)); | |||
db.getDbClient().ruleRepositoryDao().insert(dbSession, singletonList(repository)); | |||
dbSession.commit(); | |||
execute(new FakeRepositoryV1()); |
@@ -234,7 +234,7 @@ public class CompareActionTest { | |||
private void createRepository(String repositoryKey, String repositoryLanguage, String repositoryName) { | |||
RuleRepositoryDto dto = new RuleRepositoryDto(repositoryKey, repositoryLanguage, repositoryName); | |||
dbClient.ruleRepositoryDao().insertOrUpdate(session, singletonList(dto)); | |||
dbClient.ruleRepositoryDao().insert(session, singletonList(dto)); | |||
session.commit(); | |||
} | |||
} |
@@ -115,7 +115,7 @@ public class AppActionTest { | |||
private void insertRules() { | |||
RuleRepositoryDto repo1 = new RuleRepositoryDto("xoo", "xoo", "SonarQube"); | |||
RuleRepositoryDto repo2 = new RuleRepositoryDto("squid", "ws", "SonarQube"); | |||
db.getDbClient().ruleRepositoryDao().insertOrUpdate(db.getSession(), asList(repo1, repo2)); | |||
db.getDbClient().ruleRepositoryDao().insert(db.getSession(), asList(repo1, repo2)); | |||
db.getSession().commit(); | |||
} | |||
@@ -47,7 +47,7 @@ public class RepositoriesActionTest { | |||
RuleRepositoryDto repo1 = new RuleRepositoryDto("xoo", "xoo", "SonarQube"); | |||
RuleRepositoryDto repo2 = new RuleRepositoryDto("squid", "ws", "SonarQube"); | |||
RuleRepositoryDto repo3 = new RuleRepositoryDto("common-ws", "ws", "SonarQube Common"); | |||
dbTester.getDbClient().ruleRepositoryDao().insertOrUpdate(dbSession, asList(repo1, repo2, repo3)); | |||
dbTester.getDbClient().ruleRepositoryDao().insert(dbSession, asList(repo1, repo2, repo3)); | |||
dbSession.commit(); | |||
} | |||