Skip to content

Commit

Permalink
fix: apply any prefiltering specification to the search panes
Browse files Browse the repository at this point in the history
This was broken in [1], due to the creation of a new specification
without the fetch clauses.

[1]: d4c810e
  • Loading branch information
darrachequesne committed Feb 13, 2023
1 parent 8345740 commit e83b4d5
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ public Predicate toPredicate(@NonNull Root<S> root, @NonNull CriteriaQuery<?> qu
return predicates.toPredicate(criteriaBuilder);
}

private boolean isCountQuery(CriteriaQuery<?> query) {
private static boolean isCountQuery(CriteriaQuery<?> query) {
return query.getResultType() == Long.class;
}

protected void initPredicatesRecursively(Predicates predicates, CriteriaQuery<?> query, Node<Filter> node, From<S, S> from, FetchParent<S, S> fetch, CriteriaBuilder criteriaBuilder) {
private static boolean isAggregateQuery(CriteriaQuery<?> query) {
return query.getGroupList().size() > 0;
}

private void initPredicatesRecursively(Predicates predicates, CriteriaQuery<?> query, Node<Filter> node, From<S, S> from, FetchParent<S, S> fetch, CriteriaBuilder criteriaBuilder) {
if (node.isLeaf()) {
boolean hasColumnFilter = node.getData() != null;
if (hasColumnFilter) {
Expand All @@ -62,7 +66,7 @@ protected void initPredicatesRecursively(Predicates predicates, CriteriaQuery<?>
} else {
Join<S, S> join = from.join(child.getName(), JoinType.LEFT);

if (isCountQuery(query)) {
if (isCountQuery(query) || isAggregateQuery(query)) {
initPredicatesRecursively(predicates, query, child, join, join, criteriaBuilder);
} else {
Fetch<S, S> childFetch = fetch.fetch(child.getName(), JoinType.LEFT);
Expand All @@ -73,41 +77,6 @@ protected void initPredicatesRecursively(Predicates predicates, CriteriaQuery<?>
}
}

private class DataTablesSearchPaneSpecification<S> extends DataTablesSpecification<S> {

@Override
protected void initPredicatesRecursively(Predicates predicates, CriteriaQuery<?> query, Node<Filter> node, From<S, S> from,
FetchParent<S, S> fetch, CriteriaBuilder criteriaBuilder) {
if (node.isLeaf()) {
boolean hasColumnFilter = node.getData() != null;
if (hasColumnFilter) {
Filter columnFilter = node.getData();
predicates.columns.add(columnFilter.createPredicate(from, criteriaBuilder, node.getName()));
} else if (hasGlobalFilter) {
Filter globalFilter = tree.getData();
predicates.global.add(globalFilter.createPredicate(from, criteriaBuilder, node.getName()));
}
}
for (Node<Filter> child : node.getChildren()) {
Path<Object> path = from.get(child.getName());
if (path.getModel().getBindableType() == BindableType.PLURAL_ATTRIBUTE) {
// ignore OneToMany and ManyToMany relationships
continue;
}
if (child.isLeaf()) {
initPredicatesRecursively(predicates, query, child, from, fetch, criteriaBuilder);
} else {
Join<S, S> join = from.join(child.getName(), JoinType.LEFT);
initPredicatesRecursively(predicates, query, child, join, fetch, criteriaBuilder);
}
}
}
}

public Specification<T> buildSearchPane() {
return new DataTablesSearchPaneSpecification<>();
}

private static class Predicates {
public List<Predicate> columns = new ArrayList<>();
public List<Predicate> global = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ public <R> DataTablesOutput<R> findAll(DataTablesInput input,
output.setRecordsFiltered(data.getTotalElements());

if (input.getSearchPanes() != null) {
SpecificationBuilder<T> specificationSearchPaneBuilder = new SpecificationBuilder<>(input);
output.setSearchPanes(computeSearchPanes(input, specificationSearchPaneBuilder.buildSearchPane()));
output.setSearchPanes(computeSearchPanes(input, specification));
}
} catch (Exception e) {
log.warn("error while fetching records", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,27 @@ void withSearchPanes() {
);
}

@Test
void withSearchPanesAndAPreFilteringSpecification() {
Map<String, Set<String>> searchPanes = new HashMap<>();
searchPanes.put("position", new HashSet<>(asList("Software Engineer", "Integration Specialist")));
searchPanes.put("age", emptySet());

input.setSearchPanes(searchPanes);

DataTablesOutput<Employee> output = employeeRepository.findAll(input, null, new SoftwareEngineersOnly<>());
assertThat(output.getRecordsFiltered()).isEqualTo(2);
assertThat(output.getSearchPanes()).isNotNull();

assertThat(output.getSearchPanes().getOptions().get("position")).containsOnly(
new SearchPanes.Item("Software Engineer", "Software Engineer", 2, 2)
);
assertThat(output.getSearchPanes().getOptions().get("age")).containsOnly(
new SearchPanes.Item("28", "28", 1, 1),
new SearchPanes.Item("41", "41", 1, 1)
);
}

private static DataTablesInput getBasicInput() {
DataTablesInput input = new DataTablesInput();
input.addColumn("id", true, true, "");
Expand Down

0 comments on commit e83b4d5

Please sign in to comment.