use of com.evolveum.midpoint.repo.sql.query.QueryEngine in project midpoint by Evolveum.
the class ObjectRetriever method searchObjectsIterativeAttempt.
public <T extends ObjectType> void searchObjectsIterativeAttempt(Class<T> type, ObjectQuery query, ResultHandler<T> handler, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult result, Set<String> retrievedOids) {
Set<String> newlyRetrievedOids = new HashSet<>();
Session session = null;
try {
session = baseHelper.beginReadOnlyTransaction();
RQuery rQuery;
QueryEngine engine = new QueryEngine(getConfiguration(), extItemDictionary, prismContext, relationRegistry);
rQuery = engine.interpret(query, type, options, false, session);
try (ScrollableResults results = rQuery.scroll(ScrollMode.FORWARD_ONLY)) {
Iterator<GetObjectResult> iterator = new ScrollableResultsIterator<>(results);
while (iterator.hasNext()) {
GetObjectResult object = iterator.next();
if (retrievedOids.contains(object.getOid())) {
continue;
}
// TODO treat exceptions encountered within the next call
PrismObject<T> prismObject = updateLoadedObject(object, type, null, options, null, session);
/*
* We DO NOT store OIDs directly into retrievedOids, because this would mean that any duplicated results
* would get eliminated from processing. While this is basically OK, it would break existing behavior,
* and would lead to inconsistencies between e.g. "estimated total" vs "progress" in iterative tasks.
* Such inconsistencies could happen also in the current approach with retrievedOids/newlyRetrievedOids,
* but are much less likely.
* TODO reconsider this in the future - i.e. if it would not be beneficial to skip duplicate processing of objects
* TODO what about memory requirements of this data structure (consider e.g. millions of objects)
*/
newlyRetrievedOids.add(object.getOid());
if (!handler.handle(prismObject, result)) {
break;
}
}
}
session.getTransaction().commit();
} catch (SchemaException | QueryException | RuntimeException | ObjectNotFoundException ex) {
baseHelper.handleGeneralException(ex, session, result);
} finally {
baseHelper.cleanupSessionAndResult(session, result);
retrievedOids.addAll(newlyRetrievedOids);
}
}
use of com.evolveum.midpoint.repo.sql.query.QueryEngine in project midpoint by Evolveum.
the class ObjectRetriever method countObjectsAttempt.
public <T extends ObjectType> int countObjectsAttempt(Class<T> type, ObjectQuery query, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult result) {
LOGGER_PERFORMANCE.debug("> count objects {}", type.getSimpleName());
int count = 0;
Session session = null;
try {
Class<? extends RObject> hqlType = ClassMapper.getHQLTypeClass(type);
session = baseHelper.beginReadOnlyTransaction();
Number longCount;
query = refineAssignmentHolderQuery(type, query);
if (query == null || query.getFilter() == null) {
// this is 5x faster than count with 3 inner joins, it can probably improved also for queries which
// filters uses only properties from concrete entities like RUser, RRole by improving interpreter [lazyman]
// note: distinct can be ignored here, as there is no filter, so no joins
NativeQuery sqlQuery = session.createNativeQuery("SELECT COUNT(*) FROM " + RUtil.getTableName(hqlType, session));
longCount = (Number) sqlQuery.uniqueResult();
} else {
RQuery rQuery;
QueryEngine engine = new QueryEngine(getConfiguration(), extItemDictionary, prismContext, relationRegistry);
rQuery = engine.interpret(query, type, options, true, session);
longCount = rQuery.uniqueResult();
}
LOGGER.trace("Found {} objects.", longCount);
count = longCount != null ? longCount.intValue() : 0;
session.getTransaction().commit();
} catch (QueryException | RuntimeException ex) {
baseHelper.handleGeneralException(ex, session, result);
} finally {
baseHelper.cleanupSessionAndResult(session, result);
}
return count;
}
use of com.evolveum.midpoint.repo.sql.query.QueryEngine in project midpoint by Evolveum.
the class ObjectRetriever method countContainersAttempt.
public <C extends Containerable> int countContainersAttempt(Class<C> type, ObjectQuery query, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult result) {
boolean cases = AccessCertificationCaseType.class.equals(type);
boolean workItems = AccessCertificationWorkItemType.class.equals(type);
boolean caseWorkItems = CaseWorkItemType.class.equals(type);
if (!cases && !workItems && !caseWorkItems) {
throw new UnsupportedOperationException("Only AccessCertificationCaseType or AccessCertificationWorkItemType or CaseWorkItemType is supported here now.");
}
LOGGER_PERFORMANCE.debug("> count containers {}", type.getSimpleName());
Session session = null;
try {
session = baseHelper.beginReadOnlyTransaction();
QueryEngine engine = new QueryEngine(getConfiguration(), extItemDictionary, prismContext, relationRegistry);
RQuery rQuery = engine.interpret(query, type, options, true, session);
Number longCount = rQuery.uniqueResult();
LOGGER.trace("Found {} objects.", longCount);
session.getTransaction().commit();
return longCount != null ? longCount.intValue() : 0;
} catch (QueryException | RuntimeException ex) {
baseHelper.handleGeneralException(ex, session, result);
throw new AssertionError("Shouldn't get here; previous method call should throw an exception.");
} finally {
baseHelper.cleanupSessionAndResult(session, result);
}
}
use of com.evolveum.midpoint.repo.sql.query.QueryEngine in project midpoint by Evolveum.
the class QueryInterpreterTest method getInterpretedQueryWhole.
@NotNull
private <T extends Containerable> RQuery getInterpretedQueryWhole(Session session, Class<T> type, ObjectQuery query, boolean interpretCount, Collection<SelectorOptions<GetOperationOptions>> options) throws QueryException {
if (query != null) {
logger.info("QUERY TYPE TO CONVERT :\n{}", (query.getFilter() != null ? query.getFilter().debugDump(3) : null));
}
QueryEngine engine = new QueryEngine(baseHelper.getConfiguration(), extItemDictionary, prismContext, relationRegistry);
RQuery rQuery = engine.interpret(query, type, options, interpretCount, session);
// just test if DB will handle it or throws some exception
if (interpretCount) {
rQuery.uniqueResult();
} else {
rQuery.list();
}
return rQuery;
}
use of com.evolveum.midpoint.repo.sql.query.QueryEngine in project midpoint by Evolveum.
the class ObjectRetriever method executeQueryDiagnosticsRequest.
public RepositoryQueryDiagResponse executeQueryDiagnosticsRequest(RepositoryQueryDiagRequest request, OperationResult result) {
LOGGER_PERFORMANCE.debug("> execute query diagnostics {}", request);
Session session = null;
try {
// beware, not all databases support read-only transactions!
session = baseHelper.beginReadOnlyTransaction();
final String implementationLevelQuery;
final Map<String, RepositoryQueryDiagResponse.ParameterValue> implementationLevelQueryParameters;
final Query<?> query;
final boolean isMidpointQuery = request.getImplementationLevelQuery() == null;
if (isMidpointQuery) {
QueryEngine engine = new QueryEngine(getConfiguration(), extItemDictionary, prismContext, relationRegistry);
RQueryImpl rQuery = (RQueryImpl) engine.interpret(request.getQuery(), request.getType(), request.getOptions(), false, session);
query = rQuery.getQuery();
implementationLevelQuery = query.getQueryString();
implementationLevelQueryParameters = new HashMap<>();
for (Map.Entry<String, QueryParameterValue> entry : rQuery.getQuerySource().getParameters().entrySet()) {
implementationLevelQueryParameters.put(entry.getKey(), new RepositoryQueryDiagResponse.ParameterValue(entry.getValue().getValue(), entry.getValue().toString()));
}
} else {
implementationLevelQuery = (String) request.getImplementationLevelQuery();
implementationLevelQueryParameters = new HashMap<>();
query = session.createQuery(implementationLevelQuery);
}
List<?> objects = request.isTranslateOnly() ? null : query.list();
if (isMidpointQuery && objects != null) {
// raw GetObjectResult instances are useless outside repo-sql-impl module, so we'll convert them to objects
@SuppressWarnings("unchecked") List<GetObjectResult> listOfGetObjectResults = (List<GetObjectResult>) objects;
objects = queryResultToPrismObjects(listOfGetObjectResults, request.getType(), null, session, result);
}
RepositoryQueryDiagResponse response = new RepositoryQueryDiagResponse(objects, implementationLevelQuery, implementationLevelQueryParameters);
session.getTransaction().rollback();
return response;
} catch (SchemaException | QueryException | RuntimeException ex) {
baseHelper.handleGeneralException(ex, session, result);
throw new IllegalStateException("shouldn't get here");
} finally {
baseHelper.cleanupSessionAndResult(session, result);
}
}
Aggregations