Search in sources :

Example 1 with PagedList

use of com.blazebit.persistence.PagedList in project blaze-persistence by Blazebit.

the class PaginatedTypedQueryImpl method getResultList.

private PagedList<X> getResultList(int queryFirstResult, int firstRow, long totalSize) {
    if (idQuery != null) {
        idQuery.setMaxResults(pageSize);
        if (forceFirstResult || keysetMode == KeysetMode.NONE) {
            idQuery.setFirstResult(firstRow);
        } else {
            idQuery.setFirstResult(0);
        }
        List<?> ids = idQuery.getResultList();
        if (ids.isEmpty()) {
            KeysetPage newKeysetPage = null;
            if (keysetMode == KeysetMode.NEXT) {
                // When we scroll over the last page to a non existing one, we reuse the current keyset
                newKeysetPage = keysetPage;
            }
            long size;
            if (withCount && totalSize == -1) {
                size = getTotalCount();
            } else {
                size = totalSize;
            }
            if (boundedCount) {
                if (keysetMode == KeysetMode.NEXT) {
                    size = Math.max(size, keysetPage.getFirstResult() + keysetPage.getMaxResults());
                } else if (forceFirstResult || keysetMode == KeysetMode.NONE) {
                    size = Math.max(size, firstRow);
                }
            }
            return new PagedArrayList<X>(newKeysetPage, size, queryFirstResult, pageSize);
        }
        Serializable[] lowest = null;
        Serializable[] highest = null;
        Serializable[][] keysets = null;
        if (needsNewIdList) {
            if (keysetToSelectIndexMapping != null) {
                int keysetPageSize = pageSize - highestOffset;
                int size = Math.min(ids.size(), keysetPageSize);
                int lowestIndex;
                int highestIndex;
                // Swap keysets as we have inverse ordering when going to the previous page
                if (keysetMode == KeysetMode.PREVIOUS) {
                    lowestIndex = size - 1;
                    highestIndex = 0;
                } else {
                    lowestIndex = 0;
                    highestIndex = size - 1;
                }
                if (ids.get(0) instanceof Object[]) {
                    if (withExtractAllKeysets) {
                        keysets = new Serializable[size][];
                        for (int i = 0; i < size; i++) {
                            keysets[i] = KeysetPaginationHelper.extractKey((Object[]) ids.get(i), keysetToSelectIndexMapping, keysetSuffix);
                        }
                        lowest = keysets[lowestIndex];
                        highest = keysets[highestIndex];
                    } else {
                        lowest = KeysetPaginationHelper.extractKey((Object[]) ids.get(lowestIndex), keysetToSelectIndexMapping, keysetSuffix);
                        highest = KeysetPaginationHelper.extractKey((Object[]) ids.get(highestIndex), keysetToSelectIndexMapping, keysetSuffix);
                    }
                } else {
                    if (withExtractAllKeysets) {
                        keysets = new Serializable[size][];
                        for (int i = 0; i < size; i++) {
                            keysets[i] = new Serializable[] { (Serializable) (ids.get(i)) };
                        }
                        lowest = keysets[lowestIndex];
                        highest = keysets[highestIndex];
                    } else {
                        lowest = new Serializable[] { (Serializable) ids.get(lowestIndex) };
                        highest = new Serializable[] { (Serializable) ids.get(highestIndex) };
                    }
                }
                // Swap keysets as we have inverse ordering when going to the previous page
                if (keysetMode == KeysetMode.PREVIOUS) {
                    if (withExtractAllKeysets) {
                        // Reverse the keysets
                        Serializable[] tmp;
                        for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) {
                            tmp = keysets[i];
                            keysets[i] = keysets[j];
                            keysets[j] = tmp;
                        }
                    }
                }
            }
            // extract count
            if (inlinedCountQuery) {
                Object[] first = (Object[]) ids.get(0);
                totalSize = (long) first[first.length - 1];
            }
            List<Object> newIds = new ArrayList<Object>(ids.size());
            if (identifierCount > 1) {
                for (int i = 0; i < ids.size(); i++) {
                    Object[] tuple = (Object[]) ids.get(i);
                    Object newId = new Object[identifierCount];
                    System.arraycopy(tuple, 0, newId, 0, identifierCount);
                    newIds.add(newId);
                }
            } else {
                for (int i = 0; i < ids.size(); i++) {
                    Object o = ids.get(i);
                    if (o instanceof Object[]) {
                        newIds.add(((Object[]) o)[0]);
                    } else {
                        newIds.add(o);
                    }
                }
            }
            ids = newIds;
        } else if (inlinedCountQuery) {
            Object[] first = (Object[]) ids.get(0);
            int newSize = first.length - 1;
            totalSize = (long) first[first.length - 1];
            // If this would have been a non-object array type without the count query, we must unwrap the result
            List<Object> newIds = new ArrayList<>(ids.size());
            if (newSize == 1) {
                for (int i = 0; i < ids.size(); i++) {
                    newIds.add(((Object[]) ids.get(i))[0]);
                }
            } else {
                for (int i = 0; i < ids.size(); i++) {
                    Object[] tuple = (Object[]) ids.get(i);
                    Object newId = new Object[newSize];
                    System.arraycopy(tuple, 0, newId, 0, newSize);
                    newIds.add(newId);
                }
            }
            ids = newIds;
        }
        if (identifierCount > 1) {
            StringBuilder parameterNameBuilder = new StringBuilder(AbstractCommonQueryBuilder.ID_PARAM_NAME.length() + 10);
            parameterNameBuilder.append(AbstractCommonQueryBuilder.ID_PARAM_NAME).append('_');
            int start = parameterNameBuilder.length();
            Object[] empty = ids.size() < pageSize ? new Object[identifierCount] : null;
            for (int i = 0; i < pageSize; i++) {
                Object[] tuple;
                if (ids.size() > i) {
                    tuple = (Object[]) ids.get(i);
                } else {
                    tuple = empty;
                }
                for (int j = 0; j < identifierCount; j++) {
                    parameterNameBuilder.setLength(start);
                    parameterNameBuilder.append(j).append('_').append(i);
                    objectQuery.setParameter(parameterNameBuilder.toString(), tuple[j]);
                }
            }
        } else {
            objectQuery.setParameter(AbstractCommonQueryBuilder.ID_PARAM_NAME, ids);
        }
        KeysetPage newKeyset = null;
        if (keysetToSelectIndexMapping != null) {
            newKeyset = new DefaultKeysetPage(firstRow, pageSize, lowest, highest, keysets);
        }
        totalSize = Math.max(totalSize, firstRow + ids.size());
        List<X> queryResultList = objectQuery.getResultList();
        PagedList<X> pagedResultList = new PagedArrayList<X>(queryResultList, newKeyset, totalSize, queryFirstResult, pageSize);
        return pagedResultList;
    } else {
        if (!inlinedIdQuery) {
            objectQuery.setMaxResults(pageSize);
            if (forceFirstResult || keysetMode == KeysetMode.NONE) {
                objectQuery.setFirstResult(firstRow);
            } else {
                objectQuery.setFirstResult(0);
            }
        }
        List<X> result = objectQuery.getResultList();
        if (result.isEmpty()) {
            KeysetPage newKeysetPage = null;
            if (keysetMode == KeysetMode.NEXT) {
                // When we scroll over the last page to a non existing one, we reuse the current keyset
                newKeysetPage = keysetPage;
            }
            if (totalSize == -1) {
                if (inlinedCountQuery && firstRow == 0) {
                    totalSize = 0L;
                } else if (withCount) {
                    totalSize = getTotalCount();
                }
            }
            if (boundedCount) {
                if (keysetMode == KeysetMode.NEXT) {
                    totalSize = Math.max(totalSize, keysetPage.getFirstResult() + keysetPage.getMaxResults());
                } else if (forceFirstResult || keysetMode == KeysetMode.NONE) {
                    totalSize = Math.max(totalSize, firstRow);
                }
            }
            return new PagedArrayList<X>(newKeysetPage, totalSize, queryFirstResult, pageSize);
        }
        if (keysetMode == KeysetMode.PREVIOUS) {
            Collections.reverse(result);
        }
        KeysetPage newKeyset = null;
        if (keysetToSelectIndexMapping != null) {
            if (objectBuilder == null) {
                // extract count
                if (inlinedCountQuery) {
                    Object[] first = (Object[]) result.get(0);
                    totalSize = (long) first[first.length - 1];
                    // If this would have been a non-object array type without the count query, we must unwrap the result
                    if (first.length == 2) {
                        List<X> newResult = new ArrayList<>(result.size());
                        for (int i = 0; i < result.size(); i++) {
                            newResult.add((X) ((Object[]) result.get(i))[0]);
                        }
                        result = newResult;
                    }
                }
            } else if (objectBuilder instanceof KeysetExtractionObjectBuilder<?>) {
                KeysetExtractionObjectBuilder<?> keysetExtractionObjectBuilder = (KeysetExtractionObjectBuilder<?>) objectBuilder;
                Serializable[] lowest = keysetExtractionObjectBuilder.getLowest();
                Serializable[] highest = keysetExtractionObjectBuilder.getHighest();
                Serializable[][] keysets = keysetExtractionObjectBuilder.getKeysets();
                // extract count
                if (inlinedCountQuery) {
                    totalSize = keysetExtractionObjectBuilder.getCount();
                }
                newKeyset = new DefaultKeysetPage(firstRow, pageSize, lowest, highest, keysets);
            } else if (objectBuilder instanceof CountExtractionObjectBuilder<?>) {
                totalSize = ((CountExtractionObjectBuilder<X>) objectBuilder).getCount();
            }
        }
        totalSize = Math.max(totalSize, firstRow + result.size());
        PagedList<X> pagedResultList = new PagedArrayList<X>(result, newKeyset, totalSize, queryFirstResult, pageSize);
        return pagedResultList;
    }
}
Also used : Serializable(java.io.Serializable) KeysetExtractionObjectBuilder(com.blazebit.persistence.impl.builder.object.KeysetExtractionObjectBuilder) DefaultKeysetPage(com.blazebit.persistence.DefaultKeysetPage) CountExtractionObjectBuilder(com.blazebit.persistence.impl.builder.object.CountExtractionObjectBuilder) PagedArrayList(com.blazebit.persistence.PagedArrayList) ArrayList(java.util.ArrayList) KeysetPage(com.blazebit.persistence.KeysetPage) DefaultKeysetPage(com.blazebit.persistence.DefaultKeysetPage) PagedArrayList(com.blazebit.persistence.PagedArrayList) PagedArrayList(com.blazebit.persistence.PagedArrayList) ArrayList(java.util.ArrayList) PagedList(com.blazebit.persistence.PagedList) List(java.util.List)

