use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.
the class AggregationDataStoreTransaction method loadObjects.
@Override
public <T> DataStoreIterable<T> loadObjects(EntityProjection entityProjection, RequestScope scope) {
QueryResult result = null;
QueryResponse response = null;
String cacheKey = null;
try {
// Convert multivalued map to map.
Map<String, String> headers = scope.getRequestHeaders().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, (entry) -> entry.getValue().stream().collect(Collectors.joining(" "))));
queryLogger.acceptQuery(scope.getRequestId(), scope.getUser(), headers, scope.getApiVersion(), scope.getQueryParams(), scope.getPath());
Query query = buildQuery(entityProjection, scope);
Table table = (Table) query.getSource();
if (cache != null && !query.isBypassingCache()) {
String tableVersion = queryEngine.getTableVersion(table, queryEngineTransaction);
tableVersion = tableVersion == null ? "" : tableVersion;
cacheKey = tableVersion + ';' + QueryKeyExtractor.extractKey(query);
result = cache.get(cacheKey);
}
boolean isCached = result != null;
List<String> queryText = queryEngine.explain(query);
queryLogger.processQuery(scope.getRequestId(), query, queryText, isCached);
if (result == null) {
result = queryEngine.executeQuery(query, queryEngineTransaction);
if (cacheKey != null) {
// The query result needs to be streamed into an in memory list before caching.
// TODO - add a cap to how many records can be streamed back. If this is exceeded, abort caching
// and return the results.
QueryResult cacheableResult = QueryResult.builder().data(Lists.newArrayList(result.getData().iterator())).pageTotals(result.getPageTotals()).build();
cache.put(cacheKey, cacheableResult);
result = cacheableResult;
}
}
if (entityProjection.getPagination() != null && entityProjection.getPagination().returnPageTotals()) {
entityProjection.getPagination().setPageTotals(result.getPageTotals());
}
response = new QueryResponse(HttpStatus.SC_OK, result.getData(), null);
return new DataStoreIterableBuilder(result.getData()).build();
} catch (HttpStatusException e) {
response = new QueryResponse(e.getStatus(), null, e.getMessage());
throw e;
} catch (Exception e) {
response = new QueryResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, null, e.getMessage());
throw e;
} finally {
queryLogger.completeQuery(scope.getRequestId(), response);
}
}
use of com.yahoo.elide.datastores.aggregation.query.QueryResult 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();
}
use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.
the class QueryEngineTest method testPaginationWithFilter.
/**
* Nested Queries with filter - Pagination
* @throws Exception
*/
@Test
public void testPaginationWithFilter() throws Exception {
Query query = Query.builder().source(playerStatsTable).metricProjection(playerStatsTable.getMetricProjection("dailyAverageScorePerPeriod")).dimensionProjection(playerStatsTable.getDimensionProjection("overallRating")).whereFilter(filterParser.parseFilterExpression("overallRating==Great", playerStatsType, false)).timeDimensionProjection(playerStatsTable.getTimeDimensionProjection("recordedDate")).pagination(new ImmutablePagination(0, 1, false, true)).build();
QueryResult result = engine.executeQuery(query, transaction);
List<Object> data = toList(result.getData());
// Jon Doe,1234,72,Good,840,2019-07-12 00:00:00
PlayerStats stats1 = new PlayerStats();
stats1.setId("0");
stats1.setDailyAverageScorePerPeriod(2412.0f);
stats1.setOverallRating("Great");
stats1.setRecordedDate(new Day(Date.valueOf("2019-07-11")));
assertEquals(ImmutableList.of(stats1), data, "Returned record does not match");
assertEquals(1, result.getPageTotals(), "Page totals does not match");
}
use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.
the class AggregationDataStoreTransactionTest method loadObjectsPopulatesCache.
@Test
public void loadObjectsPopulatesCache() {
Mockito.reset(queryLogger);
QueryResult queryResult = QueryResult.builder().data(DATA).build();
NativeQuery myQuery = NativeQuery.builder().fromClause(playerStatsTable.getName()).projectionClause(" ").build();
when(queryEngine.getTableVersion(playerStatsTable, qeTransaction)).thenReturn("foo");
when(queryEngine.executeQuery(query, qeTransaction)).thenReturn(queryResult);
when(queryEngine.explain(query)).thenReturn(Arrays.asList(myQuery.toString()));
AggregationDataStoreTransaction transaction = new MyAggregationDataStoreTransaction(queryEngine, cache, queryLogger);
EntityProjection entityProjection = EntityProjection.builder().type(PlayerStats.class).build();
assertEquals(DATA, Lists.newArrayList(transaction.loadObjects(entityProjection, scope)));
String cacheKey = "foo;" + queryKey;
Mockito.verify(cache).get(cacheKey);
Mockito.verify(cache).put(cacheKey, queryResult);
Mockito.verifyNoMoreInteractions(cache);
Mockito.verify(queryLogger, times(1)).acceptQuery(Mockito.eq(scope.getRequestId()), any(), any(), any(), any(), any());
Mockito.verify(queryLogger, times(1)).processQuery(Mockito.eq(scope.getRequestId()), any(), any(), Mockito.eq(false));
Mockito.verify(queryLogger, times(1)).completeQuery(Mockito.eq(scope.getRequestId()), any());
}
use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.
the class AggregationDataStoreTransactionTest method loadObjectsPassesPagination.
@Test
public void loadObjectsPassesPagination() {
Mockito.reset(queryLogger);
QueryResult queryResult = QueryResult.builder().data(DATA).pageTotals(314L).build();
NativeQuery myQuery = NativeQuery.builder().fromClause(playerStatsTable.getName()).projectionClause(" ").build();
when(cache.get(anyString())).thenReturn(queryResult);
when(queryEngine.getTableVersion(playerStatsTable, qeTransaction)).thenReturn("foo");
when(queryEngine.explain(query)).thenReturn(Arrays.asList(myQuery.toString()));
AggregationDataStoreTransaction transaction = new MyAggregationDataStoreTransaction(queryEngine, cache, queryLogger);
Pagination pagination = new PaginationImpl(String.class, null, null, DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT, true, false);
EntityProjection entityProjection = EntityProjection.builder().type(PlayerStats.class).pagination(pagination).build();
assertEquals(DATA, Lists.newArrayList(transaction.loadObjects(entityProjection, scope)));
assertEquals(314L, entityProjection.getPagination().getPageTotals());
String cacheKey = "foo;" + queryKey;
Mockito.verify(queryEngine, never()).executeQuery(any(), any());
Mockito.verify(cache).get(cacheKey);
Mockito.verifyNoMoreInteractions(cache);
Mockito.verify(queryLogger, times(1)).acceptQuery(Mockito.eq(scope.getRequestId()), any(), any(), any(), any(), any());
Mockito.verify(queryLogger, times(1)).processQuery(Mockito.eq(scope.getRequestId()), any(), any(), Mockito.eq(true));
Mockito.verify(queryLogger, times(1)).completeQuery(Mockito.eq(scope.getRequestId()), any());
}
Aggregations