Search in sources :

Example 1 with Pagination

use of com.yahoo.elide.core.request.Pagination in project elide by yahoo.

the class CollectionTerminalState method handleGet.

@Override
public Supplier<Pair<Integer, JsonNode>> handleGet(StateContext state) {
    JsonApiDocument jsonApiDocument = new JsonApiDocument();
    RequestScope requestScope = state.getRequestScope();
    MultivaluedMap<String, String> queryParams = requestScope.getQueryParams();
    Set<PersistentResource> collection = getResourceCollection(requestScope).toList(LinkedHashSet::new).blockingGet();
    // Set data
    jsonApiDocument.setData(getData(collection, requestScope.getDictionary()));
    // Run include processor
    DocumentProcessor includedProcessor = new IncludedProcessor();
    includedProcessor.execute(jsonApiDocument, collection, queryParams);
    Pagination pagination = parentProjection.getPagination();
    if (parent.isPresent()) {
        pagination = parentProjection.getRelationship(relationName.orElseThrow(IllegalStateException::new)).get().getProjection().getPagination();
    }
    // Add pagination meta data
    if (!pagination.isDefaultInstance()) {
        Map<String, Number> pageMetaData = new HashMap<>();
        pageMetaData.put("number", (pagination.getOffset() / pagination.getLimit()) + 1);
        pageMetaData.put("limit", pagination.getLimit());
        // Get total records if it has been requested and add to the page meta data
        if (pagination.returnPageTotals()) {
            Long totalRecords = pagination.getPageTotals();
            pageMetaData.put("totalPages", totalRecords / pagination.getLimit() + ((totalRecords % pagination.getLimit()) > 0 ? 1 : 0));
            pageMetaData.put("totalRecords", totalRecords);
        }
        Map<String, Object> allMetaData = new HashMap<>();
        allMetaData.put("page", pageMetaData);
        Meta meta = new Meta(allMetaData);
        jsonApiDocument.setMeta(meta);
    }
    JsonNode responseBody = requestScope.getMapper().toJsonObject(jsonApiDocument);
    return () -> Pair.of(HttpStatus.SC_OK, responseBody);
}
Also used : PersistentResource(com.yahoo.elide.core.PersistentResource) Meta(com.yahoo.elide.jsonapi.models.Meta) JsonApiDocument(com.yahoo.elide.jsonapi.models.JsonApiDocument) DocumentProcessor(com.yahoo.elide.jsonapi.document.processors.DocumentProcessor) HashMap(java.util.HashMap) JsonNode(com.fasterxml.jackson.databind.JsonNode) ToString(lombok.ToString) RequestScope(com.yahoo.elide.core.RequestScope) Pagination(com.yahoo.elide.core.request.Pagination) IncludedProcessor(com.yahoo.elide.jsonapi.document.processors.IncludedProcessor)

Example 2 with Pagination

use of com.yahoo.elide.core.request.Pagination in project elide by yahoo.

the class SQLQueryEngine method executeQuery.

@Override
public QueryResult executeQuery(Query query, Transaction transaction) {
    SqlTransaction sqlTransaction = (SqlTransaction) transaction;
    ConnectionDetails details = query.getConnectionDetails();
    DataSource dataSource = details.getDataSource();
    SQLDialect dialect = details.getDialect();
    Query expandedQuery = expandMetricQueryPlans(query);
    // Translate the query into SQL.
    NativeQuery sql = toSQL(expandedQuery, dialect);
    String queryString = sql.toString();
    QueryResult.QueryResultBuilder resultBuilder = QueryResult.builder();
    NamedParamPreparedStatement stmt;
    Pagination pagination = query.getPagination();
    if (returnPageTotals(pagination)) {
        resultBuilder.pageTotals(getPageTotal(expandedQuery, sql, query, sqlTransaction));
    }
    log.debug("SQL Query: " + queryString);
    stmt = sqlTransaction.initializeStatement(queryString, dataSource);
    // Supply the query parameters to the query
    supplyFilterQueryParameters(query, stmt, dialect);
    // Run the primary query and log the time spent.
    ResultSet resultSet = runQuery(stmt, queryString, Function.identity());
    resultBuilder.data(new EntityHydrator(resultSet, query, metadataDictionary));
    return resultBuilder.build();
}
Also used : NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) Query(com.yahoo.elide.datastores.aggregation.query.Query) VersionQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.VersionQuery) DataSource(javax.sql.DataSource) Pagination(com.yahoo.elide.core.request.Pagination) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) SQLDialect(com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect) ResultSet(java.sql.ResultSet)

