package org.sonar.server.component.db;
+import com.google.common.base.Function;
import org.sonar.api.ServerComponent;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
}
public List<ComponentDto> getByUuids(final DbSession session, Collection<String> uuids) {
- return DaoUtils.partitionSelect(uuids, new DaoUtils.Function<ComponentDto, String>() {
+ return DaoUtils.executeLargeInputs(uuids, new Function<List<String>, List<ComponentDto>>() {
@Override
- public List<ComponentDto> execute(List<String> partition) {
+ public List<ComponentDto> apply(List<String> partition) {
return mapper(session).findByUuids(partition);
}
});
}
- public List<String> selectUuidsByUuids(final DbSession session, Collection<String> uuids) {
- return DaoUtils.partitionSelect(uuids, new DaoUtils.Function<String, String>() {
+ public List<String> selectExistingUuids(final DbSession session, Collection<String> uuids) {
+ return DaoUtils.executeLargeInputs(uuids, new Function<List<String>, List<String>>() {
@Override
- public List<String> execute(List<String> partition) {
- return mapper(session).selectUuidsByUuids(partition);
+ public List<String> apply(List<String> partition) {
+ return mapper(session).selectExistingUuids(partition);
}
});
}
DbSession session = dbClient.openSession(false);
try {
Set<String> viewUuidsInIndex = newHashSet(index.findAllViewUuids());
- Set<String> viewUuidInDb = newHashSet(dbClient.componentDao().selectUuidsByUuids(session, viewUuidsInIndex));
+ Set<String> viewUuidInDb = newHashSet(dbClient.componentDao().selectExistingUuids(session, viewUuidsInIndex));
Set<String> viewsToRemove = Sets.difference(viewUuidsInIndex, viewUuidInDb);
index.delete(viewsToRemove);
} finally {
}
@Test
- public void select_uuids_by_uuids() {
+ public void select_existing_uuids() {
setupData("shared");
- List<String> results = dao.selectUuidsByUuids(session, newArrayList("KLMN"));
+ List<String> results = dao.selectExistingUuids(session, newArrayList("KLMN"));
assertThat(results).containsOnly("KLMN");
- assertThat(dao.selectUuidsByUuids(session, newArrayList("KLMN", "unknown"))).hasSize(1);
- assertThat(dao.selectUuidsByUuids(session, newArrayList("unknown"))).isEmpty();
+ assertThat(dao.selectExistingUuids(session, newArrayList("KLMN", "unknown"))).hasSize(1);
+ assertThat(dao.selectExistingUuids(session, newArrayList("unknown"))).isEmpty();
}
@Test
List<ComponentDto> findByUuids(@Param("uuids") Collection<String> uuids);
- List<String> selectUuidsByUuids(@Param("uuids") Collection<String> uuids);
+ List<String> selectExistingUuids(@Param("uuids") Collection<String> uuids);
/**
* Return all project (PRJ/TRK) uuids
*/
package org.sonar.core.persistence;
+import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.sonar.core.dashboard.ActiveDashboardDao;
);
}
- public static <F, T> List<F> partitionSelect(Collection<T> input, Function<F, T> select) {
+ /**
+ * Partition by 1000 elements a list of input and execute a function on each part.
+ *
+ * The goal is to prevent issue with ORACLE when there's more than 1000 elements in a 'in ('X', 'Y', ...)'
+ * and with MsSQL when there's more than 2000 parameters in a query
+ */
+ public static <OUTPUT, INPUT> List<OUTPUT> executeLargeInputs(Collection<INPUT> input, Function<List<INPUT>, List<OUTPUT>> function) {
if (input.isEmpty()) {
return Collections.emptyList();
}
- List<F> results = newArrayList();
- List<List<T>> partitionList = Lists.partition(newArrayList(input), PARTITION_SIZE_FOR_ORACLE);
- for (List<T> partition : partitionList) {
- List<F> dtos = select.execute(partition);
- results.addAll(dtos);
+ List<OUTPUT> results = newArrayList();
+ List<List<INPUT>> partitionList = Lists.partition(newArrayList(input), PARTITION_SIZE_FOR_ORACLE);
+ for (List<INPUT> partition : partitionList) {
+ List<OUTPUT> subResults = function.apply(partition);
+ results.addAll(subResults);
}
return results;
}
- public static interface Function<F, T> {
- List<F> execute(List<T> partition);
- }
-
}
</where>
</select>
- <select id="selectUuidsByUuids" parameterType="String" resultType="String">
+ <select id="selectExistingUuids" parameterType="String" resultType="String">
select p.uuid
from projects p
<where>