use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.
the class DataStoreLoadTest method testPaginationPageTwo.
@Test
public void testPaginationPageTwo() throws Exception {
DataStoreTransaction testTransaction = searchStore.beginReadTransaction();
Map<String, Sorting.SortOrder> sortRules = new HashMap<>();
sortRules.put("name", Sorting.SortOrder.desc);
sortRules.put("modifiedDate", Sorting.SortOrder.asc);
Sorting sorting = new SortingImpl(sortRules, Item.class, dictionary);
PaginationImpl pagination = new PaginationImpl(Item.class, 1, 1, PaginationImpl.DEFAULT_PAGE_LIMIT, PaginationImpl.MAX_PAGE_LIMIT, true, false);
FilterExpression filter = filterParser.parseFilterExpression("name==cymbal*", ClassType.of(Item.class), false);
Iterable<Object> loaded = testTransaction.loadObjects(EntityProjection.builder().type(Item.class).filterExpression(filter).sorting(sorting).pagination(pagination).build(), mockScope);
assertListMatches(loaded, Lists.newArrayList(5L));
assertEquals(pagination.getPageTotals(), 3);
verify(wrappedTransaction, never()).loadObjects(any(), any());
}
use of com.yahoo.elide.core.request.Sorting 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;
}
use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.
the class InMemoryStoreTransaction method fetchData.
private DataStoreIterable<Object> fetchData(DataFetcher fetcher, EntityProjection projection, boolean filterInMemory, RequestScope scope) {
Optional<FilterExpression> filterExpression = Optional.ofNullable(projection.getFilterExpression());
Pair<Optional<FilterExpression>, Optional<FilterExpression>> expressionSplit = splitFilterExpression(scope, projection, filterInMemory);
Optional<FilterExpression> dataStoreFilter = expressionSplit.getLeft();
Optional<FilterExpression> inMemoryFilter = expressionSplit.getRight();
Optional<Sorting> dataStoreSorting = getDataStoreSorting(scope, projection, filterInMemory);
boolean sortingInMemory = dataStoreSorting.isEmpty() && projection.getSorting() != null;
Optional<Pagination> dataStorePagination = inMemoryFilter.isPresent() || sortingInMemory ? Optional.empty() : Optional.ofNullable(projection.getPagination());
DataStoreIterable<Object> loadedRecords = fetcher.fetch(dataStoreFilter, dataStoreSorting, dataStorePagination, scope);
if (loadedRecords == null) {
return new DataStoreIterableBuilder().build();
}
if (inMemoryFilter.isPresent() || (loadedRecords.needsInMemoryFilter() && projection.getFilterExpression() != null)) {
loadedRecords = filterLoadedData(loadedRecords, filterExpression, scope);
}
return sortAndPaginateLoadedData(loadedRecords, sortingInMemory, projection.getSorting(), projection.getPagination(), scope);
}
use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.
the class InMemoryStoreTransactionTest method testSortOnComputedAttribute.
@Test
public void testSortOnComputedAttribute() {
Map<String, Sorting.SortOrder> sortOrder = new HashMap<>();
sortOrder.put("fullName", Sorting.SortOrder.desc);
Editor editor1 = new Editor();
editor1.setFirstName("A");
editor1.setLastName("X");
Editor editor2 = new Editor();
editor2.setFirstName("B");
editor2.setLastName("Y");
Sorting sorting = new SortingImpl(sortOrder, Editor.class, dictionary);
EntityProjection projection = EntityProjection.builder().type(Editor.class).sorting(sorting).build();
DataStoreIterable iterable = new DataStoreIterableBuilder(Arrays.asList(editor1, editor2)).sortInMemory(false).build();
ArgumentCaptor<EntityProjection> projectionArgument = ArgumentCaptor.forClass(EntityProjection.class);
when(wrappedTransaction.loadObjects(projectionArgument.capture(), eq(scope))).thenReturn(iterable);
Collection<Object> loaded = Lists.newArrayList(inMemoryStoreTransaction.loadObjects(projection, scope));
assertNull(projectionArgument.getValue().getSorting());
assertEquals(2, loaded.size());
Object[] sorted = loaded.toArray();
assertEquals(editor2, sorted[0]);
assertEquals(editor1, sorted[1]);
}
use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.
the class InMemoryStoreTransactionTest method testFilteringRequiresInMemorySorting.
@Test
public void testFilteringRequiresInMemorySorting() {
FilterExpression expression = new InPredicate(new Path(Book.class, dictionary, "genre"), "Literary Fiction");
Map<String, Sorting.SortOrder> sortOrder = new HashMap<>();
sortOrder.put("title", Sorting.SortOrder.desc);
Sorting sorting = new SortingImpl(sortOrder, Book.class, dictionary);
EntityProjection projection = EntityProjection.builder().type(Book.class).filterExpression(expression).sorting(sorting).build();
DataStoreIterable filterInMemory = new DataStoreIterableBuilder(books).filterInMemory(true).build();
when(wrappedTransaction.loadObjects(any(), eq(scope))).thenReturn(filterInMemory);
Collection<Object> loaded = Lists.newArrayList(inMemoryStoreTransaction.loadObjects(projection, scope));
verify(wrappedTransaction, times(1)).loadObjects(any(EntityProjection.class), eq(scope));
assertEquals(2, loaded.size());
List<String> bookTitles = loaded.stream().map((o) -> ((Book) o).getTitle()).collect(Collectors.toList());
assertEquals(Lists.newArrayList("Book 3", "Book 1"), bookTitles);
}
Aggregations