Example 3 with Pagination

use of com.yahoo.elide.core.request.Pagination in project elide by yahoo.

the class SQLQueryEngine method explain.

/**
 * Returns the actual query string(s) that would be executed for the input {@link Query}.
 *
 * @param query The query customized for a particular persistent storage or storage client.
 * @param dialect SQL dialect to use for this storage.
 * @return List of SQL string(s) corresponding to the given query.
 */
public List<String> explain(Query query, SQLDialect dialect) {
    List<String> queries = new ArrayList<>();
    Query expandedQuery = expandMetricQueryPlans(query);
    NativeQuery sql = toSQL(expandedQuery, dialect);
    Pagination pagination = query.getPagination();
    if (returnPageTotals(pagination)) {
        NativeQuery paginationSql = toPageTotalSQL(expandedQuery, sql, dialect);
        if (paginationSql != null) {
            queries.add(paginationSql.toString());
        }
    }
    queries.add(sql.toString());
    return queries;
}
Also used : Pagination(com.yahoo.elide.core.request.Pagination) NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) Query(com.yahoo.elide.datastores.aggregation.query.Query) VersionQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.VersionQuery) NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) ArrayList(java.util.ArrayList)

Example 4 with Pagination

use of com.yahoo.elide.core.request.Pagination in project elide by yahoo.

the class SubCollectionFetchQueryBuilderTest method testFetchJoinExcludesParent.

@Test
public void testFetchJoinExcludesParent() {
    Publisher publisher = new Publisher();
    publisher.setId(1);
    Book book = new Book();
    book.setId(2);
    Pagination pagination = new PaginationImpl(Book.class, 0, 10, 10, 10, false, false);
    EntityProjection entityProjection = EntityProjection.builder().type(Book.class).pagination(pagination).build();
    Relationship relationshipProjection = Relationship.builder().name(BOOKS).projection(entityProjection).build();
    RelationshipImpl relationship = new RelationshipImpl(ClassType.of(Publisher.class), publisher, relationshipProjection);
    SubCollectionFetchQueryBuilder builder = new SubCollectionFetchQueryBuilder(relationship, dictionary, new TestSessionWrapper());
    TestQueryWrapper query = (TestQueryWrapper) builder.build();
    String expected = "SELECT example_Book FROM example.Publisher example_Publisher__fetch " + "JOIN example_Publisher__fetch.books example_Book " + "WHERE example_Publisher__fetch=:example_Publisher__fetch";
    String actual = query.getQueryText();
    actual = actual.replaceFirst(":publisher_name_\\w+", ":publisher_name_XXX");
    assertEquals(expected, actual);
}
Also used : Pagination(com.yahoo.elide.core.request.Pagination) EntityProjection(com.yahoo.elide.core.request.EntityProjection) PaginationImpl(com.yahoo.elide.core.pagination.PaginationImpl) SubCollectionFetchQueryBuilder(com.yahoo.elide.datastores.jpql.query.SubCollectionFetchQueryBuilder) Book(example.Book) Relationship(com.yahoo.elide.core.request.Relationship) Publisher(example.Publisher) RelationshipImpl(com.yahoo.elide.datastores.jpql.query.RelationshipImpl) Test(org.junit.jupiter.api.Test)

Example 5 with Pagination

use of com.yahoo.elide.core.request.Pagination in project elide by yahoo.

the class PersistentResource method loadRecords.

/**
 * Load a collection from the datastore.
 *
 * @param projection   the projection to load
 * @param requestScope the request scope
 * @param ids          a list of object identifiers to optionally load.  Can be empty.
 * @return a filtered collection of resources loaded from the datastore.
 */
