Skip to content

Commit

Permalink
Use SELECT COUNT to get number of patients (#645)
Browse files Browse the repository at this point in the history
instead of returning all IDs and using size().
  • Loading branch information
askask authored Nov 19, 2024
1 parent 5b69251 commit 2833e64
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
10 changes: 5 additions & 5 deletions src/main/java/org/highmed/numportal/service/AqlService.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,19 +250,19 @@ public long getAqlSize(SlimAqlDto aql, String userId) {

validateQuery(aql.getQuery());

Set<String> ehrIds;
int numberOfPatients;
try {
ehrIds =
ehrBaseService.retrieveEligiblePatientIds(Aql.builder().query(aql.getQuery()).build());
numberOfPatients =
ehrBaseService.retrieveNumberOfPatients(Aql.builder().query(aql.getQuery()).build());
} catch (AqlParseException e) {
throw new BadRequestException(AqlParseException.class, e.getLocalizedMessage(), e.getMessage());
}

if (ehrIds.size() < privacyProperties.getMinHits()) {
if (numberOfPatients < privacyProperties.getMinHits()) {
log.warn(TOO_FEW_MATCHES_RESULTS_WITHHELD_FOR_PRIVACY_REASONS);
throw new PrivacyException(AqlService.class, TOO_FEW_MATCHES_RESULTS_WITHHELD_FOR_PRIVACY_REASONS);
}
return ehrIds.size();
return numberOfPatients;
}

public List<AqlCategory> getAqlCategories() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.apache.commons.lang3.StringUtils;
import org.ehrbase.openehr.sdk.aql.dto.AqlQuery;
import org.ehrbase.openehr.sdk.aql.dto.containment.ContainmentClassExpression;
import org.ehrbase.openehr.sdk.aql.dto.operand.CountDistinctAggregateFunction;
import org.ehrbase.openehr.sdk.aql.dto.operand.IdentifiedPath;
import org.ehrbase.openehr.sdk.aql.dto.path.AqlObjectPath;
import org.ehrbase.openehr.sdk.aql.dto.select.SelectExpression;
Expand Down Expand Up @@ -118,6 +119,51 @@ public Set<String> retrieveEligiblePatientIds(String query) {
}
}

/**
* Retrieves the number of patients for the given aql
*
* @param aql The aql to retrieve patient ids for
* @return number of patients
* @throws WrongStatusCodeException in case if a malformed aql
*/
public int retrieveNumberOfPatients(Aql aql) {
return retrieveNumberOfPatients(aql.getQuery());
}

public int retrieveNumberOfPatients(String query) {
log.debug("EhrBase retrieve number of patients for query: {} ", query);
AqlQuery dto = AqlQueryParser.parse(query);
SelectExpression selectExpression = new SelectExpression();

var count = new CountDistinctAggregateFunction();
selectExpression.setColumnExpression(count);

IdentifiedPath ehrIdPath = new IdentifiedPath();
ehrIdPath.setPath(AqlObjectPath.parse(AqlQueryConstants.EHR_ID_PATH));

ContainmentClassExpression containmentClassExpression = new ContainmentClassExpression();
containmentClassExpression.setType(AqlQueryConstants.EHR_TYPE);
containmentClassExpression.setIdentifier(AqlQueryConstants.EHR_CONTAINMENT_IDENTIFIER);
ehrIdPath.setRoot(containmentClassExpression);

count.setIdentifiedPath(ehrIdPath);

dto.getSelect().setStatement(List.of(selectExpression));
log.info("Generated query for retrieveNumberOfPatients {} ", AqlRenderer.render(dto));

try {
List<Record1<Integer>> results = restClient.aqlEndpoint().execute(Query.buildNativeQuery(AqlRenderer.render(dto), Integer.class));
return results.get(0).value1();
} catch (WrongStatusCodeException e) {
log.error(INVALID_AQL_QUERY, e.getMessage(), e);
throw new WrongStatusCodeException("EhrBaseService.class", 93, 1);
} catch (ClientException e) {
log.error(ERROR_MESSAGE, e.getMessage(), e);
throw new SystemException(EhrBaseService.class, AN_ERROR_HAS_OCCURRED_CANNOT_EXECUTE_AQL,
String.format(AN_ERROR_HAS_OCCURRED_CANNOT_EXECUTE_AQL, e.getMessage()));
}
}

/**
* Executes a raw aql query
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public void getAqlSizeTest() {
SlimAqlDto aqlDto = SlimAqlDto.builder()
.query("select * from dummy_table")
.build();
Mockito.when(ehrBaseService.retrieveEligiblePatientIds(Mockito.any(Aql.class))).thenReturn(new HashSet<>(Arrays.asList("id1", "id2", "id3", "id4")));
Mockito.when(ehrBaseService.retrieveNumberOfPatients(Mockito.any(Aql.class))).thenReturn(4);
aqlService.getAqlSize(aqlDto, "4");
}

Expand All @@ -180,7 +180,7 @@ public void shouldHandlePrivacyExceptionWhenGetAqlSize() {
SlimAqlDto aqlDto = SlimAqlDto.builder()
.query("select * from dummy_table")
.build();
Mockito.when(ehrBaseService.retrieveEligiblePatientIds(Mockito.any(Aql.class))).thenReturn(new HashSet<>(Arrays.asList("id1")));
Mockito.when(ehrBaseService.retrieveNumberOfPatients(Mockito.any(Aql.class))).thenReturn(1);
aqlService.getAqlSize(aqlDto, "4");
}

Expand Down

0 comments on commit 2833e64

Please sign in to comment.