use of com.blazebit.persistence.KeysetPage in project blaze-persistence by Blazebit.
the class GraphQLEntityViewSupport method extractKeysetPage.
/**
* Extracts the {@link KeysetPage} from the page size and offset,
* as well as deserializing before or after cursors.
*
* @param first The GraphQL relay first parameter
* @param last The GraphQL relay last parameter
* @param beforeCursor The GraphQL relay before cursor
* @param afterCursor The GraphQL relay after cursor
* @return the {@link KeysetPage} or <code>null</code>
*/
public KeysetPage extractKeysetPage(Integer first, Integer last, String beforeCursor, String afterCursor) {
if (first == null && last == null && beforeCursor == null && afterCursor == null) {
return null;
} else {
KeysetPage keysetPage;
if (beforeCursor != null) {
if (afterCursor != null) {
throw new RuntimeException("Can't provide both beforeCursor and afterCursor!");
}
GraphQLCursor cursor = deserialize(beforeCursor);
keysetPage = new DefaultKeysetPage(cursor.getOffset(), cursor.getPageSize(), new DefaultKeyset(cursor.getTuple()), null);
} else if (afterCursor != null) {
if (last != null) {
// Using an after cursor with last does not make sense, so skip using the cursor
// The only problem with that is, that the cursor could refer to the last element
// If that is the case, we would still get a result, which is IMO an edge case and can be ignored
keysetPage = new DefaultKeysetPage(0, last, new DefaultKeyset(null), null);
} else {
GraphQLCursor cursor = deserialize(afterCursor);
keysetPage = new DefaultKeysetPage(cursor.getOffset(), cursor.getPageSize(), null, new DefaultKeyset(cursor.getTuple()));
}
} else if (first != null) {
keysetPage = new DefaultKeysetPage(0, first, null, null);
} else {
// Keyset with empty tuple is a special case for traversing the result list in reverse order
keysetPage = new DefaultKeysetPage(0, last, new DefaultKeyset(null), null);
}
return keysetPage;
}
}
use of com.blazebit.persistence.KeysetPage in project blaze-persistence by Blazebit.
the class OptimizedKeysetPaginationRowValueConstructorTest method keysetPaginationWithSimpleObjectQueryTest.
@Test
public void keysetPaginationWithSimpleObjectQueryTest() {
KeysetPage keyset = null;
PaginatedCriteriaBuilder<String> crit = cbf.create(em, String.class).from(Document.class, "d").orderByAsc("d.id").selectNew(new ObjectBuilder<String>() {
@Override
public <X extends SelectBuilder<X>> void applySelects(X selectBuilder) {
selectBuilder.select("d.name").select("d.owner.name");
}
@Override
public String build(Object[] tuple) {
return tuple[0] + " - " + tuple[1];
}
@Override
public List<String> buildList(List<String> list) {
return list;
}
}).page(keyset, 0, 1);
PagedList<String> result = crit.getResultList();
assertEquals(1, result.size());
assertEquals("doc1 - Karl1", result.get(0));
keyset = result.getKeysetPage();
crit = crit.page(keyset, 1, 1);
result = crit.getResultList();
assertEquals(1, result.size());
assertEquals("doc2 - Karl2", result.get(0));
}
use of com.blazebit.persistence.KeysetPage in project blaze-persistence by Blazebit.
the class OptimizedKeysetPaginationTest method keysetPaginationWithSimpleObjectQueryTest.
@Test
public void keysetPaginationWithSimpleObjectQueryTest() {
KeysetPage keyset = null;
PaginatedCriteriaBuilder<String> crit = cbf.create(em, String.class).from(DocumentWithNullableName.class, "d").orderByAsc("d.id").selectNew(new ObjectBuilder<String>() {
@Override
public <X extends SelectBuilder<X>> void applySelects(X selectBuilder) {
selectBuilder.select("d.name").select("d.owner.name");
}
@Override
public String build(Object[] tuple) {
return tuple[0] + " - " + tuple[1];
}
@Override
public List<String> buildList(List<String> list) {
return list;
}
}).page(keyset, 0, 1);
PagedList<String> result = crit.getResultList();
assertEquals(1, result.size());
assertEquals("doc1 - Karl1", result.get(0));
keyset = result.getKeysetPage();
crit = crit.page(keyset, 1, 1);
result = crit.getResultList();
assertEquals(1, result.size());
assertEquals("doc2 - Karl2", result.get(0));
}
use of com.blazebit.persistence.KeysetPage in project blaze-persistence by Blazebit.
the class KeysetPaginationTest method keysetPaginationWithSimpleObjectQueryTest.
@Test
public void keysetPaginationWithSimpleObjectQueryTest() {
KeysetPage keyset = null;
PaginatedCriteriaBuilder<String> crit = cbf.create(em, String.class).from(Document.class, "d").orderByAsc("d.id").selectNew(new ObjectBuilder<String>() {
@Override
public <X extends SelectBuilder<X>> void applySelects(X selectBuilder) {
selectBuilder.select("d.name").select("d.owner.name");
}
@Override
public String build(Object[] tuple) {
return tuple[0] + " - " + tuple[1];
}
@Override
public List<String> buildList(List<String> list) {
return list;
}
}).page(keyset, 0, 1);
PagedList<String> result = crit.getResultList();
assertEquals(1, result.size());
assertEquals("doc1 - Karl1", result.get(0));
keyset = result.getKeysetPage();
crit = crit.page(keyset, 1, 1);
result = crit.getResultList();
assertEquals(1, result.size());
assertEquals("doc2 - Karl2", result.get(0));
}
use of com.blazebit.persistence.KeysetPage in project blaze-persistence by Blazebit.
the class EntityViewSettingHelper method getQueryBuilder.
private static <T, Q extends FullQueryBuilder<T, Q>> Q getQueryBuilder(EntityViewSetting<T, Q> setting, CriteriaBuilder<?> criteriaBuilder, String entityViewRoot, ManagedViewTypeImplementor<?> managedView, Map<String, Object> properties) {
if (setting.isPaginated()) {
KeysetPage keysetPage = setting.getKeysetPage();
boolean forceUseKeyset = keysetPage != null && getBooleanProperty(properties, ConfigurationProperties.PAGINATION_FORCE_USE_KEYSET, false);
if (forceUseKeyset) {
setting.withKeysetPage(null);
}
PaginatedCriteriaBuilder<?> builder;
if (managedView instanceof FlatViewType<?>) {
if (setting.isKeysetPaginated()) {
if (setting.getFirstResult() == -1) {
builder = criteriaBuilder.pageAndNavigate(setting.getEntityId(), setting.getMaxResults()).withKeysetExtraction(true);
} else {
builder = criteriaBuilder.page(setting.getKeysetPage(), setting.getFirstResult(), setting.getMaxResults());
}
} else {
if (setting.getFirstResult() == -1) {
builder = criteriaBuilder.page(0, setting.getMaxResults());
} else {
builder = criteriaBuilder.page(setting.getFirstResult(), setting.getMaxResults());
}
}
} else {
// When the result should be paginated, we have to properly paginate by the identifier of the view
MethodAttribute<?, ?> idAttribute = ((ViewTypeImplementor<?>) managedView).getIdAttribute();
String firstExpression;
List<String> expressions;
if (idAttribute.isSubview()) {
String prefix = getMapping(entityViewRoot, idAttribute, criteriaBuilder);
ManagedViewTypeImplementor<?> type = (ManagedViewTypeImplementor<?>) ((SingularAttribute<?, ?>) idAttribute).getType();
Set<MethodAttribute<?, ?>> attributes = (Set) type.getAttributes();
Iterator<MethodAttribute<?, ?>> iterator = attributes.iterator();
firstExpression = getMapping(prefix, iterator.next(), criteriaBuilder);
if (iterator.hasNext()) {
expressions = new ArrayList<>(attributes.size() - 1);
while (iterator.hasNext()) {
expressions.add(getMapping(prefix, iterator.next(), criteriaBuilder));
}
} else {
expressions = null;
}
} else {
expressions = null;
firstExpression = getMapping(entityViewRoot, idAttribute, criteriaBuilder);
}
if (setting.isKeysetPaginated()) {
if (setting.getFirstResult() == -1) {
builder = criteriaBuilder.pageByAndNavigate(setting.getEntityId(), setting.getMaxResults(), firstExpression, getExpressionArray(expressions)).withKeysetExtraction(true);
} else {
builder = criteriaBuilder.pageBy(setting.getKeysetPage(), setting.getFirstResult(), setting.getMaxResults(), firstExpression, getExpressionArray(expressions));
}
} else {
if (setting.getFirstResult() == -1) {
builder = criteriaBuilder.pageBy(0, setting.getMaxResults(), firstExpression, getExpressionArray(expressions));
} else {
builder = criteriaBuilder.pageBy(setting.getFirstResult(), setting.getMaxResults(), firstExpression, getExpressionArray(expressions));
}
}
}
if (forceUseKeyset) {
if (keysetPage.getLowest() != null) {
builder.beforeKeyset(keysetPage.getLowest());
} else if (keysetPage.getHighest() != null) {
builder.afterKeyset(keysetPage.getHighest());
}
}
boolean disableCountQuery = getBooleanProperty(properties, ConfigurationProperties.PAGINATION_DISABLE_COUNT_QUERY, false);
if (disableCountQuery) {
builder.withCountQuery(false);
} else {
Integer boundedCount = null;
Object o = properties.get(ConfigurationProperties.PAGINATION_BOUNDED_COUNT);
if (o != null) {
if (o instanceof Integer || o instanceof Long) {
boundedCount = ((Number) o).intValue();
} else if (o instanceof String) {
boundedCount = Integer.parseInt((String) o);
} else {
throw new IllegalArgumentException("Invalid value of type " + o.getClass().getName() + " given for the integer property: " + ConfigurationProperties.PAGINATION_BOUNDED_COUNT);
}
}
if (boundedCount != null) {
builder.withBoundedCount(boundedCount);
}
}
Integer highestKeyOffset = null;
Object o = properties.get(ConfigurationProperties.PAGINATION_HIGHEST_KEYSET_OFFSET);
if (o != null) {
if (o instanceof Integer) {
highestKeyOffset = ((Number) o).intValue();
} else if (o instanceof String) {
highestKeyOffset = Integer.parseInt((String) o);
} else {
throw new IllegalArgumentException("Invalid value of type " + o.getClass().getName() + " given for the integer property: " + ConfigurationProperties.PAGINATION_HIGHEST_KEYSET_OFFSET);
}
}
if (highestKeyOffset != null) {
builder.withHighestKeysetOffset(highestKeyOffset);
}
boolean extractAllKeysets = getBooleanProperty(properties, ConfigurationProperties.PAGINATION_EXTRACT_ALL_KEYSETS, false);
if (extractAllKeysets) {
builder.withExtractAllKeysets(true);
}
return (Q) builder;
} else {
return (Q) criteriaBuilder;
}
}
Aggregations