import java.util.Collection;
import java.util.List;
+import java.util.Locale;
import java.util.Set;
+import javax.annotation.Nullable;
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;
+import static org.apache.commons.lang.StringUtils.isBlank;
public class RuleRepositoryDao implements Dao {
+ private static final String PERCENT_SIGN = "%";
+
private final System2 system2;
public RuleRepositoryDao(System2 system2) {
return dbSession.getMapper(RuleRepositoryMapper.class).selectAllKeys();
}
- /**
- * @return a non-null list ordered by key (as implemented by database, order may
- * depend on case sensitivity)
- */
- public List<RuleRepositoryDto> selectByLanguage(DbSession dbSession, String language) {
- return dbSession.getMapper(RuleRepositoryMapper.class).selectByLanguage(language);
+ public List<RuleRepositoryDto> selectByQueryAndLanguage(DbSession dbSession, @Nullable String query, @Nullable String language){
+ String queryUpgraded = toLowerCaseAndSurroundWithPercentSigns(query);
+ return dbSession.getMapper(RuleRepositoryMapper.class).selectByQueryAndLanguage(queryUpgraded,language);
}
public void insert(DbSession dbSession, Collection<RuleRepositoryDto> dtos) {
checkArgument(keys.size() < DatabaseUtils.PARTITION_SIZE_FOR_ORACLE, "too many rule repositories: %s", keys.size());
dbSession.getMapper(RuleRepositoryMapper.class).deleteIfKeyNotIn(keys);
}
+
+ private static String toLowerCaseAndSurroundWithPercentSigns(@Nullable String query) {
+ return isBlank(query) ? PERCENT_SIGN : (PERCENT_SIGN + query.toLowerCase(Locale.ENGLISH) + PERCENT_SIGN);
+ }
+
}
import java.util.List;
import java.util.Set;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.apache.ibatis.annotations.Param;
public interface RuleRepositoryMapper {
Set<String> selectAllKeys();
- List<RuleRepositoryDto> selectByLanguage(@Param("language") String language);
+ List<RuleRepositoryDto> selectByQueryAndLanguage(@Param("query") String query,@Param("language") @Nullable String language);
@CheckForNull
RuleRepositoryDto selectByKey(@Param("key") String key);
from rule_repositories
</select>
- <select id="selectByLanguage" parameterType="String" resultType="org.sonar.db.rule.RuleRepositoryDto">
+ <select id="selectByQueryAndLanguage" parameterType="String" resultType="org.sonar.db.rule.RuleRepositoryDto">
select <include refid="sqlColumns"/>
from rule_repositories
- where language = #{language}
+ where
+ ( lower(kee) like #{query}
+ or lower(name) like #{query} )
+ <if test="language != null and language != ''">
+ and language = #{language}
+ </if>
order by kee
</select>
}
@Test
- public void selectByLanguage() {
+ public void selectByQueryAndLanguage_shouldMatchOnlyOnKeeOrName(){
DbSession dbSession = dbTester.getSession();
- RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugs");
- RuleRepositoryDto dto2 = new RuleRepositoryDto("java", "java", "Java");
+ RuleRepositoryDto dto1 = new RuleRepositoryDto("a_findbugs", "java", "Findbugs");
+ RuleRepositoryDto dto2 = new RuleRepositoryDto("jdk", "java", "Java");
RuleRepositoryDto dto3 = new RuleRepositoryDto("cobol-lint", "cobol", "Cobol Lint");
- underTest.insert(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", "java");
+ List<RuleRepositoryDto> ruleRepositoryDtos = underTest.selectByQueryAndLanguage(dbSession, "%a%",null);
+
+ assertThat(ruleRepositoryDtos).extracting(RuleRepositoryDto::getName)
+ .containsExactlyInAnyOrder("Java","Findbugs");
}
+ @Test
+ public void selectByQueryAndLanguage_whenSeveralRepoMatchingForDifferentLanguages_matchOnlyTheRepoOfTheChosenLanguage(){
+ DbSession dbSession = dbTester.getSession();
+ RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugsa");
+ RuleRepositoryDto dto2 = new RuleRepositoryDto("java", "java", "Java");
+ RuleRepositoryDto dto3 = new RuleRepositoryDto("cobol-bug", "cobol", "Cobol Lint");
+ underTest.insert(dbSession, asList(dto1,dto2,dto3));
+
+ List<RuleRepositoryDto> ruleRepositoryDtos = underTest.selectByQueryAndLanguage(dbSession, "%bug%", "java");
+
+ assertThat(ruleRepositoryDtos).extracting(RuleRepositoryDto::getKey)
+ .containsExactly("findbugs");
+ }
+
+
@Test
public void selectAllKeys() {
DbSession dbSession = dbTester.getSession();
}
@Test
- public void selectByLanguage_returns_empty_list_if_no_results() {
+ public void selectByQueryAndLanguage_returnsEmptyList_when_thereIsNoResults() {
DbSession dbSession = dbTester.getSession();
RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugs");
underTest.insert(dbSession, asList(dto1));
- assertThat(underTest.selectByLanguage(dbSession, "missing")).isEmpty();
+ assertThat(underTest.selectByQueryAndLanguage(dbSession, "missing", null)).isEmpty();
}
+ @Test
+ public void selectByQueryAndLanguage_shouldBeCaseInsensitive(){
+ DbSession dbSession = dbTester.getSession();
+ RuleRepositoryDto dto1 = new RuleRepositoryDto("FINDBUGS", "java", "repoFB");
+ RuleRepositoryDto dto2 = new RuleRepositoryDto("cobol-lint", "cobol", "Cobol Lint");
+ RuleRepositoryDto dto3 = new RuleRepositoryDto("openjdk", "java", "JaVa");
+ underTest.insert(dbSession, asList(dto1,dto2,dto3));
+
+ assertThat(underTest.selectByQueryAndLanguage(dbSession,"bug", null))
+ .extracting(RuleRepositoryDto::getKey).contains("FINDBUGS");
+ assertThat(underTest.selectByQueryAndLanguage(dbSession,"COBOL", null))
+ .extracting(RuleRepositoryDto::getKey).contains("cobol-lint");
+ assertThat(underTest.selectByQueryAndLanguage(dbSession,"jAvA", null))
+ .extracting(RuleRepositoryDto::getKey).contains("openjdk");
+
+ }
+
+
+
private long selectCreatedAtByKey(DbSession dbSession, String key) {
return (long) dbTester.selectFirst(dbSession, "select created_at as \"created_at\" from rule_repositories where kee='" + key + "'")
.get("created_at");
import com.google.common.io.Resources;
import java.util.Collection;
-import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService.NewAction;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.rule.RuleRepositoryDto;
-import static org.apache.commons.lang.StringUtils.isEmpty;
/**
* @since 5.1
public class RepositoriesAction implements RulesWsAction {
private static final String LANGUAGE = "language";
- private static final String MATCH_ALL = ".*";
private final DbClient dbClient;
}
private Collection<RuleRepositoryDto> listMatchingRepositories(@Nullable String query, @Nullable String languageKey) {
- Pattern pattern = Pattern.compile(query == null ? MATCH_ALL : MATCH_ALL + Pattern.quote(query) + MATCH_ALL, Pattern.CASE_INSENSITIVE);
-
- return selectFromDb(languageKey).stream()
- .filter(r -> pattern.matcher(r.getKey()).matches() || pattern.matcher(r.getName()).matches())
- .collect(MoreCollectors.toList());
+ return selectFromDb(languageKey, query);
}
- private Collection<RuleRepositoryDto> selectFromDb(@Nullable String language) {
+ private Collection<RuleRepositoryDto> selectFromDb(@Nullable String language, @Nullable String query) {
try (DbSession dbSession = dbClient.openSession(false)) {
- if (isEmpty(language)) {
- return dbClient.ruleRepositoryDao().selectAll(dbSession);
- }
- return dbClient.ruleRepositoryDao().selectByLanguage(dbSession, language);
+ return dbClient.ruleRepositoryDao().selectByQueryAndLanguage(dbSession, query, language);
}
}
}
newRequest().setParam("q", "sonar").execute().assertJson(this.getClass(), "repositories_sonar.json");
}
+ @Test
+ public void filter_repository_by_query(){
+ newRequest().setParam("q", "xo").execute().assertJson(this.getClass(),"repositories_xoo.json");
+ newRequest().setParam("q","w").execute().assertJson(this.getClass(),"repositories_common.json");
+ }
+
+
+ @Test
+ public void filter_repository_by_query_and_language(){
+ newRequest().setParam("q","ava").setParam("language","ws").execute().assertJson(this.getClass(),"repositories_java.json");
+ newRequest().setParam("q","w").setParam("language","ws").execute().assertJson(this.getClass(),"repositories_common.json");
+ }
+
@Test
public void do_not_consider_query_as_regexp_when_filtering_repositories_by_name() {
// invalid regexp : do not fail. Query is not a regexp.