From 3e0350c4f7df7cfaf406c288374fa2e485482442 Mon Sep 17 00:00:00 2001 From: Prateek Jain Date: Thu, 13 Oct 2022 11:44:03 +0530 Subject: [PATCH 1/3] Making query generic and moving all the entity records related concerns to an internal RecordQuery interface --- .../google/cloud/datastore/DatastoreImpl.java | 4 ++- .../com/google/cloud/datastore/GqlQuery.java | 22 ++++++++++--- .../com/google/cloud/datastore/Query.java | 15 ++------- .../cloud/datastore/QueryResultsImpl.java | 11 ++++--- .../google/cloud/datastore/RecordQuery.java | 32 +++++++++++++++++++ .../cloud/datastore/StructuredQuery.java | 19 ++++++++--- .../google/cloud/datastore/DatastoreTest.java | 4 +-- 7 files changed, 78 insertions(+), 29 deletions(-) create mode 100644 google-cloud-datastore/src/main/java/com/google/cloud/datastore/RecordQuery.java diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java index 9892e1517..2d68a2294 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java @@ -180,8 +180,10 @@ public QueryResults run(Query query, ReadOption... options) { return run(toReadOptionsPb(options), query); } + @SuppressWarnings("unchecked") QueryResults run(com.google.datastore.v1.ReadOptions readOptionsPb, Query query) { - return new QueryResultsImpl<>(this, readOptionsPb, query); + return new QueryResultsImpl<>( + this, readOptionsPb, (RecordQuery) query, query.getNamespace()); } com.google.datastore.v1.RunQueryResponse runQuery( diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java index 2b99fd0a9..bebb4df9f 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java @@ -19,6 +19,7 @@ import static com.google.cloud.datastore.Validator.validateNamespace; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.api.core.InternalApi; import com.google.cloud.Timestamp; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; @@ -71,7 +72,7 @@ * @param the type of the result values this query will produce * @see GQL Reference */ -public final class GqlQuery extends Query { +public final class GqlQuery extends Query implements RecordQuery { private static final long serialVersionUID = -5514894742849230793L; @@ -80,6 +81,8 @@ public final class GqlQuery extends Query { private final ImmutableMap namedBindings; private final ImmutableList positionalBindings; + private final ResultType resultType; + static final class Binding implements Serializable { private static final long serialVersionUID = 2344746877591371548L; @@ -423,7 +426,8 @@ private static Binding toBinding( } private GqlQuery(Builder builder) { - super(builder.resultType, builder.namespace); + super(builder.namespace); + resultType = checkNotNull(builder.resultType); queryString = builder.queryString; allowLiteral = builder.allowLiteral; namedBindings = ImmutableMap.copyOf(builder.namedBindings); @@ -461,9 +465,15 @@ public List getNumberArgs() { return builder.build(); } + @Override + public ResultType getType() { + return resultType; + } + @Override public String toString() { - return super.toStringHelper() + return toStringHelper() + .add("type", getType()) .add("queryString", queryString) .add("allowLiteral", allowLiteral) .add("namedBindings", namedBindings) @@ -507,13 +517,15 @@ com.google.datastore.v1.GqlQuery toPb() { return queryPb.build(); } + @InternalApi @Override - void populatePb(com.google.datastore.v1.RunQueryRequest.Builder requestPb) { + public void populatePb(com.google.datastore.v1.RunQueryRequest.Builder requestPb) { requestPb.setGqlQuery(toPb()); } + @InternalApi @Override - Query nextQuery(com.google.datastore.v1.RunQueryResponse responsePb) { + public RecordQuery nextQuery(com.google.datastore.v1.RunQueryResponse responsePb) { return StructuredQuery.fromPb(getType(), getNamespace(), responsePb.getQuery()) .nextQuery(responsePb); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Query.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Query.java index 00aa6f17c..b0c7729ee 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Query.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Query.java @@ -16,7 +16,6 @@ package com.google.cloud.datastore; -import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; @@ -39,7 +38,6 @@ public abstract class Query implements Serializable { private static final long serialVersionUID = 7967659059395653941L; - private final ResultType resultType; private final String namespace; /** @@ -156,27 +154,18 @@ static ResultType fromPb(com.google.datastore.v1.EntityResult.ResultType type } } - Query(ResultType resultType, String namespace) { - this.resultType = checkNotNull(resultType); + Query(String namespace) { this.namespace = namespace; } - ResultType getType() { - return resultType; - } - public String getNamespace() { return namespace; } ToStringHelper toStringHelper() { - return MoreObjects.toStringHelper(this).add("type", resultType).add("namespace", namespace); + return MoreObjects.toStringHelper(this).add("namespace", namespace); } - abstract void populatePb(com.google.datastore.v1.RunQueryRequest.Builder requestPb); - - abstract Query nextQuery(com.google.datastore.v1.RunQueryResponse responsePb); - /** * Returns a new {@link GqlQuery} builder. * diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java index 9ed822985..222efa3b8 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java @@ -30,7 +30,7 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults private final com.google.datastore.v1.ReadOptions readOptionsPb; private final com.google.datastore.v1.PartitionId partitionIdPb; private final ResultType queryResultType; - private Query query; + private RecordQuery query; private ResultType actualResultType; private com.google.datastore.v1.RunQueryResponse runQueryResponsePb; private com.google.datastore.v1.Query mostRecentQueryPb; @@ -40,7 +40,10 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults private MoreResultsType moreResults; QueryResultsImpl( - DatastoreImpl datastore, com.google.datastore.v1.ReadOptions readOptionsPb, Query query) { + DatastoreImpl datastore, + com.google.datastore.v1.ReadOptions readOptionsPb, + RecordQuery query, + String namespace) { this.datastore = datastore; this.readOptionsPb = readOptionsPb; this.query = query; @@ -48,8 +51,8 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults com.google.datastore.v1.PartitionId.Builder pbBuilder = com.google.datastore.v1.PartitionId.newBuilder(); pbBuilder.setProjectId(datastore.getOptions().getProjectId()); - if (query.getNamespace() != null) { - pbBuilder.setNamespaceId(query.getNamespace()); + if (namespace != null) { + pbBuilder.setNamespaceId(namespace); } else if (datastore.getOptions().getNamespace() != null) { pbBuilder.setNamespaceId(datastore.getOptions().getNamespace()); } diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RecordQuery.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RecordQuery.java new file mode 100644 index 000000000..770837602 --- /dev/null +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RecordQuery.java @@ -0,0 +1,32 @@ +/* + * Copyright 2022 Google LLC + * + * 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 + * + * https://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.google.cloud.datastore; + +import com.google.api.core.InternalApi; +import com.google.cloud.datastore.Query.ResultType; + +/** An internal marker interface to represent {@link Query} that returns the entity records. */ +@InternalApi +public interface RecordQuery { + + ResultType getType(); + + @InternalApi + void populatePb(com.google.datastore.v1.RunQueryRequest.Builder requestPb); + + @InternalApi + RecordQuery nextQuery(com.google.datastore.v1.RunQueryResponse responsePb); +} diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java index 8e50d0867..8d2974c15 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java @@ -26,6 +26,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.core.ApiFunction; +import com.google.api.core.InternalApi; import com.google.cloud.StringEnumType; import com.google.cloud.StringEnumValue; import com.google.cloud.Timestamp; @@ -85,7 +86,7 @@ * @see Datastore * queries */ -public abstract class StructuredQuery extends Query { +public abstract class StructuredQuery extends Query implements RecordQuery { private static final long serialVersionUID = 546838955624019594L; static final String KEY_PROPERTY_NAME = "__key__"; @@ -100,6 +101,8 @@ public abstract class StructuredQuery extends Query { private final int offset; private final Integer limit; + private final ResultType resultType; + public abstract static class Filter implements Serializable { private static final long serialVersionUID = -6443285436239990860L; @@ -899,7 +902,8 @@ B mergeFrom(com.google.datastore.v1.Query queryPb) { } StructuredQuery(BuilderImpl builder) { - super(builder.resultType, builder.namespace); + super(builder.namespace); + resultType = checkNotNull(builder.resultType); kind = builder.kind; projection = ImmutableList.copyOf(builder.projection); filter = builder.filter; @@ -914,6 +918,7 @@ B mergeFrom(com.google.datastore.v1.Query queryPb) { @Override public String toString() { return toStringHelper() + .add("type", getType()) .add("kind", kind) .add("startCursor", startCursor) .add("endCursor", endCursor) @@ -1013,13 +1018,19 @@ public Integer getLimit() { public abstract Builder toBuilder(); + public ResultType getType() { + return resultType; + } + + @InternalApi @Override - void populatePb(com.google.datastore.v1.RunQueryRequest.Builder requestPb) { + public void populatePb(com.google.datastore.v1.RunQueryRequest.Builder requestPb) { requestPb.setQuery(toPb()); } + @InternalApi @Override - StructuredQuery nextQuery(com.google.datastore.v1.RunQueryResponse responsePb) { + public StructuredQuery nextQuery(com.google.datastore.v1.RunQueryResponse responsePb) { Builder builder = toBuilder(); builder.setStartCursor(new Cursor(responsePb.getBatch().getEndCursor())); if (offset > 0 && responsePb.getBatch().getSkippedResults() < offset) { diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java index fa077bc61..72067fd20 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java @@ -613,7 +613,7 @@ private List buildResponsesForQueryPagination() { Entity entity5 = Entity.newBuilder(KEY5).set("value", "value").build(); datastore.add(ENTITY3, entity4, entity5); List responses = new ArrayList<>(); - Query query = Query.newKeyQueryBuilder().build(); + RecordQuery query = Query.newKeyQueryBuilder().build(); RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); query.populatePb(requestPb); QueryResultBatch queryResultBatchPb = @@ -722,7 +722,7 @@ private List buildResponsesForQueryPaginationWithLimit() { datastore.add(ENTITY3, entity4, entity5); DatastoreRpc datastoreRpc = datastore.getOptions().getDatastoreRpcV1(); List responses = new ArrayList<>(); - Query query = Query.newEntityQueryBuilder().build(); + RecordQuery query = Query.newEntityQueryBuilder().build(); RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); query.populatePb(requestPb); QueryResultBatch queryResultBatchPb = From 0ef23244e9a4264bb8dfc34841b83173aa6e6561 Mon Sep 17 00:00:00 2001 From: Prateek Jain Date: Thu, 13 Oct 2022 11:55:05 +0530 Subject: [PATCH 2/3] fixing lint --- .../src/main/java/com/google/cloud/datastore/Query.java | 1 - 1 file changed, 1 deletion(-) diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Query.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Query.java index b0c7729ee..a0bed5984 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Query.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/Query.java @@ -16,7 +16,6 @@ package com.google.cloud.datastore; - import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.collect.Maps; From aa834031e36be75c489525fca1d4734edf374ba2 Mon Sep 17 00:00:00 2001 From: Prateek Jain Date: Thu, 13 Oct 2022 20:05:41 +0530 Subject: [PATCH 3/3] Making getType an internal function --- .../src/main/java/com/google/cloud/datastore/RecordQuery.java | 1 + 1 file changed, 1 insertion(+) diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RecordQuery.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RecordQuery.java index 770837602..9dc966457 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RecordQuery.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RecordQuery.java @@ -22,6 +22,7 @@ @InternalApi public interface RecordQuery { + @InternalApi ResultType getType(); @InternalApi