/** * 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 extends Comparable<INPUT>> List<OUTPUT> executeLargeInputs(Collection<INPUT> input, Function<List<INPUT>, List<OUTPUT>> function) { return executeLargeInputs(input, function, i -> i); }
/** * 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 extends Comparable<INPUT>> List<OUTPUT> executeLargeInputs(Collection<INPUT> input, Function<List<INPUT>, List<OUTPUT>> function, IntFunction<Integer> partitionSizeManipulations) { return executeLargeInputs(input, function, size -> size == 0 ? Collections.emptyList() : new ArrayList<>(size), partitionSizeManipulations); }
/** * Select users by logins, including disabled users. An empty list is returned * if list of logins is empty, without any db round trips. */ public List<UserDto> selectByLogins(DbSession session, Collection<String> logins) { return executeLargeInputs(logins, mapper(session)::selectByLogins); }
public List<RuleDefinitionDto> selectDefinitionByIds(DbSession session, Collection<Integer> ids) { if (ids.isEmpty()) { return emptyList(); } return executeLargeInputs(ids, mapper(session)::selectDefinitionByIds); }
/** * Select users by uuids, including disabled users. An empty list is returned * if list of uuids is empty, without any db round trips. */ public List<UserDto> selectByUuids(DbSession session, Collection<String> uuids) { return executeLargeInputs(uuids, mapper(session)::selectByUuids); }
/** * Select users by ids, including disabled users. An empty list is returned * if list of ids is empty, without any db round trips. * * Used by the Governance plugin */ public List<UserDto> selectByIds(DbSession session, Collection<Integer> ids) { return executeLargeInputs(ids, mapper(session)::selectByIds); }
public List<RuleDefinitionDto> selectDefinitionByKeys(DbSession session, Collection<RuleKey> keys) { if (keys.isEmpty()) { return emptyList(); } return executeLargeInputs(keys, mapper(session)::selectDefinitionByKeys); }
/** * Gets a list issues by their keys. The result does NOT contain {@code null} values for issues not found, so * the size of result may be less than the number of keys. A single issue is returned * if input keys contain multiple occurrences of a key. * <p>Results may be in a different order as input keys.</p> */ public List<IssueDto> selectByKeys(DbSession session, Collection<String> keys) { return executeLargeInputs(keys, mapper(session)::selectByKeys); }
public Collection<ActiveRuleDto> selectByRulesAndRuleProfileUuids(DbSession dbSession, Collection<RuleDefinitionDto> rules, Collection<String> ruleProfileUuids) { if (rules.isEmpty() || ruleProfileUuids.isEmpty()) { return emptyList(); } List<Integer> ruleIds = rules.stream().map(RuleDefinitionDto::getId).collect(MoreCollectors.toArrayList(rules.size())); ActiveRuleMapper mapper = mapper(dbSession); return executeLargeInputs(ruleIds, ruleIdsChunk -> executeLargeInputs(ruleProfileUuids, chunk -> mapper.selectByRuleIdsAndRuleProfileUuids(ruleIdsChunk, chunk))); }
public List<LiveMeasureDto> selectByComponentUuidsAndMetricIds(DbSession dbSession, Collection<String> largeComponentUuids, Collection<Integer> metricIds) { if (largeComponentUuids.isEmpty() || metricIds.isEmpty()) { return Collections.emptyList(); } return executeLargeInputs( largeComponentUuids, componentUuids -> mapper(dbSession).selectByComponentUuidsAndMetricIds(componentUuids, metricIds)); }
public List<LiveMeasureDto> selectByComponentUuidsAndMetricKeys(DbSession dbSession, Collection<String> largeComponentUuids, Collection<String> metricKeys) { if (largeComponentUuids.isEmpty() || metricKeys.isEmpty()) { return Collections.emptyList(); } return executeLargeInputs( largeComponentUuids, componentUuids -> mapper(dbSession).selectByComponentUuidsAndMetricKeys(componentUuids, metricKeys)); }
public List<PastMeasureDto> selectPastMeasures(DbSession dbSession, String componentUuid, String analysisUuid, Collection<Integer> metricIds) { if (metricIds.isEmpty()) { return emptyList(); } return executeLargeInputs( metricIds, ids -> mapper(dbSession).selectPastMeasuresOnSingleAnalysis(componentUuid, analysisUuid, ids)); }
/** * Select global or project permission of given groups and organization. Anyone virtual group is supported * through the value "zero" (0L) in {@code groupIds}. */ public List<GroupPermissionDto> selectByGroupIds(DbSession dbSession, String organizationUuid, List<Integer> groupIds, @Nullable Long projectId) { return executeLargeInputs(groupIds, groups -> mapper(dbSession).selectByGroupIds(organizationUuid, groups, projectId)); }
/** * @param analysisUuid snapshot id of the project from the previous analysis (islast=true) */ public List<DuplicationUnitDto> selectCandidates(DbSession session, @Nullable String analysisUuid, String language, Collection<String> hashes) { return executeLargeInputs( hashes, partition -> session.getMapper(DuplicationMapper.class).selectCandidates(analysisUuid, language, partition)); }
public List<ComponentDto> selectByKeysAndBranch(DbSession session, Collection<String> keys, String branch) { List<String> dbKeys = keys.stream().map(k -> generateBranchKey(k, branch)).collect(toList()); List<String> allKeys = Stream.of(keys, dbKeys).flatMap(Collection::stream).collect(toList()); return executeLargeInputs(allKeys, subKeys -> mapper(session).selectByKeysAndBranch(subKeys, branch)); }
public List<ComponentDto> selectByKeysAndPullRequest(DbSession session, Collection<String> keys, String pullRequestId) { List<String> dbKeys = keys.stream().map(k -> generatePullRequestKey(k, pullRequestId)).collect(toList()); List<String> allKeys = Stream.of(keys, dbKeys).flatMap(Collection::stream).collect(toList()); return executeLargeInputs(allKeys, subKeys -> mapper(session).selectByKeysAndBranch(subKeys, pullRequestId)); }
/** * Keep only authorized user that have the given permission on a given project. * Please Note that if the permission is 'Anyone' is NOT taking into account by this method. */ public Collection<Integer> keepAuthorizedUsersForRoleAndProject(DbSession dbSession, Collection<Integer> userIds, String role, long projectId) { return executeLargeInputs( userIds, partitionOfIds -> mapper(dbSession).keepAuthorizedUsersForRoleAndProject(role, projectId, partitionOfIds), partitionSize -> partitionSize / 3); }
public List<RuleDto> selectByIds(DbSession session, String organizationUuid, List<Integer> ids) { if (ids.isEmpty()) { return emptyList(); } return ensureOrganizationIsSet( organizationUuid, executeLargeInputs(ids, chunk -> mapper(session).selectByIds(organizationUuid, chunk))); }
public List<RuleDto> selectByKeys(DbSession session, String organizationUuid, Collection<RuleKey> keys) { if (keys.isEmpty()) { return emptyList(); } return ensureOrganizationIsSet(organizationUuid, executeLargeInputs(keys, chunk -> mapper(session).selectByKeys(organizationUuid, chunk))); }
@Test public void executeLargeInputs_on_empty_list() { List<String> outputs = DatabaseUtils.executeLargeInputs(Collections.emptyList(), new Function<List<Integer>, List<String>>() { @Override public List<String> apply(List<Integer> input) { fail("No partition should be made on empty list"); return Collections.emptyList(); } }); assertThat(outputs).isEmpty(); }