Skip to content

Commit

Permalink
Merge 49226d4 into 93476a2
Browse files Browse the repository at this point in the history
  • Loading branch information
mtso committed Mar 2, 2019
2 parents 93476a2 + 49226d4 commit 89671f3
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-datastore</artifactId>
<version>1.46.0</version>
<version>1.63.0</version>
</dependency>
</dependencies>
<build>
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/com/jmethods/catatumbo/DefaultQueryResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public class DefaultQueryResponse<T> implements QueryResponse<T> {
*/
protected DatastoreCursor endCursor = null;

/**
* Query execution metadata
*/
protected QueryResponseMetadata metadata = null;

/**
* Creates a new instance of <code>BaseQueryResponse</code>.
*
Expand Down Expand Up @@ -96,4 +101,19 @@ public void setEndCursor(DatastoreCursor endCursor) {
this.endCursor = endCursor;
}

@Override
public QueryResponseMetadata getQueryResponseMetadata() {
return metadata;
}

/**
* Sets the query metadata to the given value.
*
* @param metadata
* the query execution metadata
*/
public void setQueryResponseMetadata(QueryResponseMetadata metadata) {
this.metadata = metadata;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2019 Sai Pullabhotla.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.jmethods.catatumbo;

/**
* Default implementation of {@link QueryResponseMetadata} interface.
*
* @author Matthew Tso
*/
public class DefaultQueryResponseMetadata implements QueryResponseMetadata {

/**
* The query state metadata value.
*/
private QueryResponseMetadata.QueryState queryState;

public DefaultQueryResponseMetadata(QueryResponseMetadata.QueryState queryState) {
this.queryState = queryState;
}

public QueryResponseMetadata.QueryState getQueryState() {
return queryState;
}

}
7 changes: 7 additions & 0 deletions src/main/java/com/jmethods/catatumbo/QueryResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,11 @@ public interface QueryResponse<T> {
*/
DatastoreCursor getEndCursor();

/**
* Returns metadata on the query execution.
*
* @return query execution metadata
*/
QueryResponseMetadata getQueryResponseMetadata();

}
99 changes: 99 additions & 0 deletions src/main/java/com/jmethods/catatumbo/QueryResponseMetadata.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2019 Sai Pullabhotla.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.jmethods.catatumbo;

import com.google.datastore.v1.QueryResultBatch;

/**
* Contains metadata on the query execution result within the context of a {@link QueryResponse}.
*
* @author Matthew Tso
*/
public interface QueryResponseMetadata {

/**
* Returns the query execution's query state.
*
* @return query state
*/
QueryState getQueryState();

/**
* The result state value returned in a query execution.
*
* @author Matthew Tso
*/
enum QueryState {
/**
* Possibly unspecified enum value.
*/
MORE_RESULTS_TYPE_UNSPECIFIED,

/**
* Query execution is not finished.
*/
NOT_FINISHED,

/**
* There *may* be more results after the specified limit (possibly a false positive).
*/
MORE_RESULTS_AFTER_LIMIT,

/**
* There *may* be more results after the specified end cursor (possibly a false positive).
*/
MORE_RESULTS_AFTER_CURSOR,

/**
* There are no more results left to query for.
*/
NO_MORE_RESULTS,

/**
* Unrecognized state.
*/
UNRECOGNIZED;

/**
* Initialize a QueryState from a Datastore QueryResultBatch.MoreResultsType enum value.
*
* @param moreResultsType original enum value.
* @return query state enum
*/
public static QueryState forMoreResultsType(QueryResultBatch.MoreResultsType moreResultsType) {
if (null == moreResultsType) {
return null;
}
switch (moreResultsType) {
case MORE_RESULTS_TYPE_UNSPECIFIED:
return MORE_RESULTS_TYPE_UNSPECIFIED;
case NOT_FINISHED:
return NOT_FINISHED;
case MORE_RESULTS_AFTER_LIMIT:
return MORE_RESULTS_AFTER_LIMIT;
case MORE_RESULTS_AFTER_CURSOR:
return MORE_RESULTS_AFTER_CURSOR;
case NO_MORE_RESULTS:
return NO_MORE_RESULTS;
case UNRECOGNIZED:
return UNRECOGNIZED;
default:
throw new IllegalStateException("null value should have been caught earlier.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@
import com.jmethods.catatumbo.DefaultDatastoreCursor;
import com.jmethods.catatumbo.DefaultDatastoreKey;
import com.jmethods.catatumbo.DefaultQueryResponse;
import com.jmethods.catatumbo.DefaultQueryResponseMetadata;
import com.jmethods.catatumbo.EntityManagerException;
import com.jmethods.catatumbo.EntityQueryRequest;
import com.jmethods.catatumbo.KeyQueryRequest;
import com.jmethods.catatumbo.ProjectionQueryRequest;
import com.jmethods.catatumbo.QueryResponse;
import com.jmethods.catatumbo.QueryResponseMetadata;

/**
* Worker class for performing read operations on the Cloud Datastore.
Expand Down Expand Up @@ -360,6 +362,9 @@ public <E> QueryResponse<E> executeEntityQueryRequest(Class<E> expectedResultTyp
}
response.setResults(entities);
response.setEndCursor(new DefaultDatastoreCursor(results.getCursorAfter().toUrlSafe()));
response.setQueryResponseMetadata(
new DefaultQueryResponseMetadata(
QueryResponseMetadata.QueryState.forMoreResultsType(results.getMoreResults())));
entityManager.executeEntityListeners(CallbackType.POST_LOAD, entities);
return response;
} catch (DatastoreException exp) {
Expand Down Expand Up @@ -397,6 +402,9 @@ public <E> QueryResponse<E> executeProjectionQueryRequest(Class<E> expectedResul
}
response.setResults(entities);
response.setEndCursor(new DefaultDatastoreCursor(results.getCursorAfter().toUrlSafe()));
response.setQueryResponseMetadata(
new DefaultQueryResponseMetadata(
QueryResponseMetadata.QueryState.forMoreResultsType(results.getMoreResults())));
// TODO should we invoke PostLoad callback for projected entities?
return response;
} catch (DatastoreException exp) {
Expand Down Expand Up @@ -431,6 +439,9 @@ public QueryResponse<DatastoreKey> executeKeyQueryRequest(KeyQueryRequest reques
}
response.setResults(entities);
response.setEndCursor(new DefaultDatastoreCursor(results.getCursorAfter().toUrlSafe()));
response.setQueryResponseMetadata(
new DefaultQueryResponseMetadata(
QueryResponseMetadata.QueryState.forMoreResultsType(results.getMoreResults())));
return response;
} catch (DatastoreException exp) {
throw new EntityManagerException(exp);
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/com/jmethods/catatumbo/EntityManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,7 @@ public void testExecute() {
System.out.println("Start Cursor: " + response.getStartCursor());
System.out.println("End Cursor: " + response.getEndCursor());
assertTrue(tasks.size() == 50);
assertNotNull(response.getQueryResponseMetadata().getQueryState());
}

@Test
Expand Down Expand Up @@ -2083,6 +2084,7 @@ public void testExecuteProjectionQuery() {
task.getCompletionDate());
}
assertTrue(tasks.size() == 50);
assertNotNull(response.getQueryResponseMetadata().getQueryState());
}

@Test
Expand All @@ -2107,6 +2109,7 @@ public void testExecuteKeyQuery() {
System.out.printf("%-10s %20s %s\n", key.kind(), key.nameOrId(), key.getEncoded());
}
assertTrue(keys.size() == 50);
assertNotNull(response.getQueryResponseMetadata().getQueryState());
}

@Test(expected = EntityManagerException.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2019 Sai Pullabhotla, Matthew Tso.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.jmethods.catatumbo;

import java.util.Arrays;

import com.google.datastore.v1.QueryResultBatch;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import static junit.framework.TestCase.assertEquals;

/**
* @author Matthew Tso
*/
@RunWith(Parameterized.class)
public class QueryResponseMetadataTest {
private final QueryResultBatch.MoreResultsType input;
private final QueryResponseMetadata.QueryState expected;

public QueryResponseMetadataTest(QueryResultBatch.MoreResultsType input,
QueryResponseMetadata.QueryState expected) {
this.input = input;
this.expected = expected;
}

@Parameterized.Parameters
public static Iterable<Object[]> testCases() {
return Arrays.asList(new Object[][] {
{
QueryResultBatch.MoreResultsType.MORE_RESULTS_TYPE_UNSPECIFIED,
QueryResponseMetadata.QueryState.MORE_RESULTS_TYPE_UNSPECIFIED
},
{
QueryResultBatch.MoreResultsType.NOT_FINISHED,
QueryResponseMetadata.QueryState.NOT_FINISHED,
},
{
QueryResultBatch.MoreResultsType.MORE_RESULTS_AFTER_LIMIT,
QueryResponseMetadata.QueryState.MORE_RESULTS_AFTER_LIMIT,
},
{
QueryResultBatch.MoreResultsType.MORE_RESULTS_AFTER_CURSOR,
QueryResponseMetadata.QueryState.MORE_RESULTS_AFTER_CURSOR,
},
{
QueryResultBatch.MoreResultsType.NO_MORE_RESULTS,
QueryResponseMetadata.QueryState.NO_MORE_RESULTS,
},
{
QueryResultBatch.MoreResultsType.UNRECOGNIZED,
QueryResponseMetadata.QueryState.UNRECOGNIZED,
},
{
null,
null,
},
});
}

@Test
public void testQueryStateMapping() {
QueryResponseMetadata.QueryState actual = QueryResponseMetadata.QueryState.forMoreResultsType(input);
assertEquals(expected, actual);
}
}

0 comments on commit 89671f3

Please sign in to comment.