Example 2 with PagedList

use of com.blazebit.persistence.PagedList 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));
}
Also used : KeysetPage(com.blazebit.persistence.KeysetPage) PagedList(com.blazebit.persistence.PagedList) List(java.util.List) ObjectBuilder(com.blazebit.persistence.ObjectBuilder) Document(com.blazebit.persistence.testsuite.entity.Document) SelectBuilder(com.blazebit.persistence.SelectBuilder) Test(org.junit.Test)

Example 3 with PagedList

use of com.blazebit.persistence.PagedList 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));
}
Also used : KeysetPage(com.blazebit.persistence.KeysetPage) PagedList(com.blazebit.persistence.PagedList) List(java.util.List) ObjectBuilder(com.blazebit.persistence.ObjectBuilder) SelectBuilder(com.blazebit.persistence.SelectBuilder) DocumentWithNullableName(com.blazebit.persistence.testsuite.entity.DocumentWithNullableName) Test(org.junit.Test)

Example 4 with PagedList

use of com.blazebit.persistence.PagedList 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));
}
Also used : KeysetPage(com.blazebit.persistence.KeysetPage) PagedList(com.blazebit.persistence.PagedList) List(java.util.List) ObjectBuilder(com.blazebit.persistence.ObjectBuilder) Document(com.blazebit.persistence.testsuite.entity.Document) SelectBuilder(com.blazebit.persistence.SelectBuilder) Test(org.junit.Test)

