use of com.blazebit.persistence.Keyset in project blaze-persistence by Blazebit.
the class KeysetManager method buildOptimizedKeysetPredicate.
public void buildOptimizedKeysetPredicate(StringBuilder sb, int positionalOffset) {
KeysetLink keysetLink = getKeysetLink();
KeysetMode keysetMode = keysetLink.getKeysetMode();
Keyset keyset = keysetLink.getKeyset();
Serializable[] key = keyset.getTuple();
OrderByExpression extractedNonNullableExpression = null;
if (key != null) {
boolean hasNullableOrderBys = false;
// TODO: Determine if order by expression has parameter as that will ruin reordering of expressions in row value constructor
boolean hasParameterInOrderBy = false;
for (OrderByExpression orderByExpression : orderByExpressions) {
if (orderByExpression.isNullable()) {
hasNullableOrderBys = true;
break;
}
}
extractedNonNullableExpression = orderByExpressions.get(0);
// if all order bys are non-nullable because null elements would break the row value comparison.
if (hasNullableOrderBys || hasParameterInOrderBy || !dbmsDialect.supportsFullRowValueComparison() || !jpaProvider.supportsCustomFunctions()) {
// Under certain conditions, we cannot render an optimized form because we would need to include
// null checks involving disjunction on the top predicate level which would contradict the main idea of the
// optimization.
boolean optimizationAllowed = !extractedNonNullableExpression.isNullable() || keysetMode == KeysetMode.NEXT && extractedNonNullableExpression.isNullFirst() && key[0] != null || keysetMode == KeysetMode.PREVIOUS && !extractedNonNullableExpression.isNullFirst() && key[0] != null;
if (optimizationAllowed) {
applyOptimizedKeysetNotNullItem(extractedNonNullableExpression, sb, 0, key[0], keysetMode, false, positionalOffset);
if (orderByExpressions.size() > 1) {
sb.append(" AND NOT (");
applyKeysetItem(sb, extractedNonNullableExpression.getExpression(), "=", 0, key[0], positionalOffset);
sb.append(" AND ");
buildOptimizedPredicate0(keysetMode, key, sb, orderByExpressions, positionalOffset);
sb.append(")");
}
} else {
buildKeysetPredicate0(keysetMode, key, sb, orderByExpressions, positionalOffset);
}
} else {
// we can use row value constructor syntax
// the rendering is heavily bound to the way this is parsed in RowValueComparisonFunction
queryGenerator.setClauseType(ClauseType.WHERE);
queryGenerator.setQueryBuffer(sb);
queryGenerator.setClauseType(null);
sb.append(jpaProvider.getCustomFunctionInvocation(RowValueComparisonFunction.FUNCTION_NAME, 1)).append('\'').append(keysetMode == KeysetMode.SAME ? "<=" : "<").append('\'');
for (int i = 0; i < orderByExpressions.size(); i++) {
OrderByExpression orderByExpression = orderByExpressions.get(i);
sb.append(",CASE WHEN (1=NULLIF(1,1) AND ");
if (orderByExpression.isDescending() && keysetMode != KeysetMode.PREVIOUS || orderByExpression.isAscending() && keysetMode == KeysetMode.PREVIOUS) {
// Placeholder is needed as we need to render the parameter at the end to retain JDBC parameter order
sb.append("1=NULLIF(1,1)");
} else {
applyKeysetParameter(sb, i, key[i], positionalOffset);
sb.append('=');
queryGenerator.generate(orderByExpression.getExpression());
}
sb.append(") THEN 1 ELSE 0 END");
}
// We have to render right hand side parameters at the end to retain the correct order
for (int i = 0; i < orderByExpressions.size(); i++) {
OrderByExpression orderByExpression = orderByExpressions.get(i);
if (orderByExpression.isDescending() && keysetMode != KeysetMode.PREVIOUS || orderByExpression.isAscending() && keysetMode == KeysetMode.PREVIOUS) {
sb.append(",CASE WHEN (1=NULLIF(1,1) AND ");
queryGenerator.generate(orderByExpression.getExpression());
sb.append('=');
applyKeysetParameter(sb, i, key[i], positionalOffset);
sb.append(") THEN 1 ELSE 0 END");
}
}
sb.append(") = 0");
}
}
}
use of com.blazebit.persistence.Keyset in project blaze-persistence by Blazebit.
the class GraphQLEntityViewSupport method createRelayConnection.
/**
* Returns a relay connection from the given result list.
*
* @param list the result list
* @return the relay connection
*/
public <T> Connection<T> createRelayConnection(List<T> list) {
List<Edge<T>> edges = new ArrayList<>(list.size());
boolean hasPreviousPage;
boolean hasNextPage;
KeysetPage keysetPage;
if (list instanceof PagedList<?>) {
PagedList<T> data = (PagedList<T>) list;
hasPreviousPage = data.getFirstResult() != 0;
hasNextPage = data.getTotalSize() == -1 || data.getFirstResult() + data.getMaxResults() < data.getTotalSize();
keysetPage = data.getKeysetPage();
} else {
hasPreviousPage = true;
hasNextPage = true;
keysetPage = null;
}
if (keysetPage == null) {
for (int i = 0; i < list.size(); i++) {
edges.add(new DefaultEdge<>(list.get(i), new DefaultConnectionCursor(Integer.toString(i + 1))));
}
} else {
PagedList<T> data = (PagedList<T>) list;
List<Keyset> keysets = keysetPage.getKeysets();
int listSize = list.size();
if (listSize != 0 && keysets.size() != listSize) {
int end = listSize - 1;
edges.add(new DefaultEdge<>(list.get(0), new DefaultConnectionCursor(Base64.getEncoder().encodeToString(serializeCursor(data.getFirstResult(), data.getMaxResults(), keysetPage.getLowest().getTuple())))));
for (int i = 1; i < end; i++) {
T node = list.get(i);
edges.add(new DefaultEdge<>(node, new DefaultConnectionCursor(Integer.toString(i + 1))));
}
edges.add(new DefaultEdge<>(list.get(end), new DefaultConnectionCursor(Base64.getEncoder().encodeToString(serializeCursor(data.getFirstResult(), data.getMaxResults(), keysetPage.getHighest().getTuple())))));
} else {
for (int i = 0; i < list.size(); i++) {
T node = list.get(i);
edges.add(new DefaultEdge<>(node, new DefaultConnectionCursor(Base64.getEncoder().encodeToString(serializeCursor(data.getFirstResult(), data.getMaxResults(), keysets.get(i).getTuple())))));
}
}
}
PageInfo pageInfo;
if (edges.isEmpty()) {
pageInfo = new DefaultPageInfo(null, null, hasPreviousPage, hasNextPage);
} else {
pageInfo = new DefaultPageInfo(edges.get(0).getCursor(), edges.get(edges.size() - 1).getCursor(), hasPreviousPage, hasNextPage);
}
return new DefaultConnection<>(edges, pageInfo);
}
use of com.blazebit.persistence.Keyset in project blaze-persistence by Blazebit.
the class KeysetManager method buildKeysetPredicate.
public void buildKeysetPredicate(StringBuilder sb, int positionalOffset) {
KeysetLink keysetLink = getKeysetLink();
KeysetMode keysetMode = keysetLink.getKeysetMode();
Keyset keyset = keysetLink.getKeyset();
Serializable[] key = keyset.getTuple();
if (key != null) {
buildKeysetPredicate0(keysetMode, key, sb, orderByExpressions, positionalOffset);
}
}
Aggregations