Skip to content

Commit

Permalink
repo-sqale: URI cache methods take any Object on input
Browse files Browse the repository at this point in the history
QName and String is processed as before, the rest is toString-ed.
This is better for handling anyURI (String) or real QName from schema
in a unified fashion both for filter and delta application.
Added test for shadow search by objectClass (that uses QName value).
  • Loading branch information
virgo47 committed Jul 12, 2021
1 parent 6b070d5 commit be5d1d5
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,15 @@ public void clearCaches() {
extItemCache.initialize(this::newJdbcSession);
}

/** @see UriCache#searchId(String) */
public Integer searchCachedUriId(String uri) {
return uriCache.searchId(uri);
/**
* Supports search for URI ID by QName or String or any other type using `toString`.
*/
public @NotNull Integer searchCachedUriId(@NotNull Object uri) {
if (uri instanceof QName) {
return uriCache.searchId((QName) uri);
} else {
return uriCache.searchId(uri.toString());
}
}

/**
Expand All @@ -95,7 +101,7 @@ public Integer searchCachedUriId(String uri) {
}

/** Returns ID for URI creating new cache row in DB as needed. */
public Integer processCacheableUri(String uri) {
public Integer processCacheableUri(Object uri) {
return uriCache.processCacheableUri(uri);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* no DB access by the URI cache itself; TODO: later possible access when not found
* * `resolve` returns URI/ID for ID/URI or throws exception if not found, this is for situations
* where the entry for URI is expected to exist already, still no DB access required; TODO: later possible access when not found
* * finally, {@link #processCacheableUri(String)} accesses the database if the URI is not found
* * finally, {@link #processCacheableUri(Object)} accesses the database if the URI is not found
* in the cache in order to write it there.
*
* URIs are stored either as is when provided as a String or using {@link QNameUtil#qNameToUri(QName)}
Expand Down Expand Up @@ -111,11 +111,6 @@ private void updateMaps(MUri row) {
return getId(QNameUtil.qNameToUri(qName));
}

/** Returns ID for QName, possibly {@link #UNKNOWN_ID} - does not work with underlying database. */
public @NotNull Integer searchId(@NotNull QName qName) {
return searchId(QNameUtil.qNameToUri(qName));
}

/** Returns ID for QName or throws exception - does not work with underlying database. */
public @NotNull Integer resolveUriToId(@NotNull QName qName) {
return resolveUriToId(QNameUtil.qNameToUri(qName));
Expand All @@ -128,6 +123,15 @@ private void updateMaps(MUri row) {
return id;
}

/** Returns ID for provided URI value of `QName/String/Object#toString`. */
public @NotNull Integer searchId(@NotNull Object uri) {
if (uri instanceof QName) {
return searchId(QNameUtil.qNameToUri((QName) uri));
} else {
return searchId(uri.toString());
}
}

/** Returns ID for string or {@link #UNKNOWN_ID} - does not work with underlying database. */
public @NotNull Integer searchId(@NotNull String uri) {
Integer id = uriToId.getOrDefault(uri, UNKNOWN_ID);
Expand Down Expand Up @@ -160,27 +164,31 @@ public String getUri(Integer id) {
* Returns ID for URI creating new cache row in DB as needed.
* Returns null for null URI parameter.
*/
public synchronized @Nullable Integer processCacheableUri(@Nullable String uri) {
public synchronized @Nullable Integer processCacheableUri(@Nullable Object uri) {
if (uri == null) {
return null;
}
if (jdbcSessionSupplier == null) {
throw new IllegalStateException("URI cache was not initialized yet!");
}

Integer id = getId(uri);
String uriString = uri instanceof QName
? QNameUtil.qNameToUri((QName) uri)
: uri.toString();

Integer id = getId(uriString);
if (id != null) {
return id;
}

QUri qu = QUri.DEFAULT;
try (JdbcSession jdbcSession = jdbcSessionSupplier.get().startTransaction()) {
id = jdbcSession.newInsert(qu)
.set(qu.uri, uri)
.set(qu.uri, uriString)
.executeWithKey(qu.id);
jdbcSession.commit();

updateMaps(MUri.of(id, uri));
updateMaps(MUri.of(id, uriString));
}
// TODO query when constraint violation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* These paths are generally not ordered by, which is a relief, otherwise JOIN would be needed.
*/
public class UriItemFilterProcessor
extends SinglePathItemFilterProcessor<String, NumberPath<Integer>> {
extends SinglePathItemFilterProcessor<Object, NumberPath<Integer>> {

public <Q extends FlexibleRelationalPathBase<R>, R> UriItemFilterProcessor(
SqlQueryContext<?, Q, R> context,
Expand All @@ -37,10 +37,10 @@ public <Q extends FlexibleRelationalPathBase<R>, R> UriItemFilterProcessor(
}

@Override
public Predicate process(PropertyValueFilter<String> filter) throws QueryException {
public Predicate process(PropertyValueFilter<Object> filter) throws QueryException {
return createBinaryCondition(filter, path,
ValueFilterValues.from(filter,
u -> ((SqaleRepoContext) context.repositoryContext()).searchCachedUriId(u)));
((SqaleRepoContext) context.repositoryContext())::searchCachedUriId));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ public void initObjects() throws Exception {
ShadowType shadow1 = new ShadowType(prismContext).name("shadow-1")
.pendingOperation(new PendingOperationType().attemptNumber(1))
.pendingOperation(new PendingOperationType().attemptNumber(2))
.objectClass(SchemaConstants.RI_ACCOUNT_OBJECT_CLASS)
.extension(new ExtensionType(prismContext));
addExtensionValue(shadow1.getExtension(), "string", "string-value");
ItemName shadowAttributeName = new ItemName("http://example.com/p", "string-mv");
Expand Down Expand Up @@ -557,6 +558,14 @@ public void test146SearchTaskByEnumValueProvidedAsStringIsNotSupported() {
.isInstanceOf(SystemException.class);
}

@Test
public void test150SearchShadowByObjectClass() throws SchemaException {
// this uses URI mapping with QName instead of String
searchObjectTest("having specified object class", ShadowType.class,
f -> f.item(ShadowType.F_OBJECT_CLASS).eq(SchemaConstants.RI_ACCOUNT_OBJECT_CLASS),
shadow1Oid);
}

/**
* Searching by outcome in output in workitem in a case.
* This is a special-case column.
Expand Down

0 comments on commit be5d1d5

Please sign in to comment.