-
Notifications
You must be signed in to change notification settings - Fork 0
Implement global filter #120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2e2a603
3d036a8
5e68b50
2e8c92e
426ee55
91c0309
b1fc653
798b9cf
476bb51
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,15 +12,15 @@ | |
import jakarta.persistence.criteria.Root; | ||
import org.gridsuite.sensitivityanalysis.server.dto.resultselector.ResultsSelector; | ||
import org.gridsuite.sensitivityanalysis.server.entities.AnalysisResultEntity; | ||
import org.gridsuite.sensitivityanalysis.server.entities.ContingencyResultEntity; | ||
import org.gridsuite.sensitivityanalysis.server.entities.RawSensitivityResultEntity; | ||
import org.gridsuite.sensitivityanalysis.server.entities.SensitivityResultEntity; | ||
import org.springframework.data.jpa.domain.Specification; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.util.CollectionUtils; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.UUID; | ||
import java.util.*; | ||
import java.util.stream.Collectors; | ||
|
||
/** | ||
* Builds specifications for querying {@link SensitivityResultEntity} objects. | ||
|
@@ -59,7 +59,14 @@ public Specification<SensitivityResultEntity> addSpecificFilterWhenChildrenFilte | |
} | ||
|
||
public Specification<SensitivityResultEntity> buildSpecificationFromSelector(UUID resultUuid, List<ResourceFilterDTO> resourceFilters, ResultsSelector selector) { | ||
return buildSpecification(resultUuid, resourceFilters, false) | ||
Specification<SensitivityResultEntity> baseSpec = buildSpecification(resultUuid, Collections.emptyList(), false); | ||
Specification<SensitivityResultEntity> resourceFilterSpec = buildCustomResourceFilterSpecification(resourceFilters); | ||
Comment on lines
+62
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is this change that breaks the filter by column (cf request change). Probably because you don't use the specification functions anymore (like appendTextFilterToSpecification...) |
||
Specification<SensitivityResultEntity> finalSpec = baseSpec; | ||
if (resourceFilterSpec != null) { | ||
finalSpec = finalSpec.and(resourceFilterSpec); | ||
} | ||
|
||
return finalSpec | ||
.and(fieldIn( | ||
List.of(selector.getFunctionType()), | ||
ResultsSelector.Fields.functionType, | ||
|
@@ -74,6 +81,67 @@ public Specification<SensitivityResultEntity> buildSpecificationFromSelector(UUI | |
null)); | ||
} | ||
|
||
private Specification<SensitivityResultEntity> buildCustomResourceFilterSpecification(List<ResourceFilterDTO> resourceFilters) { | ||
if (resourceFilters == null || resourceFilters.isEmpty()) { | ||
return Specification.where(null); | ||
} | ||
Map<String, List<ResourceFilterDTO>> filtersByColumn = resourceFilters.stream() | ||
.filter(Objects::nonNull) | ||
.collect(Collectors.groupingBy(ResourceFilterDTO::column)); | ||
Specification<SensitivityResultEntity> finalSpec = null; | ||
for (List<ResourceFilterDTO> filtersForColumn : filtersByColumn.values()) { | ||
Specification<SensitivityResultEntity> columnSpec = buildOrSpecificationForColumn(filtersForColumn); | ||
|
||
if (columnSpec != null) { | ||
finalSpec = finalSpec == null ? columnSpec : finalSpec.and(columnSpec); | ||
} | ||
} | ||
return finalSpec; | ||
} | ||
|
||
private Specification<SensitivityResultEntity> buildOrSpecificationForColumn(List<ResourceFilterDTO> filters) { | ||
if (filters.isEmpty()) { | ||
return null; | ||
} | ||
Specification<SensitivityResultEntity> columnSpec = null; | ||
for (ResourceFilterDTO filter : filters) { | ||
Specification<SensitivityResultEntity> singleFilterSpec = createSingleFilterSpecification(filter); | ||
columnSpec = columnSpec == null ? singleFilterSpec : columnSpec.or(singleFilterSpec); | ||
} | ||
return columnSpec; | ||
} | ||
|
||
private Specification<SensitivityResultEntity> createSingleFilterSpecification(ResourceFilterDTO filter) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you forgot to take into account the DataType of the Filter. The behavior is different between text and numbers. |
||
return (root, query, criteriaBuilder) -> { | ||
if (filter.value() instanceof List<?> valueList && !valueList.isEmpty()) { | ||
Path<Object> fieldPath = getFieldPathForFilter(root, filter.column()); | ||
|
||
switch (filter.type()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are a lot more type that should be handled I think : NOT_EQUAL, CONTAINS... (like in Actually why don't you use |
||
case IN: | ||
return fieldPath.in(valueList); | ||
case EQUALS: | ||
if (valueList.size() == 1) { | ||
return criteriaBuilder.equal(fieldPath, valueList.getFirst()); | ||
} | ||
return fieldPath.in(valueList); | ||
default: | ||
return criteriaBuilder.and(); | ||
} | ||
} | ||
return criteriaBuilder.and(); | ||
}; | ||
} | ||
|
||
private Path<Object> getFieldPathForFilter(Root<SensitivityResultEntity> root, String column) { | ||
return switch (column) { | ||
case "functionId" -> root.get(SensitivityResultEntity.Fields.functionId); | ||
case "variableId" -> root.get(SensitivityResultEntity.Fields.variableId); | ||
case "contingencyId" -> root.get(SensitivityResultEntity.Fields.contingencyResult) | ||
.get(ContingencyResultEntity.Fields.contingencyId); | ||
default -> root.get(column); | ||
}; | ||
} | ||
|
||
public Specification<SensitivityResultEntity> nullRawValue() { | ||
return (root, query, criteriaBuilder) -> criteriaBuilder.and( | ||
criteriaBuilder.isNull( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change JsonProcessingException to Exception doesn't it mean that any throw will be considered a bad request error ?
If you want to catch everything maybe : ?
But if you think that we can consider any error in the controller to be a badRequest, then fine.