Example 5 with PagedList

use of com.blazebit.persistence.PagedList 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);
}
Also used : Keyset(com.blazebit.persistence.Keyset) DefaultKeyset(com.blazebit.persistence.DefaultKeyset) PagedList(com.blazebit.persistence.PagedList) ArrayList(java.util.ArrayList) KeysetPage(com.blazebit.persistence.KeysetPage) DefaultKeysetPage(com.blazebit.persistence.DefaultKeysetPage) PageInfo(graphql.relay.PageInfo) DefaultPageInfo(graphql.relay.DefaultPageInfo) DefaultConnection(graphql.relay.DefaultConnection) DefaultEdge(graphql.relay.DefaultEdge) Edge(graphql.relay.Edge) DefaultPageInfo(graphql.relay.DefaultPageInfo) DefaultConnectionCursor(graphql.relay.DefaultConnectionCursor)

Aggregations

PagedList (com.blazebit.persistence.PagedList)6 KeysetPage (com.blazebit.persistence.KeysetPage)5 List (java.util.List)4 ObjectBuilder (com.blazebit.persistence.ObjectBuilder)3 SelectBuilder (com.blazebit.persistence.SelectBuilder)3 Test (org.junit.Test)3 DefaultKeysetPage (com.blazebit.persistence.DefaultKeysetPage)2 Document (com.blazebit.persistence.testsuite.entity.Document)2 ArrayList (java.util.ArrayList)2 DefaultKeyset (com.blazebit.persistence.DefaultKeyset)1 Keyset (com.blazebit.persistence.Keyset)1 PagedArrayList (com.blazebit.persistence.PagedArrayList)1 PaginatedCriteriaBuilder (com.blazebit.persistence.PaginatedCriteriaBuilder)1 BlazeCriteriaBuilder (com.blazebit.persistence.criteria.BlazeCriteriaBuilder)1 KeysetPageable (com.blazebit.persistence.deltaspike.data.KeysetPageable)1 CountExtractionObjectBuilder (com.blazebit.persistence.impl.builder.object.CountExtractionObjectBuilder)1 KeysetExtractionObjectBuilder (com.blazebit.persistence.impl.builder.object.KeysetExtractionObjectBuilder)1 DocumentWithNullableName (com.blazebit.persistence.testsuite.entity.DocumentWithNullableName)1 DefaultConnection (graphql.relay.DefaultConnection)1 DefaultConnectionCursor (graphql.relay.DefaultConnectionCursor)1