public static Observable<PersistentResource> loadRecords(EntityProjection projection, List<String> ids, RequestScope requestScope) {
    Type<?> loadClass = projection.getType();
    Pagination pagination = projection.getPagination();
    Sorting sorting = projection.getSorting();
    FilterExpression filterExpression = projection.getFilterExpression();
    EntityDictionary dictionary = requestScope.getDictionary();
    DataStoreTransaction tx = requestScope.getTransaction();
    if (shouldSkipCollection(loadClass, ReadPermission.class, requestScope, projection.getRequestedFields())) {
        if (ids.isEmpty()) {
            return Observable.empty();
        }
        throw new InvalidObjectIdentifierException(ids.toString(), dictionary.getJsonAliasFor(loadClass));
    }
    Set<String> requestedFields = projection.getRequestedFields();
    if (pagination != null && !pagination.isDefaultInstance() && !CanPaginateVisitor.canPaginate(loadClass, dictionary, requestScope, requestedFields)) {
        throw new BadRequestException(String.format("Cannot paginate %s", dictionary.getJsonAliasFor(loadClass)));
    }
    Set<PersistentResource> newResources = new LinkedHashSet<>();
    if (!ids.isEmpty()) {
        String typeAlias = dictionary.getJsonAliasFor(loadClass);
        newResources = requestScope.getNewPersistentResources().stream().filter(resource -> typeAlias.equals(resource.getTypeName()) && ids.contains(resource.getUUID().orElse(""))).collect(Collectors.toSet());
        FilterExpression idExpression = buildIdFilterExpression(ids, loadClass, dictionary, requestScope);
        // Combine filters if necessary
        filterExpression = Optional.ofNullable(filterExpression).map(fe -> (FilterExpression) new AndFilterExpression(idExpression, fe)).orElse(idExpression);
    }
    Optional<FilterExpression> permissionFilter = getPermissionFilterExpression(loadClass, requestScope, requestedFields);
    if (permissionFilter.isPresent()) {
        if (filterExpression != null) {
            filterExpression = new AndFilterExpression(filterExpression, permissionFilter.get());
        } else {
            filterExpression = permissionFilter.get();
        }
    }
    EntityProjection modifiedProjection = projection.copyOf().filterExpression(filterExpression).sorting(sorting).pagination(pagination).build();
    Observable<PersistentResource> existingResources = filter(ReadPermission.class, Optional.ofNullable(modifiedProjection.getFilterExpression()), projection.getRequestedFields(), Observable.fromIterable(new PersistentResourceSet(tx.loadObjects(modifiedProjection, requestScope), requestScope)));
    // TODO: Sort again in memory now that two sets are glommed together?
    Observable<PersistentResource> allResources = Observable.fromIterable(newResources).mergeWith(existingResources);
    Set<String> foundIds = new HashSet<>();
    allResources = allResources.doOnNext((resource) -> {
        String id = (String) resource.getUUID().orElseGet(resource::getId);
        if (ids.contains(id)) {
            foundIds.add(id);
        }
    });
    allResources = allResources.doOnComplete(() -> {
        Set<String> missedIds = Sets.difference(new HashSet<>(ids), foundIds);
        if (!missedIds.isEmpty()) {
            throw new InvalidObjectIdentifierException(missedIds.toString(), dictionary.getJsonAliasFor(loadClass));
        }
    });
    return allResources;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Resource(com.yahoo.elide.jsonapi.models.Resource) Data(com.yahoo.elide.jsonapi.models.Data) StringUtils(org.apache.commons.lang3.StringUtils) UpdatePermission(com.yahoo.elide.annotation.UpdatePermission) ClassType(com.yahoo.elide.core.type.ClassType) DeletePermission(com.yahoo.elide.annotation.DeletePermission) Argument(com.yahoo.elide.core.request.Argument) InvalidSyntaxException(com.yahoo.elide.core.audit.InvalidSyntaxException) Map(java.util.Map) DataStoreIterable(com.yahoo.elide.core.datastore.DataStoreIterable) LifeCycleHookBinding(com.yahoo.elide.annotation.LifeCycleHookBinding) EntityBinding(com.yahoo.elide.core.dictionary.EntityBinding) NonNull(lombok.NonNull) Collection(java.util.Collection) Set(java.util.Set) CoerceUtil(com.yahoo.elide.core.utils.coerce.CoerceUtil) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Sets(com.google.common.collect.Sets) Serializable(java.io.Serializable) Objects(java.util.Objects) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) List(java.util.List) Annotation(java.lang.annotation.Annotation) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) Optional(java.util.Optional) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) Attribute(com.yahoo.elide.core.request.Attribute) InvalidAttributeException(com.yahoo.elide.core.exceptions.InvalidAttributeException) Function(java.util.function.Function) Supplier(java.util.function.Supplier) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) IterableUtils(org.apache.commons.collections4.IterableUtils) LogMessageImpl(com.yahoo.elide.core.audit.LogMessageImpl) DELETE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.DELETE) EntityDictionary.getType(com.yahoo.elide.core.dictionary.EntityDictionary.getType) JsonIgnore(com.fasterxml.jackson.annotation.JsonIgnore) Predicates(com.google.common.base.Predicates) InternalServerErrorException(com.yahoo.elide.core.exceptions.InternalServerErrorException) CanPaginateVisitor(com.yahoo.elide.core.security.visitors.CanPaginateVisitor) Observable(io.reactivex.Observable) LogMessage(com.yahoo.elide.core.audit.LogMessage) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) LinkedHashSet(java.util.LinkedHashSet) UPDATE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.UPDATE) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) VerifyFieldAccessFilterExpressionVisitor(com.yahoo.elide.core.filter.visitors.VerifyFieldAccessFilterExpressionVisitor) ChangeSpec(com.yahoo.elide.core.security.ChangeSpec) COLLECTION_TYPE(com.yahoo.elide.core.type.ClassType.COLLECTION_TYPE) Sorting(com.yahoo.elide.core.request.Sorting) InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) InvalidObjectIdentifierException(com.yahoo.elide.core.exceptions.InvalidObjectIdentifierException) InPredicate(com.yahoo.elide.core.filter.predicates.InPredicate) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Relationship(com.yahoo.elide.jsonapi.models.Relationship) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException) ReadPermission(com.yahoo.elide.annotation.ReadPermission) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) Pagination(com.yahoo.elide.core.request.Pagination) ResourceIdentifier(com.yahoo.elide.jsonapi.models.ResourceIdentifier) TreeMap(java.util.TreeMap) CreatePermission(com.yahoo.elide.annotation.CreatePermission) CREATE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.CREATE) Type(com.yahoo.elide.core.type.Type) Preconditions(com.google.common.base.Preconditions) Comparator(java.util.Comparator) Collections(java.util.Collections) EMPTY_BINDING(com.yahoo.elide.core.dictionary.EntityBinding.EMPTY_BINDING) Audit(com.yahoo.elide.annotation.Audit) NonTransferable(com.yahoo.elide.annotation.NonTransferable) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Sorting(com.yahoo.elide.core.request.Sorting) Pagination(com.yahoo.elide.core.request.Pagination) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) InvalidObjectIdentifierException(com.yahoo.elide.core.exceptions.InvalidObjectIdentifierException) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Aggregations

Pagination (com.yahoo.elide.core.request.Pagination)18 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)8 Sorting (com.yahoo.elide.core.request.Sorting)7 DataStoreIterable (com.yahoo.elide.core.datastore.DataStoreIterable)6 EntityProjection (com.yahoo.elide.core.request.EntityProjection)6 Collection (java.util.Collection)6 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)5 Optional (java.util.Optional)5 BadRequestException (com.yahoo.elide.core.exceptions.BadRequestException)4 ArrayList (java.util.ArrayList)4 List (java.util.List)4 Collectors (java.util.stream.Collectors)4 Preconditions (com.google.common.base.Preconditions)3 DataStoreIterableBuilder (com.yahoo.elide.core.datastore.DataStoreIterableBuilder)3 DataStoreTransaction (com.yahoo.elide.core.datastore.DataStoreTransaction)3 AndFilterExpression (com.yahoo.elide.core.filter.expression.AndFilterExpression)3 PaginationImpl (com.yahoo.elide.core.pagination.PaginationImpl)3 Type (com.yahoo.elide.core.type.Type)3 NativeQuery (com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery)3 Map (java.util.Map)3