Skip to content

Commit

Permalink
Small cleanup of db query result processing.
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed May 10, 2017
1 parent ebd4e4c commit 253d240
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 84 deletions.
Expand Up @@ -322,7 +322,7 @@ private PrismObject resolve(Session session, String oid, String defaultName, ROb
}
Query query = session.getNamedQuery("get.object");
query.setParameter("oid", oid);
query.setResultTransformer(GetObjectResult.RESULT_TRANSFORMER);
query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer());
GetObjectResult object = (GetObjectResult) query.uniqueResult();

PrismObject result;
Expand Down
Expand Up @@ -167,7 +167,7 @@ public <T extends ObjectType> PrismObject<T> getObjectInternal(Session session,
if (!lockForUpdate) {
Query query = session.getNamedQuery("get.object");
query.setString("oid", oid);
query.setResultTransformer(GetObjectResult.RESULT_TRANSFORMER);
query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer());
query.setLockOptions(lockOptions);

fullObject = (GetObjectResult) query.uniqueResult();
Expand Down Expand Up @@ -230,7 +230,7 @@ public <F extends FocusType> PrismObject<F> searchShadowOwnerAttempt(String shad
LOGGER.trace("Selecting account shadow owner for account {}.", new Object[]{shadowOid});
Query query = session.getNamedQuery("searchShadowOwner.getOwner");
query.setString("oid", shadowOid);
query.setResultTransformer(GetObjectResult.RESULT_TRANSFORMER);
query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer());

List<GetObjectResult> focuses = query.list();
LOGGER.trace("Found {} focuses, transforming data to JAXB types.", focuses != null ? focuses.size() : 0);
Expand Down Expand Up @@ -268,7 +268,7 @@ public PrismObject<UserType> listAccountShadowOwnerAttempt(String accountOid, Op
session = baseHelper.beginReadOnlyTransaction();
Query query = session.getNamedQuery("listAccountShadowOwner.getUser");
query.setString("oid", accountOid);
query.setResultTransformer(GetObjectResult.RESULT_TRANSFORMER);
query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer());

List<GetObjectResult> users = query.list();
LOGGER.trace("Found {} users, transforming data to JAXB types.", users != null ? users.size() : 0);
Expand Down Expand Up @@ -569,7 +569,7 @@ public <T extends ShadowType> List<PrismObject<T>> listResourceObjectShadowsAtte
session = baseHelper.beginReadOnlyTransaction();
Query query = session.getNamedQuery("listResourceObjectShadows");
query.setString("oid", resourceOid);
query.setResultTransformer(GetObjectResult.RESULT_TRANSFORMER);
query.setResultTransformer(GetObjectResult.RESULT_STYLE.getResultTransformer());

List<GetObjectResult> shadows = query.list();
LOGGER.debug("Query returned {} shadows, transforming to JAXB types.", shadows != null ? shadows.size() : 0);
Expand Down
Expand Up @@ -40,14 +40,14 @@
import com.evolveum.midpoint.repo.sql.util.GetCertificationWorkItemResult;
import com.evolveum.midpoint.repo.sql.util.GetContainerableResult;
import com.evolveum.midpoint.repo.sql.util.GetObjectResult;
import com.evolveum.midpoint.repo.sql.util.ResultStyle;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationWorkItemType;
import org.hibernate.Session;
import org.hibernate.transform.ResultTransformer;
import org.jetbrains.annotations.NotNull;

import java.util.*;
Expand Down Expand Up @@ -114,11 +114,13 @@ public RootHibernateQuery interpret(ObjectQuery query, @NotNull Class<? extends

InterpretationContext context = new InterpretationContext(this, type, prismContext, session);
interpretQueryFilter(context, query);
String rootAlias = context.getHibernateQuery().getPrimaryEntityAlias();
ResultStyle resultStyle = getResultStyle(context);

if (countingObjects) {
interpretPagingAndSorting(context, query, true);
RootHibernateQuery hibernateQuery = context.getHibernateQuery();
hibernateQuery.addProjectionElement(new CountProjectionElement(getIdentifiers(context), distinct));
hibernateQuery.addProjectionElement(new CountProjectionElement(resultStyle.getIdentifiers(rootAlias), distinct));
return hibernateQuery;
}

Expand All @@ -134,74 +136,42 @@ u.oid in (select distinct u.oid from RUser u where ...)
boolean distinctBlobCapable = !repoConfiguration.isUsingOracle() && !repoConfiguration.isUsingSQLServer();
RootHibernateQuery hibernateQuery = context.getHibernateQuery();
hibernateQuery.setDistinct(distinct);
hibernateQuery.addProjectionElementsFor(getIdentifiers(context));
hibernateQuery.addProjectionElementsFor(resultStyle.getIdentifiers(rootAlias));
if (distinct && !distinctBlobCapable) {
String subqueryText = "\n" + hibernateQuery.getAsHqlText(2, true);
InterpretationContext wrapperContext = new InterpretationContext(this, type, prismContext, session);
interpretPagingAndSorting(wrapperContext, query, false);
RootHibernateQuery wrapperQuery = wrapperContext.getHibernateQuery();
wrapperQuery.addProjectionElementsFor(getIdentifiers(context));
wrapperQuery.addProjectionElementsFor(getContentAttributes(context));
wrapperQuery.setResultTransformer(getResultTransformer(context));
String wrappedRootAlias = wrapperQuery.getPrimaryEntityAlias();
wrapperQuery.setResultTransformer(resultStyle.getResultTransformer());
wrapperQuery.addProjectionElementsFor(resultStyle.getIdentifiers(wrappedRootAlias));
wrapperQuery.addProjectionElementsFor(resultStyle.getContentAttributes(wrappedRootAlias));
wrapperQuery.getConditions().add(
wrapperQuery.createIn(wrapperQuery.getPrimaryEntityAlias() + ".oid", subqueryText));
wrapperQuery.addParametersFrom(hibernateQuery.getParameters());
return wrapperQuery;
} else {
interpretPagingAndSorting(context, query, false);
hibernateQuery.addProjectionElementsFor(getContentAttributes(context));
hibernateQuery.setResultTransformer(resultStyle.getResultTransformer());
hibernateQuery.addProjectionElementsFor(resultStyle.getContentAttributes(rootAlias));
if (distinct) {
hibernateQuery.addProjectionElementsFor(getOrderingAttributes(context)); // SQL requires this
}
hibernateQuery.setResultTransformer(getResultTransformer(context));
return hibernateQuery;
}
}

private List<String> getIdentifiers(InterpretationContext context) throws QueryException {
String rootAlias = context.getHibernateQuery().getPrimaryEntityAlias();
if (context.isObject()) {
return Collections.singletonList(rootAlias + ".oid");
} else if (AccessCertificationCaseType.class.equals(context.getType())) {
return Arrays.asList(rootAlias + ".ownerOid", rootAlias + ".id");
} else if (AccessCertificationWorkItemType.class.equals(context.getType())) {
return Arrays.asList(rootAlias + ".ownerOwnerOid", rootAlias + ".ownerId", rootAlias + ".id");
} else {
throw new QueryException("Unsupported type: " + context.getType());
}
}

private List<String> getContentAttributes(InterpretationContext context) throws QueryException {
String rootAlias = context.getHibernateQuery().getPrimaryEntityAlias();
if (context.isObject()) {
return Arrays.asList(
rootAlias + ".fullObject",
rootAlias + ".stringsCount",
rootAlias + ".longsCount",
rootAlias + ".datesCount",
rootAlias + ".referencesCount",
rootAlias + ".polysCount",
rootAlias + ".booleansCount");
} else if (AccessCertificationCaseType.class.equals(context.getType())) {
return Collections.singletonList(rootAlias + ".fullObject");
} else if (AccessCertificationWorkItemType.class.equals(context.getType())) {
return Collections.emptyList();
} else {
throw new QueryException("Unsupported type: " + context.getType());
}
}

private List<String> getOrderingAttributes(InterpretationContext context) {
return context.getHibernateQuery().getOrderingList().stream().map(o -> o.getByProperty()).collect(Collectors.toList());
}

private ResultTransformer getResultTransformer(InterpretationContext context) throws QueryException {
private ResultStyle getResultStyle(InterpretationContext context) throws QueryException {
if (context.isObject()) {
return GetObjectResult.RESULT_TRANSFORMER;
return GetObjectResult.RESULT_STYLE;
} else if (AccessCertificationCaseType.class.equals(context.getType())) {
return GetContainerableResult.RESULT_TRANSFORMER;
return GetContainerableResult.RESULT_STYLE;
} else if (AccessCertificationWorkItemType.class.equals(context.getType())) {
return GetCertificationWorkItemResult.RESULT_TRANSFORMER;
return GetCertificationWorkItemResult.RESULT_STYLE;
} else {
throw new QueryException("Unsupported type: " + context.getType());
}
Expand All @@ -216,8 +186,7 @@ private void interpretQueryFilter(InterpretationContext context, ObjectQuery que

public Condition interpretFilter(InterpretationContext context, ObjectFilter filter, Restriction parent) throws QueryException {
Restriction restriction = findAndCreateRestriction(filter, context, parent);
Condition condition = restriction.interpret();
return condition;
return restriction.interpret();
}

private <T extends ObjectFilter> Restriction findAndCreateRestriction(@NotNull T filter,
Expand Down Expand Up @@ -326,7 +295,7 @@ private void interpretPagingAndSorting(InterpretationContext context, ObjectQuer
}
}

protected void updatePagingAndSortingByOid(RootHibernateQuery hibernateQuery, ObjectPagingAfterOid paging) {
private void updatePagingAndSortingByOid(RootHibernateQuery hibernateQuery, ObjectPagingAfterOid paging) {
String rootAlias = hibernateQuery.getPrimaryEntityAlias();
if (paging.getOrderBy() != null || paging.getDirection() != null || paging.getOffset() != null) {
throw new IllegalArgumentException("orderBy, direction nor offset is allowed on ObjectPagingAfterOid");
Expand All @@ -337,13 +306,10 @@ protected void updatePagingAndSortingByOid(RootHibernateQuery hibernateQuery, Ob
}
}

public <T extends Containerable> void updatePagingAndSorting(InterpretationContext context,
ObjectPaging paging) throws QueryException {

if (paging == null) {
private void updatePagingAndSorting(InterpretationContext context, ObjectPaging paging) throws QueryException {
if (paging == null) {
return;
}

RootHibernateQuery hibernateQuery = context.getHibernateQuery();
if (paging.getOffset() != null) {
hibernateQuery.setFirstResult(paging.getOffset());
Expand Down
Expand Up @@ -21,18 +21,36 @@
import org.jetbrains.annotations.NotNull;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
* @author mederly
*/
public class GetCertificationWorkItemResult implements Serializable {

public static final ResultTransformer RESULT_TRANSFORMER = new BasicTransformerAdapter() {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return new GetCertificationWorkItemResult((String) tuple[0], (Integer) tuple[1], (Integer) tuple[2]);
}
};
public static final ResultStyle RESULT_STYLE = new ResultStyle() {
@Override
public ResultTransformer getResultTransformer() {
return new BasicTransformerAdapter() {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return new GetCertificationWorkItemResult((String) tuple[0], (Integer) tuple[1], (Integer) tuple[2]);
}
};
}

@Override
public List<String> getIdentifiers(String rootAlias) {
return Arrays.asList(rootAlias + ".ownerOwnerOid", rootAlias + ".ownerId", rootAlias + ".id");
}

@Override
public List<String> getContentAttributes(String basePath) {
return Collections.emptyList();
}
};

@NotNull private final String campaignOid;
@NotNull private final Integer caseId;
Expand Down
Expand Up @@ -5,27 +5,41 @@
import org.jetbrains.annotations.NotNull;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
* @author lazyman
* @author mederly
*/
public class GetContainerableResult implements Serializable {

public static final ResultTransformer RESULT_TRANSFORMER = new BasicTransformerAdapter() {
public static final ResultStyle RESULT_STYLE = new ResultStyle() {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return new GetContainerableResult(tuple); // ownerOid, id, fullObject
public ResultTransformer getResultTransformer() {
return new BasicTransformerAdapter() {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return new GetContainerableResult((String) tuple[0], (byte[]) tuple[2]);
}
};
}

@Override
public List<String> getIdentifiers(String rootAlias) {
return Arrays.asList(rootAlias + ".ownerOid", rootAlias + ".id");
}

@Override
public List<String> getContentAttributes(String rootAlias) {
return Collections.singletonList(rootAlias + ".fullObject");
}
};

private final String ownerOid;
private final byte[] fullObject;

private GetContainerableResult(Object[] values) {
this((String) values[0], (byte[]) values[2]);
}

private GetContainerableResult(@NotNull String ownerOid, @NotNull byte[] fullObject) {
this.fullObject = fullObject;
this.ownerOid = ownerOid;
Expand Down
Expand Up @@ -6,6 +6,9 @@
import org.jetbrains.annotations.NotNull;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
* @author lazyman
Expand All @@ -15,11 +18,38 @@ public class GetObjectResult implements Serializable {
public static final Class[] EXT_COUNT_CLASSES = new Class[]{ROExtString.class, ROExtLong.class, ROExtDate.class,
ROExtReference.class, ROExtPolyString.class, ROExtBoolean.class};

public static final ResultTransformer RESULT_TRANSFORMER = new BasicTransformerAdapter() {
public static final ResultStyle RESULT_STYLE = new ResultStyle() {
@Override
public ResultTransformer getResultTransformer() {
return new BasicTransformerAdapter() {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return new GetObjectResult((String) tuple[0], (byte[]) tuple[1],
tuple.length > 2 ? (Short) tuple[2] : null,
tuple.length > 3 ? (Short) tuple[3] : null,
tuple.length > 4 ? (Short) tuple[4] : null,
tuple.length > 5 ? (Short) tuple[5] : null,
tuple.length > 6 ? (Short) tuple[6] : null,
tuple.length > 7 ? (Short) tuple[7] : null);
}
};
}

@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return new GetObjectResult(tuple);
public List<String> getIdentifiers(String rootAlias) {
return Collections.singletonList(rootAlias + ".oid");
}

@Override
public List<String> getContentAttributes(String rootAlias) {
return Arrays.asList(
rootAlias + ".fullObject",
rootAlias + ".stringsCount",
rootAlias + ".longsCount",
rootAlias + ".datesCount",
rootAlias + ".referencesCount",
rootAlias + ".polysCount",
rootAlias + ".booleansCount");
}
};

Expand All @@ -33,16 +63,6 @@ public Object transformTuple(Object[] tuple, String[] aliases) {
private Short polysCount;
private Short booleansCount;

public GetObjectResult(Object[] values) {
this((String) values[0], (byte[]) values[1],
values.length > 2 ? (Short) values[2] : null,
values.length > 3 ? (Short) values[3] : null,
values.length > 4 ? (Short) values[4] : null,
values.length > 5 ? (Short) values[5] : null,
values.length > 6 ? (Short) values[6] : null,
values.length > 7 ? (Short) values[7] : null);
}

public GetObjectResult(@NotNull String oid, @NotNull byte[] fullObject, Short stringsCount, Short longsCount, Short datesCount,
Short referencesCount, Short polysCount, Short booleansCount) {

Expand Down
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2010-2017 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.evolveum.midpoint.repo.sql.util;

import org.hibernate.transform.ResultTransformer;

import java.util.List;

/**
* @author mederly
*/
public interface ResultStyle {
ResultTransformer getResultTransformer();
List<String> getIdentifiers(String basePath);
List<String> getContentAttributes(String basePath);
}

0 comments on commit 253d240

Please sign in to comment.