Skip to content

Commit

Permalink
Native repo: added countReferences + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
virgo47 committed Jan 20, 2023
1 parent 0a352c2 commit f0f2079
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1275,10 +1275,56 @@ private <T extends Containerable> SearchResultList<T> executeSearchContainers(Cl
}
}

public int countReferences(
@Nullable ObjectQuery query,
@Nullable Collection<SelectorOptions<GetOperationOptions>> options,
@NotNull OperationResult parentResult) throws SchemaException {
Objects.requireNonNull(query, "Query must be provided for reference search");
Objects.requireNonNull(parentResult, "Operation result must not be null.");

OperationResult operationResult = parentResult.subresult(opNamePrefix + OP_COUNT_REFERENCES)
.addParam("query", query)
.build();

try {
logSearchInputParameters(ObjectReferenceType.class, query, "Count references");

query = ObjectQueryUtil.simplifyQuery(query);
if (ObjectQueryUtil.isNoneQuery(query)) {
return 0;
}

return executeCountReferences(query, options);
} catch (RepositoryException | RuntimeException e) {
throw handledGeneralException(e, operationResult);
} catch (Throwable t) {
recordFatalError(operationResult, t);
throw t;
} finally {
operationResult.close();
}
}

public int executeCountReferences(
ObjectQuery query, Collection<SelectorOptions<GetOperationOptions>> options)
throws RepositoryException {
long opHandle = registerOperationStart(OP_COUNT_REFERENCES, ObjectReferenceType.class);
try {
QReferenceMapping<?, ?, ?, ?> refMapping = determineMapping(query.getFilter());
SqaleQueryContext<ObjectReferenceType, ?, ?> queryContext =
SqaleQueryContext.from(
refMapping, sqlRepoContext, sqlRepoContext.newQuery(), null);
return sqlQueryExecutor.count(queryContext, query, options);
} finally {
registerOperationFinish(opHandle);
}
}

public SearchResultList<ObjectReferenceType> searchReferences(
@Nullable ObjectQuery query,
@Nullable Collection<SelectorOptions<GetOperationOptions>> options,
@NotNull OperationResult parentResult) throws SchemaException {
Objects.requireNonNull(query, "Query must be provided for reference search");
Objects.requireNonNull(parentResult, "Operation result must not be null.");

OperationResult operationResult = parentResult.subresult(opNamePrefix + OP_SEARCH_REFERENCES)
Expand Down Expand Up @@ -1309,13 +1355,7 @@ public SearchResultList<ObjectReferenceType> executeSearchReferences(
throws SchemaException, RepositoryException {
long opHandle = registerOperationStart(OP_SEARCH_REFERENCES, ObjectReferenceType.class);
try {
ObjectFilter filter = query.getFilter();
if (!(filter instanceof OwnedByFilter || filter instanceof LogicalFilter)) {
throw new UnsupportedOperationException("Invalid filter for reference search: " + filter
+ "\nReference search filter should be OWNED-BY filter or a logical filter with it.");
}

QReferenceMapping<?, ?, ?, ?> refMapping = determineMapping(filter);
QReferenceMapping<?, ?, ?, ?> refMapping = determineMapping(query.getFilter());
SqaleQueryContext<ObjectReferenceType, ?, ?> queryContext =
SqaleQueryContext.from(
refMapping, sqlRepoContext, sqlRepoContext.newQuery(), null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2472,7 +2472,15 @@ public void test800SearchReference() throws SchemaException {
.hasSize(2)
.anyMatch(r -> refMatches(r, user1Oid, roleOtherOid, relation2))
.anyMatch(r -> refMatches(r, user3Oid, roleAvIOid, relation2));
// TODO metadata check

and("value metadata is returned in references that have them");
assertThat(result)
.filteredOn(r -> r.getOid().equals(roleOtherOid))
.singleElement()
.extracting(r -> r.asReferenceValue().getValueMetadata())
// A bit of a train-wreck... but it should work.
.matches(m -> m.getRealValue(ValueMetadataType.class).getProvenance()
.getAcquisition().get(0).getChannel().equals("acquisition-channel"));
}

@Test
Expand Down Expand Up @@ -2511,7 +2519,7 @@ public void test802SearchReferenceWithAnyRelation() throws SchemaException {
}

@Test
public void test805SearchLinkRefs() throws SchemaException {
public void test810SearchLinkRefs() throws SchemaException {
when("searching link references (pure owned-by filter)");
OperationResult operationResult = createOperationResult();
ObjectQuery refQuery = prismContext.queryForReferenceOwnedBy(UserType.class, UserType.F_LINK_REF)
Expand All @@ -2524,6 +2532,22 @@ public void test805SearchLinkRefs() throws SchemaException {
.anyMatch(r -> refMatches(r, user3Oid, shadow1Oid, ORG_DEFAULT));
}

@Test
public void test811CountLinkRefs() throws SchemaException {
when("counting link references (pure owned-by filter)");
OperationResult operationResult = createOperationResult();
ObjectQuery refQuery = prismContext
.queryForReferenceOwnedBy(UserType.class, UserType.F_LINK_REF)
.build();
queryRecorder.clearBufferAndStartRecording();
int result = repositoryService.countReferences(refQuery, null, operationResult);
display(queryRecorder.dumpQueryBuffer());

then("expected ref count returned");
assertThatOperationResult(operationResult).isSuccess();
assertThat(result).isEqualTo(1);
}

@Test
public void test819ReferenceQueryFailsOnWrongTopLevelPath() {
assertThatThrownBy(
Expand All @@ -2538,6 +2562,28 @@ public void test819ReferenceQueryFailsOnWrongTopLevelPath() {

// TODO test wrong ref type
// TODO test multiple owned-by (failing)

@Test
public void test890ReferenceSearchWithNullQueryFails() {
OperationResult operationResult = createOperationResult();
assertThatThrownBy(
() -> searchReferences(null, operationResult, null))
.isInstanceOf(NullPointerException.class)
.hasMessage("Query must be provided for reference search");
}

@Test
public void test891ReferenceSearchWithNullFilterFails() {
OperationResult operationResult = createOperationResult();
assertThatThrownBy(
() -> searchReferences(
// The type for the query does not affect the search directly.
// This is not how to construct real query for reference search, of course.
prismContext.queryFor(UserType.class).build(),
operationResult, null))
.isInstanceOf(SystemException.class)
.hasMessageStartingWith("Invalid filter for reference search: null");
}
// endregion

// region special cases
Expand Down

0 comments on commit f0f2079

Please sign in to comment.