From a77fd34b49d29413df9c5816541b742e1293dbaf Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 14 Sep 2015 09:16:15 -0700 Subject: [PATCH 01/29] Update values and keys to v1beta3 --- gcloud-java-datastore/pom.xml | 20 +++++ .../datastore/BaseDatastoreBatchWriter.java | 3 +- .../google/gcloud/datastore/BaseEntity.java | 12 ++- .../com/google/gcloud/datastore/BaseKey.java | 23 +++--- .../google/gcloud/datastore/BatchImpl.java | 4 +- .../google/gcloud/datastore/BlobValue.java | 8 +- .../google/gcloud/datastore/BooleanValue.java | 8 +- .../gcloud/datastore/DatastoreImpl.java | 15 ++-- .../com/google/gcloud/datastore/DateTime.java | 22 ++++-- .../gcloud/datastore/DateTimeValue.java | 15 ++-- .../google/gcloud/datastore/DoubleValue.java | 8 +- .../google/gcloud/datastore/EntityValue.java | 25 +++--- .../com/google/gcloud/datastore/GqlQuery.java | 7 +- .../gcloud/datastore/IncompleteKey.java | 21 ++--- .../java/com/google/gcloud/datastore/Key.java | 8 +- .../com/google/gcloud/datastore/KeyValue.java | 8 +- .../google/gcloud/datastore/ListValue.java | 27 +++---- .../google/gcloud/datastore/LongValue.java | 8 +- .../google/gcloud/datastore/NullValue.java | 6 +- .../google/gcloud/datastore/PathElement.java | 17 ++-- .../gcloud/datastore/ProjectionEntity.java | 4 +- .../com/google/gcloud/datastore/Query.java | 7 +- .../com/google/gcloud/datastore/RawValue.java | 30 +++---- .../google/gcloud/datastore/StringValue.java | 8 +- .../gcloud/datastore/StructuredQuery.java | 9 ++- .../gcloud/datastore/TransactionImpl.java | 4 +- .../com/google/gcloud/datastore/Value.java | 78 +++++++------------ .../google/gcloud/datastore/ValueBuilder.java | 8 +- .../gcloud/datastore/ValueMarshaller.java | 6 +- .../google/gcloud/datastore/package-info.java | 4 +- .../BaseDatastoreBatchWriterTest.java | 16 ++-- .../gcloud/datastore/BlobValueTest.java | 11 +-- .../gcloud/datastore/BooleanValueTest.java | 11 +-- .../gcloud/datastore/DatastoreTest.java | 15 ++-- .../gcloud/datastore/DateTimeValueTest.java | 11 +-- .../gcloud/datastore/DoubleValueTest.java | 11 +-- .../gcloud/datastore/EntityValueTest.java | 17 +--- .../google/gcloud/datastore/KeyValueTest.java | 11 +-- .../gcloud/datastore/ListValueTest.java | 15 +--- .../gcloud/datastore/LongValueTest.java | 11 +-- .../gcloud/datastore/NullValueTest.java | 12 +-- .../google/gcloud/datastore/RawValueTest.java | 16 ++-- .../gcloud/datastore/SerializationTest.java | 13 ++-- .../gcloud/datastore/StringValueTest.java | 12 +-- .../google/gcloud/datastore/ValueTest.java | 65 +++------------- 45 files changed, 294 insertions(+), 376 deletions(-) diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 52b3f62232c4..8315836f67cd 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -13,12 +13,32 @@ gcloud-java-pom 0.0.8-SNAPSHOT + + + sonatype-snapshots + sonatype-snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + true + + + ${project.groupId} gcloud-java-core ${project.version} + + com.google.cloud.datastore + datastore-v1beta3-protos + 0.0.1-SNAPSHOT + + + com.google.cloud.datastore + datastore-v1beta3-proto-client + 0.0.1-SNAPSHOT + com.google.apis google-api-services-datastore-protobuf diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java index 7eaf5c535f26..8d0eec117bdf 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java @@ -214,7 +214,8 @@ protected DatastoreV1.Mutation.Builder toMutationPb() { mutationPb.addUpsert(entity.toPb()); } for (Key key : toDelete()) { - mutationPb.addDelete(key.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //mutationPb.addDelete(key.toPb()); } return mutationPb; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 3a79f3053a1e..665b4d8d24b9 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -93,11 +93,13 @@ private B self() { protected B fill(DatastoreV1.Entity entityPb) { Map> copiedProperties = Maps.newHashMap(); for (DatastoreV1.Property property : entityPb.getPropertyList()) { - copiedProperties.put(property.getName(), Value.fromPb(property.getValue())); + // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + //copiedProperties.put(property.getName(), Value.fromPb(property.getValue())); } properties(copiedProperties); if (entityPb.hasKey()) { - key((K) IncompleteKey.fromPb(entityPb.getKey())); + // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + //key((K) IncompleteKey.fromPb(entityPb.getKey())); } return self(); } @@ -389,11 +391,13 @@ protected final DatastoreV1.Entity toPb() { for (Map.Entry> entry : properties.entrySet()) { DatastoreV1.Property.Builder propertyPb = DatastoreV1.Property.newBuilder(); propertyPb.setName(entry.getKey()); - propertyPb.setValue(entry.getValue().toPb()); + // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + //propertyPb.setValue(entry.getValue().toPb()); entityPb.addProperty(propertyPb.build()); } if (key != null) { - entityPb.setKey(key.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //entityPb.setKey(key.toPb()); } return entityPb.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java index 865b95ed8518..fdc973c6c4cc 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java @@ -20,8 +20,8 @@ import static com.google.gcloud.datastore.Validator.validateKind; import static com.google.gcloud.datastore.Validator.validateNamespace; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.util.LinkedList; @@ -31,7 +31,7 @@ /** * Base class for keys. */ -abstract class BaseKey extends Serializable { +abstract class BaseKey extends Serializable { private static final long serialVersionUID = -4671243265877410635L; @@ -172,20 +172,21 @@ public boolean equals(Object obj) { } @Override - protected DatastoreV1.Key toPb() { - DatastoreV1.Key.Builder keyPb = DatastoreV1.Key.newBuilder(); - DatastoreV1.PartitionId.Builder partitionIdPb = DatastoreV1.PartitionId.newBuilder(); - if (projectId != null) { - partitionIdPb.setDatasetId(projectId); + protected com.google.datastore.v1beta3.Key toPb() { + com.google.datastore.v1beta3.Key.Builder keyPb = com.google.datastore.v1beta3.Key.newBuilder(); + com.google.datastore.v1beta3.PartitionId.Builder partitionIdPb = + com.google.datastore.v1beta3.PartitionId.newBuilder(); + if (!Strings.isNullOrEmpty(projectId)) { + partitionIdPb.setProjectId(projectId); } - if (namespace != null) { - partitionIdPb.setNamespace(namespace); + if (!Strings.isNullOrEmpty(namespace)) { + partitionIdPb.setNamespaceId(namespace); } - if (partitionIdPb.hasDatasetId() || partitionIdPb.hasNamespace()) { + if (!partitionIdPb.getProjectId().isEmpty() || !partitionIdPb.getNamespaceId().isEmpty()) { keyPb.setPartitionId(partitionIdPb.build()); } for (PathElement pathEntry : path) { - keyPb.addPathElement(pathEntry.toPb()); + keyPb.addPath(pathEntry.toPb()); } return keyPb.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java index 8cb41304500b..95cdfbb10f01 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java @@ -43,7 +43,9 @@ public List generatedKeys() { return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), new Function() { @Override public Key apply(DatastoreV1.Key keyPb) { - return Key.fromPb(keyPb); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return Key.fromPb(keyPb); + return Key.builder(null).build(); // TODO(ajaykannan): remove this line when possible } }); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java index fb61c0b9ad34..19d545e1790c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.BLOB_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.BLOB_VALUE_FIELD_NUMBER; public final class BlobValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(Blob value) { } @Override - protected Blob getValue(DatastoreV1.Value from) { + protected Blob getValue(com.google.datastore.v1beta3.Value from) { return new Blob(from.getBlobValue()); } @Override - protected void setValue(BlobValue from, DatastoreV1.Value.Builder to) { + protected void setValue(BlobValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setBlobValue(from.get().byteString()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java index 2dd98a5013ac..3e1bdc14e822 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.BOOLEAN_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.BOOLEAN_VALUE_FIELD_NUMBER; public final class BooleanValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(Boolean value) { } @Override - protected Boolean getValue(DatastoreV1.Value from) { + protected Boolean getValue(com.google.datastore.v1beta3.Value from) { return from.getBooleanValue(); } @Override - protected void setValue(BooleanValue from, DatastoreV1.Value.Builder to) { + protected void setValue(BooleanValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setBooleanValue(from.get()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 6f2454c62167..23d4f74a8da1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -126,12 +126,14 @@ public List allocateId(IncompleteKey... keys) { } DatastoreV1.AllocateIdsRequest.Builder requestPb = DatastoreV1.AllocateIdsRequest.newBuilder(); for (IncompleteKey key : keys) { - requestPb.addKey(trimNameOrId(key).toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //requestPb.addKey(trimNameOrId(key).toPb()); } DatastoreV1.AllocateIdsResponse responsePb = allocateIds(requestPb.build()); ImmutableList.Builder keyList = ImmutableList.builder(); for (DatastoreV1.Key keyPb : responsePb.getKeyList()) { - keyList.add(Key.fromPb(keyPb)); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // keyList.add(Key.fromPb(keyPb)); } return keyList.build(); } @@ -193,7 +195,8 @@ public List add(FullEntity... entities) { if (completeEntity != null) { responseBuilder.add(completeEntity); } else { - responseBuilder.add(Entity.builder(Key.fromPb(allocatedKeys.next()), entity).build()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //responseBuilder.add(Entity.builder(Key.fromPb(allocatedKeys.next()), entity).build()); } } return responseBuilder.build(); @@ -223,7 +226,8 @@ Iterator get(DatastoreV1.ReadOptions readOptionsPb, final Key... keys) { requestPb.setReadOptions(readOptionsPb); } for (Key k : Sets.newLinkedHashSet(Arrays.asList(keys))) { - requestPb.addKey(k.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //requestPb.addKey(k.toPb()); } return new ResultsIterator(requestPb); } @@ -310,7 +314,8 @@ public void delete(Key... keys) { DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); Set dedupKeys = new LinkedHashSet<>(Arrays.asList(keys)); for (Key key : dedupKeys) { - mutationPb.addDelete(key.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //mutationPb.addDelete(key.toPb()); } commitMutation(mutationPb); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java index af5a17ef7ef3..0d5c99d2b3fd 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java @@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.Value; import com.google.protobuf.InvalidProtocolBufferException; import org.joda.time.format.ISODateTimeFormat; @@ -34,7 +32,7 @@ * @see Google Cloud Datastore * Entities, Properties, and Keys */ -public final class DateTime extends Serializable +public final class DateTime extends Serializable implements Comparable { private static final long serialVersionUID = 7343324797621228378L; @@ -98,12 +96,24 @@ public static DateTime copyFrom(Calendar calendar) { } @Override - protected Value toPb() { - return DatastoreV1.Value.newBuilder().setIntegerValue(timestampMicroseconds).build(); + protected com.google.datastore.v1beta3.Value toPb() { + return com.google.datastore.v1beta3.Value.newBuilder() + .setTimestampValue(microsecondsToTimestampPb(timestampMicroseconds)).build(); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return new DateTime(DatastoreV1.Value.parseFrom(bytesPb).getIntegerValue()); + return new DateTime(timestampPbToMicroseconds(com.google.datastore.v1beta3.Value + .parseFrom(bytesPb).getTimestampValue())); + } + + protected static long timestampPbToMicroseconds(com.google.protobuf.Timestamp timestampPb) { + return timestampPb.getSeconds() * 10^6 + timestampPb.getNanos() / 10^3; + } + + protected static com.google.protobuf.Timestamp microsecondsToTimestampPb(long microseconds) { + long seconds = microseconds / 10^6; + int nanos = (int) (microseconds % 10^6) * 10^3; + return com.google.protobuf.Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build(); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java index 7aec5c7d3c47..e9c42ffabf4c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.TIMESTAMP_MICROSECONDS_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.TIMESTAMP_VALUE_FIELD_NUMBER; public final class DateTimeValue extends Value { @@ -31,7 +29,7 @@ public final class DateTimeValue extends Value { @Override public int getProtoFieldId() { - return TIMESTAMP_MICROSECONDS_VALUE_FIELD_NUMBER; + return TIMESTAMP_VALUE_FIELD_NUMBER; } @Override @@ -40,13 +38,14 @@ public Builder newBuilder(DateTime value) { } @Override - protected DateTime getValue(DatastoreV1.Value from) { - return new DateTime(from.getTimestampMicrosecondsValue()); + protected DateTime getValue(com.google.datastore.v1beta3.Value from) { + return new DateTime(DateTime.timestampPbToMicroseconds(from.getTimestampValue())); } @Override - protected void setValue(DateTimeValue from, DatastoreV1.Value.Builder to) { - to.setTimestampMicrosecondsValue(from.get().timestampMicroseconds()); + protected void setValue(DateTimeValue from, com.google.datastore.v1beta3.Value.Builder to) { + to.setTimestampValue(DateTime.microsecondsToTimestampPb(from.get() + .timestampMicroseconds())); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java index d12bbe317aef..cf543ad94b78 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java @@ -16,7 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.DOUBLE_VALUE_FIELD_NUMBER; +import static com.google.datastore.v1beta3.Value.DOUBLE_VALUE_FIELD_NUMBER; import com.google.api.services.datastore.DatastoreV1; @@ -40,12 +40,12 @@ public Builder newBuilder(Double value) { } @Override - protected Double getValue(DatastoreV1.Value from) { + protected Double getValue(com.google.datastore.v1beta3.Value from) { return from.getDoubleValue(); } - + @Override - protected void setValue(DoubleValue from, DatastoreV1.Value.Builder to) { + protected void setValue(DoubleValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setDoubleValue(from.get()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java index da32c8eb2462..3105f9fa0dd9 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java @@ -16,10 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.ENTITY_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; -import com.google.common.base.Preconditions; +import static com.google.datastore.v1beta3.Value.ENTITY_VALUE_FIELD_NUMBER; public class EntityValue extends Value> { @@ -41,13 +38,16 @@ public Builder newBuilder(FullEntity value) { } @Override - protected FullEntity getValue(DatastoreV1.Value from) { - return FullEntity.fromPb(from.getEntityValue()); + protected FullEntity getValue(com.google.datastore.v1beta3.Value from) { + // TODO(ajaykannan): uncomment this line when possible in datastore v1beta3 transition + //return FullEntity.fromPb(from.getEntityValue()); + return null; // TODO(ajaykannan): remove this line when possible } @Override - protected void setValue(EntityValue from, DatastoreV1.Value.Builder to) { - to.setEntityValue(from.get().toPb()); + protected void setValue(EntityValue from, com.google.datastore.v1beta3.Value.Builder to) { + // TODO(ajaykannan): uncomment this line when possible in datastore v1beta3 transition + //to.setEntityValue(from.get().toPb()); } }; @@ -57,13 +57,6 @@ private Builder() { super(ValueType.ENTITY); } - @Override - public Builder indexed(boolean indexed) { - // see issue #25 - Preconditions.checkArgument(!indexed, "EntityValue can't be indexed"); - return super.indexed(indexed); - } - @Override public EntityValue build() { return new EntityValue(this); @@ -88,6 +81,6 @@ public static EntityValue of(FullEntity entity) { } public static Builder builder(FullEntity entity) { - return new Builder().set(entity).indexed(false); + return new Builder().set(entity); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index e9bd8e12cfd8..ff659805a34d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -135,7 +135,8 @@ protected DatastoreV1.GqlQueryArg toPb() { argPb.setCursor(cursor.byteString()); } if (value != null) { - argPb.setValue(value.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //argPb.setValue(value.toPb()); } return argPb.build(); } @@ -150,7 +151,9 @@ static Binding fromPb(DatastoreV1.GqlQueryArg argPb) { if (argPb.hasCursor()) { return new Binding(name, new Cursor(argPb.getCursor())); } - return new Binding(name, Value.fromPb(argPb.getValue())); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return new Binding(name, Value.fromPb(argPb.getValue())); + return new Binding(name, new Cursor(null)); // TODO(ajaykannan): remove this line when possible } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java index 6134eed2905b..0eabefe32643 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java @@ -16,7 +16,6 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.protobuf.InvalidProtocolBufferException; @@ -55,25 +54,27 @@ public IncompleteKey build() { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Key.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Key.parseFrom(bytesPb)); } - static IncompleteKey fromPb(DatastoreV1.Key keyPb) { + static IncompleteKey fromPb(com.google.datastore.v1beta3.Key keyPb) { String projectId = null; String namespace = null; if (keyPb.hasPartitionId()) { - DatastoreV1.PartitionId partitionIdPb = keyPb.getPartitionId(); - if (partitionIdPb.hasDatasetId()) { - projectId = partitionIdPb.getDatasetId(); + com.google.datastore.v1beta3.PartitionId partitionIdPb = keyPb.getPartitionId(); + projectId = partitionIdPb.getProjectId(); + if (projectId.isEmpty()) { + projectId = null; } - if (partitionIdPb.hasNamespace()) { - namespace = partitionIdPb.getNamespace(); + namespace = partitionIdPb.getNamespaceId(); + if (namespace.isEmpty()) { + namespace = null; } } - List pathElementsPb = keyPb.getPathElementList(); + List pathElementsPb = keyPb.getPathList(); Preconditions.checkArgument(!pathElementsPb.isEmpty(), "Path must not be empty"); ImmutableList.Builder pathBuilder = ImmutableList.builder(); - for (DatastoreV1.Key.PathElement pathElementPb : pathElementsPb) { + for (com.google.datastore.v1beta3.Key.PathElement pathElementPb : pathElementsPb) { pathBuilder.add(PathElement.fromPb(pathElementPb)); } ImmutableList path = pathBuilder.build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java index c625c067f6c2..04dbdddf8e23 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java @@ -18,7 +18,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.protobuf.InvalidProtocolBufferException; @@ -153,7 +152,8 @@ public String toUrlSafe() { public static Key fromUrlSafe(String urlSafe) { try { String utf8Str = URLDecoder.decode(urlSafe, UTF_8.name()); - DatastoreV1.Key.Builder builder = DatastoreV1.Key.newBuilder(); + com.google.datastore.v1beta3.Key.Builder builder = + com.google.datastore.v1beta3.Key.newBuilder(); TextFormat.merge(utf8Str, builder); return fromPb(builder.build()); } catch (UnsupportedEncodingException e) { @@ -165,10 +165,10 @@ public static Key fromUrlSafe(String urlSafe) { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Key.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Key.parseFrom(bytesPb)); } - static Key fromPb(DatastoreV1.Key keyPb) { + static Key fromPb(com.google.datastore.v1beta3.Key keyPb) { IncompleteKey key = IncompleteKey.fromPb(keyPb); Preconditions.checkState(key instanceof Key, "Key is not complete"); return (Key) key; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java index 252f48ebc92a..fc1823730d12 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.KEY_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.KEY_VALUE_FIELD_NUMBER; public final class KeyValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(Key key) { } @Override - protected Key getValue(DatastoreV1.Value from) { + protected Key getValue(com.google.datastore.v1beta3.Value from) { return Key.fromPb(from.getKeyValue()); } @Override - protected void setValue(KeyValue from, DatastoreV1.Value.Builder to) { + protected void setValue(KeyValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setKeyValue(from.get().toPb()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java index 41c7e82788b5..242a2956b682 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java @@ -16,9 +16,8 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.LIST_VALUE_FIELD_NUMBER; +import static com.google.datastore.v1beta3.Value.ARRAY_VALUE_FIELD_NUMBER; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -36,7 +35,7 @@ public final class ListValue extends Value>> { @Override public int getProtoFieldId() { - return LIST_VALUE_FIELD_NUMBER; + return ARRAY_VALUE_FIELD_NUMBER; } @Override @@ -45,19 +44,23 @@ public Builder newBuilder(List> values) { } @Override - protected List> getValue(DatastoreV1.Value from) { - List> properties = new ArrayList<>(from.getListValueCount()); - for (DatastoreV1.Value valuePb : from.getListValueList()) { + protected List> getValue(com.google.datastore.v1beta3.Value from) { + List> properties = new ArrayList<>(from.getArrayValue().getValuesCount()); + for (com.google.datastore.v1beta3.Value valuePb : from.getArrayValue().getValuesList()) { properties.add(Value.fromPb(valuePb)); } return properties; } @Override - protected void setValue(ListValue from, DatastoreV1.Value.Builder to) { + protected void setValue(ListValue from, com.google.datastore.v1beta3.Value.Builder to) { + List propertiesPb = + new ArrayList(); for (Value property : from.get()) { - to.addListValue(property.toPb()); + propertiesPb.add(property.toPb()); } + to.setArrayValue(com.google.datastore.v1beta3.ArrayValue.newBuilder() + .addAllValues(propertiesPb)); } }; @@ -71,7 +74,7 @@ private Builder() { } public Builder addValue(Value value) { - // see datastore_v1.proto definition for list_value + // see datastore.proto definition for list_value Preconditions.checkArgument(value.type() != ValueType.LIST, "Cannot contain another list"); listBuilder.add(value); return this; @@ -85,12 +88,6 @@ public Builder addValue(Value first, Value... other) { return this; } - @Override - public Builder indexed(boolean indexed) { - // see issue #26 - throw DatastoreException.throwInvalidRequest("ListValue can't specify index"); - } - /** * Copy the list of values. * diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java index 43d139e90249..18cdead6280a 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.INTEGER_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.INTEGER_VALUE_FIELD_NUMBER; public final class LongValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(Long value) { } @Override - protected Long getValue(DatastoreV1.Value from) { + protected Long getValue(com.google.datastore.v1beta3.Value from) { return from.getIntegerValue(); } @Override - protected void setValue(LongValue from, DatastoreV1.Value.Builder to) { + protected void setValue(LongValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setIntegerValue(from.get()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java index 58fed152ffd5..173ee3ef79f0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java @@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument; -import com.google.api.services.datastore.DatastoreV1; - public final class NullValue extends Value { private static final long serialVersionUID = 8497300779013002270L; @@ -40,12 +38,12 @@ public int getProtoFieldId() { } @Override - protected Void getValue(DatastoreV1.Value from) { + protected Void getValue(com.google.datastore.v1beta3.Value from) { return null; } @Override - protected void setValue(NullValue from, DatastoreV1.Value.Builder to) { + protected void setValue(NullValue from, com.google.datastore.v1beta3.Value.Builder to) { // nothing to set } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java index 186ed97adcde..c0196a6326fe 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Strings; import com.google.protobuf.InvalidProtocolBufferException; @@ -28,7 +27,7 @@ /** * Represents a single element in a key's path. */ -public final class PathElement extends Serializable { +public final class PathElement extends Serializable { private static final long serialVersionUID = -7968078857690784595L; @@ -86,8 +85,8 @@ public boolean equals(Object obj) { } @Override - protected DatastoreV1.Key.PathElement toPb() { - DatastoreV1.Key.PathElement.Builder pathElementPb = DatastoreV1.Key.PathElement.newBuilder(); + protected com.google.datastore.v1beta3.Key.PathElement toPb() { + com.google.datastore.v1beta3.Key.PathElement.Builder pathElementPb = com.google.datastore.v1beta3.Key.PathElement.newBuilder(); pathElementPb.setKind(kind); if (id != null) { pathElementPb.setId(id); @@ -99,15 +98,17 @@ protected DatastoreV1.Key.PathElement toPb() { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Key.PathElement.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Key.PathElement.parseFrom(bytesPb)); } - static PathElement fromPb(DatastoreV1.Key.PathElement pathElementPb) { + static PathElement fromPb(com.google.datastore.v1beta3.Key.PathElement pathElementPb) { String kind = pathElementPb.getKind(); - if (pathElementPb.hasId()) { + if (pathElementPb.getIdTypeCase() == + com.google.datastore.v1beta3.Key.PathElement.IdTypeCase.ID) { return of(kind, pathElementPb.getId()); } - if (pathElementPb.hasName()) { + if (pathElementPb.getIdTypeCase() == + com.google.datastore.v1beta3.Key.PathElement.IdTypeCase.NAME) { return of(kind, pathElementPb.getName()); } return of(kind); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java index 1ba054b68161..46a528617a0c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java @@ -56,7 +56,7 @@ public ProjectionEntity build() { @Override public DateTime getDateTime(String name) { Value value = getValue(name); - if (value.hasMeaning() && value.meaning() == 18 && value instanceof LongValue) { + if (value.meaning() == 18 && value instanceof LongValue) { return new DateTime(getLong(name)); } return ((Value) value).get(); @@ -66,7 +66,7 @@ public DateTime getDateTime(String name) { @Override public Blob getBlob(String name) { Value value = getValue(name); - if (value.hasMeaning() && value.meaning() == 18 && value instanceof StringValue) { + if (value.meaning() == 18 && value instanceof StringValue) { return new Blob(ByteString.copyFromUtf8(getString(name))); } return ((Value) value).get(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index 343535d94628..fdd120ccbe85 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -66,7 +66,8 @@ public abstract static class ResultType implements java.io.Serializable { if (!entityPb.hasKey()) { return null; } - return Key.fromPb(entityPb.getKey()); + //TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return Key.fromPb(entityPb.getKey()); } return ProjectionEntity.fromPb(entityPb); } @@ -88,7 +89,9 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = -8514289244104446252L; @Override protected Key convert(DatastoreV1.Entity entityPb) { - return Key.fromPb(entityPb.getKey()); + //TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return Key.fromPb(entityPb.getKey()); + return Key.builder(null).build(); // TODO(ajaykannan): remove this line when possible } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java index 9d447cf4289b..d60f215cd5f2 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java @@ -16,19 +16,17 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; - -public final class RawValue extends Value { +public final class RawValue extends Value { private static final long serialVersionUID = -3359604598651897941L; - static final BaseMarshaller MARSHALLER = - new BaseMarshaller() { + static final BaseMarshaller MARSHALLER = + new BaseMarshaller() { private static final long serialVersionUID = 5320642719486106244L; @Override - public Builder newBuilder(DatastoreV1.Value value) { + public Builder newBuilder(com.google.datastore.v1beta3.Value value) { return builder(value); } @@ -38,18 +36,18 @@ public int getProtoFieldId() { } @Override - protected DatastoreV1.Value getValue(DatastoreV1.Value from) { + protected com.google.datastore.v1beta3.Value getValue(com.google.datastore.v1beta3.Value from) { return from; } @Override - protected void setValue(RawValue from, DatastoreV1.Value.Builder to) { + protected void setValue(RawValue from, com.google.datastore.v1beta3.Value.Builder to) { to.mergeFrom(from.get()); } }; public static final class Builder - extends Value.BaseBuilder { + extends Value.BaseBuilder { private Builder() { super(ValueType.RAW_VALUE); @@ -65,7 +63,7 @@ private RawValue(Builder builder) { super(builder); } - RawValue(DatastoreV1.Value valuePb) { + RawValue(com.google.datastore.v1beta3.Value valuePb) { this(builder(valuePb)); } @@ -74,18 +72,14 @@ public Builder toBuilder() { return new Builder().mergeFrom(this); } - static RawValue of(DatastoreV1.Value valuePb) { + static RawValue of(com.google.datastore.v1beta3.Value valuePb) { return new RawValue(valuePb); } - static Builder builder(DatastoreV1.Value valuePb) { + static Builder builder(com.google.datastore.v1beta3.Value valuePb) { Builder builder = new Builder(); - if (valuePb.hasIndexed()) { - builder.indexed(valuePb.getIndexed()); - } - if (valuePb.hasMeaning()) { - builder.meaning(valuePb.getMeaning()); - } + builder.excludeFromIndexes(valuePb.getExcludeFromIndexes()); + builder.meaning(valuePb.getMeaning()); builder.set(valuePb); return builder; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java index 95a31e714876..4b2c8e123be7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.STRING_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.STRING_VALUE_FIELD_NUMBER; public final class StringValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(String value) { } @Override - protected String getValue(DatastoreV1.Value from) { + protected String getValue(com.google.datastore.v1beta3.Value from) { return from.getStringValue(); } @Override - protected void setValue(StringValue from, DatastoreV1.Value.Builder to) { + protected void setValue(StringValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setStringValue(from.get()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index ce596307d6da..b034b15995a3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -228,8 +228,10 @@ private PropertyFilter(String property, Operator operator, Value value) { public static PropertyFilter fromPb(DatastoreV1.PropertyFilter propertyFilterPb) { String property = propertyFilterPb.getProperty().getName(); Operator operator = Operator.fromPb(propertyFilterPb.getOperator()); - Value value = Value.fromPb(propertyFilterPb.getValue()); - return new PropertyFilter(property, operator, value); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //Value value = Value.fromPb(propertyFilterPb.getValue()); + //return new PropertyFilter(property, operator, value); + return new PropertyFilter(property, operator, null); // TODO(ajaykannan): remove this line when possible } @Override @@ -435,7 +437,8 @@ protected DatastoreV1.Filter toPb() { propertyFilterPb.getPropertyBuilder().setName(property); propertyFilterPb.setOperator(operator.toPb()); if (value != null) { - propertyFilterPb.setValue(value.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //propertyFilterPb.setValue(value.toPb()); } return filterPb.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index ae677aa005d6..62978ce73be6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -47,7 +47,9 @@ public List generatedKeys() { return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), new Function() { @Override public Key apply(DatastoreV1.Key keyPb) { - return Key.fromPb(keyPb); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return Key.fromPb(keyPb); + return Key.builder(null).build(); //: TODO(ajaykannan) remove this placeholder line } }); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java index c5fc63a960b1..94e1d7de545f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.InvalidProtocolBufferException; @@ -33,14 +32,14 @@ * * @param the type of the content for this value */ -public abstract class Value extends Serializable { +public abstract class Value extends Serializable { private static final long serialVersionUID = -1899638277588872742L; private final transient ValueType valueType; - private final transient Boolean indexed; - private final transient Integer meaning; + private final transient boolean excludeFromIndexes; + private final transient int meaning; private final transient V value; interface BuilderFactory, B extends ValueBuilder> @@ -55,34 +54,26 @@ abstract static class BaseMarshaller, B extends ValueBuild @SuppressWarnings("deprecation") @Override - public final B fromProto(DatastoreV1.Value proto) { + public final B fromProto(com.google.datastore.v1beta3.Value proto) { B builder = newBuilder(getValue(proto)); - if (proto.hasIndexed()) { - builder.indexed(proto.getIndexed()); - } - if (proto.hasMeaning()) { - builder.meaning(proto.getMeaning()); - } + builder.excludeFromIndexes(proto.getExcludeFromIndexes()); + builder.meaning(proto.getMeaning()); return builder; } @SuppressWarnings("deprecation") @Override - public final DatastoreV1.Value toProto(P value) { - DatastoreV1.Value.Builder builder = DatastoreV1.Value.newBuilder(); - if (value.hasIndexed()) { - builder.setIndexed(value.indexed()); - } - if (value.hasMeaning()) { - builder.setMeaning(value.meaning()); - } + public final com.google.datastore.v1beta3.Value toProto(P value) { + com.google.datastore.v1beta3.Value.Builder builder = com.google.datastore.v1beta3.Value.newBuilder(); + builder.setExcludeFromIndexes(value.excludeFromIndexes()); + builder.setMeaning(value.meaning()); setValue(value, builder); return builder.build(); } - protected abstract V getValue(DatastoreV1.Value from); + protected abstract V getValue(com.google.datastore.v1beta3.Value from); - protected abstract void setValue(P from, DatastoreV1.Value.Builder to); + protected abstract void setValue(P from, com.google.datastore.v1beta3.Value.Builder to); } @SuppressWarnings("deprecation") @@ -90,8 +81,8 @@ abstract static class BaseBuilder, B extends BaseBuilder { private final ValueType valueType; - private Boolean indexed; - private Integer meaning; + private boolean excludeFromIndexes; + private int meaning; private V value; BaseBuilder(ValueType valueType) { @@ -105,30 +96,30 @@ public ValueType getValueType() { @Override public B mergeFrom(P other) { - indexed = other.indexed(); + excludeFromIndexes = other.excludeFromIndexes(); meaning = other.meaning(); set(other.get()); return self(); } @Override - public Boolean getIndexed() { - return indexed; + public boolean getExcludeFromIndexes() { + return excludeFromIndexes; } @Override - public B indexed(boolean indexed) { - this.indexed = indexed; + public B excludeFromIndexes(boolean excludeFromIndexes) { + this.excludeFromIndexes = excludeFromIndexes; return self(); } @Override - public Integer getMeaning() { + public int getMeaning() { return meaning; } @Override - public B meaning(Integer meaning) { + public B meaning(int meaning) { this.meaning = meaning; return self(); } @@ -155,7 +146,7 @@ private B self() {

, B extends BaseBuilder> Value(ValueBuilder builder) { valueType = builder.getValueType(); - indexed = builder.getIndexed(); + excludeFromIndexes = builder.getExcludeFromIndexes(); meaning = builder.getMeaning(); value = builder.get(); } @@ -164,21 +155,12 @@ public final ValueType type() { return valueType; } - public final boolean hasIndexed() { - return indexed != null; - } - - public final Boolean indexed() { - return indexed; - } - - @Deprecated - public final boolean hasMeaning() { - return meaning != null; + public final boolean excludeFromIndexes() { + return excludeFromIndexes; } @Deprecated - public final Integer meaning() { + public final int meaning() { return meaning; } @@ -190,7 +172,7 @@ public final V get() { @Override public int hashCode() { - return Objects.hash(valueType, indexed, meaning, value); + return Objects.hash(valueType, excludeFromIndexes, meaning, value); } @Override @@ -204,18 +186,18 @@ public boolean equals(Object obj) { } Value other = (Value) obj; return Objects.equals(valueType, other.valueType) - && Objects.equals(indexed, other.indexed) + && Objects.equals(excludeFromIndexes, other.excludeFromIndexes) && Objects.equals(meaning, other.meaning) && Objects.equals(value, other.value); } @Override @SuppressWarnings("unchecked") - protected DatastoreV1.Value toPb() { + protected com.google.datastore.v1beta3.Value toPb() { return type().getMarshaller().toProto(this); } - static Value fromPb(DatastoreV1.Value proto) { + static Value fromPb(com.google.datastore.v1beta3.Value proto) { for (Entry entry : proto.getAllFields().entrySet()) { FieldDescriptor descriptor = entry.getKey(); if (descriptor.getName().endsWith("_value")) { @@ -232,6 +214,6 @@ static Value fromPb(DatastoreV1.Value proto) { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Value.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Value.parseFrom(bytesPb)); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java index f5b5d4c1319b..5094062e1ec8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java @@ -25,14 +25,14 @@ public interface ValueBuilder, B extends ValueBuilder, B extends ValueBuilder> extends java.io.Serializable { - B fromProto(DatastoreV1.Value proto); + B fromProto(com.google.datastore.v1beta3.Value proto); - DatastoreV1.Value toProto(P value); + com.google.datastore.v1beta3.Value toProto(P value); int getProtoFieldId(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java index 3b402820e663..f63be902c319 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java @@ -27,7 +27,7 @@ * if (entity == null) { * entity = Entity.builder(key) * .set("name", "John Do") - * .set("age", LongValue.builder(100).indexed(false).build()) + * .set("age", LongValue.builder(100).excludeFromIndexes(true).build()) * .set("updated", false) * .build(); * datastore.put(entity); @@ -37,7 +37,7 @@ * String[] name = entity.getString("name").split(" "); * entity = Entity.builder(entity) * .set("name", name[0]) - * .set("last_name", StringValue.builder(name[1]).indexed(false).build()) + * .set("last_name", StringValue.builder(name[1]).excludeFromIndexes(true).build()) * .set("updated", true) * .remove("old_property") * .set("new_property", 1.1) diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java index ad8e0cee266a..28fea360ecf4 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java @@ -272,10 +272,11 @@ public void testPutWhenNotActive() throws Exception { @Test public void testDelete() throws Exception { + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) - .addDelete(KEY2.toPb()) - .addDelete(KEY3.toPb()) + //.addDelete(KEY1.toPb()) + //.addDelete(KEY2.toPb()) + //.addDelete(KEY3.toPb()) .build(); batchWriter.delete(KEY1, KEY2); batchWriter.delete(KEY3); @@ -284,9 +285,10 @@ public void testDelete() throws Exception { @Test public void testDeleteAfterAdd() throws Exception { + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() .addInsertAutoId(INCOMPLETE_ENTITY_1.toPb()) - .addDelete(KEY1.toPb()) + //.addDelete(KEY1.toPb()) .build(); batchWriter.add(ENTITY1); batchWriter.addWithDeferredIdAllocation(INCOMPLETE_ENTITY_1); @@ -296,8 +298,9 @@ public void testDeleteAfterAdd() throws Exception { @Test public void testDeleteAfterUpdate() throws Exception { + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) + //.addDelete(KEY1.toPb()) .build(); batchWriter.update(ENTITY1); batchWriter.delete(KEY1); @@ -306,8 +309,9 @@ public void testDeleteAfterUpdate() throws Exception { @Test public void testDeleteAfterPut() throws Exception { + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) + //.addDelete(KEY1.toPb()) .build(); batchWriter.put(ENTITY1); batchWriter.delete(KEY1); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java index 40d0299d8fb3..2a4c0dc956e3 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { BlobValue value = BlobValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { BlobValue.Builder builder = BlobValue.builder(CONTENT); - BlobValue value = builder.meaning(1).indexed(false).build(); + BlobValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java index 16bbe9cbf518..bff3d67c9465 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java @@ -35,19 +35,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { BooleanValue value = BooleanValue.of(false); assertFalse(value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { BooleanValue.Builder builder = BooleanValue.builder(true); - BooleanValue value = builder.meaning(1).indexed(true).build(); + BooleanValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertTrue(value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertTrue(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 156f9684f8ba..65872abb79e7 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -59,7 +59,8 @@ public class DatastoreTest { private static final String KIND3 = "kind3"; private static final NullValue NULL_VALUE = NullValue.of(); private static final StringValue STR_VALUE = StringValue.of("str"); - private static final BooleanValue BOOL_VALUE = BooleanValue.builder(false).indexed(false).build(); + private static final BooleanValue BOOL_VALUE = BooleanValue.builder(false) + .excludeFromIndexes(true).build(); private static final IncompleteKey INCOMPLETE_KEY1 = IncompleteKey.builder(PROJECT_ID, KIND1).build(); private static final IncompleteKey INCOMPLETE_KEY2 = @@ -636,17 +637,19 @@ public void testKeyFactory() { @Test public void testRetires() throws Exception { - DatastoreV1.LookupRequest requestPb = - DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //DatastoreV1.LookupRequest requestPb = + // DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); DatastoreV1.LookupResponse responsePb = DatastoreV1.LookupResponse.newBuilder() .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())).build(); DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(rpcMock); - EasyMock.expect(rpcMock.lookup(requestPb)) - .andThrow(new DatastoreRpc.DatastoreRpcException(Reason.UNAVAILABLE)) - .andReturn(responsePb); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //EasyMock.expect(rpcMock.lookup(requestPb)) + // .andThrow(new DatastoreRpc.DatastoreRpcException(Reason.UNAVAILABLE)) + // .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = this.options.toBuilder() .retryParams(RetryParams.getDefaultInstance()) diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java index d7fef2ca69b9..c90e8c88ba52 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { DateTimeValue value = DateTimeValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { DateTimeValue.Builder builder = DateTimeValue.builder(CONTENT); - DateTimeValue value = builder.meaning(1).indexed(false).build(); + DateTimeValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java index fa39511a45de..24d9113ce873 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { DoubleValue value = DoubleValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { DoubleValue.Builder builder = DoubleValue.builder(CONTENT); - DoubleValue value = builder.meaning(1).indexed(false).build(); + DoubleValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java index cd1f7af38067..e7df91ac0016 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java @@ -38,25 +38,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { EntityValue value = EntityValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); - assertFalse(value.hasMeaning()); - } - - @Test(expected = IllegalArgumentException.class) - public void testIndexedNotAllowed() { - EntityValue.builder(CONTENT).indexed(true); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { EntityValue.Builder builder = EntityValue.builder(CONTENT); - EntityValue value = builder.meaning(1).indexed(false).build(); + EntityValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java index 131a80462a62..b2e916983b8a 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { KeyValue value = KeyValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { KeyValue.Builder builder = KeyValue.builder(CONTENT); - KeyValue value = builder.meaning(1).indexed(false).build(); + KeyValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java index 36e3571d49ac..23a9325f22de 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java @@ -41,24 +41,17 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { ListValue value = ListValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); - } - - @Test(expected = DatastoreException.class) - public void testIndexedCannotBeSpecified() { - ListValue.builder().indexed(false); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { ListValue.Builder builder = ListValue.builder().set(CONTENT); - ListValue value = builder.meaning(1).build(); + ListValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertFalse(value.hasIndexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); builder = ListValue.builder(); for (Value v : CONTENT) { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java index c4c899785d68..717c1567bc45 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { LongValue value = LongValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { LongValue.Builder builder = LongValue.builder(CONTENT); - LongValue value = builder.meaning(1).indexed(false).build(); + LongValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java index a42fdaf0229f..0856fced7992 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java @@ -31,24 +31,20 @@ public void testToBuilder() throws Exception { assertEquals(value, value.toBuilder().build()); } - @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { NullValue value = NullValue.of(); assertNull(value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { NullValue.Builder builder = NullValue.builder(); - NullValue value = builder.meaning(1).indexed(false).build(); + NullValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertNull(value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java index 4d63bc89bacb..1ab1c36538de 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java @@ -20,13 +20,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.google.api.services.datastore.DatastoreV1; - import org.junit.Test; public class RawValueTest { - private static final DatastoreV1.Value CONTENT = StringValue.of("hello").toPb(); + private static final com.google.datastore.v1beta3.Value CONTENT = StringValue.of("hello").toPb(); @Test public void testToBuilder() throws Exception { @@ -34,24 +32,20 @@ public void testToBuilder() throws Exception { assertEquals(value, value.toBuilder().build()); } - @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { RawValue value = RawValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { RawValue.Builder builder = RawValue.builder(CONTENT); - RawValue value = builder.meaning(1).indexed(false).build(); + RawValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 5f3bfc036fa2..9dfdd33c873d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import com.google.gcloud.AuthCredentials; @@ -82,27 +81,27 @@ public class SerializationTest { .addOrderBy(OrderBy.asc("p")) .build(); private static final KeyValue KEY_VALUE = KeyValue.of(KEY1); - private static final NullValue NULL_VALUE = NullValue.builder().indexed(true).build(); + private static final NullValue NULL_VALUE = NullValue.builder().excludeFromIndexes(true).build(); private static final StringValue STRING_VALUE = StringValue.of("hello"); private static final LongValue LONG_VALUE = LongValue.of(123); private static final DoubleValue DOUBLE_VALUE = DoubleValue.of(12.34); private static final BooleanValue BOOLEAN_VALUE = BooleanValue.of(true); private static final DateTimeValue DATE_AND_TIME_VALUE = DateTimeValue.of(DateTime.now()); private static final BlobValue BLOB_VALUE = BlobValue.of(BLOB1); - private static final RawValue RAW_VALUE = RawValue.of( - DatastoreV1.Value.newBuilder().setBlobKeyValue("blob-key").setMeaning(18).build()); + private static final RawValue RAW_VALUE = RawValue.of(com.google.datastore.v1beta3.Value + .newBuilder().setStringValue("blob-key").setMeaning(18).build()); private static final Entity ENTITY1 = Entity.builder(KEY1).build(); private static final Entity ENTITY2 = Entity.builder(KEY2).set("null", NullValue.of()).build(); private static final Entity ENTITY3 = Entity.builder(KEY2) .set("p1", StringValue.builder("hi1").meaning(10).build()) - .set("p2", StringValue.builder("hi2").meaning(11).indexed(false).build()) - .set("p3", LongValue.builder(100).indexed(false).meaning(100).build()) + .set("p2", StringValue.builder("hi2").meaning(11).excludeFromIndexes(true).build()) + .set("p3", LongValue.builder(100).excludeFromIndexes(true).meaning(100).build()) .set("blob", BLOB1) .build(); private static final FullEntity EMBEDDED_ENTITY = Entity.builder(INCOMPLETE_KEY1) .set("p1", STRING_VALUE) - .set("p2", LongValue.builder(100).indexed(false).meaning(100).build()) + .set("p2", LongValue.builder(100).excludeFromIndexes(true).meaning(100).build()) .build(); private static final EntityValue EMBEDDED_ENTITY_VALUE1 = EntityValue.of(ENTITY1); private static final EntityValue EMBEDDED_ENTITY_VALUE2 = EntityValue.of(ENTITY2); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java index a2cacd6574aa..4f02568bf924 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java @@ -32,24 +32,20 @@ public void testToBuilder() throws Exception { assertEquals(value, value.toBuilder().build()); } - @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { StringValue value = StringValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { StringValue.Builder builder = StringValue.builder(CONTENT); - StringValue value = builder.meaning(1).indexed(false).build(); + StringValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java index 973a3c3c0da4..12908add4c8e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; @@ -116,67 +115,22 @@ public void testType() throws Exception { } @Test - public void testHasIndexed() throws Exception { + public void testExcludeFromIndexes() throws Exception { for (Map.Entry> entry : typeToValue.entrySet()) { - ValueType valueType = entry.getKey(); - Boolean indexed = entry.getValue().hasIndexed(); - switch (valueType) { - case ENTITY: - assertTrue(indexed); - break; - default: - assertFalse(indexed); - break; - } - } - - TestBuilder builder = new TestBuilder(); - assertFalse(builder.build().hasIndexed()); - assertTrue(builder.indexed(false).build().hasIndexed()); - assertTrue(builder.indexed(true).build().hasIndexed()); - } - - @Test - public void testIndexed() throws Exception { - for (Map.Entry> entry : typeToValue.entrySet()) { - ValueType valueType = entry.getKey(); - Boolean indexed = entry.getValue().indexed(); - switch (valueType) { - case ENTITY: - assertFalse(indexed); - break; - default: - assertNull(indexed); - break; - } - } - - TestBuilder builder = new TestBuilder(); - assertNull(builder.build().indexed()); - assertFalse(builder.indexed(false).build().indexed()); - assertTrue(builder.indexed(true).build().indexed()); - } - - @SuppressWarnings("deprecation") - @Test - public void testHasMeaning() throws Exception { - for (Value value: typeToValue.values()) { - assertFalse(value.hasMeaning()); + assertFalse(entry.getValue().excludeFromIndexes()); } TestBuilder builder = new TestBuilder(); - assertTrue(builder.meaning(10).build().hasMeaning()); + assertFalse(builder.build().excludeFromIndexes()); + assertTrue(builder.excludeFromIndexes(true).build().excludeFromIndexes()); + assertFalse(builder.excludeFromIndexes(false).build().excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testMeaning() throws Exception { - for (Value value: typeToValue.values()) { - assertNull(value.meaning()); - } - TestBuilder builder = new TestBuilder(); - assertEquals(Integer.valueOf(10), builder.meaning(10).build().meaning()); + assertEquals(10, builder.meaning(10).build().meaning()); } @Test @@ -197,12 +151,11 @@ public void testGet() throws Exception { public void testToBuilder() throws Exception { Set content = Collections.singleton("bla"); ValueBuilder builder = new TestBuilder(); - builder.meaning(1).set(content).indexed(true); + builder.meaning(1).set(content).excludeFromIndexes(true); Value value = builder.build(); builder = value.toBuilder(); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertTrue(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); assertEquals(ValueType.LIST, value.type()); assertEquals(content, value.get()); assertEquals(value, builder.build()); From 9f40a5f4b9a8d60e02e5cf4b004bee290b231eba Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 14 Sep 2015 15:25:12 -0700 Subject: [PATCH 02/29] Default projectId and namespace are empty strings, NullValue and DateTime are fixed, along with other minor edits --- .../datastore/BaseDatastoreBatchWriter.java | 2 +- .../google/gcloud/datastore/BaseEntity.java | 8 ++--- .../com/google/gcloud/datastore/BaseKey.java | 17 ++++------- .../google/gcloud/datastore/BatchImpl.java | 4 +-- .../gcloud/datastore/DatastoreImpl.java | 10 +++---- .../com/google/gcloud/datastore/DateTime.java | 17 +++++------ .../google/gcloud/datastore/DoubleValue.java | 4 +-- .../google/gcloud/datastore/EntityValue.java | 6 ++-- .../com/google/gcloud/datastore/GqlQuery.java | 6 ++-- .../gcloud/datastore/IncompleteKey.java | 10 ++----- .../google/gcloud/datastore/KeyFactory.java | 3 +- .../google/gcloud/datastore/NullValue.java | 9 ++++-- .../google/gcloud/datastore/PathElement.java | 18 +++++------ .../com/google/gcloud/datastore/Query.java | 6 ++-- .../com/google/gcloud/datastore/RawValue.java | 3 +- .../gcloud/datastore/StructuredQuery.java | 6 ++-- .../gcloud/datastore/TransactionImpl.java | 4 +-- .../google/gcloud/datastore/Validator.java | 12 ++++---- .../com/google/gcloud/datastore/Value.java | 24 +++++---------- .../google/gcloud/datastore/ValueType.java | 4 +++ .../BaseDatastoreBatchWriterTest.java | 30 ++++++++++++------- .../google/gcloud/datastore/BaseKeyTest.java | 3 +- .../gcloud/datastore/DatastoreTest.java | 15 +++++----- .../gcloud/datastore/KeyFactoryTest.java | 8 ++--- .../gcloud/datastore/ListValueTest.java | 2 +- .../gcloud/datastore/SerializationTest.java | 19 +++++++----- 26 files changed, 125 insertions(+), 125 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java index 8d0eec117bdf..d94eafbb42f6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java @@ -214,7 +214,7 @@ protected DatastoreV1.Mutation.Builder toMutationPb() { mutationPb.addUpsert(entity.toPb()); } for (Key key : toDelete()) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //mutationPb.addDelete(key.toPb()); } return mutationPb; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 665b4d8d24b9..8608e4fcedc9 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -93,12 +93,12 @@ private B self() { protected B fill(DatastoreV1.Entity entityPb) { Map> copiedProperties = Maps.newHashMap(); for (DatastoreV1.Property property : entityPb.getPropertyList()) { - // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //copiedProperties.put(property.getName(), Value.fromPb(property.getValue())); } properties(copiedProperties); if (entityPb.hasKey()) { - // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //key((K) IncompleteKey.fromPb(entityPb.getKey())); } return self(); @@ -391,12 +391,12 @@ protected final DatastoreV1.Entity toPb() { for (Map.Entry> entry : properties.entrySet()) { DatastoreV1.Property.Builder propertyPb = DatastoreV1.Property.newBuilder(); propertyPb.setName(entry.getKey()); - // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //propertyPb.setValue(entry.getValue().toPb()); entityPb.addProperty(propertyPb.build()); } if (key != null) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //entityPb.setKey(key.toPb()); } return entityPb.build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java index fdc973c6c4cc..2e6264af9927 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java @@ -21,7 +21,6 @@ import static com.google.gcloud.datastore.Validator.validateNamespace; import com.google.common.base.Preconditions; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.util.LinkedList; @@ -41,8 +40,8 @@ abstract class BaseKey extends Serializable { abstract static class Builder> { - String projectId; - String namespace; + String projectId = ""; + String namespace = ""; String kind; final List ancestors; @@ -176,15 +175,9 @@ protected com.google.datastore.v1beta3.Key toPb() { com.google.datastore.v1beta3.Key.Builder keyPb = com.google.datastore.v1beta3.Key.newBuilder(); com.google.datastore.v1beta3.PartitionId.Builder partitionIdPb = com.google.datastore.v1beta3.PartitionId.newBuilder(); - if (!Strings.isNullOrEmpty(projectId)) { - partitionIdPb.setProjectId(projectId); - } - if (!Strings.isNullOrEmpty(namespace)) { - partitionIdPb.setNamespaceId(namespace); - } - if (!partitionIdPb.getProjectId().isEmpty() || !partitionIdPb.getNamespaceId().isEmpty()) { - keyPb.setPartitionId(partitionIdPb.build()); - } + partitionIdPb.setProjectId(projectId); + partitionIdPb.setNamespaceId(namespace); + keyPb.setPartitionId(partitionIdPb.build()); for (PathElement pathEntry : path) { keyPb.addPath(pathEntry.toPb()); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java index 95cdfbb10f01..c86ae28b3344 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java @@ -43,9 +43,9 @@ public List generatedKeys() { return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), new Function() { @Override public Key apply(DatastoreV1.Key keyPb) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //return Key.fromPb(keyPb); - return Key.builder(null).build(); // TODO(ajaykannan): remove this line when possible + return Key.builder(null).build(); // TODO(ajaykannan): fix me! } }); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 23d4f74a8da1..c21c0c2a7087 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -126,13 +126,13 @@ public List allocateId(IncompleteKey... keys) { } DatastoreV1.AllocateIdsRequest.Builder requestPb = DatastoreV1.AllocateIdsRequest.newBuilder(); for (IncompleteKey key : keys) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //requestPb.addKey(trimNameOrId(key).toPb()); } DatastoreV1.AllocateIdsResponse responsePb = allocateIds(requestPb.build()); ImmutableList.Builder keyList = ImmutableList.builder(); for (DatastoreV1.Key keyPb : responsePb.getKeyList()) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! // keyList.add(Key.fromPb(keyPb)); } return keyList.build(); @@ -195,7 +195,7 @@ public List add(FullEntity... entities) { if (completeEntity != null) { responseBuilder.add(completeEntity); } else { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //responseBuilder.add(Entity.builder(Key.fromPb(allocatedKeys.next()), entity).build()); } } @@ -226,7 +226,7 @@ Iterator get(DatastoreV1.ReadOptions readOptionsPb, final Key... keys) { requestPb.setReadOptions(readOptionsPb); } for (Key k : Sets.newLinkedHashSet(Arrays.asList(keys))) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //requestPb.addKey(k.toPb()); } return new ResultsIterator(requestPb); @@ -314,7 +314,7 @@ public void delete(Key... keys) { DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); Set dedupKeys = new LinkedHashSet<>(Arrays.asList(keys)); for (Key key : dedupKeys) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //mutationPb.addDelete(key.toPb()); } commitMutation(mutationPb); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java index 0d5c99d2b3fd..eca352f5ba0c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java @@ -32,7 +32,7 @@ * @see Google Cloud Datastore * Entities, Properties, and Keys */ -public final class DateTime extends Serializable +public final class DateTime extends Serializable implements Comparable { private static final long serialVersionUID = 7343324797621228378L; @@ -96,24 +96,23 @@ public static DateTime copyFrom(Calendar calendar) { } @Override - protected com.google.datastore.v1beta3.Value toPb() { - return com.google.datastore.v1beta3.Value.newBuilder() - .setTimestampValue(microsecondsToTimestampPb(timestampMicroseconds)).build(); + protected com.google.protobuf.Timestamp toPb() { + return microsecondsToTimestampPb(timestampMicroseconds); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return new DateTime(timestampPbToMicroseconds(com.google.datastore.v1beta3.Value - .parseFrom(bytesPb).getTimestampValue())); + return new DateTime(timestampPbToMicroseconds( + com.google.protobuf.Timestamp.parseFrom(bytesPb))); } protected static long timestampPbToMicroseconds(com.google.protobuf.Timestamp timestampPb) { - return timestampPb.getSeconds() * 10^6 + timestampPb.getNanos() / 10^3; + return timestampPb.getSeconds() * 1000000 + timestampPb.getNanos() / 1000; } protected static com.google.protobuf.Timestamp microsecondsToTimestampPb(long microseconds) { - long seconds = microseconds / 10^6; - int nanos = (int) (microseconds % 10^6) * 10^3; + long seconds = microseconds / 1000000; + int nanos = (int) (microseconds % 1000000) * 1000; return com.google.protobuf.Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build(); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java index cf543ad94b78..d7409d08fe63 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java @@ -18,8 +18,6 @@ import static com.google.datastore.v1beta3.Value.DOUBLE_VALUE_FIELD_NUMBER; -import com.google.api.services.datastore.DatastoreV1; - public final class DoubleValue extends Value { private static final long serialVersionUID = -5096238337676649540L; @@ -43,7 +41,7 @@ public Builder newBuilder(Double value) { protected Double getValue(com.google.datastore.v1beta3.Value from) { return from.getDoubleValue(); } - + @Override protected void setValue(DoubleValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setDoubleValue(from.get()); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java index 3105f9fa0dd9..16ca55aec4a6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java @@ -39,14 +39,14 @@ public Builder newBuilder(FullEntity value) { @Override protected FullEntity getValue(com.google.datastore.v1beta3.Value from) { - // TODO(ajaykannan): uncomment this line when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //return FullEntity.fromPb(from.getEntityValue()); - return null; // TODO(ajaykannan): remove this line when possible + return null; // TODO(ajaykannan): fix me! } @Override protected void setValue(EntityValue from, com.google.datastore.v1beta3.Value.Builder to) { - // TODO(ajaykannan): uncomment this line when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //to.setEntityValue(from.get().toPb()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index ff659805a34d..54110a89c3e0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -135,7 +135,7 @@ protected DatastoreV1.GqlQueryArg toPb() { argPb.setCursor(cursor.byteString()); } if (value != null) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //argPb.setValue(value.toPb()); } return argPb.build(); @@ -151,9 +151,9 @@ static Binding fromPb(DatastoreV1.GqlQueryArg argPb) { if (argPb.hasCursor()) { return new Binding(name, new Cursor(argPb.getCursor())); } - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //return new Binding(name, Value.fromPb(argPb.getValue())); - return new Binding(name, new Cursor(null)); // TODO(ajaykannan): remove this line when possible + return new Binding(name, new Cursor(null)); // TODO(ajaykannan): fix me! } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java index 0eabefe32643..367bdbafed71 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java @@ -58,18 +58,12 @@ protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { } static IncompleteKey fromPb(com.google.datastore.v1beta3.Key keyPb) { - String projectId = null; - String namespace = null; + String projectId = ""; + String namespace = ""; if (keyPb.hasPartitionId()) { com.google.datastore.v1beta3.PartitionId partitionIdPb = keyPb.getPartitionId(); projectId = partitionIdPb.getProjectId(); - if (projectId.isEmpty()) { - projectId = null; - } namespace = partitionIdPb.getNamespaceId(); - if (namespace.isEmpty()) { - namespace = null; - } } List pathElementsPb = keyPb.getPathList(); Preconditions.checkArgument(!pathElementsPb.isEmpty(), "Path must not be empty"); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java index 28f852ed5355..c5b9d77a8cd7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java @@ -16,6 +16,7 @@ package com.google.gcloud.datastore; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; /** @@ -35,7 +36,7 @@ public KeyFactory(String projectId, String namespace) { super(projectId); namespace(namespace); this.pi = projectId; - this.ns = namespace; + this.ns = MoreObjects.firstNonNull(namespace, ""); } public IncompleteKey newKey() { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java index 173ee3ef79f0..ed314200b8bb 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java @@ -18,6 +18,8 @@ import static com.google.common.base.Preconditions.checkArgument; +import static com.google.datastore.v1beta3.Value.NULL_VALUE_FIELD_NUMBER; + public final class NullValue extends Value { private static final long serialVersionUID = 8497300779013002270L; @@ -34,7 +36,7 @@ public Builder newBuilder(Void value) { @Override public int getProtoFieldId() { - return 0; + return NULL_VALUE_FIELD_NUMBER; } @Override @@ -44,11 +46,12 @@ protected Void getValue(com.google.datastore.v1beta3.Value from) { @Override protected void setValue(NullValue from, com.google.datastore.v1beta3.Value.Builder to) { - // nothing to set + to.setNullValue(com.google.protobuf.NullValue.NULL_VALUE); } }; - public static final class Builder extends Value.BaseBuilder { + public static final class Builder + extends Value.BaseBuilder { private Builder() { super(ValueType.NULL); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java index c0196a6326fe..b0eb9fd83855 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java @@ -86,7 +86,8 @@ public boolean equals(Object obj) { @Override protected com.google.datastore.v1beta3.Key.PathElement toPb() { - com.google.datastore.v1beta3.Key.PathElement.Builder pathElementPb = com.google.datastore.v1beta3.Key.PathElement.newBuilder(); + com.google.datastore.v1beta3.Key.PathElement.Builder pathElementPb = + com.google.datastore.v1beta3.Key.PathElement.newBuilder(); pathElementPb.setKind(kind); if (id != null) { pathElementPb.setId(id); @@ -103,15 +104,14 @@ protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { static PathElement fromPb(com.google.datastore.v1beta3.Key.PathElement pathElementPb) { String kind = pathElementPb.getKind(); - if (pathElementPb.getIdTypeCase() == - com.google.datastore.v1beta3.Key.PathElement.IdTypeCase.ID) { - return of(kind, pathElementPb.getId()); + switch (pathElementPb.getIdTypeCase()) { + case ID: + return of(kind, pathElementPb.getId()); + case NAME: + return of(kind, pathElementPb.getName()); + default: + return of(kind); } - if (pathElementPb.getIdTypeCase() == - com.google.datastore.v1beta3.Key.PathElement.IdTypeCase.NAME) { - return of(kind, pathElementPb.getName()); - } - return of(kind); } static PathElement of(String kind) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index fdd120ccbe85..f3dd254ce9a3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -66,7 +66,7 @@ public abstract static class ResultType implements java.io.Serializable { if (!entityPb.hasKey()) { return null; } - //TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //TODO(ajaykannan): fix me! //return Key.fromPb(entityPb.getKey()); } return ProjectionEntity.fromPb(entityPb); @@ -89,9 +89,9 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = -8514289244104446252L; @Override protected Key convert(DatastoreV1.Entity entityPb) { - //TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //TODO(ajaykannan): fix me! //return Key.fromPb(entityPb.getKey()); - return Key.builder(null).build(); // TODO(ajaykannan): remove this line when possible + return Key.builder(null).build(); // TODO(ajaykannan): fix me! } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java index d60f215cd5f2..cd64bcdeff05 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java @@ -36,7 +36,8 @@ public int getProtoFieldId() { } @Override - protected com.google.datastore.v1beta3.Value getValue(com.google.datastore.v1beta3.Value from) { + protected com.google.datastore.v1beta3.Value getValue( + com.google.datastore.v1beta3.Value from) { return from; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index b034b15995a3..1dd35cb4f191 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -228,10 +228,10 @@ private PropertyFilter(String property, Operator operator, Value value) { public static PropertyFilter fromPb(DatastoreV1.PropertyFilter propertyFilterPb) { String property = propertyFilterPb.getProperty().getName(); Operator operator = Operator.fromPb(propertyFilterPb.getOperator()); - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //Value value = Value.fromPb(propertyFilterPb.getValue()); //return new PropertyFilter(property, operator, value); - return new PropertyFilter(property, operator, null); // TODO(ajaykannan): remove this line when possible + return new PropertyFilter(property, operator, null); // TODO(ajaykannan): fix me! } @Override @@ -437,7 +437,7 @@ protected DatastoreV1.Filter toPb() { propertyFilterPb.getPropertyBuilder().setName(property); propertyFilterPb.setOperator(operator.toPb()); if (value != null) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //propertyFilterPb.setValue(value.toPb()); } return filterPb.build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index 62978ce73be6..ae9d0e50f0d7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -47,9 +47,9 @@ public List generatedKeys() { return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), new Function() { @Override public Key apply(DatastoreV1.Key keyPb) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //return Key.fromPb(keyPb); - return Key.builder(null).build(); //: TODO(ajaykannan) remove this placeholder line + return Key.builder(null).build(); // TODO(ajaykannan): fix me! } }); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java index 09a3fa7defcc..791adec53101 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java @@ -45,13 +45,13 @@ static String validateDatabase(String projectId) { } static String validateNamespace(String namespace) { - if (namespace != null) { - checkArgument(!namespace.isEmpty(), "namespace must not be an empty string"); - checkArgument(namespace.length() <= MAX_NAMESPACE_LENGTH, - "namespace must not contain more than 100 characters"); - checkArgument(NAMESPACE_PATTERN.matcher(namespace).matches(), - "namespace must the following pattern: " + NAMESPACE_PATTERN.pattern()); + if (Strings.isNullOrEmpty(namespace)) { + return ""; } + checkArgument(namespace.length() <= MAX_NAMESPACE_LENGTH, + "namespace must not contain more than 100 characters"); + checkArgument(NAMESPACE_PATTERN.matcher(namespace).matches(), + "namespace must the following pattern: " + NAMESPACE_PATTERN.pattern()); return namespace; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java index 94e1d7de545f..9e4aae0fb6f5 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java @@ -18,10 +18,9 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.datastore.v1beta3.Value.ValueTypeCase; import com.google.protobuf.InvalidProtocolBufferException; -import java.util.Map.Entry; import java.util.Objects; /** @@ -64,7 +63,8 @@ public final B fromProto(com.google.datastore.v1beta3.Value proto) { @SuppressWarnings("deprecation") @Override public final com.google.datastore.v1beta3.Value toProto(P value) { - com.google.datastore.v1beta3.Value.Builder builder = com.google.datastore.v1beta3.Value.newBuilder(); + com.google.datastore.v1beta3.Value.Builder builder = + com.google.datastore.v1beta3.Value.newBuilder(); builder.setExcludeFromIndexes(value.excludeFromIndexes()); builder.setMeaning(value.meaning()); setValue(value, builder); @@ -160,7 +160,7 @@ public final boolean excludeFromIndexes() { } @Deprecated - public final int meaning() { + final int meaning() { return meaning; } @@ -198,18 +198,10 @@ protected com.google.datastore.v1beta3.Value toPb() { } static Value fromPb(com.google.datastore.v1beta3.Value proto) { - for (Entry entry : proto.getAllFields().entrySet()) { - FieldDescriptor descriptor = entry.getKey(); - if (descriptor.getName().endsWith("_value")) { - ValueType valueType = ValueType.getByDescriptorId(descriptor.getNumber()); - if (valueType == null) { - // unsupported type - return RawValue.MARSHALLER.fromProto(proto).build(); - } - return valueType.getMarshaller().fromProto(proto).build(); - } - } - return NullValue.MARSHALLER.fromProto(proto).build(); + ValueTypeCase descriptorId = proto.getValueTypeCase(); + ValueType valueType = ValueType.getByDescriptorId(descriptorId.getNumber()); + return valueType == null ? RawValue.MARSHALLER.fromProto(proto).build() + : valueType.getMarshaller().fromProto(proto).build(); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java index b09583103a59..20c89a86e7a0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java @@ -80,6 +80,10 @@ public enum ValueType { */ RAW_VALUE(RawValue.MARSHALLER); + /** + * TODO(ajaykannan): add GEO_POINT_VALUE + * Will represent a geolocation value in latitude/longitude + */ private static final ImmutableMap DESCRIPTOR_TO_TYPE_MAP; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java index 28fea360ecf4..43df45d7a04e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java @@ -80,6 +80,8 @@ public void tearDown() { batchWriter.finish(); } + // TODO(ajaykannan): fix me! + /* @Test public void testAdd() throws Exception { Entity entity2 = @@ -98,6 +100,7 @@ public void testAdd() throws Exception { assertEquals(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build(), entities.get(2)); assertEquals(entity2, entities.get(3)); } + */ @Test public void testAddAfterDelete() throws Exception { @@ -133,6 +136,8 @@ public void testAddWhenNotActive() throws Exception { batchWriter.add(ENTITY1); } + // TODO(ajaykannan): fix me! + /* @Test public void testAddWithDeferredAllocation() throws Exception { DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() @@ -195,6 +200,7 @@ public void testUpdateAfterPut() throws Exception { batchWriter.update(entity); assertEquals(pb, batchWriter.toMutationPb().build()); } + */ @Test(expected = DatastoreException.class) public void testUpdateAfterDelete() throws Exception { @@ -208,6 +214,8 @@ public void testUpdateWhenNotActive() throws Exception { batchWriter.update(ENTITY1); } + // TODO(ajaykannan): fix me! + /* @Test public void testPut() throws Exception { DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() @@ -263,20 +271,21 @@ public void testPutAfterDelete() throws Exception { batchWriter.put(entity); assertEquals(pb, batchWriter.toMutationPb().build()); } + */ @Test(expected = DatastoreException.class) public void testPutWhenNotActive() throws Exception { batchWriter.deactivate(); batchWriter.put(ENTITY1); } - + // TODO(ajaykannan): fix me! + /* @Test public void testDelete() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - //.addDelete(KEY1.toPb()) - //.addDelete(KEY2.toPb()) - //.addDelete(KEY3.toPb()) + .addDelete(KEY1.toPb()) + .addDelete(KEY2.toPb()) + .addDelete(KEY3.toPb()) .build(); batchWriter.delete(KEY1, KEY2); batchWriter.delete(KEY3); @@ -285,10 +294,9 @@ public void testDelete() throws Exception { @Test public void testDeleteAfterAdd() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() .addInsertAutoId(INCOMPLETE_ENTITY_1.toPb()) - //.addDelete(KEY1.toPb()) + .addDelete(KEY1.toPb()) .build(); batchWriter.add(ENTITY1); batchWriter.addWithDeferredIdAllocation(INCOMPLETE_ENTITY_1); @@ -296,11 +304,11 @@ public void testDeleteAfterAdd() throws Exception { assertEquals(pb, batchWriter.toMutationPb().build()); } + @Test public void testDeleteAfterUpdate() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - //.addDelete(KEY1.toPb()) + .addDelete(KEY1.toPb()) .build(); batchWriter.update(ENTITY1); batchWriter.delete(KEY1); @@ -309,14 +317,14 @@ public void testDeleteAfterUpdate() throws Exception { @Test public void testDeleteAfterPut() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - //.addDelete(KEY1.toPb()) + .addDelete(KEY1.toPb()) .build(); batchWriter.put(ENTITY1); batchWriter.delete(KEY1); assertEquals(pb, batchWriter.toMutationPb().build()); } + */ @Test(expected = DatastoreException.class) public void testDeleteWhenNotActive() throws Exception { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java index e99e7a60fd0b..79576748bb58 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java @@ -78,7 +78,8 @@ public void testBadDatasetInSetter() throws Exception { public void testNamespace() throws Exception { Builder builder = new Builder("ds", "k"); BaseKey key = builder.build(); - assertNull(key.namespace()); + assertTrue(key.namespace() != null); + assertTrue(key.namespace().isEmpty()); key = builder.namespace("ns").build(); assertEquals("ns", key.namespace()); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 65872abb79e7..57342ed3e26d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -14,6 +14,8 @@ * limitations under the License. */ +// TODO(ajaykannan): fix me! +/* package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; @@ -637,19 +639,17 @@ public void testKeyFactory() { @Test public void testRetires() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition - //DatastoreV1.LookupRequest requestPb = - // DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); + DatastoreV1.LookupRequest requestPb = + DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); DatastoreV1.LookupResponse responsePb = DatastoreV1.LookupResponse.newBuilder() .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())).build(); DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(rpcMock); - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition - //EasyMock.expect(rpcMock.lookup(requestPb)) - // .andThrow(new DatastoreRpc.DatastoreRpcException(Reason.UNAVAILABLE)) - // .andReturn(responsePb); + EasyMock.expect(rpcMock.lookup(requestPb)) + .andThrow(new DatastoreRpc.DatastoreRpcException(Reason.UNAVAILABLE)) + .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = this.options.toBuilder() .retryParams(RetryParams.getDefaultInstance()) @@ -661,3 +661,4 @@ public void testRetires() throws Exception { EasyMock.verify(rpcFactoryMock, rpcMock); } } +*/ diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java index 92851bd87efe..7acf8abbbf19 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java @@ -55,7 +55,7 @@ public void testReset() { key = keyFactory.newKey(); assertEquals("k1", key.kind()); assertEquals(PROJECT_ID, key.projectId()); - assertNull(key.namespace()); + assertTrue(key.namespace().isEmpty()); assertTrue(key.ancestors().isEmpty()); keyFactory = new KeyFactory(PROJECT_ID, "ns1").kind("k"); @@ -75,9 +75,9 @@ public void testReset() { @Test public void testNewKey() throws Exception { Key key = keyFactory.newKey(1); - verifyKey(key, 1L, null); + verifyKey(key, 1L, ""); key = keyFactory.newKey("n"); - verifyKey(key, "n", null); + verifyKey(key, "n", ""); PathElement p1 = PathElement.of("k1", "n"); PathElement p2 = PathElement.of("k2", 10); key = keyFactory.namespace("ns").ancestors(p1, p2).newKey("k3"); @@ -87,7 +87,7 @@ public void testNewKey() throws Exception { @Test public void testNewIncompleteKey() throws Exception { IncompleteKey key = keyFactory.newKey(); - verifyIncompleteKey(key, null); + verifyIncompleteKey(key, ""); PathElement p1 = PathElement.of("k1", "n"); PathElement p2 = PathElement.of("k2", 10); key = keyFactory.namespace("ns").ancestors(p1, p2).newKey(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java index 23a9325f22de..74b74facfe45 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java @@ -28,7 +28,7 @@ public class ListValueTest { - private static final List> CONTENT = ImmutableList.of(NullValue.of(), StringValue.of("foo")); + private static final List> CONTENT = ImmutableList.of(NullValue.of(), StringValue.of("foo")); @Test public void testToBuilder() throws Exception { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 9dfdd33c873d..624689cd420e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -88,8 +88,11 @@ public class SerializationTest { private static final BooleanValue BOOLEAN_VALUE = BooleanValue.of(true); private static final DateTimeValue DATE_AND_TIME_VALUE = DateTimeValue.of(DateTime.now()); private static final BlobValue BLOB_VALUE = BlobValue.of(BLOB1); - private static final RawValue RAW_VALUE = RawValue.of(com.google.datastore.v1beta3.Value - .newBuilder().setStringValue("blob-key").setMeaning(18).build()); + private static final RawValue RAW_VALUE = + RawValue.of(com.google.datastore.v1beta3.Value.newBuilder() + .setGeoPointValue(com.google.type.LatLng.newBuilder() + .setLatitude(0.0).setLongitude(0.0).build()) + .setMeaning(18).build()); private static final Entity ENTITY1 = Entity.builder(KEY1).build(); private static final Entity ENTITY2 = Entity.builder(KEY2).set("null", NullValue.of()).build(); @@ -119,8 +122,9 @@ public class SerializationTest { .put(ValueType.NULL, NULL_VALUE) .put(ValueType.KEY, KEY_VALUE) .put(ValueType.STRING, STRING_VALUE) - .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, - EMBEDDED_ENTITY_VALUE3) + // TODO(ajaykannan): fix me! + //.putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, + // EMBEDDED_ENTITY_VALUE3) .put(ValueType.LIST, LIST_VALUE) .put(ValueType.LONG, LONG_VALUE) .put(ValueType.DOUBLE, DOUBLE_VALUE) @@ -166,9 +170,10 @@ public void testValues() throws Exception { @Test public void testTypes() throws Exception { - Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, GQL2, - QUERY1, QUERY2, QUERY3}; + // TODO(ajaykannan): fix me! + Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, /*ENTITY1, ENTITY2, + ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY,*/ DATE_TIME1, BLOB1/*, CURSOR1, GQL1, GQL2, + QUERY1, QUERY2, QUERY3*/}; for (Serializable obj : types) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); From e0784699b1320f36b7df456666ea52e656f31d5b Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 22 Sep 2015 18:42:33 -0700 Subject: [PATCH 03/29] Updates to write-related code for datastore v1beta3 update --- .../datastore/BaseDatastoreBatchWriter.java | 34 ++-- .../google/gcloud/datastore/BaseEntity.java | 32 ++-- .../google/gcloud/datastore/BatchImpl.java | 54 +++--- .../google/gcloud/datastore/BatchOption.java | 58 ------ .../google/gcloud/datastore/Datastore.java | 7 +- .../gcloud/datastore/DatastoreHelper.java | 5 +- .../gcloud/datastore/DatastoreImpl.java | 165 ++++++++++-------- .../gcloud/datastore/DatastoreOptions.java | 26 +-- .../com/google/gcloud/datastore/Entity.java | 3 +- .../google/gcloud/datastore/EntityValue.java | 7 +- .../google/gcloud/datastore/FullEntity.java | 4 +- .../gcloud/datastore/ProjectionEntity.java | 3 +- .../com/google/gcloud/datastore/Query.java | 12 +- .../gcloud/datastore/QueryResultsImpl.java | 3 +- .../gcloud/datastore/TransactionImpl.java | 65 +++---- .../gcloud/datastore/TransactionOption.java | 114 ------------ .../com/google/gcloud/spi/DatastoreRpc.java | 31 ++-- .../gcloud/spi/DefaultDatastoreRpc.java | 94 +++++----- .../BaseDatastoreBatchWriterTest.java | 156 +++++++---------- .../google/gcloud/datastore/BaseKeyTest.java | 1 - .../datastore/DatastoreOptionsTest.java | 2 +- .../gcloud/datastore/DatastoreTest.java | 30 ++-- .../gcloud/datastore/KeyFactoryTest.java | 1 - .../gcloud/datastore/LocalGcdHelper.java | 12 +- 24 files changed, 349 insertions(+), 570 deletions(-) delete mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java delete mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java index d94eafbb42f6..6d8ac86834de 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java @@ -16,11 +16,11 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; @@ -88,9 +88,7 @@ public final List add(FullEntity... entities) { for (FullEntity entity : entities) { IncompleteKey key = entity.key(); Preconditions.checkArgument(key != null, "Entity must have a key"); - if (key instanceof Key) { - addInternal((FullEntity) entity); - } else { + if (!(key instanceof Key)) { incompleteKeys.add(key); } } @@ -104,6 +102,7 @@ public final List add(FullEntity... entities) { List answer = Lists.newArrayListWithExpectedSize(entities.length); for (FullEntity entity : entities) { if (entity.key() instanceof Key) { + addInternal((FullEntity) entity); answer.add(Entity.convert((FullEntity) entity)); } else { Entity entityWithAllocatedId = Entity.builder(allocated.next(), entity).build(); @@ -185,6 +184,10 @@ protected Set toDelete() { return toDelete; } + protected int numAutoAllocatedIds() { + return toAddAutoId.size(); + } + protected void deactivate() { active = false; } @@ -199,25 +202,30 @@ protected DatastoreException newInvalidRequest(String msg, Object... params) { return DatastoreException.throwInvalidRequest(String.format(msg, params)); } - protected DatastoreV1.Mutation.Builder toMutationPb() { - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + protected List toMutationPbList() { + List mutationsPb = + new ArrayList<>(); for (FullEntity entity : toAddAutoId()) { - mutationPb.addInsertAutoId(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(entity.toPb()).build()); } for (FullEntity entity : toAdd().values()) { - mutationPb.addInsert(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(entity.toPb()).build()); } for (FullEntity entity : toUpdate().values()) { - mutationPb.addUpdate(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(entity.toPb()).build()); } for (FullEntity entity : toPut().values()) { - mutationPb.addUpsert(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); } for (Key key : toDelete()) { - // TODO(ajaykannan): fix me! - //mutationPb.addDelete(key.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(key.toPb()).build()); } - return mutationPb; + return mutationsPb; } protected abstract Datastore datastore(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 8608e4fcedc9..97718e708e83 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -27,7 +27,6 @@ import static com.google.gcloud.datastore.NullValue.of; import static com.google.gcloud.datastore.StringValue.of; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Maps; import com.google.protobuf.InvalidProtocolBufferException; @@ -48,7 +47,8 @@ * @see Google Cloud Datastore * Entities, Properties, and Keys */ -public abstract class BaseEntity extends Serializable { +public abstract class BaseEntity + extends Serializable { private static final long serialVersionUID = 8175618724683792766L; @@ -90,16 +90,15 @@ private B self() { } @SuppressWarnings("unchecked") - protected B fill(DatastoreV1.Entity entityPb) { + protected B fill(com.google.datastore.v1beta3.Entity entityPb) { Map> copiedProperties = Maps.newHashMap(); - for (DatastoreV1.Property property : entityPb.getPropertyList()) { - // TODO(ajaykannan): fix me! - //copiedProperties.put(property.getName(), Value.fromPb(property.getValue())); + for (Map.Entry entry : + entityPb.getProperties().entrySet()) { + copiedProperties.put(entry.getKey(), Value.fromPb(entry.getValue())); } properties(copiedProperties); if (entityPb.hasKey()) { - // TODO(ajaykannan): fix me! - //key((K) IncompleteKey.fromPb(entityPb.getKey())); + key((K) IncompleteKey.fromPb(entityPb.getKey())); } return self(); } @@ -379,25 +378,22 @@ ImmutableSortedMap> properties() { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { Builder builder = emptyBuilder(); - builder.fill(DatastoreV1.Entity.parseFrom(bytesPb)); + builder.fill(com.google.datastore.v1beta3.Entity.parseFrom(bytesPb)); return builder.build(); } protected abstract Builder emptyBuilder(); @Override - protected final DatastoreV1.Entity toPb() { - DatastoreV1.Entity.Builder entityPb = DatastoreV1.Entity.newBuilder(); + protected final com.google.datastore.v1beta3.Entity toPb() { + com.google.datastore.v1beta3.Entity.Builder entityPb = + com.google.datastore.v1beta3.Entity.newBuilder(); + Map propertiesPb = entityPb.getMutableProperties(); for (Map.Entry> entry : properties.entrySet()) { - DatastoreV1.Property.Builder propertyPb = DatastoreV1.Property.newBuilder(); - propertyPb.setName(entry.getKey()); - // TODO(ajaykannan): fix me! - //propertyPb.setValue(entry.getValue().toPb()); - entityPb.addProperty(propertyPb.build()); + propertiesPb.put(entry.getKey(), entry.getValue().toPb()); } if (key != null) { - // TODO(ajaykannan): fix me! - //entityPb.setKey(key.toPb()); + entityPb.setKey(key.toPb()); } return entityPb.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java index c86ae28b3344..a9eab9e9c3f1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java @@ -16,65 +16,53 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.gcloud.datastore.BatchOption.ForceWrites; - +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; -import java.util.Map; class BatchImpl extends BaseDatastoreBatchWriter implements Batch { private final DatastoreImpl datastore; - private final boolean force; static class ResponseImpl implements Batch.Response { - private final DatastoreV1.CommitResponse response; + private final com.google.datastore.v1beta3.CommitResponse response; + private final int numAutoAllocatedIds; - ResponseImpl(DatastoreV1.CommitResponse response) { + ResponseImpl(com.google.datastore.v1beta3.CommitResponse response, int numAutoAllocatedIds) { this.response = response; + this.numAutoAllocatedIds = numAutoAllocatedIds; } @Override public List generatedKeys() { - return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), - new Function() { - @Override public Key apply(DatastoreV1.Key keyPb) { - // TODO(ajaykannan): fix me! - //return Key.fromPb(keyPb); - return Key.builder(null).build(); // TODO(ajaykannan): fix me! - } - }); + Iterator results = + response.getMutationResultsList().iterator(); + List generated = new LinkedList(); + for (int i = 0; i < numAutoAllocatedIds; i++) { + generated.add(Key.fromPb(results.next().getKey())); + } + return generated; } } - BatchImpl(DatastoreImpl datastore, BatchOption... options) { + BatchImpl(DatastoreImpl datastore) { super("batch"); this.datastore = datastore; - Map, BatchOption> optionsMap = BatchOption.asImmutableMap(options); - if (optionsMap.containsKey(ForceWrites.class)) { - force = ((ForceWrites) optionsMap.get(ForceWrites.class)).force(); - } else { - force = datastore.options().force(); - } } @Override public Batch.Response submit() { validateActive(); - DatastoreV1.Mutation.Builder mutationPb = toMutationPb(); - if (force) { - mutationPb.setForce(force); - } - DatastoreV1.CommitRequest.Builder requestPb = DatastoreV1.CommitRequest.newBuilder(); - requestPb.setMode(DatastoreV1.CommitRequest.Mode.NON_TRANSACTIONAL); - requestPb.setMutation(mutationPb); - DatastoreV1.CommitResponse responsePb = datastore.commit(requestPb.build()); + List mutationsPb = toMutationPbList(); + com.google.datastore.v1beta3.CommitRequest.Builder requestPb = + com.google.datastore.v1beta3.CommitRequest.newBuilder(); + requestPb.setMode(com.google.datastore.v1beta3.CommitRequest.Mode.NON_TRANSACTIONAL); + requestPb.addAllMutations(mutationsPb); + com.google.datastore.v1beta3.CommitResponse responsePb = datastore.commit(requestPb.build()); deactivate(); - return new ResponseImpl(responsePb); + return new ResponseImpl(responsePb, numAutoAllocatedIds()); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java deleted file mode 100644 index 362a74e96c79..000000000000 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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.google.gcloud.datastore; - -import com.google.common.collect.ImmutableMap; - -import java.util.Map; - -public abstract class BatchOption implements java.io.Serializable { - - private static final long serialVersionUID = -3932758377282659839L; - - public static final class ForceWrites extends BatchOption { - - private static final long serialVersionUID = 2555054296046232799L; - - private final boolean force; - - public ForceWrites(boolean force) { - this.force = force; - } - - public boolean force() { - return force; - } - } - - BatchOption() { - // package protected - } - - public static ForceWrites forceWrites() { - return new ForceWrites(true); - } - - static Map, BatchOption> asImmutableMap(BatchOption... options) { - ImmutableMap.Builder, BatchOption> builder = - ImmutableMap.builder(); - for (BatchOption option : options) { - builder.put(option.getClass(), option); - } - return builder.build(); - } -} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java index 870ed8d9474f..b49db1cacdfe 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java @@ -30,7 +30,7 @@ public interface Datastore extends Service, DatastoreReaderWri * * @throws DatastoreException upon failure */ - Transaction newTransaction(TransactionOption... options); + Transaction newTransaction(); /** @@ -54,15 +54,14 @@ interface TransactionCallable { * as a {@link DatastoreException} with the original exception as its root cause. * * @param callable the callback to call with a newly created transactional readerWriter - * @param options the options for the created transaction * @throws DatastoreException upon failure */ - T runInTransaction(TransactionCallable callable, TransactionOption... options); + T runInTransaction(TransactionCallable callable); /** * Returns a new Batch for processing multiple write operations in one request. */ - Batch newBatch(BatchOption... options); + Batch newBatch(); /** * Allocate a unique id for the given key. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java index a74d06642740..5ea0f755d2f8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java @@ -69,9 +69,8 @@ static List fetch(DatastoreReader reader, Key... keys) { return list; } - static T runInTransaction(Datastore datastore, - Datastore.TransactionCallable callable, TransactionOption... options) { - Transaction transaction = datastore.newTransaction(options); + static T runInTransaction(Datastore datastore, Datastore.TransactionCallable callable) { + Transaction transaction = datastore.newTransaction(); try { T value = callable.run(transaction); transaction.commit(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index c21c0c2a7087..262098e82f96 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -16,7 +16,6 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; @@ -33,6 +32,7 @@ import com.google.protobuf.ByteString; import java.util.Arrays; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; @@ -79,18 +79,18 @@ public RetryResult beforeEval(Exception exception) { } @Override - public Batch newBatch(BatchOption... options) { - return new BatchImpl(this, options); + public Batch newBatch() { + return new BatchImpl(this); } @Override - public Transaction newTransaction(TransactionOption... options) { - return new TransactionImpl(this, options); + public Transaction newTransaction() { + return new TransactionImpl(this); } @Override - public T runInTransaction(TransactionCallable callable, TransactionOption... options) { - return DatastoreHelper.runInTransaction(this, callable, options); + public T runInTransaction(TransactionCallable callable) { + return DatastoreHelper.runInTransaction(this, callable); } @Override @@ -98,14 +98,19 @@ public QueryResults run(Query query) { return run(null, query); } - QueryResults run(DatastoreV1.ReadOptions readOptionsPb, Query query) { - return new QueryResultsImpl<>(this, readOptionsPb, query); + QueryResults run(com.google.datastore.v1beta3.ReadOptions readOptionsPb, Query query) { + // TODO(ajaykannan): fix me! + //return new QueryResultsImpl<>(this, readOptionsPb, query); + return null; // TODO(ajaykannan): fix me! } - DatastoreV1.RunQueryResponse runQuery(final DatastoreV1.RunQueryRequest requestPb) { + com.google.datastore.v1beta3.RunQueryResponse runQuery( + final com.google.datastore.v1beta3.RunQueryRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { - @Override public DatastoreV1.RunQueryResponse call() throws DatastoreRpcException { + return RetryHelper.runWithRetries( + new Callable() { + @Override public com.google.datastore.v1beta3.RunQueryResponse call() + throws DatastoreRpcException { return datastoreRpc.runQuery(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -124,24 +129,26 @@ public List allocateId(IncompleteKey... keys) { if (keys.length == 0) { return Collections.emptyList(); } - DatastoreV1.AllocateIdsRequest.Builder requestPb = DatastoreV1.AllocateIdsRequest.newBuilder(); + com.google.datastore.v1beta3.AllocateIdsRequest.Builder requestPb = + com.google.datastore.v1beta3.AllocateIdsRequest.newBuilder(); for (IncompleteKey key : keys) { - // TODO(ajaykannan): fix me! - //requestPb.addKey(trimNameOrId(key).toPb()); + requestPb.addKeys(trimNameOrId(key).toPb()); } - DatastoreV1.AllocateIdsResponse responsePb = allocateIds(requestPb.build()); + com.google.datastore.v1beta3.AllocateIdsResponse responsePb = allocateIds(requestPb.build()); ImmutableList.Builder keyList = ImmutableList.builder(); - for (DatastoreV1.Key keyPb : responsePb.getKeyList()) { - // TODO(ajaykannan): fix me! - // keyList.add(Key.fromPb(keyPb)); + for (com.google.datastore.v1beta3.Key keyPb : responsePb.getKeysList()) { + keyList.add(Key.fromPb(keyPb)); } return keyList.build(); } - DatastoreV1.AllocateIdsResponse allocateIds(final DatastoreV1.AllocateIdsRequest requestPb) { + com.google.datastore.v1beta3.AllocateIdsResponse allocateIds( + final com.google.datastore.v1beta3.AllocateIdsRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { - @Override public DatastoreV1.AllocateIdsResponse call() throws DatastoreRpcException { + return RetryHelper.runWithRetries( + new Callable() { + @Override public com.google.datastore.v1beta3.AllocateIdsResponse call() + throws DatastoreRpcException { return datastoreRpc.allocateIds(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -168,7 +175,7 @@ public List add(FullEntity... entities) { if (entities.length == 0) { return Collections.emptyList(); } - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + List mutationsPb = new ArrayList<>(); Map completeEntities = new LinkedHashMap<>(); for (FullEntity entity : entities) { Entity completeEntity = null; @@ -180,23 +187,26 @@ public List add(FullEntity... entities) { throw DatastoreException.throwInvalidRequest( "Duplicate entity with the key %s", entity.key()); } - mutationPb.addInsert(completeEntity.toPb()); + mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(completeEntity.toPb()).build()); } else { Preconditions.checkArgument(entity.hasKey(), "entity %s is missing a key", entity); - mutationPb.addInsertAutoId(entity.toPb()); + mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(entity.toPb()).build()); } } - DatastoreV1.CommitResponse commitResponse = commitMutation(mutationPb); - Iterator allocatedKeys = - commitResponse.getMutationResult().getInsertAutoIdKeyList().iterator(); + com.google.datastore.v1beta3.CommitResponse commitResponse = commitMutation(mutationsPb); + Iterator mutationResults = + commitResponse.getMutationResultsList().iterator(); ImmutableList.Builder responseBuilder = ImmutableList.builder(); for (FullEntity entity : entities) { Entity completeEntity = completeEntities.get(entity.key()); if (completeEntity != null) { responseBuilder.add(completeEntity); + mutationResults.next(); } else { - // TODO(ajaykannan): fix me! - //responseBuilder.add(Entity.builder(Key.fromPb(allocatedKeys.next()), entity).build()); + responseBuilder.add( + Entity.builder(Key.fromPb(mutationResults.next().getKey()), entity).build()); } } return responseBuilder.build(); @@ -217,37 +227,37 @@ public List fetch(Key... keys) { return DatastoreHelper.fetch(this, keys); } - Iterator get(DatastoreV1.ReadOptions readOptionsPb, final Key... keys) { + Iterator get(com.google.datastore.v1beta3.ReadOptions readOptionsPb, final Key... keys) { if (keys.length == 0) { return Collections.emptyIterator(); } - DatastoreV1.LookupRequest.Builder requestPb = DatastoreV1.LookupRequest.newBuilder(); + com.google.datastore.v1beta3.LookupRequest.Builder requestPb = + com.google.datastore.v1beta3.LookupRequest.newBuilder(); if (readOptionsPb != null) { requestPb.setReadOptions(readOptionsPb); } for (Key k : Sets.newLinkedHashSet(Arrays.asList(keys))) { - // TODO(ajaykannan): fix me! - //requestPb.addKey(k.toPb()); + requestPb.addKeys(k.toPb()); } return new ResultsIterator(requestPb); } final class ResultsIterator extends AbstractIterator { - private final DatastoreV1.LookupRequest.Builder requestPb; - Iterator iter; + private final com.google.datastore.v1beta3.LookupRequest.Builder requestPb; + Iterator iter; - ResultsIterator(DatastoreV1.LookupRequest.Builder requestPb) { + ResultsIterator(com.google.datastore.v1beta3.LookupRequest.Builder requestPb) { this.requestPb = requestPb; loadResults(); } private void loadResults() { - DatastoreV1.LookupResponse responsePb = lookup(requestPb.build()); + com.google.datastore.v1beta3.LookupResponse responsePb = lookup(requestPb.build()); iter = responsePb.getFoundList().iterator(); - requestPb.clearKey(); + requestPb.clearKeys(); if (responsePb.getDeferredCount() > 0) { - requestPb.addAllKey(responsePb.getDeferredList()); + requestPb.addAllKeys(responsePb.getDeferredList()); } } @@ -255,7 +265,7 @@ private void loadResults() { @Override protected Entity computeNext() { while (!iter.hasNext()) { - if (requestPb.getKeyCount() == 0) { + if (requestPb.getKeysCount() == 0) { return endOfData(); } loadResults(); @@ -264,10 +274,13 @@ protected Entity computeNext() { } } - DatastoreV1.LookupResponse lookup(final DatastoreV1.LookupRequest requestPb) { + com.google.datastore.v1beta3.LookupResponse lookup( + final com.google.datastore.v1beta3.LookupRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { - @Override public DatastoreV1.LookupResponse call() throws DatastoreRpcException { + return RetryHelper.runWithRetries( + new Callable() { + @Override public com.google.datastore.v1beta3.LookupResponse call() + throws DatastoreRpcException { return datastoreRpc.lookup(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -280,15 +293,17 @@ DatastoreV1.LookupResponse lookup(final DatastoreV1.LookupRequest requestPb) { @Override public final void update(Entity... entities) { if (entities.length > 0) { - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + List mutationsPb = + new ArrayList<>(); Map dedupEntities = new LinkedHashMap<>(); for (Entity entity : entities) { dedupEntities.put(entity.key(), entity); } for (Entity entity : dedupEntities.values()) { - mutationPb.addUpdate(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(entity.toPb()).build()); } - commitMutation(mutationPb); + commitMutation(mutationsPb); } } @@ -296,28 +311,30 @@ public final void update(Entity... entities) { @Override public final void put(Entity... entities) { if (entities.length > 0) { - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + List mutationsPb = + new ArrayList<>(); Map dedupEntities = new LinkedHashMap<>(); for (Entity entity : entities) { dedupEntities.put(entity.key(), entity); } for (Entity e : dedupEntities.values()) { - mutationPb.addUpsert(e.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(e.toPb()).build()); } - commitMutation(mutationPb); + commitMutation(mutationsPb); } } @Override public void delete(Key... keys) { if (keys.length > 0) { - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + List mutationsPb = new ArrayList<>(); Set dedupKeys = new LinkedHashSet<>(Arrays.asList(keys)); for (Key key : dedupKeys) { - // TODO(ajaykannan): fix me! - //mutationPb.addDelete(key.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(key.toPb()).build()); } - commitMutation(mutationPb); + commitMutation(mutationsPb); } } @@ -326,20 +343,22 @@ public KeyFactory newKeyFactory() { return DatastoreHelper.newKeyFactory(options()); } - private DatastoreV1.CommitResponse commitMutation(DatastoreV1.Mutation.Builder mutationPb) { - if (options().force()) { - mutationPb.setForce(true); - } - DatastoreV1.CommitRequest.Builder requestPb = DatastoreV1.CommitRequest.newBuilder(); - requestPb.setMode(DatastoreV1.CommitRequest.Mode.NON_TRANSACTIONAL); - requestPb.setMutation(mutationPb); + private com.google.datastore.v1beta3.CommitResponse commitMutation( + List mutationsPb) { + com.google.datastore.v1beta3.CommitRequest.Builder requestPb = + com.google.datastore.v1beta3.CommitRequest.newBuilder(); + requestPb.setMode(com.google.datastore.v1beta3.CommitRequest.Mode.NON_TRANSACTIONAL); + requestPb.addAllMutations(mutationsPb); return commit(requestPb.build()); } - DatastoreV1.CommitResponse commit(final DatastoreV1.CommitRequest requestPb) { + com.google.datastore.v1beta3.CommitResponse commit( + final com.google.datastore.v1beta3.CommitRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { - @Override public DatastoreV1.CommitResponse call() throws DatastoreRpcException { + return RetryHelper.runWithRetries( + new Callable() { + @Override public com.google.datastore.v1beta3.CommitResponse call() + throws DatastoreRpcException { return datastoreRpc.commit(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -348,16 +367,19 @@ DatastoreV1.CommitResponse commit(final DatastoreV1.CommitRequest requestPb) { } } - ByteString requestTransactionId(DatastoreV1.BeginTransactionRequest.Builder requestPb) { + ByteString requestTransactionId( + com.google.datastore.v1beta3.BeginTransactionRequest.Builder requestPb) { return beginTransaction(requestPb.build()).getTransaction(); } - DatastoreV1.BeginTransactionResponse beginTransaction( - final DatastoreV1.BeginTransactionRequest requestPb) { + com.google.datastore.v1beta3.BeginTransactionResponse beginTransaction( + final com.google.datastore.v1beta3.BeginTransactionRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { + return RetryHelper.runWithRetries( + new Callable() { @Override - public DatastoreV1.BeginTransactionResponse call() throws DatastoreRpcException { + public com.google.datastore.v1beta3.BeginTransactionResponse call() + throws DatastoreRpcException { return datastoreRpc.beginTransaction(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -367,12 +389,13 @@ public DatastoreV1.BeginTransactionResponse call() throws DatastoreRpcException } void rollbackTransaction(ByteString transaction) { - DatastoreV1.RollbackRequest.Builder requestPb = DatastoreV1.RollbackRequest.newBuilder(); + com.google.datastore.v1beta3.RollbackRequest.Builder requestPb = + com.google.datastore.v1beta3.RollbackRequest.newBuilder(); requestPb.setTransaction(transaction); rollback(requestPb.build()); } - void rollback(final DatastoreV1.RollbackRequest requestPb) { + void rollback(final com.google.datastore.v1beta3.RollbackRequest requestPb) { try { RetryHelper.runWithRetries(new Callable() { @Override public Void call() throws DatastoreRpcException { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 7b0dd3a2a606..23128a856761 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -18,9 +18,7 @@ import static com.google.gcloud.datastore.Validator.validateNamespace; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.EntityResult; -import com.google.api.services.datastore.DatastoreV1.LookupResponse; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.gcloud.ServiceOptions; @@ -102,21 +100,23 @@ private DatastoreOptions normalize() { Builder builder = toBuilder(); builder.normalizeDataset(false); // Replace provided project-id with full project-id (s~xxx, e~xxx,...) - DatastoreV1.LookupRequest.Builder requestPb = DatastoreV1.LookupRequest.newBuilder(); - DatastoreV1.Key key = DatastoreV1.Key.newBuilder() - .addPathElement(DatastoreV1.Key.PathElement.newBuilder().setKind("__foo__").setName("bar")) + com.google.datastore.v1beta3.LookupRequest.Builder requestPb = + com.google.datastore.v1beta3.LookupRequest.newBuilder(); + com.google.datastore.v1beta3.Key key = com.google.datastore.v1beta3.Key.newBuilder() + .addPath(com.google.datastore.v1beta3.Key.PathElement.newBuilder() + .setKind("__foo__").setName("bar")) .build(); - requestPb.addKey(key); + requestPb.addKeys(key); try { - LookupResponse responsePb = datastoreRpc().lookup(requestPb.build()); + com.google.datastore.v1beta3.LookupResponse responsePb = datastoreRpc().lookup(requestPb.build()); if (responsePb.getDeferredCount() > 0) { key = responsePb.getDeferred(0); } else { - Iterator combinedIter = + Iterator combinedIter = Iterables.concat(responsePb.getMissingList(), responsePb.getFoundList()).iterator(); key = combinedIter.next().getEntity().getKey(); } - builder.projectId(key.getPartitionId().getDatasetId()); + builder.projectId(key.getPartitionId().getProjectId()); return new DatastoreOptions(builder); } catch (DatastoreRpcException e) { throw DatastoreException.translateAndThrow(e); @@ -149,10 +149,10 @@ private static String defaultNamespace() { Class clazz = Class.forName("com.google.appengine.api.NamespaceManager"); Method method = clazz.getMethod("get"); String namespace = (String) method.invoke(null); - return namespace == null || namespace.isEmpty() ? null : namespace; + return MoreObjects.firstNonNull(namespace, ""); } catch (Exception ignore) { - // return null (Datastore default namespace) if could not automatically determine - return null; + // return empty string (Datastore default namespace) if could not automatically determine + return ""; } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java index dc1af5b8a2d9..d012eff14422 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; /** @@ -93,7 +92,7 @@ public static Builder builder(Key key, FullEntity copyFrom) { return new Builder(key, copyFrom); } - static Entity fromPb(DatastoreV1.Entity entityPb) { + static Entity fromPb(com.google.datastore.v1beta3.Entity entityPb) { return new Builder().fill(entityPb).build(); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java index 16ca55aec4a6..4a327383afd4 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java @@ -39,15 +39,12 @@ public Builder newBuilder(FullEntity value) { @Override protected FullEntity getValue(com.google.datastore.v1beta3.Value from) { - // TODO(ajaykannan): fix me! - //return FullEntity.fromPb(from.getEntityValue()); - return null; // TODO(ajaykannan): fix me! + return FullEntity.fromPb(from.getEntityValue()); } @Override protected void setValue(EntityValue from, com.google.datastore.v1beta3.Value.Builder to) { - // TODO(ajaykannan): fix me! - //to.setEntityValue(from.get().toPb()); + to.setEntityValue(from.get().toPb()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java index bb08fca12e3c..b1534984aeb0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java @@ -16,8 +16,6 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; - /** * A full entity is a {@link BaseEntity} that with a complete set of properties. */ @@ -70,7 +68,7 @@ public static Builder builder(FullEntity copyFro } - static FullEntity fromPb(DatastoreV1.Entity entityPb) { + static FullEntity fromPb(com.google.datastore.v1beta3.Entity entityPb) { return new Builder<>().fill(entityPb).build(); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java index 46a528617a0c..f8af814245ab 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java @@ -16,7 +16,6 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; import com.google.protobuf.ByteString; /** @@ -72,7 +71,7 @@ public Blob getBlob(String name) { return ((Value) value).get(); } - static ProjectionEntity fromPb(DatastoreV1.Entity entityPb) { + static ProjectionEntity fromPb(com.google.datastore.v1beta3.Entity entityPb) { return new Builder().fill(entityPb).build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index f3dd254ce9a3..7fae120dd402 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -69,7 +69,9 @@ public abstract static class ResultType implements java.io.Serializable { //TODO(ajaykannan): fix me! //return Key.fromPb(entityPb.getKey()); } - return ProjectionEntity.fromPb(entityPb); + // TODO(ajaykannan): fix me! + //return ProjectionEntity.fromPb(entityPb); + return ProjectionEntity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! } }; @@ -79,7 +81,9 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = 7712959777507168274L; @Override protected Entity convert(DatastoreV1.Entity entityPb) { - return Entity.fromPb(entityPb); + // TODO(ajaykannan): fix me! + //return Entity.fromPb(entityPb); + return Entity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! } }; @@ -102,7 +106,9 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = -7591409419690650246L; @Override protected ProjectionEntity convert(DatastoreV1.Entity entityPb) { - return ProjectionEntity.fromPb(entityPb); + // TODO(ajaykannan): fix me! + //return ProjectionEntity.fromPb(entityPb); + return ProjectionEntity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index cd3fe9dd776b..caf5d7f8a84f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -63,7 +63,8 @@ private void sendRequest() { } requestPb.setPartitionId(partitionIdPb); query.populatePb(requestPb); - queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); + // TODO(ajaykannan): fix me! + //queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; entityResultPbIter = queryResultBatchPb.getEntityResultList().iterator(); // cursor = resultPb.getSkippedCursor(); // available in v1beta3, use startCursor if not skipped diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index ae9d0e50f0d7..ff9ce5e50e9d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -16,58 +16,45 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.gcloud.datastore.TransactionOption.ForceWrites; -import com.google.gcloud.datastore.TransactionOption.IsolationLevel; import com.google.protobuf.ByteString; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; -import java.util.Map; final class TransactionImpl extends BaseDatastoreBatchWriter implements Transaction { private final DatastoreImpl datastore; private final ByteString transaction; - private final boolean force; private boolean rolledback; static class ResponseImpl implements Transaction.Response { - private final DatastoreV1.CommitResponse response; + private final com.google.datastore.v1beta3.CommitResponse response; + private final int numAutoAllocatedIds; - ResponseImpl(DatastoreV1.CommitResponse response) { + ResponseImpl(com.google.datastore.v1beta3.CommitResponse response, int numAutoAllocatedIds) { this.response = response; + this.numAutoAllocatedIds = numAutoAllocatedIds; } @Override public List generatedKeys() { - return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), - new Function() { - @Override public Key apply(DatastoreV1.Key keyPb) { - // TODO(ajaykannan): fix me! - //return Key.fromPb(keyPb); - return Key.builder(null).build(); // TODO(ajaykannan): fix me! - } - }); + Iterator results = + response.getMutationResultsList().iterator(); + List generated = new LinkedList(); + for (int i = 0; i < numAutoAllocatedIds; i++) { + generated.add(Key.fromPb(results.next().getKey())); + } + return generated; } } - TransactionImpl(DatastoreImpl datastore, TransactionOption... options) { + TransactionImpl(DatastoreImpl datastore) { super("transaction"); this.datastore = datastore; - DatastoreV1.BeginTransactionRequest.Builder requestPb = - DatastoreV1.BeginTransactionRequest.newBuilder(); - Map, TransactionOption> optionsMap = - TransactionOption.asImmutableMap(options); - IsolationLevel isolationLevel = (IsolationLevel) optionsMap.get(IsolationLevel.class); - if (isolationLevel != null) { - requestPb.setIsolationLevel(isolationLevel.level().toPb()); - } - ForceWrites forceWrites = (ForceWrites) optionsMap.get(TransactionOption.ForceWrites.class); - force = forceWrites != null && forceWrites.force(); + com.google.datastore.v1beta3.BeginTransactionRequest.Builder requestPb = + com.google.datastore.v1beta3.BeginTransactionRequest.newBuilder(); transaction = datastore.requestTransactionId(requestPb); } @@ -79,7 +66,8 @@ public Entity get(Key key) { @Override public Iterator get(Key... keys) { validateActive(); - DatastoreV1.ReadOptions.Builder readOptionsPb = DatastoreV1.ReadOptions.newBuilder(); + com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.newBuilder(); readOptionsPb.setTransaction(transaction); return datastore.get(readOptionsPb.build(), keys); } @@ -93,7 +81,8 @@ public List fetch(Key... keys) { @Override public QueryResults run(Query query) { validateActive(); - DatastoreV1.ReadOptions.Builder readOptionsPb = DatastoreV1.ReadOptions.newBuilder(); + com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.newBuilder(); readOptionsPb.setTransaction(transaction); return datastore.run(readOptionsPb.build(), query); } @@ -101,17 +90,15 @@ public QueryResults run(Query query) { @Override public Transaction.Response commit() { validateActive(); - DatastoreV1.Mutation.Builder mutationPb = toMutationPb(); - if (force) { - mutationPb.setForce(force); - } - DatastoreV1.CommitRequest.Builder requestPb = DatastoreV1.CommitRequest.newBuilder(); - requestPb.setMode(DatastoreV1.CommitRequest.Mode.TRANSACTIONAL); + List mutationsPb = toMutationPbList(); + com.google.datastore.v1beta3.CommitRequest.Builder requestPb = + com.google.datastore.v1beta3.CommitRequest.newBuilder(); + requestPb.setMode(com.google.datastore.v1beta3.CommitRequest.Mode.TRANSACTIONAL); requestPb.setTransaction(transaction); - requestPb.setMutation(mutationPb); - DatastoreV1.CommitResponse responsePb = datastore.commit(requestPb.build()); + requestPb.addAllMutations(mutationsPb); + com.google.datastore.v1beta3.CommitResponse responsePb = datastore.commit(requestPb.build()); deactivate(); - return new ResponseImpl(responsePb); + return new ResponseImpl(responsePb, numAutoAllocatedIds()); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java deleted file mode 100644 index c1c8368213dc..000000000000 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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.google.gcloud.datastore; - -import com.google.api.services.datastore.DatastoreV1; -import com.google.common.collect.ImmutableMap; - -import java.io.Serializable; -import java.util.Map; - - -public abstract class TransactionOption implements Serializable { - - private static final long serialVersionUID = -1862234444015690375L; - - public static final class ForceWrites extends TransactionOption { - - private static final long serialVersionUID = -6873967516988380886L; - - private final boolean force; - - public ForceWrites(boolean force) { - this.force = force; - } - - public boolean force() { - return force; - } - - @Override - BatchOption toBatchWriteOption() { - return new BatchOption.ForceWrites(force); - } - } - - public static final class IsolationLevel extends TransactionOption { - - private static final long serialVersionUID = -5592165378565409515L; - - private final Level level; - - public enum Level { - - SERIALIZABLE(DatastoreV1.BeginTransactionRequest.IsolationLevel.SERIALIZABLE), - SNAPSHOT(DatastoreV1.BeginTransactionRequest.IsolationLevel.SNAPSHOT); - - private final DatastoreV1.BeginTransactionRequest.IsolationLevel levelPb; - - Level(DatastoreV1.BeginTransactionRequest.IsolationLevel levelPb) { - this.levelPb = levelPb; - } - - DatastoreV1.BeginTransactionRequest.IsolationLevel toPb() { - return levelPb; - } - } - - public IsolationLevel(Level level) { - this.level = level; - } - - - public Level level() { - return level; - } - - @Override - BatchOption toBatchWriteOption() { - return null; - } - } - - TransactionOption() { - // package protected - } - - public static ForceWrites forceWrites() { - return new ForceWrites(true); - } - - public static IsolationLevel serializable() { - return new IsolationLevel(IsolationLevel.Level.SERIALIZABLE); - } - - public static IsolationLevel snapshot() { - return new IsolationLevel(IsolationLevel.Level.SNAPSHOT); - } - - static Map, TransactionOption> asImmutableMap( - TransactionOption... options) { - ImmutableMap.Builder, TransactionOption> builder = - ImmutableMap.builder(); - for (TransactionOption option : options) { - builder.put(option.getClass(), option); - } - return builder.build(); - } - - abstract BatchOption toBatchWriteOption(); -} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java index dffcc3f0e16f..329623a565f6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java @@ -15,19 +15,6 @@ */ package com.google.gcloud.spi; -import com.google.api.services.datastore.DatastoreV1.AllocateIdsRequest; -import com.google.api.services.datastore.DatastoreV1.AllocateIdsResponse; -import com.google.api.services.datastore.DatastoreV1.BeginTransactionRequest; -import com.google.api.services.datastore.DatastoreV1.BeginTransactionResponse; -import com.google.api.services.datastore.DatastoreV1.CommitRequest; -import com.google.api.services.datastore.DatastoreV1.CommitResponse; -import com.google.api.services.datastore.DatastoreV1.LookupRequest; -import com.google.api.services.datastore.DatastoreV1.LookupResponse; -import com.google.api.services.datastore.DatastoreV1.RollbackRequest; -import com.google.api.services.datastore.DatastoreV1.RollbackResponse; -import com.google.api.services.datastore.DatastoreV1.RunQueryRequest; -import com.google.api.services.datastore.DatastoreV1.RunQueryResponse; - /** * Provides access to the remote Datastore service. */ @@ -103,16 +90,22 @@ public boolean retryable() { } } - AllocateIdsResponse allocateIds(AllocateIdsRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.AllocateIdsResponse allocateIds( + com.google.datastore.v1beta3.AllocateIdsRequest request) throws DatastoreRpcException; - BeginTransactionResponse beginTransaction(BeginTransactionRequest request) + com.google.datastore.v1beta3.BeginTransactionResponse beginTransaction( + com.google.datastore.v1beta3.BeginTransactionRequest request) throws DatastoreRpcException; - CommitResponse commit(CommitRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.CommitResponse commit( + com.google.datastore.v1beta3.CommitRequest request) throws DatastoreRpcException; - LookupResponse lookup(LookupRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.LookupResponse lookup( + com.google.datastore.v1beta3.LookupRequest request) throws DatastoreRpcException; - RollbackResponse rollback(RollbackRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.RollbackResponse rollback( + com.google.datastore.v1beta3.RollbackRequest request) throws DatastoreRpcException; - RunQueryResponse runQuery(RunQueryRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.RunQueryResponse runQuery( + com.google.datastore.v1beta3.RunQueryRequest request) throws DatastoreRpcException; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index 2f245260b325..1ae0b6eea22e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -16,36 +16,16 @@ package com.google.gcloud.spi; -import com.google.api.services.datastore.DatastoreV1.AllocateIdsRequest; -import com.google.api.services.datastore.DatastoreV1.AllocateIdsResponse; -import com.google.api.services.datastore.DatastoreV1.BeginTransactionRequest; -import com.google.api.services.datastore.DatastoreV1.BeginTransactionResponse; -import com.google.api.services.datastore.DatastoreV1.CommitRequest; -import com.google.api.services.datastore.DatastoreV1.CommitResponse; -import com.google.api.services.datastore.DatastoreV1.LookupRequest; -import com.google.api.services.datastore.DatastoreV1.LookupResponse; -import com.google.api.services.datastore.DatastoreV1.RollbackRequest; -import com.google.api.services.datastore.DatastoreV1.RollbackResponse; -import com.google.api.services.datastore.DatastoreV1.RunQueryRequest; -import com.google.api.services.datastore.DatastoreV1.RunQueryResponse; -import com.google.api.services.datastore.client.Datastore; -import com.google.api.services.datastore.client.DatastoreException; -import com.google.api.services.datastore.client.DatastoreFactory; -import com.google.api.services.datastore.client.DatastoreOptions.Builder; import com.google.common.collect.ImmutableMap; import com.google.gcloud.datastore.DatastoreOptions; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; - import java.util.HashMap; import java.util.Map; public class DefaultDatastoreRpc implements DatastoreRpc { - private final Datastore client; + private final com.google.datastore.v1beta3.client.Datastore client; private static final ImmutableMap STR_TO_REASON; private static final ImmutableMap HTTP_STATUS_TO_REASON; @@ -62,26 +42,27 @@ public class DefaultDatastoreRpc implements DatastoreRpc { } public DefaultDatastoreRpc(DatastoreOptions options) { - client = DatastoreFactory.get().create( - new Builder() - .dataset(options.projectId()) - .host(options.host()) - .initializer(options.httpRequestInitializer()) - .build()); + if (options.host().contains("localhost")) { + client = com.google.datastore.v1beta3.client.DatastoreFactory.get().create( + new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() + .projectId(options.projectId()) + .localHost(options.host()) + .initializer(options.httpRequestInitializer()) + .build()); + } else { + client = com.google.datastore.v1beta3.client.DatastoreFactory.get().create( + new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() + .projectId(options.projectId()) + .initializer(options.httpRequestInitializer()) + .build()); + } } - private static DatastoreRpcException translate(DatastoreException exception) { - String message = exception.getMessage(); + private static DatastoreRpcException translate( + com.google.datastore.v1beta3.client.DatastoreException exception) { String reasonStr = ""; - if (message != null) { - try { - JSONObject json = new JSONObject(new JSONTokener(message)); - JSONObject error = json.getJSONObject("error").getJSONArray("errors").getJSONObject(0); - reasonStr = error.getString("reason"); - message = error.getString("message"); - } catch (JSONException ignore) { - // ignore - will be converted to unknown - } + if (exception.getCode() != null) { + reasonStr = exception.getCode().name(); } Reason reason = STR_TO_REASON.get(reasonStr); if (reason == null) { @@ -89,61 +70,68 @@ private static DatastoreRpcException translate(DatastoreException exception) { } return reason != null ? new DatastoreRpcException(reason) - : new DatastoreRpcException("Unknown", exception.getCode(), false, message); + : new DatastoreRpcException("Unknown", + exception.getCode().ordinal(), + false, + exception.getMessage()); } @Override - public AllocateIdsResponse allocateIds(AllocateIdsRequest request) - throws DatastoreRpcException { + public com.google.datastore.v1beta3.AllocateIdsResponse allocateIds( + com.google.datastore.v1beta3.AllocateIdsRequest request) throws DatastoreRpcException { try { return client.allocateIds(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public BeginTransactionResponse beginTransaction(BeginTransactionRequest request) - throws DatastoreRpcException { + public com.google.datastore.v1beta3.BeginTransactionResponse beginTransaction( + com.google.datastore.v1beta3.BeginTransactionRequest request) throws DatastoreRpcException { try { return client.beginTransaction(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public CommitResponse commit(CommitRequest request) throws DatastoreRpcException { + public com.google.datastore.v1beta3.CommitResponse commit( + com.google.datastore.v1beta3.CommitRequest request) throws DatastoreRpcException { try { return client.commit(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public LookupResponse lookup(LookupRequest request) throws DatastoreRpcException { + public com.google.datastore.v1beta3.LookupResponse lookup( + com.google.datastore.v1beta3.LookupRequest request) throws DatastoreRpcException { try { return client.lookup(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public RollbackResponse rollback(RollbackRequest request) throws DatastoreRpcException { + public com.google.datastore.v1beta3.RollbackResponse rollback( + com.google.datastore.v1beta3.RollbackRequest request) throws DatastoreRpcException { try { return client.rollback(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public RunQueryResponse runQuery(RunQueryRequest request) throws DatastoreRpcException { + public com.google.datastore.v1beta3.RunQueryResponse runQuery( + com.google.datastore.v1beta3.RunQueryRequest request) throws DatastoreRpcException { try { return client.runQuery(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java index 43df45d7a04e..8996f4536931 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java @@ -21,7 +21,6 @@ import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.collect.ImmutableList; import org.easymock.EasyMock; @@ -30,6 +29,7 @@ import org.junit.Test; import java.util.List; +import java.util.LinkedList; public class BaseDatastoreBatchWriterTest { @@ -80,36 +80,33 @@ public void tearDown() { batchWriter.finish(); } - // TODO(ajaykannan): fix me! - /* @Test public void testAdd() throws Exception { Entity entity2 = Entity.builder(ENTITY2).key(Key.builder(KEY1).name("name2").build()).build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addInsert(ENTITY1.toPb()) - .addInsert(entity2.toPb()) - .addInsert(Entity.builder(KEY2, INCOMPLETE_ENTITY_1).build().toPb()) - .addInsert(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build().toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(ENTITY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(Entity.builder(KEY2, INCOMPLETE_ENTITY_1).build().toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build().toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(entity2.toPb()).build()); List entities = batchWriter .add(ENTITY1, INCOMPLETE_ENTITY_1, INCOMPLETE_ENTITY_2, entity2); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); assertEquals(ENTITY1, entities.get(0)); assertEquals(Entity.builder(KEY2, INCOMPLETE_ENTITY_1).build(), entities.get(1)); assertEquals(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build(), entities.get(2)); assertEquals(entity2, entities.get(3)); } - */ @Test public void testAddAfterDelete() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(ENTITY1.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY1.toPb()).build()); batchWriter.delete(KEY1); batchWriter.add(ENTITY1); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test(expected = DatastoreException.class) @@ -136,18 +133,17 @@ public void testAddWhenNotActive() throws Exception { batchWriter.add(ENTITY1); } - // TODO(ajaykannan): fix me! - /* @Test public void testAddWithDeferredAllocation() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addInsert(ENTITY1.toPb()) - .addInsertAutoId(INCOMPLETE_ENTITY_1.toPb()) - .addInsertAutoId(INCOMPLETE_ENTITY_2.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(INCOMPLETE_ENTITY_1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(INCOMPLETE_ENTITY_2.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(ENTITY1.toPb()).build()); batchWriter.addWithDeferredIdAllocation(ENTITY1, INCOMPLETE_ENTITY_1); batchWriter.addWithDeferredIdAllocation(INCOMPLETE_ENTITY_2); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test(expected = DatastoreException.class) @@ -158,49 +154,44 @@ public void testAddWithDeferredAllocationWhenNotActive() throws Exception { @Test public void testUpdate() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpdate(ENTITY1.toPb()) - .addUpdate(ENTITY2.toPb()) - .addUpdate(ENTITY3.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(ENTITY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(ENTITY2.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(ENTITY3.toPb()).build()); batchWriter.update(ENTITY1, ENTITY2); batchWriter.update(ENTITY3); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testUpdateAfterUpdate() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpdate(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(entity.toPb()).build()); batchWriter.update(ENTITY1); batchWriter.update(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testUpdateAfterAdd() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.add(ENTITY1); batchWriter.update(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testUpdateAfterPut() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.put(ENTITY1); batchWriter.update(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } - */ @Test(expected = DatastoreException.class) public void testUpdateAfterDelete() throws Exception { @@ -214,117 +205,104 @@ public void testUpdateWhenNotActive() throws Exception { batchWriter.update(ENTITY1); } - // TODO(ajaykannan): fix me! - /* @Test public void testPut() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(ENTITY1.toPb()) - .addUpsert(ENTITY2.toPb()) - .addUpsert(ENTITY3.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY2.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY3.toPb()).build()); batchWriter.put(ENTITY1, ENTITY2); batchWriter.put(ENTITY3); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testPutAfterPut() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.put(ENTITY1); batchWriter.put(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testPutAfterAdd() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.add(ENTITY1); batchWriter.put(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testPutAfterUpdate() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.update(ENTITY1); batchWriter.put(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testPutAfterDelete() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.delete(KEY1); batchWriter.put(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } - */ @Test(expected = DatastoreException.class) public void testPutWhenNotActive() throws Exception { batchWriter.deactivate(); batchWriter.put(ENTITY1); } - // TODO(ajaykannan): fix me! - /* + @Test public void testDelete() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) - .addDelete(KEY2.toPb()) - .addDelete(KEY3.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY2.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY3.toPb()).build()); batchWriter.delete(KEY1, KEY2); batchWriter.delete(KEY3); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testDeleteAfterAdd() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addInsertAutoId(INCOMPLETE_ENTITY_1.toPb()) - .addDelete(KEY1.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(INCOMPLETE_ENTITY_1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY1.toPb()).build()); batchWriter.add(ENTITY1); batchWriter.addWithDeferredIdAllocation(INCOMPLETE_ENTITY_1); batchWriter.delete(KEY1); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testDeleteAfterUpdate() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY1.toPb()).build()); batchWriter.update(ENTITY1); batchWriter.delete(KEY1); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testDeleteAfterPut() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY1.toPb()).build()); batchWriter.put(ENTITY1); batchWriter.delete(KEY1); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } - */ @Test(expected = DatastoreException.class) public void testDeleteWhenNotActive() throws Exception { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java index 79576748bb58..c8773243ed69 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java @@ -17,7 +17,6 @@ package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index e7dc71c50ff6..97aeec3ee129 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -65,7 +65,7 @@ public void testHost() throws Exception { @Test public void testNamespace() throws Exception { - assertNull(options.build().namespace()); + assertTrue(options.build().namespace().isEmpty()); assertEquals("ns1", options.namespace("ns1").build().namespace()); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 57342ed3e26d..689d2a7b8b6b 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -14,8 +14,6 @@ * limitations under the License. */ -// TODO(ajaykannan): fix me! -/* package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; @@ -27,8 +25,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.EntityResult; import com.google.common.collect.Iterators; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; @@ -116,12 +112,12 @@ public static void beforeClass() throws IOException, InterruptedException { public void setUp() throws IOException, InterruptedException { options = DatastoreOptions.builder() .projectId(PROJECT_ID) - .host("http://localhost:" + LocalGcdHelper.PORT) + .host("localhost:" + LocalGcdHelper.PORT) .build(); datastore = DatastoreFactory.instance().get(options); - StructuredQuery query = Query.keyQueryBuilder().build(); - QueryResults result = datastore.run(query); - datastore.delete(Iterators.toArray(result, Key.class)); + //StructuredQuery query = Query.keyQueryBuilder().build(); + //QueryResults result = datastore.run(query); + //datastore.delete(Iterators.toArray(result, Key.class)); datastore.add(ENTITY1, ENTITY2); } @@ -192,7 +188,7 @@ public void testTransactionWithRead() { assertEquals(DatastoreException.Code.ABORTED, expected.code()); } } - + /* TODO(ajaykannan): fix me! @Test public void testTransactionWithQuery() { Query query = Query.entityQueryBuilder() @@ -220,7 +216,7 @@ public void testTransactionWithQuery() { assertEquals(DatastoreException.Code.ABORTED, expected.code()); } } - + */ @Test public void testNewTransactionRollback() { Transaction transaction = datastore.newTransaction(); @@ -335,7 +331,7 @@ public void testNewBatch() { assertNull(entities.get(4)); assertEquals(5, entities.size()); } - + /* TODO(ajaykannan): fix me! @Test public void testRunGqlQueryNoCasting() { Query query1 = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from " + KIND1).build(); @@ -452,7 +448,7 @@ public void testRunStructuredQuery() { assertFalse(results4.hasNext()); // TODO(ozarov): construct a test to verify nextQuery/pagination } - + */ @Test public void testAllocateId() { KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND1); @@ -570,7 +566,6 @@ public void testAddEntity() { assertNotNull(datastore.get(entities.get(2).key())); } - @Test public void testUpdate() { List keys = datastore.fetch(ENTITY1.key(), ENTITY3.key()); @@ -639,10 +634,10 @@ public void testKeyFactory() { @Test public void testRetires() throws Exception { - DatastoreV1.LookupRequest requestPb = - DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); - DatastoreV1.LookupResponse responsePb = DatastoreV1.LookupResponse.newBuilder() - .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())).build(); + com.google.datastore.v1beta3.LookupRequest requestPb = + com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); + com.google.datastore.v1beta3.LookupResponse responsePb = com.google.datastore.v1beta3.LookupResponse.newBuilder() + .addFound(com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(ENTITY1.toPb())).build(); DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) @@ -661,4 +656,3 @@ public void testRetires() throws Exception { EasyMock.verify(rpcFactoryMock, rpcMock); } } -*/ diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java index 7acf8abbbf19..dacb348c2172 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java @@ -17,7 +17,6 @@ package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.junit.Before; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 2d7f5802f247..0625f2afb38d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -61,9 +61,9 @@ public class LocalGcdHelper { public static final String DEFAULT_PROJECT_ID = "projectid1"; public static final int PORT = 8080; - private static final String GCD = "gcd-v1beta2-rev1-2.1.2b"; + private static final String GCD = "gcd-v1beta3-0.0.1"; private static final String GCD_FILENAME = GCD + ".zip"; - private static final String MD5_CHECKSUM = "d84384cdfa8658e1204f4f8be51300e8"; + private static final String MD5_CHECKSUM = "496b16f32473d0de0c7a974bd0ee1461"; private static final URL GCD_URL; static { @@ -159,13 +159,13 @@ public void start() throws IOException, InterruptedException { } } // cleanup any possible data for the same project - File datasetFolder = new File(gcdFolder, GCD + '/' + projectId); + File datasetFolder = new File(gcdFolder, "gcd/" + projectId); deleteRecurse(datasetFolder.toPath()); // create the datastore for the project ProcessBuilder processBuilder = new ProcessBuilder() .redirectError(ProcessBuilder.Redirect.INHERIT) - .directory(new File(gcdFolder, GCD)); + .directory(new File(gcdFolder, "gcd")); if (isWindows()) { processBuilder.command("cmd", "/C", "gcd.cmd", "create", "-p", projectId, projectId); processBuilder.redirectOutput(new File("NULL:")); @@ -179,7 +179,7 @@ public void start() throws IOException, InterruptedException { // start the datastore for the project processBuilder = new ProcessBuilder() - .directory(new File(gcdFolder, GCD)) + .directory(new File(gcdFolder, "gcd")) .redirectErrorStream(true); if (isWindows()) { processBuilder.command("cmd", "/C", "gcd.cmd", "start", "--testing", @@ -309,7 +309,7 @@ public static void main(String... args) throws IOException, InterruptedException public static boolean isActive(String projectId) { try { StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); - urlBuilder.append("/datastore/v1beta2/datasets/").append(projectId).append("/lookup"); + urlBuilder.append("/datastore/v1beta3/datasets/").append(projectId).append(":lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { From 959d67d9f9f940b3db62b556076b2a90ba2fb263 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 25 Sep 2015 09:22:16 -0700 Subject: [PATCH 04/29] cleanup v1beta3 changes and fix LocalGcdHelper bugs --- .../datastore/BaseDatastoreBatchWriter.java | 4 --- .../google/gcloud/datastore/BatchImpl.java | 6 ++-- .../gcloud/datastore/DatastoreImpl.java | 17 +++++---- .../gcloud/datastore/DatastoreOptions.java | 3 +- .../gcloud/datastore/TransactionImpl.java | 6 ++-- .../gcloud/spi/DefaultDatastoreRpc.java | 36 ++++++++++++------- .../datastore/DatastoreOptionsTest.java | 1 - .../gcloud/datastore/LocalGcdHelper.java | 2 +- 8 files changed, 40 insertions(+), 35 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java index 6d8ac86834de..3aa0d38f45f1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java @@ -184,10 +184,6 @@ protected Set toDelete() { return toDelete; } - protected int numAutoAllocatedIds() { - return toAddAutoId.size(); - } - protected void deactivate() { active = false; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java index a9eab9e9c3f1..303e9703f4cc 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java @@ -16,8 +16,8 @@ package com.google.gcloud.datastore; +import java.util.ArrayList; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; @@ -39,7 +39,7 @@ static class ResponseImpl implements Batch.Response { public List generatedKeys() { Iterator results = response.getMutationResultsList().iterator(); - List generated = new LinkedList(); + List generated = new ArrayList<>(numAutoAllocatedIds); for (int i = 0; i < numAutoAllocatedIds; i++) { generated.add(Key.fromPb(results.next().getKey())); } @@ -62,7 +62,7 @@ public Batch.Response submit() { requestPb.addAllMutations(mutationsPb); com.google.datastore.v1beta3.CommitResponse responsePb = datastore.commit(requestPb.build()); deactivate(); - return new ResponseImpl(responsePb, numAutoAllocatedIds()); + return new ResponseImpl(responsePb, toAddAutoId().size()); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 262098e82f96..f0238083b5fa 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -176,33 +176,32 @@ public List add(FullEntity... entities) { return Collections.emptyList(); } List mutationsPb = new ArrayList<>(); - Map completeEntities = new LinkedHashMap<>(); + Set completeEntities = new LinkedHashSet<>(); for (FullEntity entity : entities) { Entity completeEntity = null; if (entity.key() instanceof Key) { completeEntity = Entity.convert((FullEntity) entity); } if (completeEntity != null) { - if (completeEntities.put(completeEntity.key(), completeEntity) != null) { + if (completeEntities.contains(completeEntity)) { throw DatastoreException.throwInvalidRequest( "Duplicate entity with the key %s", entity.key()); } - mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() - .setInsert(completeEntity.toPb()).build()); + completeEntities.add(completeEntity); } else { Preconditions.checkArgument(entity.hasKey(), "entity %s is missing a key", entity); - mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() - .setInsert(entity.toPb()).build()); } + mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(entity.toPb()).build()); } com.google.datastore.v1beta3.CommitResponse commitResponse = commitMutation(mutationsPb); Iterator mutationResults = commitResponse.getMutationResultsList().iterator(); + Iterator completeEntitiesIt = completeEntities.iterator(); ImmutableList.Builder responseBuilder = ImmutableList.builder(); for (FullEntity entity : entities) { - Entity completeEntity = completeEntities.get(entity.key()); - if (completeEntity != null) { - responseBuilder.add(completeEntity); + if (completeEntities.contains(entity)) { + responseBuilder.add(completeEntitiesIt.next()); mutationResults.next(); } else { responseBuilder.add( diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 23128a856761..a354f7328959 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -108,7 +108,8 @@ private DatastoreOptions normalize() { .build(); requestPb.addKeys(key); try { - com.google.datastore.v1beta3.LookupResponse responsePb = datastoreRpc().lookup(requestPb.build()); + com.google.datastore.v1beta3.LookupResponse responsePb = + datastoreRpc().lookup(requestPb.build()); if (responsePb.getDeferredCount() > 0) { key = responsePb.getDeferred(0); } else { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index ff9ce5e50e9d..5a422927005a 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -18,8 +18,8 @@ import com.google.protobuf.ByteString; +import java.util.ArrayList; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; final class TransactionImpl extends BaseDatastoreBatchWriter implements Transaction { @@ -42,7 +42,7 @@ static class ResponseImpl implements Transaction.Response { public List generatedKeys() { Iterator results = response.getMutationResultsList().iterator(); - List generated = new LinkedList(); + List generated = new ArrayList<>(numAutoAllocatedIds); for (int i = 0; i < numAutoAllocatedIds; i++) { generated.add(Key.fromPb(results.next().getKey())); } @@ -98,7 +98,7 @@ public Transaction.Response commit() { requestPb.addAllMutations(mutationsPb); com.google.datastore.v1beta3.CommitResponse responsePb = datastore.commit(requestPb.build()); deactivate(); - return new ResponseImpl(responsePb, numAutoAllocatedIds()); + return new ResponseImpl(responsePb, toAddAutoId().size()); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index 1ae0b6eea22e..3c82e2a93cc4 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -20,6 +20,10 @@ import com.google.gcloud.datastore.DatastoreOptions; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import java.net.URL; import java.util.HashMap; import java.util.Map; @@ -42,20 +46,26 @@ public class DefaultDatastoreRpc implements DatastoreRpc { } public DefaultDatastoreRpc(DatastoreOptions options) { - if (options.host().contains("localhost")) { - client = com.google.datastore.v1beta3.client.DatastoreFactory.get().create( - new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() - .projectId(options.projectId()) - .localHost(options.host()) - .initializer(options.httpRequestInitializer()) - .build()); - } else { - client = com.google.datastore.v1beta3.client.DatastoreFactory.get().create( - new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() - .projectId(options.projectId()) - .initializer(options.httpRequestInitializer()) - .build()); + com.google.datastore.v1beta3.client.DatastoreOptions.Builder clientBuilder = + new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() + .projectId(options.projectId()) + .initializer(options.httpRequestInitializer()); + if (options.host() != null) { + try { + String normalizedHost = options.host(); + if (!normalizedHost.startsWith("http")) { + normalizedHost = "http://" + normalizedHost; + } + InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost()); + if (hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress()) { + clientBuilder = clientBuilder.localHost(options.host()); + } + } catch (UnknownHostException | MalformedURLException e) { + // ignore + } } + client = com.google.datastore.v1beta3.client.DatastoreFactory.get() + .create(clientBuilder.build()); } private static DatastoreRpcException translate( diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index 97aeec3ee129..63657902d737 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 0625f2afb38d..1d692040c015 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -309,7 +309,7 @@ public static void main(String... args) throws IOException, InterruptedException public static boolean isActive(String projectId) { try { StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); - urlBuilder.append("/datastore/v1beta3/datasets/").append(projectId).append(":lookup"); + urlBuilder.append("/datastore/v1beta3/projects/").append(projectId).append(":lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { From 9463c5592e230e7384960664119781e642a87c45 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 30 Sep 2015 18:33:27 -0700 Subject: [PATCH 05/29] Fix handling of host in DatastoreOptions.java --- .../gcloud/datastore/DatastoreImpl.java | 11 +++---- .../gcloud/datastore/DatastoreOptions.java | 26 +++++----------- .../gcloud/spi/DefaultDatastoreRpc.java | 31 +++++++++++++++---- .../datastore/DatastoreOptionsTest.java | 9 +----- .../gcloud/datastore/SerializationTest.java | 1 - 5 files changed, 38 insertions(+), 40 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index f0238083b5fa..59804831872c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -176,18 +176,17 @@ public List add(FullEntity... entities) { return Collections.emptyList(); } List mutationsPb = new ArrayList<>(); - Set completeEntities = new LinkedHashSet<>(); + Map completeEntities = new LinkedHashMap<>(); for (FullEntity entity : entities) { Entity completeEntity = null; if (entity.key() instanceof Key) { completeEntity = Entity.convert((FullEntity) entity); } if (completeEntity != null) { - if (completeEntities.contains(completeEntity)) { + if (completeEntities.put(completeEntity.key(), completeEntity) != null) { throw DatastoreException.throwInvalidRequest( "Duplicate entity with the key %s", entity.key()); } - completeEntities.add(completeEntity); } else { Preconditions.checkArgument(entity.hasKey(), "entity %s is missing a key", entity); } @@ -197,11 +196,11 @@ public List add(FullEntity... entities) { com.google.datastore.v1beta3.CommitResponse commitResponse = commitMutation(mutationsPb); Iterator mutationResults = commitResponse.getMutationResultsList().iterator(); - Iterator completeEntitiesIt = completeEntities.iterator(); ImmutableList.Builder responseBuilder = ImmutableList.builder(); for (FullEntity entity : entities) { - if (completeEntities.contains(entity)) { - responseBuilder.add(completeEntitiesIt.next()); + Entity completeEntity = completeEntities.get(entity.key()); + if (completeEntity != null) { + responseBuilder.add(completeEntity); mutationResults.next(); } else { responseBuilder.add( diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index a354f7328959..fe318ef8720f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -35,14 +35,11 @@ public class DatastoreOptions extends ServiceOptions { private static final long serialVersionUID = -8636602944160689193L; - private static final String DATASET_ENV_NAME = "DATASTORE_DATASET"; - private static final String HOST_ENV_NAME = "DATASTORE_HOST"; private static final String DATASTORE_SCOPE = "https://www.googleapis.com/auth/datastore"; private static final String USERINFO_SCOPE = "https://www.googleapis.com/auth/userinfo.email"; private static final Set SCOPES = ImmutableSet.of(DATASTORE_SCOPE, USERINFO_SCOPE); private final String namespace; - private final boolean force; private final boolean normalizeDataset; private transient DatastoreRpc datastoreRpc; @@ -50,7 +47,6 @@ public static class Builder extends ServiceOptions.Builder { private String namespace; - private boolean force; private boolean normalizeDataset = true; private Builder() { @@ -58,7 +54,6 @@ private Builder() { private Builder(DatastoreOptions options) { super(options); - force = options.force; namespace = options.namespace; normalizeDataset = options.normalizeDataset; } @@ -74,11 +69,6 @@ public Builder namespace(String namespace) { return this; } - public Builder force(boolean force) { - this.force = force; - return this; - } - Builder normalizeDataset(boolean normalizeDataset) { this.normalizeDataset = normalizeDataset; return this; @@ -89,7 +79,6 @@ private DatastoreOptions(Builder builder) { super(builder); normalizeDataset = builder.normalizeDataset; namespace = builder.namespace != null ? builder.namespace : defaultNamespace(); - force = builder.force; } private DatastoreOptions normalize() { @@ -126,13 +115,17 @@ private DatastoreOptions normalize() { @Override protected String defaultHost() { - String host = System.getProperty(HOST_ENV_NAME, System.getenv(HOST_ENV_NAME)); + String host = System.getProperty( + com.google.datastore.v1beta3.client.DatastoreHelper.LOCAL_HOST_ENV_VAR, + System.getenv(com.google.datastore.v1beta3.client.DatastoreHelper.LOCAL_HOST_ENV_VAR)); return host != null ? host : super.defaultHost(); } @Override protected String defaultProject() { - String projectId = System.getProperty(DATASET_ENV_NAME, System.getenv(DATASET_ENV_NAME)); + String projectId = System.getProperty( + com.google.datastore.v1beta3.client.DatastoreHelper.PROJECT_ID_ENV_VAR, + System.getenv(com.google.datastore.v1beta3.client.DatastoreHelper.PROJECT_ID_ENV_VAR)); if (projectId == null) { projectId = appEngineAppId(); } @@ -157,10 +150,6 @@ private static String defaultNamespace() { } } - public boolean force() { - return force; - } - @Override protected Set scopes() { return SCOPES; @@ -173,7 +162,7 @@ public Builder toBuilder() { @Override public int hashCode() { - return baseHashCode() ^ Objects.hash(namespace, force, normalizeDataset); + return baseHashCode() ^ Objects.hash(namespace, normalizeDataset); } @Override @@ -183,7 +172,6 @@ public boolean equals(Object obj) { } DatastoreOptions other = (DatastoreOptions) obj; return baseEquals(other) && Objects.equals(namespace, other.namespace) - && Objects.equals(force, other.force) && Objects.equals(normalizeDataset, other.normalizeDataset); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index 3c82e2a93cc4..31fe2f8e0d66 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -50,22 +50,41 @@ public DefaultDatastoreRpc(DatastoreOptions options) { new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() .projectId(options.projectId()) .initializer(options.httpRequestInitializer()); - if (options.host() != null) { + if (isLocalHost(options.host())) { + clientBuilder = clientBuilder.localHost(options.host()); + } else if (!options.host() + .equals(com.google.datastore.v1beta3.client.DatastoreFactory.DEFAULT_HOST)) { + String fullURL = options.host(); + if (fullURL.charAt(fullURL.length() - 1) != '/') { + fullURL = fullURL + '/'; + } + fullURL = fullURL + "datastore/v1beta3/projects/" + options.projectId(); + clientBuilder = clientBuilder.projectId(null).projectEndpoint(fullURL); + } + client = com.google.datastore.v1beta3.client.DatastoreFactory.get() + .create(clientBuilder.build()); + } + + private static boolean isLocalHost(String host) { + if (host != null) { try { - String normalizedHost = options.host(); - if (!normalizedHost.startsWith("http")) { + String normalizedHost = host; + if (!includesScheme(normalizedHost)) { normalizedHost = "http://" + normalizedHost; } InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost()); if (hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress()) { - clientBuilder = clientBuilder.localHost(options.host()); + return true; } } catch (UnknownHostException | MalformedURLException e) { // ignore } } - client = com.google.datastore.v1beta3.client.DatastoreFactory.get() - .create(clientBuilder.build()); + return false; + } + + private static boolean includesScheme(String url) { + return url.startsWith("http://") || url.startsWith("https://"); } private static DatastoreRpcException translate( diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index 63657902d737..161dfc078f6c 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -68,12 +68,6 @@ public void testNamespace() throws Exception { assertEquals("ns1", options.namespace("ns1").build().namespace()); } - @Test - public void testForce() throws Exception { - assertFalse(options.build().force()); - assertTrue(options.force(true).build().force()); - } - @Test public void testDatastore() throws Exception { assertSame(datastoreRpcFactory, options.build().serviceRpcFactory()); @@ -82,12 +76,11 @@ public void testDatastore() throws Exception { @Test public void testToBuilder() throws Exception { - DatastoreOptions original = options.namespace("ns1").force(true).build(); + DatastoreOptions original = options.namespace("ns1").build(); DatastoreOptions copy = original.toBuilder().build(); assertEquals(original.projectId(), copy.projectId()); assertEquals(original.namespace(), copy.namespace()); assertEquals(original.host(), copy.host()); - assertEquals(original.force(), copy.force()); assertEquals(original.retryParams(), copy.retryParams()); assertEquals(original.authCredentials(), copy.authCredentials()); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 624689cd420e..bd4a683f9c9c 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -148,7 +148,6 @@ public void testServiceOptions() throws Exception { .namespace("ns1") .retryParams(RetryParams.getDefaultInstance()) .authCredentials(AuthCredentials.noCredentials()) - .force(true) .build(); serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); From 4d2fe25b88f32abb9cc4c3d4bc01fbfde1221a79 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 5 Oct 2015 08:03:49 -0700 Subject: [PATCH 06/29] Remove scheme from localhost and check if user-provided host is null/empty --- .../gcloud/spi/DefaultDatastoreRpc.java | 24 +++++++++++++------ .../gcloud/datastore/LocalGcdHelper.java | 3 ++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index 31fe2f8e0d66..c6e3f396e574 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -16,6 +16,7 @@ package com.google.gcloud.spi; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.gcloud.datastore.DatastoreOptions; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; @@ -51,14 +52,16 @@ public DefaultDatastoreRpc(DatastoreOptions options) { .projectId(options.projectId()) .initializer(options.httpRequestInitializer()); if (isLocalHost(options.host())) { - clientBuilder = clientBuilder.localHost(options.host()); - } else if (!options.host() - .equals(com.google.datastore.v1beta3.client.DatastoreFactory.DEFAULT_HOST)) { + clientBuilder = clientBuilder.localHost(removeScheme(options.host())); + } else if (!com.google.datastore.v1beta3.client.DatastoreFactory.DEFAULT_HOST + .equals(options.host()) && !Strings.isNullOrEmpty(options.host())) { String fullURL = options.host(); if (fullURL.charAt(fullURL.length() - 1) != '/') { fullURL = fullURL + '/'; } - fullURL = fullURL + "datastore/v1beta3/projects/" + options.projectId(); + fullURL = fullURL + "datastore/" + + com.google.datastore.v1beta3.client.DatastoreFactory.VERSION + "/projects/" + + options.projectId(); clientBuilder = clientBuilder.projectId(null).projectEndpoint(fullURL); } client = com.google.datastore.v1beta3.client.DatastoreFactory.get() @@ -73,9 +76,7 @@ private static boolean isLocalHost(String host) { normalizedHost = "http://" + normalizedHost; } InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost()); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress()) { - return true; - } + return hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress(); } catch (UnknownHostException | MalformedURLException e) { // ignore } @@ -87,6 +88,15 @@ private static boolean includesScheme(String url) { return url.startsWith("http://") || url.startsWith("https://"); } + private static String removeScheme(String url) { + if (url.startsWith("https://")) { + return url.substring("https://".length()); + } else if (url.startsWith("http://")) { + return url.substring("http://".length()); + } + return url; + } + private static DatastoreRpcException translate( com.google.datastore.v1beta3.client.DatastoreException exception) { String reasonStr = ""; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 1d692040c015..1054b461ab0d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -309,7 +309,8 @@ public static void main(String... args) throws IOException, InterruptedException public static boolean isActive(String projectId) { try { StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); - urlBuilder.append("/datastore/v1beta3/projects/").append(projectId).append(":lookup"); + urlBuilder.append("/datastore/" + com.google.datastore.v1beta3.client.DatastoreFactory.VERSION + + "/projects/").append(projectId).append(":lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { From e0aaaba871960a006fb82dc5972c015ea987c980 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 5 Oct 2015 09:27:23 -0700 Subject: [PATCH 07/29] Fix version in LocalGcdHelper and check for null values when removing URL scheme --- .../com/google/gcloud/spi/DefaultDatastoreRpc.java | 10 ++++++---- .../com/google/gcloud/datastore/LocalGcdHelper.java | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index c6e3f396e574..3063dda6eca3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -89,10 +89,12 @@ private static boolean includesScheme(String url) { } private static String removeScheme(String url) { - if (url.startsWith("https://")) { - return url.substring("https://".length()); - } else if (url.startsWith("http://")) { - return url.substring("http://".length()); + if (url != null) { + if (url.startsWith("https://")) { + return url.substring("https://".length()); + } else if (url.startsWith("http://")) { + return url.substring("http://".length()); + } } return url; } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 1054b461ab0d..1d692040c015 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -309,8 +309,7 @@ public static void main(String... args) throws IOException, InterruptedException public static boolean isActive(String projectId) { try { StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); - urlBuilder.append("/datastore/" + com.google.datastore.v1beta3.client.DatastoreFactory.VERSION - + "/projects/").append(projectId).append(":lookup"); + urlBuilder.append("/datastore/v1beta3/projects/").append(projectId).append(":lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { From c029c378fd2d09928802c75f8ca9c21e2aafb477 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 5 Oct 2015 15:55:10 -0700 Subject: [PATCH 08/29] Update query-related datastore code to v1beta3 --- .../com/google/gcloud/datastore/Blob.java | 10 +- .../com/google/gcloud/datastore/Cursor.java | 15 +- .../gcloud/datastore/DatastoreImpl.java | 4 +- .../com/google/gcloud/datastore/GqlQuery.java | 129 ++++++------ .../com/google/gcloud/datastore/Query.java | 59 +++--- .../google/gcloud/datastore/QueryResults.java | 1 - .../gcloud/datastore/QueryResultsImpl.java | 44 ++-- .../gcloud/datastore/StructuredQuery.java | 191 ++++++++---------- .../gcloud/datastore/DatastoreTest.java | 19 +- .../gcloud/datastore/SerializationTest.java | 12 +- 10 files changed, 221 insertions(+), 263 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java index 5a759240be38..fbe2887d9b35 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java @@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.Value; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.protobuf.ByteString; @@ -37,7 +35,7 @@ * * @see Google Cloud Datastore Entities, Properties, and Keys */ -public final class Blob extends Serializable { +public final class Blob extends Serializable { private static final long serialVersionUID = 3835421019618247721L; @@ -146,12 +144,12 @@ public static Blob copyFrom(InputStream input) throws IOException { } @Override - protected Value toPb() { - return DatastoreV1.Value.newBuilder().setBlobValue(byteString).build(); + protected com.google.datastore.v1beta3.Value toPb() { + return com.google.datastore.v1beta3.Value.newBuilder().setBlobValue(byteString).build(); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return new Blob(DatastoreV1.Value.parseFrom(bytesPb).getBlobValue()); + return new Blob(com.google.datastore.v1beta3.Value.parseFrom(bytesPb).getBlobValue()); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java index 42a8cee8e5a2..df237e4d897c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java @@ -19,8 +19,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.Value; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.Preconditions; @@ -37,7 +35,7 @@ * A Google Cloud Datastore cursor. * The cursor can be used to as a starting point or an ending point for a {@link Query} */ -public final class Cursor extends Serializable { +public final class Cursor extends Serializable { private static final long serialVersionUID = -1423744878777486541L; @@ -89,7 +87,8 @@ public String toUrlSafe() { public static Cursor fromUrlSafe(String urlSafe) { try { String utf8Str = URLDecoder.decode(urlSafe, UTF_8.name()); - DatastoreV1.Value.Builder builder = DatastoreV1.Value.newBuilder(); + com.google.datastore.v1beta3.Value.Builder builder = + com.google.datastore.v1beta3.Value.newBuilder(); TextFormat.merge(utf8Str, builder); return fromPb(builder.build()); } catch (UnsupportedEncodingException | ParseException e) { @@ -102,16 +101,16 @@ public static Cursor copyFrom(byte[] bytes) { } @Override - protected Value toPb() { - return DatastoreV1.Value.newBuilder().setBlobValue(byteString).build(); + protected com.google.datastore.v1beta3.Value toPb() { + return com.google.datastore.v1beta3.Value.newBuilder().setBlobValue(byteString).build(); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Value.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Value.parseFrom(bytesPb)); } - static Cursor fromPb(DatastoreV1.Value valuePb) { + static Cursor fromPb(com.google.datastore.v1beta3.Value valuePb) { return new Cursor(valuePb.getBlobValue()); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 59804831872c..fdd8917d11e2 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -99,9 +99,7 @@ public QueryResults run(Query query) { } QueryResults run(com.google.datastore.v1beta3.ReadOptions readOptionsPb, Query query) { - // TODO(ajaykannan): fix me! - //return new QueryResultsImpl<>(this, readOptionsPb, query); - return null; // TODO(ajaykannan): fix me! + return new QueryResultsImpl<>(this, readOptionsPb, query); } com.google.datastore.v1beta3.RunQueryResponse runQuery( diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 54110a89c3e0..2c02aa7b970c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.gcloud.datastore.Validator.validateNamespace; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -75,25 +74,22 @@ public final class GqlQuery extends Query { private final transient String queryString; private final transient boolean allowLiteral; - private final transient ImmutableList namedBindings; + private final transient ImmutableMap namedBindings; private final transient ImmutableList positionalBindings; - static final class Binding extends Serializable { + static final class Binding extends Serializable { private static final long serialVersionUID = 1976895435257636275L; - private final transient String name; private final transient Cursor cursor; private final transient Value value; - Binding(String name, Cursor cursor) { - this.name = name; + Binding(Cursor cursor) { this.cursor = checkNotNull(cursor); value = null; } - Binding(String name, Value value) { - this.name = name; + Binding(Value value) { this.value = checkNotNull(value); cursor = null; } @@ -102,13 +98,9 @@ Object cursorOrValue() { return MoreObjects.firstNonNull(cursor, value); } - String name() { - return name; - } - @Override public int hashCode() { - return Objects.hash(name, cursor, value); + return Objects.hash(cursor, value); } @Override @@ -120,40 +112,36 @@ public boolean equals(Object obj) { return false; } Binding other = (Binding) obj; - return Objects.equals(name, other.name) - && Objects.equals(cursor, other.cursor) - && Objects.equals(value, other.value); + return Objects.equals(cursor, other.cursor) && Objects.equals(value, other.value); } @Override - protected DatastoreV1.GqlQueryArg toPb() { - DatastoreV1.GqlQueryArg.Builder argPb = DatastoreV1.GqlQueryArg.newBuilder(); - if (name != null) { - argPb.setName(name); - } + protected com.google.datastore.v1beta3.GqlQueryParameter toPb() { + com.google.datastore.v1beta3.GqlQueryParameter.Builder argPb = + com.google.datastore.v1beta3.GqlQueryParameter.newBuilder(); if (cursor != null) { argPb.setCursor(cursor.byteString()); } if (value != null) { - // TODO(ajaykannan): fix me! - //argPb.setValue(value.toPb()); + argPb.setValue(value.toPb()); } return argPb.build(); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.GqlQueryArg.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.GqlQueryParameter.parseFrom(bytesPb)); } - static Binding fromPb(DatastoreV1.GqlQueryArg argPb) { - String name = argPb.hasName() ? argPb.getName() : null; - if (argPb.hasCursor()) { - return new Binding(name, new Cursor(argPb.getCursor())); + static Binding fromPb(com.google.datastore.v1beta3.GqlQueryParameter argPb) { + switch (argPb.getParameterTypeCase()) { + case CURSOR: + return new Binding(new Cursor(argPb.getCursor())); + case VALUE: + return new Binding(Value.fromPb(argPb.getValue())); + default: + return null; } - // TODO(ajaykannan): fix me! - //return new Binding(name, Value.fromPb(argPb.getValue())); - return new Binding(name, new Cursor(null)); // TODO(ajaykannan): fix me! } } @@ -196,52 +184,52 @@ public Builder clearBindings() { } public Builder setBinding(String name, Cursor cursor) { - namedBindings.put(name, new Binding(name, cursor)); + namedBindings.put(name, new Binding(cursor)); return this; } public Builder setBinding(String name, String... value) { - namedBindings.put(name, toBinding(name, StringValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(StringValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder setBinding(String name, long... value) { - namedBindings.put(name, toBinding(name, LongValue.MARSHALLER, Longs.asList(value))); + namedBindings.put(name, toBinding(LongValue.MARSHALLER, Longs.asList(value))); return this; } public Builder setBinding(String name, double... value) { - namedBindings.put(name, toBinding(name, DoubleValue.MARSHALLER, Doubles.asList(value))); + namedBindings.put(name, toBinding(DoubleValue.MARSHALLER, Doubles.asList(value))); return this; } public Builder setBinding(String name, boolean... value) { - namedBindings.put(name, toBinding(name, BooleanValue.MARSHALLER, Booleans.asList(value))); + namedBindings.put(name, toBinding(BooleanValue.MARSHALLER, Booleans.asList(value))); return this; } public Builder setBinding(String name, DateTime... value) { - namedBindings.put(name, toBinding(name, DateTimeValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(DateTimeValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder setBinding(String name, Key... value) { - namedBindings.put(name, toBinding(name, KeyValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder setBinding(String name, FullEntity... value) { - namedBindings.put(name, toBinding(name, EntityValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(EntityValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder setBinding(String name, Blob... value) { - namedBindings.put(name, toBinding(name, BlobValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(BlobValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder addBinding(Cursor cursor) { - positionalBindings.add(new Binding(null, cursor)); + positionalBindings.add(new Binding(cursor)); return this; } @@ -289,11 +277,7 @@ public GqlQuery build() { return new GqlQuery<>(this); } - private static Binding toBinding(Value.BuilderFactory builderFactory, List values) { - return toBinding(null, builderFactory, values); - } - - private static Binding toBinding(String name, Value.BuilderFactory builderFactory, + private static Binding toBinding(Value.BuilderFactory builderFactory, List values) { List> list = new ArrayList<>(values.size()); for (Object object : values) { @@ -309,7 +293,7 @@ private static Binding toBinding(String name, Value.BuilderFactory } else { value = new ListValue(list); } - return new Binding(name, value); + return new Binding(value); } } @@ -317,7 +301,7 @@ private GqlQuery(Builder builder) { super(builder.resultType, builder.namespace); queryString = builder.queryString; allowLiteral = builder.allowLiteral; - namedBindings = ImmutableList.copyOf(builder.namedBindings.values()); + namedBindings = ImmutableMap.copyOf(builder.namedBindings); positionalBindings = ImmutableList.copyOf(builder.positionalBindings); } @@ -334,8 +318,8 @@ public boolean allowLiteral() { */ public Map namedBindings() { ImmutableMap.Builder builder = ImmutableSortedMap.naturalOrder(); - for (Binding binding : namedBindings) { - builder.put(binding.name(), binding.cursorOrValue()); + for (Map.Entry binding : namedBindings.entrySet()) { + builder.put(binding.getKey(), binding.getValue().cursorOrValue()); } return builder.build(); } @@ -373,26 +357,29 @@ public boolean equals(Object obj) { } @Override - protected DatastoreV1.GqlQuery toPb() { - DatastoreV1.GqlQuery.Builder queryPb = DatastoreV1.GqlQuery.newBuilder(); + protected com.google.datastore.v1beta3.GqlQuery toPb() { + com.google.datastore.v1beta3.GqlQuery.Builder queryPb = + com.google.datastore.v1beta3.GqlQuery.newBuilder(); queryPb.setQueryString(queryString); - queryPb.setAllowLiteral(allowLiteral); - for (Binding argument : namedBindings) { - queryPb.addNameArg(argument.toPb()); + queryPb.setAllowLiterals(allowLiteral); + Map namedBindingsPb = + queryPb.getMutableNamedBindings(); + for (Map.Entry entry : namedBindings.entrySet()) { + namedBindingsPb.put(entry.getKey(), entry.getValue().toPb()); } for (Binding argument : positionalBindings) { - queryPb.addNumberArg(argument.toPb()); + queryPb.addPositionalBindings(argument.toPb()); } return queryPb.build(); } @Override - protected void populatePb(DatastoreV1.RunQueryRequest.Builder requestPb) { + protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb) { requestPb.setGqlQuery(toPb()); } @Override - protected GqlQuery nextQuery(DatastoreV1.QueryResultBatch responsePb) { + protected GqlQuery nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb) { // See issue #17 throw new UnsupportedOperationException("paging for this query is not implemented yet"); } @@ -400,23 +387,27 @@ protected GqlQuery nextQuery(DatastoreV1.QueryResultBatch responsePb) { @Override protected Object fromPb(ResultType resultType, String namespace, byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(resultType, namespace, DatastoreV1.GqlQuery.parseFrom(bytesPb)); + return fromPb(resultType, namespace, com.google.datastore.v1beta3.GqlQuery.parseFrom(bytesPb)); } private static GqlQuery fromPb( - ResultType resultType, String ns, DatastoreV1.GqlQuery queryPb) { + ResultType resultType, String ns, com.google.datastore.v1beta3.GqlQuery queryPb) { Builder builder = new Builder<>(resultType, queryPb.getQueryString()); builder.namespace(ns); - if (queryPb.hasAllowLiteral()) { - builder.allowLiteral = queryPb.getAllowLiteral(); - } - for (DatastoreV1.GqlQueryArg nameArg : queryPb.getNameArgList()) { - Binding argument = Binding.fromPb(nameArg); - builder.namedBindings.put(argument.name(), argument); + builder.allowLiteral = queryPb.getAllowLiterals(); + for (Map.Entry nameArg + : queryPb.getNamedBindings().entrySet()) { + Binding currBinding = Binding.fromPb(nameArg.getValue()); + if (currBinding != null) { + builder.namedBindings.put(nameArg.getKey(), currBinding); + } } - for (DatastoreV1.GqlQueryArg numberArg : queryPb.getNumberArgList()) { - Binding argument = Binding.fromPb(numberArg); - builder.positionalBindings.add(argument); + for (com.google.datastore.v1beta3.GqlQueryParameter numberArg + : queryPb.getPositionalBindingsList()) { + Binding currBinding = Binding.fromPb(numberArg); + if (currBinding != null) { + builder.positionalBindings.add(currBinding); + } } return builder.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index 7fae120dd402..6e962d92fb2f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.collect.Maps; @@ -54,68 +53,65 @@ public abstract class Query extends Serializable { public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = 2104157695425806623L; - private static final Map> - PB_TO_INSTANCE = Maps.newEnumMap(DatastoreV1.EntityResult.ResultType.class); + private static final Map> + PB_TO_INSTANCE = Maps.newEnumMap( + com.google.datastore.v1beta3.EntityResult.ResultType.class); static final ResultType UNKNOWN = new ResultType(null, Object.class) { private static final long serialVersionUID = 1602329532153860907L; - @Override protected Object convert(DatastoreV1.Entity entityPb) { - if (entityPb.getPropertyCount() == 0) { + @Override protected Object convert(com.google.datastore.v1beta3.Entity entityPb) { + if (entityPb.getProperties().size() == 0) { if (!entityPb.hasKey()) { return null; } - //TODO(ajaykannan): fix me! - //return Key.fromPb(entityPb.getKey()); + return Key.fromPb(entityPb.getKey()); } - // TODO(ajaykannan): fix me! - //return ProjectionEntity.fromPb(entityPb); - return ProjectionEntity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! + return ProjectionEntity.fromPb(entityPb); } }; public static final ResultType ENTITY = - new ResultType(DatastoreV1.EntityResult.ResultType.FULL, Entity.class) { + new ResultType( + com.google.datastore.v1beta3.EntityResult.ResultType.FULL, Entity.class) { private static final long serialVersionUID = 7712959777507168274L; - @Override protected Entity convert(DatastoreV1.Entity entityPb) { - // TODO(ajaykannan): fix me! - //return Entity.fromPb(entityPb); - return Entity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! + @Override protected Entity convert(com.google.datastore.v1beta3.Entity entityPb) { + return Entity.fromPb(entityPb); } }; public static final ResultType KEY = - new ResultType(DatastoreV1.EntityResult.ResultType.KEY_ONLY, Key.class) { + new ResultType( + com.google.datastore.v1beta3.EntityResult.ResultType.KEY_ONLY, Key.class) { private static final long serialVersionUID = -8514289244104446252L; - @Override protected Key convert(DatastoreV1.Entity entityPb) { - //TODO(ajaykannan): fix me! - //return Key.fromPb(entityPb.getKey()); - return Key.builder(null).build(); // TODO(ajaykannan): fix me! + @Override protected Key convert(com.google.datastore.v1beta3.Entity entityPb) { + return Key.fromPb(entityPb.getKey()); } }; public static final ResultType PROJECTION_ENTITY = - new ResultType(DatastoreV1.EntityResult.ResultType.PROJECTION, + new ResultType( + com.google.datastore.v1beta3.EntityResult.ResultType.PROJECTION, ProjectionEntity.class) { private static final long serialVersionUID = -7591409419690650246L; - @Override protected ProjectionEntity convert(DatastoreV1.Entity entityPb) { - // TODO(ajaykannan): fix me! - //return ProjectionEntity.fromPb(entityPb); - return ProjectionEntity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! + @Override protected ProjectionEntity convert( + com.google.datastore.v1beta3.Entity entityPb) { + return ProjectionEntity.fromPb(entityPb); } }; private final Class resultClass; - private final DatastoreV1.EntityResult.ResultType queryType; + private final com.google.datastore.v1beta3.EntityResult.ResultType queryType; - private ResultType(DatastoreV1.EntityResult.ResultType queryType, Class resultClass) { + private ResultType(com.google.datastore.v1beta3.EntityResult.ResultType queryType, + Class resultClass) { this.queryType = queryType; this.resultClass = resultClass; if (queryType != null) { @@ -156,9 +152,9 @@ boolean isAssignableFrom(ResultType otherResultType) { return resultClass.isAssignableFrom(otherResultType.resultClass); } - protected abstract V convert(DatastoreV1.Entity entityPb); + protected abstract V convert(com.google.datastore.v1beta3.Entity entityPb); - static ResultType fromPb(DatastoreV1.EntityResult.ResultType typePb) { + static ResultType fromPb(com.google.datastore.v1beta3.EntityResult.ResultType typePb) { return MoreObjects.firstNonNull(PB_TO_INSTANCE.get(typePb), UNKNOWN); } } @@ -193,9 +189,10 @@ protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { protected abstract Object fromPb(ResultType resultType, String namespace, byte[] bytesPb) throws InvalidProtocolBufferException; - protected abstract void populatePb(DatastoreV1.RunQueryRequest.Builder requestPb); + protected abstract void populatePb( + com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb); - protected abstract Query nextQuery(DatastoreV1.QueryResultBatch responsePb); + protected abstract Query nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb); /** * Returns a new {@link GqlQuery} builder. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java index b23c56a7c395..5b4f71da3963 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java @@ -36,7 +36,6 @@ public interface QueryResults extends Iterator { /** * Returns the Cursor for point after the value returned in the last {@link #next} call. - * Not currently implemented (depends on v1beta3). */ Cursor cursorAfter(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index caf5d7f8a84f..b3c51ceb9eeb 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -16,11 +16,11 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.QueryResultBatch.MoreResultsType; +import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType; import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; import com.google.gcloud.datastore.Query.ResultType; +import com.google.protobuf.ByteString; import java.util.Iterator; import java.util.Objects; @@ -28,46 +28,49 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults { private final DatastoreImpl datastore; - private final DatastoreV1.ReadOptions readOptionsPb; - private final DatastoreV1.PartitionId partitionIdPb; + private final com.google.datastore.v1beta3.ReadOptions readOptionsPb; + private final com.google.datastore.v1beta3.PartitionId partitionIdPb; private final ResultType queryResultType; private Query query; private ResultType actualResultType; - private DatastoreV1.QueryResultBatch queryResultBatchPb; + private com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb; private boolean lastBatch; - private Iterator entityResultPbIter; - //private ByteString cursor; // only available in v1beta3 + private Iterator entityResultPbIter; + private ByteString cursor; - QueryResultsImpl(DatastoreImpl datastore, DatastoreV1.ReadOptions readOptionsPb, + QueryResultsImpl(DatastoreImpl datastore, com.google.datastore.v1beta3.ReadOptions readOptionsPb, Query query) { this.datastore = datastore; this.readOptionsPb = readOptionsPb; this.query = query; queryResultType = query.type(); - DatastoreV1.PartitionId.Builder pbBuilder = DatastoreV1.PartitionId.newBuilder(); - pbBuilder.setDatasetId(datastore.options().projectId()); + com.google.datastore.v1beta3.PartitionId.Builder pbBuilder = + com.google.datastore.v1beta3.PartitionId.newBuilder(); + pbBuilder.setProjectId(datastore.options().projectId()); if (query.namespace() != null) { - pbBuilder.setNamespace(query.namespace()); + pbBuilder.setNamespaceId(query.namespace()); } else if (datastore.options().namespace() != null) { - pbBuilder.setNamespace(datastore.options().namespace()); + pbBuilder.setNamespaceId(datastore.options().namespace()); } partitionIdPb = pbBuilder.build(); sendRequest(); } private void sendRequest() { - DatastoreV1.RunQueryRequest.Builder requestPb = DatastoreV1.RunQueryRequest.newBuilder(); + com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = + com.google.datastore.v1beta3.RunQueryRequest.newBuilder(); if (readOptionsPb != null) { requestPb.setReadOptions(readOptionsPb); } requestPb.setPartitionId(partitionIdPb); query.populatePb(requestPb); - // TODO(ajaykannan): fix me! - //queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); + queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; - entityResultPbIter = queryResultBatchPb.getEntityResultList().iterator(); - // cursor = resultPb.getSkippedCursor(); // available in v1beta3, use startCursor if not skipped + entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); + if (queryResultBatchPb.getSkippedResults() > 0) { + cursor = queryResultBatchPb.getSkippedCursor(); + } actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) { // projection entity can represent all type of results @@ -86,8 +89,8 @@ protected T computeNext() { if (!entityResultPbIter.hasNext()) { return endOfData(); } - DatastoreV1.EntityResult entityResultPb = entityResultPbIter.next(); - //cursor = entityResultPb.getCursor(); // only available in v1beta3 + com.google.datastore.v1beta3.EntityResult entityResultPb = entityResultPbIter.next(); + cursor = entityResultPb.getCursor(); @SuppressWarnings("unchecked") T result = (T) actualResultType.convert(entityResultPb.getEntity()); return result; @@ -100,7 +103,6 @@ public Class resultClass() { @Override public Cursor cursorAfter() { - //return new Cursor(cursor); // only available in v1beta3 - return null; + return new Cursor(cursor); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 1dd35cb4f191..7c1cf815879e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -25,7 +25,6 @@ import static com.google.gcloud.datastore.LongValue.of; import static com.google.gcloud.datastore.StringValue.of; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.Preconditions; @@ -103,13 +102,17 @@ public abstract static class Filter implements Serializable { Filter() { } - protected abstract DatastoreV1.Filter toPb(); + protected abstract com.google.datastore.v1beta3.Filter toPb(); - static Filter fromPb(DatastoreV1.Filter filterPb) { - if (filterPb.hasCompositeFilter()) { - return CompositeFilter.fromPb(filterPb.getCompositeFilter()); + static Filter fromPb(com.google.datastore.v1beta3.Filter filterPb) { + switch (filterPb.getFilterTypeCase()) { + case COMPOSITE_FILTER: + return CompositeFilter.fromPb(filterPb.getCompositeFilter()); + case PROPERTY_FILTER: + return PropertyFilter.fromPb(filterPb.getPropertyFilter()); + default: + return null; } - return PropertyFilter.fromPb(filterPb.getPropertyFilter()); } } @@ -122,11 +125,11 @@ public static final class CompositeFilter extends Filter { enum Operator { AND; - DatastoreV1.CompositeFilter.Operator toPb() { - return DatastoreV1.CompositeFilter.Operator.valueOf(name()); + com.google.datastore.v1beta3.CompositeFilter.Operator toPb() { + return com.google.datastore.v1beta3.CompositeFilter.Operator.valueOf(name()); } - static Operator fromPb(DatastoreV1.CompositeFilter.Operator operatorPb) { + static Operator fromPb(com.google.datastore.v1beta3.CompositeFilter.Operator operatorPb) { return valueOf(operatorPb.name()); } } @@ -169,11 +172,14 @@ public boolean equals(Object obj) { && filters.equals(other.filters); } - static CompositeFilter fromPb(DatastoreV1.CompositeFilter compositeFilterPb) { - Operator operator = Operator.fromPb(compositeFilterPb.getOperator()); + static CompositeFilter fromPb(com.google.datastore.v1beta3.CompositeFilter compositeFilterPb) { + Operator operator = Operator.fromPb(compositeFilterPb.getOp()); ImmutableList.Builder filters = ImmutableList.builder(); - for (DatastoreV1.Filter filterPb : compositeFilterPb.getFilterList()) { - filters.add(Filter.fromPb(filterPb)); + for (com.google.datastore.v1beta3.Filter filterPb : compositeFilterPb.getFiltersList()) { + Filter currFilter = Filter.fromPb(filterPb); + if (currFilter != null) { + filters.add(currFilter); + } } return new CompositeFilter(operator, filters.build()); } @@ -183,12 +189,14 @@ public static CompositeFilter and(Filter first, Filter... other) { } @Override - protected DatastoreV1.Filter toPb() { - DatastoreV1.Filter.Builder filterPb = DatastoreV1.Filter.newBuilder(); - DatastoreV1.CompositeFilter.Builder compositeFilterPb = filterPb.getCompositeFilterBuilder(); - compositeFilterPb.setOperator(operator.toPb()); + protected com.google.datastore.v1beta3.Filter toPb() { + com.google.datastore.v1beta3.Filter.Builder filterPb = + com.google.datastore.v1beta3.Filter.newBuilder(); + com.google.datastore.v1beta3.CompositeFilter.Builder compositeFilterPb = + filterPb.getCompositeFilterBuilder(); + compositeFilterPb.setOp(operator.toPb()); for (Filter filter : filters) { - compositeFilterPb.addFilter(filter.toPb()); + compositeFilterPb.addFilters(filter.toPb()); } return filterPb.build(); } @@ -210,11 +218,11 @@ enum Operator { EQUAL, HAS_ANCESTOR; - DatastoreV1.PropertyFilter.Operator toPb() { - return DatastoreV1.PropertyFilter.Operator.valueOf(name()); + com.google.datastore.v1beta3.PropertyFilter.Operator toPb() { + return com.google.datastore.v1beta3.PropertyFilter.Operator.valueOf(name()); } - static Operator fromPb(DatastoreV1.PropertyFilter.Operator operatorPb) { + static Operator fromPb(com.google.datastore.v1beta3.PropertyFilter.Operator operatorPb) { return valueOf(operatorPb.name()); } } @@ -225,13 +233,11 @@ private PropertyFilter(String property, Operator operator, Value value) { this.value = checkNotNull(value); } - public static PropertyFilter fromPb(DatastoreV1.PropertyFilter propertyFilterPb) { + public static PropertyFilter fromPb(com.google.datastore.v1beta3.PropertyFilter propertyFilterPb) { String property = propertyFilterPb.getProperty().getName(); - Operator operator = Operator.fromPb(propertyFilterPb.getOperator()); - // TODO(ajaykannan): fix me! - //Value value = Value.fromPb(propertyFilterPb.getValue()); - //return new PropertyFilter(property, operator, value); - return new PropertyFilter(property, operator, null); // TODO(ajaykannan): fix me! + Operator operator = Operator.fromPb(propertyFilterPb.getOp()); + Value value = Value.fromPb(propertyFilterPb.getValue()); + return new PropertyFilter(property, operator, value); } @Override @@ -431,14 +437,15 @@ public static PropertyFilter isNull(String property) { } @Override - protected DatastoreV1.Filter toPb() { - DatastoreV1.Filter.Builder filterPb = DatastoreV1.Filter.newBuilder(); - DatastoreV1.PropertyFilter.Builder propertyFilterPb = filterPb.getPropertyFilterBuilder(); + protected com.google.datastore.v1beta3.Filter toPb() { + com.google.datastore.v1beta3.Filter.Builder filterPb = + com.google.datastore.v1beta3.Filter.newBuilder(); + com.google.datastore.v1beta3.PropertyFilter.Builder propertyFilterPb = + filterPb.getPropertyFilterBuilder(); propertyFilterPb.getPropertyBuilder().setName(property); - propertyFilterPb.setOperator(operator.toPb()); + propertyFilterPb.setOp(operator.toPb()); if (value != null) { - // TODO(ajaykannan): fix me! - //propertyFilterPb.setValue(value.toPb()); + propertyFilterPb.setValue(value.toPb()); } return filterPb.build(); } @@ -455,11 +462,11 @@ public enum Direction { ASCENDING, DESCENDING; - DatastoreV1.PropertyOrder.Direction toPb() { - return DatastoreV1.PropertyOrder.Direction.valueOf(name()); + com.google.datastore.v1beta3.PropertyOrder.Direction toPb() { + return com.google.datastore.v1beta3.PropertyOrder.Direction.valueOf(name()); } - static Direction fromPb(DatastoreV1.PropertyOrder.Direction directionPb) { + static Direction fromPb(com.google.datastore.v1beta3.PropertyOrder.Direction directionPb) { return valueOf(directionPb.name()); } } @@ -495,10 +502,11 @@ public Direction direction() { return direction; } - DatastoreV1.PropertyOrder toPb() { - return DatastoreV1.PropertyOrder.newBuilder() + com.google.datastore.v1beta3.PropertyOrder toPb() { + return com.google.datastore.v1beta3.PropertyOrder.newBuilder() .setDirection(direction.toPb()) - .setProperty(DatastoreV1.PropertyReference.newBuilder().setName(property).build()) + .setProperty(com.google.datastore.v1beta3.PropertyReference.newBuilder() + .setName(property).build()) .build(); } @@ -510,7 +518,7 @@ public static OrderBy desc(String property) { return new OrderBy(property, OrderBy.Direction.DESCENDING); } - static OrderBy fromPb(DatastoreV1.PropertyOrder propertyOrderPb) { + static OrderBy fromPb(com.google.datastore.v1beta3.PropertyOrder propertyOrderPb) { String property = propertyOrderPb.getProperty().getName(); Direction direction = Direction.fromPb(propertyOrderPb.getDirection()); return new OrderBy(property, direction); @@ -521,30 +529,15 @@ public static final class Projection implements Serializable { private static final long serialVersionUID = 3083707957256279470L; - private final Aggregate aggregate; private final String property; - public enum Aggregate { - - FIRST; - - DatastoreV1.PropertyExpression.AggregationFunction toPb() { - return DatastoreV1.PropertyExpression.AggregationFunction.valueOf(name()); - } - - static Aggregate fromPb(DatastoreV1.PropertyExpression.AggregationFunction aggregatePb) { - return valueOf(aggregatePb.name()); - } - } - - private Projection(Aggregate aggregate, String property) { - this.aggregate = aggregate; + private Projection(String property) { this.property = property; } @Override public int hashCode() { - return Objects.hash(property, aggregate); + return Objects.hash(property); } @Override @@ -555,51 +548,31 @@ public boolean equals(Object obj) { if (!(obj instanceof Projection)) { return false; } - Projection other = (Projection) obj; - return Objects.equals(property, other.property) - && Objects.equals(aggregate, other.aggregate); + return Objects.equals(property, ((Projection) obj).property); } @Override public String toString() { ToStringHelper toStringHelper = MoreObjects.toStringHelper(this); toStringHelper.add("property", property); - if (aggregate != null) { - toStringHelper.add("aggregate", aggregate); - } return toStringHelper.toString(); } - DatastoreV1.PropertyExpression toPb() { - DatastoreV1.PropertyExpression.Builder expressionPb = - DatastoreV1.PropertyExpression.newBuilder(); - if (aggregate != null) { - expressionPb.setAggregationFunction(aggregate.toPb()); - } + com.google.datastore.v1beta3.Projection toPb() { + com.google.datastore.v1beta3.Projection.Builder expressionPb = + com.google.datastore.v1beta3.Projection.newBuilder(); expressionPb.setProperty( - DatastoreV1.PropertyReference.newBuilder().setName(property).build()); + com.google.datastore.v1beta3.PropertyReference.newBuilder().setName(property).build()); return expressionPb.build(); } - public static Projection fromPb(DatastoreV1.PropertyExpression propertyExpressionPb) { - String property = propertyExpressionPb.getProperty().getName(); - Aggregate aggregate = null; - if (propertyExpressionPb.hasAggregationFunction()) { - aggregate = Aggregate.fromPb(propertyExpressionPb.getAggregationFunction()); - } - return new Projection(aggregate, property); + public static Projection fromPb( + com.google.datastore.v1beta3.Projection projectionPb) { + return new Projection(projectionPb.getProperty().getName()); } public static Projection property(String property) { - return new Projection(null, property); - } - - public static Projection aggregate(Aggregate aggregate, String property) { - return new Projection(aggregate, property); - } - - public static Projection first(String property) { - return new Projection(Aggregate.FIRST, property); + return new Projection(property); } } @@ -714,32 +687,34 @@ B addGroupBy(String property, String... others) { return self(); } - B mergeFrom(DatastoreV1.Query queryPb) { + B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { if (queryPb.getKindCount() > 0) { kind(queryPb.getKind(0).getName()); } - if (queryPb.hasStartCursor()) { + if (!queryPb.getStartCursor().isEmpty()) { startCursor(new Cursor(queryPb.getStartCursor())); } - if (queryPb.hasEndCursor()) { + if (!queryPb.getEndCursor().isEmpty()) { endCursor(new Cursor(queryPb.getEndCursor())); } - if (queryPb.hasOffset()) { - offset(queryPb.getOffset()); - } + offset(queryPb.getOffset()); if (queryPb.hasLimit()) { - limit(queryPb.getLimit()); + limit(queryPb.getLimit().getValue()); } if (queryPb.hasFilter()) { - filter(Filter.fromPb(queryPb.getFilter())); + Filter currFilter = Filter.fromPb(queryPb.getFilter()); + if (currFilter != null) { + filter(currFilter); + } } - for (DatastoreV1.PropertyOrder orderByPb : queryPb.getOrderList()) { + for (com.google.datastore.v1beta3.PropertyOrder orderByPb : queryPb.getOrderList()) { addOrderBy(OrderBy.fromPb(orderByPb)); } - for (DatastoreV1.PropertyExpression projectionPb : queryPb.getProjectionList()) { + for (com.google.datastore.v1beta3.Projection projectionPb + : queryPb.getProjectionList()) { addProjection(Projection.fromPb(projectionPb)); } - for (DatastoreV1.PropertyReference groupByPb : queryPb.getGroupByList()) { + for (com.google.datastore.v1beta3.PropertyReference groupByPb : queryPb.getDistinctOnList()) { addGroupBy(groupByPb.getName()); } return self(); @@ -777,7 +752,7 @@ public static final class KeyQueryBuilder extends BaseBuilder nextQuery(DatastoreV1.QueryResultBatch responsePb) { + protected StructuredQuery nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb) { Builder builder = new Builder<>(type()); builder.mergeFrom(toPb()); builder.startCursor(new Cursor(responsePb.getEndCursor())); @@ -929,15 +904,16 @@ protected StructuredQuery nextQuery(DatastoreV1.QueryResultBatch responsePb) } else { builder.offset(0); if (limit != null) { - builder.limit(limit - responsePb.getEntityResultCount()); + builder.limit(limit - responsePb.getEntityResultsCount()); } } return builder.build(); } @Override - protected DatastoreV1.Query toPb() { - DatastoreV1.Query.Builder queryPb = DatastoreV1.Query.newBuilder(); + protected com.google.datastore.v1beta3.Query toPb() { + com.google.datastore.v1beta3.Query.Builder queryPb = + com.google.datastore.v1beta3.Query.newBuilder(); if (kind != null) { queryPb.addKindBuilder().setName(kind); } @@ -951,7 +927,7 @@ protected DatastoreV1.Query toPb() { queryPb.setOffset(offset); } if (limit != null) { - queryPb.setLimit(limit); + queryPb.setLimit(com.google.protobuf.Int32Value.newBuilder().setValue(limit.intValue())); } if (filter != null) { queryPb.setFilter(filter.toPb()); @@ -960,7 +936,8 @@ protected DatastoreV1.Query toPb() { queryPb.addOrder(value.toPb()); } for (String value : groupBy) { - queryPb.addGroupBy(DatastoreV1.PropertyReference.newBuilder().setName(value).build()); + queryPb.addDistinctOn(com.google.datastore.v1beta3.PropertyReference.newBuilder() + .setName(value).build()); } for (Projection value : projection) { queryPb.addProjection(value.toPb()); @@ -971,11 +948,11 @@ protected DatastoreV1.Query toPb() { @Override protected Object fromPb(ResultType resultType, String namespace, byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(resultType, namespace, DatastoreV1.Query.parseFrom(bytesPb)); + return fromPb(resultType, namespace, com.google.datastore.v1beta3.Query.parseFrom(bytesPb)); } private static StructuredQuery fromPb(ResultType resultType, String namespace, - DatastoreV1.Query queryPb) { + com.google.datastore.v1beta3.Query queryPb) { BaseBuilder builder; if (resultType.equals(ResultType.ENTITY)) { builder = new EntityQueryBuilder(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 689d2a7b8b6b..e3a71d8a8aa2 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -115,9 +115,9 @@ public void setUp() throws IOException, InterruptedException { .host("localhost:" + LocalGcdHelper.PORT) .build(); datastore = DatastoreFactory.instance().get(options); - //StructuredQuery query = Query.keyQueryBuilder().build(); - //QueryResults result = datastore.run(query); - //datastore.delete(Iterators.toArray(result, Key.class)); + StructuredQuery query = Query.keyQueryBuilder().build(); + QueryResults result = datastore.run(query); + datastore.delete(Iterators.toArray(result, Key.class)); datastore.add(ENTITY1, ENTITY2); } @@ -188,7 +188,7 @@ public void testTransactionWithRead() { assertEquals(DatastoreException.Code.ABORTED, expected.code()); } } - /* TODO(ajaykannan): fix me! + @Test public void testTransactionWithQuery() { Query query = Query.entityQueryBuilder() @@ -216,7 +216,7 @@ public void testTransactionWithQuery() { assertEquals(DatastoreException.Code.ABORTED, expected.code()); } } - */ + @Test public void testNewTransactionRollback() { Transaction transaction = datastore.newTransaction(); @@ -331,7 +331,7 @@ public void testNewBatch() { assertNull(entities.get(4)); assertEquals(5, entities.size()); } - /* TODO(ajaykannan): fix me! + @Test public void testRunGqlQueryNoCasting() { Query query1 = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from " + KIND1).build(); @@ -431,7 +431,7 @@ public void testRunStructuredQuery() { StructuredQuery projectionQuery = Query.projectionEntityQueryBuilder() .kind(KIND2) - .projection(Projection.property("age"), Projection.first("name")) + .projection(Projection.property("age")) .filter(PropertyFilter.gt("age", 18)) .groupBy("age") .orderBy(OrderBy.asc("age")) @@ -443,12 +443,11 @@ public void testRunStructuredQuery() { ProjectionEntity entity = results4.next(); assertEquals(ENTITY2.key(), entity.key()); assertEquals(20, entity.getLong("age")); - assertEquals("Dan", entity.getString("name")); - assertEquals(2, entity.properties().size()); + assertEquals(1, entity.properties().size()); assertFalse(results4.hasNext()); // TODO(ozarov): construct a test to verify nextQuery/pagination } - */ + @Test public void testAllocateId() { KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND1); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index bd4a683f9c9c..0c65ab76c681 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -122,9 +122,8 @@ public class SerializationTest { .put(ValueType.NULL, NULL_VALUE) .put(ValueType.KEY, KEY_VALUE) .put(ValueType.STRING, STRING_VALUE) - // TODO(ajaykannan): fix me! - //.putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, - // EMBEDDED_ENTITY_VALUE3) + .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, + EMBEDDED_ENTITY_VALUE3) .put(ValueType.LIST, LIST_VALUE) .put(ValueType.LONG, LONG_VALUE) .put(ValueType.DOUBLE, DOUBLE_VALUE) @@ -169,10 +168,9 @@ public void testValues() throws Exception { @Test public void testTypes() throws Exception { - // TODO(ajaykannan): fix me! - Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, /*ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY,*/ DATE_TIME1, BLOB1/*, CURSOR1, GQL1, GQL2, - QUERY1, QUERY2, QUERY3*/}; + Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, + ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, GQL2, + QUERY1, QUERY2, QUERY3}; for (Serializable obj : types) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); From 16afb0d0ba2f67f61f8027391440b9686479423f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 13 Oct 2015 12:11:55 -0700 Subject: [PATCH 09/29] fix distinct and cursor code --- .../com/google/gcloud/datastore/GqlQuery.java | 15 +- .../com/google/gcloud/datastore/Query.java | 2 +- .../gcloud/datastore/QueryResultsImpl.java | 4 + .../gcloud/datastore/StructuredQuery.java | 150 +++++++----------- .../gcloud/datastore/DatastoreTest.java | 7 +- .../gcloud/datastore/SerializationTest.java | 5 +- 6 files changed, 73 insertions(+), 110 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 2c02aa7b970c..8e023c0c224e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -20,6 +20,7 @@ import static com.google.gcloud.datastore.Validator.validateNamespace; import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; @@ -137,10 +138,8 @@ static Binding fromPb(com.google.datastore.v1beta3.GqlQueryParameter argPb) { switch (argPb.getParameterTypeCase()) { case CURSOR: return new Binding(new Cursor(argPb.getCursor())); - case VALUE: - return new Binding(Value.fromPb(argPb.getValue())); default: - return null; + return new Binding(Value.fromPb(argPb.getValue())); } } } @@ -398,16 +397,14 @@ private static GqlQuery fromPb( for (Map.Entry nameArg : queryPb.getNamedBindings().entrySet()) { Binding currBinding = Binding.fromPb(nameArg.getValue()); - if (currBinding != null) { - builder.namedBindings.put(nameArg.getKey(), currBinding); - } + Preconditions.checkState(currBinding != null); + builder.namedBindings.put(nameArg.getKey(), currBinding); } for (com.google.datastore.v1beta3.GqlQueryParameter numberArg : queryPb.getPositionalBindingsList()) { Binding currBinding = Binding.fromPb(numberArg); - if (currBinding != null) { - builder.positionalBindings.add(currBinding); - } + Preconditions.checkState(currBinding != null); + builder.positionalBindings.add(currBinding); } return builder.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index 6e962d92fb2f..c45efde3e30d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -62,7 +62,7 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = 1602329532153860907L; @Override protected Object convert(com.google.datastore.v1beta3.Entity entityPb) { - if (entityPb.getProperties().size() == 0) { + if (entityPb.getProperties().isEmpty()) { if (!entityPb.hasKey()) { return null; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index b3c51ceb9eeb..40f1aee9dc5e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -70,6 +70,10 @@ private void sendRequest() { entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); if (queryResultBatchPb.getSkippedResults() > 0) { cursor = queryResultBatchPb.getSkippedCursor(); + } else if (entityResultPbIter.hasNext()) { + cursor = queryResultBatchPb.getEntityResults(0).getCursor(); + } else { + cursor = queryResultBatchPb.getEndCursor(); } actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 7c1cf815879e..4151ae4b462c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -68,7 +68,7 @@ * .kind(kind) * .projection(Projection.property("age"), Projection.first("name")) * .filter(PropertyFilter.gt("age", 18)) - * .groupBy("age") + * .distinct("age") * .orderBy(OrderBy.asc("age")) * .limit(10) * .build(); @@ -86,9 +86,9 @@ public class StructuredQuery extends Query { private static final String KEY_PROPERTY_NAME = "__key__"; private final transient String kind; - private final ImmutableList projection; + private final ImmutableList projection; private final transient Filter filter; - private final ImmutableList groupBy; + private final ImmutableList distinctOn; private final transient ImmutableList orderBy; private final transient Cursor startCursor; private final transient Cursor endCursor; @@ -108,10 +108,8 @@ static Filter fromPb(com.google.datastore.v1beta3.Filter filterPb) { switch (filterPb.getFilterTypeCase()) { case COMPOSITE_FILTER: return CompositeFilter.fromPb(filterPb.getCompositeFilter()); - case PROPERTY_FILTER: - return PropertyFilter.fromPb(filterPb.getPropertyFilter()); default: - return null; + return PropertyFilter.fromPb(filterPb.getPropertyFilter()); } } } @@ -525,65 +523,15 @@ static OrderBy fromPb(com.google.datastore.v1beta3.PropertyOrder propertyOrderPb } } - public static final class Projection implements Serializable { - - private static final long serialVersionUID = 3083707957256279470L; - - private final String property; - - private Projection(String property) { - this.property = property; - } - - @Override - public int hashCode() { - return Objects.hash(property); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof Projection)) { - return false; - } - return Objects.equals(property, ((Projection) obj).property); - } - - @Override - public String toString() { - ToStringHelper toStringHelper = MoreObjects.toStringHelper(this); - toStringHelper.add("property", property); - return toStringHelper.toString(); - } - - com.google.datastore.v1beta3.Projection toPb() { - com.google.datastore.v1beta3.Projection.Builder expressionPb = - com.google.datastore.v1beta3.Projection.newBuilder(); - expressionPb.setProperty( - com.google.datastore.v1beta3.PropertyReference.newBuilder().setName(property).build()); - return expressionPb.build(); - } - - public static Projection fromPb( - com.google.datastore.v1beta3.Projection projectionPb) { - return new Projection(projectionPb.getProperty().getName()); - } - - public static Projection property(String property) { - return new Projection(property); - } - } - static class BaseBuilder> { private final ResultType resultType; private String namespace; private String kind; - private final List projection = new LinkedList<>(); + private final List projection = new LinkedList<>(); private Filter filter; - private final List groupBy = new LinkedList<>(); + private boolean distinctOnAll = false; + private final List distinctOn = new LinkedList<>(); private final List orderBy = new LinkedList<>(); private Cursor startCursor; private Cursor endCursor; @@ -658,32 +606,39 @@ B clearProjection() { return self(); } - B projection(Projection projection, Projection... others) { + B projection(String projection, String... others) { clearProjection(); addProjection(projection, others); return self(); } - B addProjection(Projection projection, Projection... others) { + B addProjection(String projection, String... others) { this.projection.add(projection); Collections.addAll(this.projection, others); return self(); } - B clearGroupBy() { - groupBy.clear(); + B clearDistinct() { + distinctOn.clear(); + distinctOnAll = false; return self(); } - B groupBy(String property, String... others) { - clearGroupBy(); - addGroupBy(property, others); + B distinct(String... properties) { + clearDistinct(); + if (properties.length == 0) { + this.distinctOnAll = true; + } else if (properties.length == 1) { + addDistinct(properties[0]); + } else { + addDistinct(properties[0], Arrays.copyOfRange(properties, 1, properties.length)); + } return self(); } - B addGroupBy(String property, String... others) { - this.groupBy.add(property); - Collections.addAll(this.groupBy, others); + B addDistinct(String property, String... others) { + this.distinctOn.add(property); + Collections.addAll(this.distinctOn, others); return self(); } @@ -712,15 +667,20 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { } for (com.google.datastore.v1beta3.Projection projectionPb : queryPb.getProjectionList()) { - addProjection(Projection.fromPb(projectionPb)); + addProjection(projectionPb.getProperty().getName()); } - for (com.google.datastore.v1beta3.PropertyReference groupByPb : queryPb.getDistinctOnList()) { - addGroupBy(groupByPb.getName()); + for (com.google.datastore.v1beta3.PropertyReference distinctOnPb : queryPb.getDistinctOnList()) { + addDistinct(distinctOnPb.getName()); } + distinctOnAll = false; return self(); } public StructuredQuery build() { + if (distinctOnAll) { + clearDistinct(); + this.distinctOn.addAll(this.projection); + } return new StructuredQuery<>(this); } } @@ -748,14 +708,14 @@ public static final class KeyQueryBuilder extends BaseBuilder projection() { + public List projection() { return projection; } @@ -865,8 +825,8 @@ public Filter filter() { return filter; } - public List groupBy() { - return groupBy; + public List distinct() { + return distinctOn; } public ImmutableList orderBy() { @@ -935,12 +895,16 @@ protected com.google.datastore.v1beta3.Query toPb() { for (OrderBy value : orderBy) { queryPb.addOrder(value.toPb()); } - for (String value : groupBy) { + for (String value : distinctOn) { queryPb.addDistinctOn(com.google.datastore.v1beta3.PropertyReference.newBuilder() .setName(value).build()); } - for (Projection value : projection) { - queryPb.addProjection(value.toPb()); + for (String value : projection) { + com.google.datastore.v1beta3.Projection.Builder expressionPb = + com.google.datastore.v1beta3.Projection.newBuilder(); + expressionPb.setProperty( + com.google.datastore.v1beta3.PropertyReference.newBuilder().setName(value).build()); + queryPb.addProjection(expressionPb.build()); } return queryPb.build(); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index e3a71d8a8aa2..41f0c4df8d92 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -29,7 +29,6 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; import com.google.gcloud.datastore.StructuredQuery.OrderBy; -import com.google.gcloud.datastore.StructuredQuery.Projection; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; import com.google.gcloud.spi.DatastoreRpc; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; @@ -421,7 +420,7 @@ public void testRunStructuredQuery() { StructuredQuery keyOnlyProjectionQuery = Query.projectionEntityQueryBuilder() - .kind(KIND1).projection(Projection.property("__key__")).build(); + .kind(KIND1).projection("__key__").build(); QueryResults results3 = datastore.run(keyOnlyProjectionQuery); assertTrue(results3.hasNext()); ProjectionEntity projectionEntity = results3.next(); @@ -431,9 +430,9 @@ public void testRunStructuredQuery() { StructuredQuery projectionQuery = Query.projectionEntityQueryBuilder() .kind(KIND2) - .projection(Projection.property("age")) + .projection("age") .filter(PropertyFilter.gt("age", 18)) - .groupBy("age") + .distinct("age") .orderBy(OrderBy.asc("age")) .limit(10) .build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 0c65ab76c681..d946246db279 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -26,7 +26,6 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.StructuredQuery.CompositeFilter; import com.google.gcloud.datastore.StructuredQuery.OrderBy; -import com.google.gcloud.datastore.StructuredQuery.Projection; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; import org.junit.Test; @@ -71,13 +70,13 @@ public class SerializationTest { private static final Query QUERY3 = Query.projectionEntityQueryBuilder() .kind("k") .namespace("ns1") - .projection(Projection.property("p")) + .projection("p") .limit(100) .offset(5) .startCursor(CURSOR1) .endCursor(CURSOR2) .filter(CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"))) - .addGroupBy("p") + .addDistinct("p") .addOrderBy(OrderBy.asc("p")) .build(); private static final KeyValue KEY_VALUE = KeyValue.of(KEY1); From acf2c4207f384d9e4d8f7ce958a1d7ac2263ff7a Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 14 Oct 2015 18:55:30 -0700 Subject: [PATCH 10/29] Include cursor workaround, fix distinct in StructuredQuery, and remove extra checks --- .../com/google/gcloud/datastore/GqlQuery.java | 7 +++---- .../gcloud/datastore/QueryResultsImpl.java | 14 ++++++------- .../gcloud/datastore/StructuredQuery.java | 20 ++++++++++--------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 8e023c0c224e..7fcb562fea89 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -20,7 +20,6 @@ import static com.google.gcloud.datastore.Validator.validateNamespace; import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; @@ -138,8 +137,10 @@ static Binding fromPb(com.google.datastore.v1beta3.GqlQueryParameter argPb) { switch (argPb.getParameterTypeCase()) { case CURSOR: return new Binding(new Cursor(argPb.getCursor())); - default: + case VALUE: return new Binding(Value.fromPb(argPb.getValue())); + default: + throw new AssertionError("Unexpected enum value " + argPb.getParameterTypeCase()); } } } @@ -397,13 +398,11 @@ private static GqlQuery fromPb( for (Map.Entry nameArg : queryPb.getNamedBindings().entrySet()) { Binding currBinding = Binding.fromPb(nameArg.getValue()); - Preconditions.checkState(currBinding != null); builder.namedBindings.put(nameArg.getKey(), currBinding); } for (com.google.datastore.v1beta3.GqlQueryParameter numberArg : queryPb.getPositionalBindingsList()) { Binding currBinding = Binding.fromPb(numberArg); - Preconditions.checkState(currBinding != null); builder.positionalBindings.add(currBinding); } return builder.build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index 40f1aee9dc5e..38eb3dd1c393 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -16,9 +16,9 @@ package com.google.gcloud.datastore; -import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType; import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; +import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType; import com.google.gcloud.datastore.Query.ResultType; import com.google.protobuf.ByteString; @@ -55,6 +55,11 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults } partitionIdPb = pbBuilder.build(); sendRequest(); + if (queryResultBatchPb.getSkippedResults() > 0) { + cursor = queryResultBatchPb.getSkippedCursor(); + } else { + cursor = ByteString.EMPTY; + } } private void sendRequest() { @@ -68,13 +73,6 @@ private void sendRequest() { queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); - if (queryResultBatchPb.getSkippedResults() > 0) { - cursor = queryResultBatchPb.getSkippedCursor(); - } else if (entityResultPbIter.hasNext()) { - cursor = queryResultBatchPb.getEntityResults(0).getCursor(); - } else { - cursor = queryResultBatchPb.getEndCursor(); - } actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) { // projection entity can represent all type of results diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 4151ae4b462c..c49ddddc9c02 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -108,8 +108,10 @@ static Filter fromPb(com.google.datastore.v1beta3.Filter filterPb) { switch (filterPb.getFilterTypeCase()) { case COMPOSITE_FILTER: return CompositeFilter.fromPb(filterPb.getCompositeFilter()); - default: + case PROPERTY_FILTER: return PropertyFilter.fromPb(filterPb.getPropertyFilter()); + default: + throw new AssertionError("Unexpected enum value " + filterPb.getFilterTypeCase()); } } } @@ -530,7 +532,7 @@ static class BaseBuilder> { private String kind; private final List projection = new LinkedList<>(); private Filter filter; - private boolean distinctOnAll = false; + private boolean distinct = false; private final List distinctOn = new LinkedList<>(); private final List orderBy = new LinkedList<>(); private Cursor startCursor; @@ -620,14 +622,16 @@ B addProjection(String projection, String... others) { B clearDistinct() { distinctOn.clear(); - distinctOnAll = false; + distinct = false; return self(); } B distinct(String... properties) { clearDistinct(); if (properties.length == 0) { - this.distinctOnAll = true; + clearDistinct(); + this.distinct = true; + this.distinctOn.addAll(this.projection); } else if (properties.length == 1) { addDistinct(properties[0]); } else { @@ -637,6 +641,9 @@ B distinct(String... properties) { } B addDistinct(String property, String... others) { + if (this.distinct) { + throw new IllegalStateException("\"distinct()\" is currently set."); + } this.distinctOn.add(property); Collections.addAll(this.distinctOn, others); return self(); @@ -672,15 +679,10 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { for (com.google.datastore.v1beta3.PropertyReference distinctOnPb : queryPb.getDistinctOnList()) { addDistinct(distinctOnPb.getName()); } - distinctOnAll = false; return self(); } public StructuredQuery build() { - if (distinctOnAll) { - clearDistinct(); - this.distinctOn.addAll(this.projection); - } return new StructuredQuery<>(this); } } From 0c2f9e93ffb78aadb55c3abf558e47c616336c18 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 15 Oct 2015 15:52:50 -0700 Subject: [PATCH 11/29] standardize distinctOn naming --- .../gcloud/datastore/StructuredQuery.java | 45 +++++++------------ .../gcloud/datastore/DatastoreTest.java | 17 +++---- .../gcloud/datastore/SerializationTest.java | 25 ++++++----- 3 files changed, 38 insertions(+), 49 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index c49ddddc9c02..1b82991cb8c8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -68,7 +68,7 @@ * .kind(kind) * .projection(Projection.property("age"), Projection.first("name")) * .filter(PropertyFilter.gt("age", 18)) - * .distinct("age") + * .distinctOn("age") * .orderBy(OrderBy.asc("age")) * .limit(10) * .build(); @@ -532,7 +532,6 @@ static class BaseBuilder> { private String kind; private final List projection = new LinkedList<>(); private Filter filter; - private boolean distinct = false; private final List distinctOn = new LinkedList<>(); private final List orderBy = new LinkedList<>(); private Cursor startCursor; @@ -620,30 +619,18 @@ B addProjection(String projection, String... others) { return self(); } - B clearDistinct() { + B clearDistinctOn() { distinctOn.clear(); - distinct = false; return self(); } - B distinct(String... properties) { - clearDistinct(); - if (properties.length == 0) { - clearDistinct(); - this.distinct = true; - this.distinctOn.addAll(this.projection); - } else if (properties.length == 1) { - addDistinct(properties[0]); - } else { - addDistinct(properties[0], Arrays.copyOfRange(properties, 1, properties.length)); - } + B distinctOn(String property, String... others) { + clearDistinctOn(); + addDistinctOn(property, others); return self(); } - B addDistinct(String property, String... others) { - if (this.distinct) { - throw new IllegalStateException("\"distinct()\" is currently set."); - } + B addDistinctOn(String property, String... others) { this.distinctOn.add(property); Collections.addAll(this.distinctOn, others); return self(); @@ -677,7 +664,7 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { addProjection(projectionPb.getProperty().getName()); } for (com.google.datastore.v1beta3.PropertyReference distinctOnPb : queryPb.getDistinctOnList()) { - addDistinct(distinctOnPb.getName()); + addDistinctOn(distinctOnPb.getName()); } return self(); } @@ -717,7 +704,7 @@ public static final class KeyQueryBuilder extends BaseBuilder distinct() { + public List distinctOn() { return distinctOn; } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 41f0c4df8d92..f0fbd4ab96c0 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -428,14 +428,15 @@ public void testRunStructuredQuery() { assertTrue(projectionEntity.names().isEmpty()); assertFalse(results2.hasNext()); - StructuredQuery projectionQuery = Query.projectionEntityQueryBuilder() - .kind(KIND2) - .projection("age") - .filter(PropertyFilter.gt("age", 18)) - .distinct("age") - .orderBy(OrderBy.asc("age")) - .limit(10) - .build(); + StructuredQuery projectionQuery = + Query.projectionEntityQueryBuilder() + .kind(KIND2) + .projection("age") + .filter(PropertyFilter.gt("age", 18)) + .distinctOn("age") + .orderBy(OrderBy.asc("age")) + .limit(10) + .build(); QueryResults results4 = datastore.run(projectionQuery); assertTrue(results4.hasNext()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index d946246db279..2e083250f35e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -67,18 +67,19 @@ public class SerializationTest { .kind("k") .filter(PropertyFilter.eq("p1", "hello")) .build(); - private static final Query QUERY3 = Query.projectionEntityQueryBuilder() - .kind("k") - .namespace("ns1") - .projection("p") - .limit(100) - .offset(5) - .startCursor(CURSOR1) - .endCursor(CURSOR2) - .filter(CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"))) - .addDistinct("p") - .addOrderBy(OrderBy.asc("p")) - .build(); + private static final Query QUERY3 = + Query.projectionEntityQueryBuilder() + .kind("k") + .namespace("ns1") + .projection("p") + .limit(100) + .offset(5) + .startCursor(CURSOR1) + .endCursor(CURSOR2) + .filter(CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"))) + .addDistinctOn("p") + .addOrderBy(OrderBy.asc("p")) + .build(); private static final KeyValue KEY_VALUE = KeyValue.of(KEY1); private static final NullValue NULL_VALUE = NullValue.builder().excludeFromIndexes(true).build(); private static final StringValue STRING_VALUE = StringValue.of("hello"); From 35ea69a5a4102de920f7732b52e29ebc8372d974 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 16 Oct 2015 11:06:08 -0700 Subject: [PATCH 12/29] Add missing case for start_cursor --- .../com/google/gcloud/datastore/QueryResultsImpl.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index 38eb3dd1c393..bb2b65fcc646 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -34,6 +34,7 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults private Query query; private ResultType actualResultType; private com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb; + private com.google.datastore.v1beta3.Query mostRecentQueryPb; private boolean lastBatch; private Iterator entityResultPbIter; private ByteString cursor; @@ -58,7 +59,7 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults if (queryResultBatchPb.getSkippedResults() > 0) { cursor = queryResultBatchPb.getSkippedCursor(); } else { - cursor = ByteString.EMPTY; + cursor = mostRecentQueryPb.getStartCursor(); } } @@ -70,7 +71,13 @@ private void sendRequest() { } requestPb.setPartitionId(partitionIdPb); query.populatePb(requestPb); - queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); + com.google.datastore.v1beta3.RunQueryResponse runQueryResponsePb = + datastore.runQuery(requestPb.build()); + queryResultBatchPb = runQueryResponsePb.getBatch(); + mostRecentQueryPb = runQueryResponsePb.getQuery(); + if (mostRecentQueryPb == null) { + mostRecentQueryPb = requestPb.getQuery(); + } lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); From 02a56a831bd04734dd171a553dc569637d2059c6 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 16 Oct 2015 14:47:39 -0700 Subject: [PATCH 13/29] Don't allow user to set project id or namespace to null --- .../src/main/java/com/google/gcloud/ServiceOptions.java | 3 ++- .../src/main/java/com/google/gcloud/datastore/KeyFactory.java | 2 +- .../src/main/java/com/google/gcloud/datastore/Validator.java | 4 +--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 206e1fecaa58..066116e59c2f 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -122,7 +122,8 @@ protected B self() { } public B projectId(String projectId) { - this.projectId = projectId; + this.projectId = + checkNotNull(projectId, "Project ID cannot be set to null. Leave unset for default."); return self(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java index c5b9d77a8cd7..7d645cf21945 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java @@ -29,7 +29,7 @@ public final class KeyFactory extends BaseKey.Builder { private final String ns; public KeyFactory(String projectId) { - this(projectId, null); + this(projectId, ""); } public KeyFactory(String projectId, String namespace) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java index 791adec53101..dc7069cebf62 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java @@ -45,9 +45,7 @@ static String validateDatabase(String projectId) { } static String validateNamespace(String namespace) { - if (Strings.isNullOrEmpty(namespace)) { - return ""; - } + checkArgument(namespace != null, "Namespace cannot be null. Leave unset for default."); checkArgument(namespace.length() <= MAX_NAMESPACE_LENGTH, "namespace must not contain more than 100 characters"); checkArgument(NAMESPACE_PATTERN.matcher(namespace).matches(), From a98d09640198c6d7effb6a8379a915664fb41b3f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 16 Oct 2015 16:52:28 -0700 Subject: [PATCH 14/29] remove extra firstNonNull in KeyFactory --- .../src/main/java/com/google/gcloud/datastore/KeyFactory.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java index 7d645cf21945..7c4efb91762d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java @@ -16,7 +16,6 @@ package com.google.gcloud.datastore; -import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; /** @@ -36,7 +35,7 @@ public KeyFactory(String projectId, String namespace) { super(projectId); namespace(namespace); this.pi = projectId; - this.ns = MoreObjects.firstNonNull(namespace, ""); + this.ns = namespace; } public IncompleteKey newKey() { From f6eedddbb5d0f8a297633a524cf0eee08046c53c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 19 Oct 2015 13:08:54 -0700 Subject: [PATCH 15/29] Support GeoPoint value in Datastore v1beta3 --- .../google/gcloud/datastore/BaseEntity.java | 17 ++++ .../com/google/gcloud/datastore/GeoPoint.java | 83 ++++++++++++++++++ .../gcloud/datastore/GeoPointValue.java | 84 +++++++++++++++++++ .../com/google/gcloud/datastore/GqlQuery.java | 10 +++ .../gcloud/datastore/StructuredQuery.java | 5 ++ .../google/gcloud/datastore/ValueType.java | 6 +- .../gcloud/datastore/BaseEntityTest.java | 21 +++-- .../gcloud/datastore/DatastoreTest.java | 28 ++++--- .../google/gcloud/datastore/GeoPointTest.java | 77 +++++++++++++++++ .../gcloud/datastore/GeoPointValueTest.java | 52 ++++++++++++ .../gcloud/datastore/SerializationTest.java | 38 ++++----- .../google/gcloud/datastore/ValueTest.java | 2 + 12 files changed, 384 insertions(+), 39 deletions(-) create mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java create mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java create mode 100644 gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java create mode 100644 gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 97718e708e83..06ed0f419ac7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -21,6 +21,7 @@ import static com.google.gcloud.datastore.DateTimeValue.of; import static com.google.gcloud.datastore.DoubleValue.of; import static com.google.gcloud.datastore.EntityValue.of; +import static com.google.gcloud.datastore.GeoPointValue.of; import static com.google.gcloud.datastore.KeyValue.of; import static com.google.gcloud.datastore.ListValue.of; import static com.google.gcloud.datastore.LongValue.of; @@ -159,6 +160,11 @@ public B set(String name, DateTime value) { return self(); } + public B set(String name, GeoPoint value) { + properties.put(name, of(value)); + return self(); + } + public B set(String name, Key value) { properties.put(name, of(value)); return self(); @@ -320,6 +326,17 @@ public DateTime getDateTime(String name) { return ((Value) getValue(name)).get(); } + /** + * Returns the property value as a GeoPoint. + * + * @throws DatastoreException if not such property. + * @throws ClassCastException if value is not a GeoPoint. + */ + @SuppressWarnings("unchecked") + public GeoPoint getGeoPoint(String name) { + return ((Value) getValue(name)).get(); + } + /** * Returns the property value as a Key. * diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java new file mode 100644 index 000000000000..5d7d87ebc121 --- /dev/null +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.datastore; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.protobuf.InvalidProtocolBufferException; + +import java.util.Objects; + +/** + * A Google Cloud Datastore GeoPoint (represented by latitude and longitude in degrees). + * This class is immutable. + * + * @see Google Cloud Datastore + * Entities, Properties, and Keys + */ +public final class GeoPoint extends Serializable { + + private static final long serialVersionUID = 9077060962655752073L; + + private final transient double latitude; + private final transient double longitude; + + GeoPoint(double latitude, double longitude) { + checkArgument( + latitude >= -90.0 && latitude <= 90.0, "latitude must be in the range [-90, 90] degrees"); + checkArgument( + longitude >= -180.0 && longitude <= 180.0, + "latitude must be in the range [-180, 180] degrees"); + this.latitude = latitude; + this.longitude = longitude; + } + + @Override + public String toString() { + return Double.toString(latitude) + ", " + Double.toString(longitude); + } + + @Override + public int hashCode() { + return Objects.hash(latitude, longitude); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || (obj instanceof GeoPoint && new Double(this.latitude).equals(((GeoPoint) obj).latitude)) + && new Double(this.longitude).equals(((GeoPoint) obj).longitude); + } + + public static GeoPoint of(double latitude, double longitude) { + return new GeoPoint(latitude, longitude); + } + + @Override + protected com.google.type.LatLng toPb() { + return com.google.type.LatLng.newBuilder() + .setLatitude(latitude) + .setLongitude(longitude) + .build(); + } + + @Override + protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { + com.google.type.LatLng parsedLatLng = com.google.type.LatLng.parseFrom(bytesPb); + return new GeoPoint(parsedLatLng.getLatitude(), parsedLatLng.getLongitude()); + } +} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java new file mode 100644 index 000000000000..0f6b5c2003e6 --- /dev/null +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.datastore; + +import static com.google.datastore.v1beta3.Value.GEO_POINT_VALUE_FIELD_NUMBER; + +public final class GeoPointValue extends Value { + + private static final long serialVersionUID = -5810614280642405898L; + + static final BaseMarshaller MARSHALLER = + new BaseMarshaller() { + + private static final long serialVersionUID = -3550567536035178649L; + + @Override + public int getProtoFieldId() { + return GEO_POINT_VALUE_FIELD_NUMBER; + } + + @Override + public Builder newBuilder(GeoPoint value) { + return builder(value); + } + + @Override + protected GeoPoint getValue(com.google.datastore.v1beta3.Value from) { + return new GeoPoint( + from.getGeoPointValue().getLatitude(), from.getGeoPointValue().getLongitude()); + } + + @Override + protected void setValue(GeoPointValue from, com.google.datastore.v1beta3.Value.Builder to) { + to.setGeoPointValue(from.get().toPb()); + } + }; + + public static final class Builder extends Value.BaseBuilder { + + private Builder() { + super(ValueType.GEO_POINT); + } + + @Override + public GeoPointValue build() { + return new GeoPointValue(this); + } + } + + public GeoPointValue(GeoPoint value) { + this(builder(value)); + } + + private GeoPointValue(Builder builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new Builder().mergeFrom(this); + } + + public static GeoPointValue of(GeoPoint value) { + return new GeoPointValue(value); + } + + public static Builder builder(GeoPoint value) { + return new Builder().set(value); + } +} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 7fcb562fea89..2205c7c270a3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -212,6 +212,11 @@ public Builder setBinding(String name, DateTime... value) { namedBindings.put(name, toBinding(DateTimeValue.MARSHALLER, Arrays.asList(value))); return this; } + + public Builder setBinding(String name, GeoPoint... value) { + namedBindings.put(name, toBinding(GeoPointValue.MARSHALLER, Arrays.asList(value))); + return this; + } public Builder setBinding(String name, Key... value) { namedBindings.put(name, toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); @@ -258,6 +263,11 @@ public Builder addBinding(DateTime... value) { return this; } + public Builder addBinding(GeoPoint... value) { + positionalBindings.add(toBinding(GeoPointValue.MARSHALLER, Arrays.asList(value))); + return this; + } + public Builder addBinding(Key... value) { positionalBindings.add(toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); return this; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 1b82991cb8c8..87f92f6d05b4 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -21,6 +21,7 @@ import static com.google.gcloud.datastore.BooleanValue.of; import static com.google.gcloud.datastore.DateTimeValue.of; import static com.google.gcloud.datastore.DoubleValue.of; +import static com.google.gcloud.datastore.GeoPointValue.of; import static com.google.gcloud.datastore.KeyValue.of; import static com.google.gcloud.datastore.LongValue.of; import static com.google.gcloud.datastore.StringValue.of; @@ -420,6 +421,10 @@ public static PropertyFilter eq(String property, DateTime value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } + public static PropertyFilter eq(String property, GeoPoint value) { + return new PropertyFilter(property, Operator.EQUAL, of(value)); + } + public static PropertyFilter eq(String property, Key value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java index 20c89a86e7a0..8326001c8fbc 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java @@ -78,12 +78,12 @@ public enum ValueType { /** * Represents a raw/unparsed value. */ - RAW_VALUE(RawValue.MARSHALLER); + RAW_VALUE(RawValue.MARSHALLER), /** - * TODO(ajaykannan): add GEO_POINT_VALUE - * Will represent a geolocation value in latitude/longitude + * Represents a {@link GeoPoint} value */ + GEO_POINT(GeoPointValue.MARSHALLER); private static final ImmutableMap DESCRIPTOR_TO_TYPE_MAP; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java index 5ece01508d3a..8053b2d80b1d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java @@ -35,6 +35,7 @@ public class BaseEntityTest { private static final Blob BLOB = Blob.copyFrom(new byte[]{1, 2}); private static final DateTime DATE_TIME = DateTime.now(); + private static final GeoPoint GEO_POINT = new GeoPoint(30.5, -40.5); private static final Key KEY = Key.builder("ds1", "k1", "n1").build(); private static final Entity ENTITY = Entity.builder(KEY).set("name", "foo").build(); private static final IncompleteKey INCOMPLETE_KEY = IncompleteKey.builder("ds1", "k1").build(); @@ -62,9 +63,9 @@ public void setUp() { builder = new Builder(); builder.set("blob", BLOB).set("boolean", true).set("dateTime", DATE_TIME); builder.set("double", 1.25).set("key", KEY).set("string", "hello world"); - builder.set("long", 125).setNull("null").set("entity", ENTITY); + builder.set("long", 125).setNull("null").set("entity", ENTITY).set("geoPoint", GEO_POINT); builder.set("partialEntity", PARTIAL_ENTITY).set("stringValue", StringValue.of("bla")); - builder.set("list1", NullValue.of(), StringValue.of("foo")); + builder.set("list1", NullValue.of(), StringValue.of("foo"), GeoPointValue.of(GEO_POINT)); builder.set("list2", ImmutableList.of(LongValue.of(10), DoubleValue.of(2))); builder.set("list3", Collections.singletonList(BooleanValue.of(true))); } @@ -149,6 +150,12 @@ public void testGetDateTime() throws Exception { assertEquals(dateTime, entity.getDateTime("dateTime")); } + @Test + public void testGetGeoPoint() throws Exception { + BaseEntity entity = builder.build(); + assertEquals(GEO_POINT, entity.getGeoPoint("geoPoint")); + } + @Test public void testGetKey() throws Exception { BaseEntity entity = builder.build(); @@ -171,9 +178,10 @@ public void testGetEntity() throws Exception { public void testGetList() throws Exception { BaseEntity entity = builder.build(); List> list = entity.getList("list1"); - assertEquals(2, list.size()); + assertEquals(3, list.size()); assertEquals(NullValue.of(), list.get(0)); assertEquals("foo", list.get(1).get()); + assertEquals(GEO_POINT, list.get(2).get()); list = entity.getList("list2"); assertEquals(2, list.size()); assertEquals(Long.valueOf(10), list.get(0).get()); @@ -196,9 +204,10 @@ public void testGetBlob() throws Exception { @Test public void testNames() throws Exception { - Set names = ImmutableSet.builder() - .add("string", "stringValue", "boolean", "double", "long", "list1", "list2", "list3") - .add("entity", "partialEntity", "null", "dateTime", "blob", "key") + Set names = + ImmutableSet.builder() + .add("string", "stringValue", "boolean", "double", "long", "list1", "list2", "list3") + .add("entity", "partialEntity", "null", "dateTime", "geoPoint", "blob", "key") .build(); BaseEntity entity = builder.build(); assertEquals(names, entity.names()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index f0fbd4ab96c0..320c4f3d67c8 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -74,6 +74,7 @@ public class DatastoreTest { .build(); private static final ListValue LIST_VALUE2 = ListValue.of(Collections.singletonList(KEY_VALUE)); private static final DateTimeValue DATE_TIME_VALUE = new DateTimeValue(DateTime.now()); + private static final GeoPointValue GEO_POINT_VALUE = new GeoPointValue(new GeoPoint(30.5, 40.5)); private static final FullEntity PARTIAL_ENTITY1 = FullEntity.builder(INCOMPLETE_KEY2).set("str", STR_VALUE).set("bool", BOOL_VALUE) .set("list", LIST_VALUE1).build(); @@ -83,13 +84,15 @@ public class DatastoreTest { private static final FullEntity PARTIAL_ENTITY3 = FullEntity.builder(PARTIAL_ENTITY1).key(IncompleteKey.builder(PROJECT_ID, KIND3).build()) .build(); - private static final Entity ENTITY1 = Entity.builder(KEY1) - .set("str", STR_VALUE) - .set("date", DATE_TIME_VALUE) - .set("bool", BOOL_VALUE) - .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) - .set("list", LIST_VALUE2) - .build(); + private static final Entity ENTITY1 = + Entity.builder(KEY1) + .set("str", STR_VALUE) + .set("date", DATE_TIME_VALUE) + .set("geoPoint", GEO_POINT_VALUE) + .set("bool", BOOL_VALUE) + .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) + .set("list", LIST_VALUE2) + .build(); private static final Entity ENTITY2 = Entity.builder(ENTITY1).key(KEY2).remove("str") .set("name", "Dan").setNull("null").set("age", 20).build(); private static final Entity ENTITY3 = Entity.builder(ENTITY1).key(KEY3).remove("str") @@ -504,9 +507,11 @@ public void testGet() { assertEquals(LIST_VALUE2, value3); DateTimeValue value4 = entity.getValue("date"); assertEquals(DATE_TIME_VALUE, value4); - FullEntity value5 = entity.getEntity("partial1"); - assertEquals(PARTIAL_ENTITY1, value5); - assertEquals(5, entity.names().size()); + GeoPointValue value5 = entity.getValue("geoPoint"); + assertEquals(GEO_POINT_VALUE, value5); + FullEntity value6 = entity.getEntity("partial1"); + assertEquals(PARTIAL_ENTITY1, value6); + assertEquals(6, entity.names().size()); assertFalse(entity.contains("bla")); } @@ -528,7 +533,8 @@ public void testGetArray() { assertEquals(PARTIAL_ENTITY2, partial1); assertEquals(ENTITY2, partial2); assertEquals(ValueType.BOOLEAN, entity3.getValue("bool").type()); - assertEquals(6, entity3.names().size()); + assertEquals(GEO_POINT_VALUE, entity3.getValue("geoPoint")); + assertEquals(7, entity3.names().size()); assertFalse(entity3.contains("bla")); try { entity3.getString("str"); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java new file mode 100644 index 000000000000..61bcf0fd4f26 --- /dev/null +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.datastore; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class GeoPointTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private static GeoPoint gp1 = new GeoPoint(10.5, 20.5); + private static GeoPoint gp2 = new GeoPoint(10.5, 30.5); + + private static final String INVALID_LAT_MESSAGE = + "latitude must be in the range [-90, 90] degrees"; + private static final String INVALID_LNG_MESSAGE = + "latitude must be in the range [-180, 180] degrees"; + + @Test + public void testEquals() { + assertEquals(gp1, gp1); + assertNotEquals(gp1, gp2); + } + + @Test + public void testUpperLatRange() { + new GeoPoint(90, 0); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(INVALID_LAT_MESSAGE); + new GeoPoint(91, 0); + } + + @Test + public void testLowerLatRange() { + new GeoPoint(-90, 0); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(INVALID_LAT_MESSAGE); + new GeoPoint(-91, 0); + } + + @Test + public void testUpperLngRange() { + new GeoPoint(0, 180); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(INVALID_LNG_MESSAGE); + new GeoPoint(0, 181); + } + + @Test + public void testLowerLngRange() { + new GeoPoint(0, 180); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(INVALID_LNG_MESSAGE); + new GeoPoint(0, -181); + } +} + diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java new file mode 100644 index 000000000000..82380efca8d3 --- /dev/null +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.datastore; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class GeoPointValueTest { + +private static final GeoPoint CONTENT = new GeoPoint(37.4, -122.1); + + @Test + public void testToBuilder() throws Exception { + GeoPointValue value = GeoPointValue.of(CONTENT); + assertEquals(value, value.toBuilder().build()); + } + + @SuppressWarnings("deprecation") + @Test + public void testOf() throws Exception { + GeoPointValue value = GeoPointValue.of(CONTENT); + assertEquals(CONTENT, value.get()); + assertFalse(value.excludeFromIndexes()); + } + + @SuppressWarnings("deprecation") + @Test + public void testBuilder() throws Exception { + GeoPointValue.Builder builder = GeoPointValue.builder(CONTENT); + GeoPointValue value = builder.meaning(1).excludeFromIndexes(true).build(); + assertEquals(CONTENT, value.get()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); + } +} diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 2e083250f35e..fe2be0a04b76 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -45,6 +45,7 @@ public class SerializationTest { IncompleteKey.builder(KEY1, "v").ancestors(PathElement.of("p", 1)).build(); private static final Key KEY2 = Key.builder(KEY1, "v", 2).build(); private static final DateTime DATE_TIME1 = DateTime.now(); + private static final GeoPoint GEO_POINT = new GeoPoint(30.5, 40.5); private static final Blob BLOB1 = Blob.copyFrom(UTF_8.encode("hello world")); private static final Cursor CURSOR1 = Cursor.copyFrom(new byte[] {1,2}); private static final Cursor CURSOR2 = Cursor.copyFrom(new byte[]{10}); @@ -89,10 +90,8 @@ public class SerializationTest { private static final DateTimeValue DATE_AND_TIME_VALUE = DateTimeValue.of(DateTime.now()); private static final BlobValue BLOB_VALUE = BlobValue.of(BLOB1); private static final RawValue RAW_VALUE = - RawValue.of(com.google.datastore.v1beta3.Value.newBuilder() - .setGeoPointValue(com.google.type.LatLng.newBuilder() - .setLatitude(0.0).setLongitude(0.0).build()) - .setMeaning(18).build()); + RawValue.of(com.google.datastore.v1beta3.Value.newBuilder().setMeaning(18).build()); + private static final GeoPointValue GEO_POINT_VALUE = GeoPointValue.of(GEO_POINT); private static final Entity ENTITY1 = Entity.builder(KEY1).build(); private static final Entity ENTITY2 = Entity.builder(KEY2).set("null", NullValue.of()).build(); @@ -119,19 +118,20 @@ public class SerializationTest { @SuppressWarnings("rawtypes") private static final Multimap TYPE_TO_VALUES = ImmutableMultimap.builder() - .put(ValueType.NULL, NULL_VALUE) - .put(ValueType.KEY, KEY_VALUE) - .put(ValueType.STRING, STRING_VALUE) - .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, - EMBEDDED_ENTITY_VALUE3) - .put(ValueType.LIST, LIST_VALUE) - .put(ValueType.LONG, LONG_VALUE) - .put(ValueType.DOUBLE, DOUBLE_VALUE) - .put(ValueType.BOOLEAN, BOOLEAN_VALUE) - .put(ValueType.DATE_TIME, DATE_AND_TIME_VALUE) - .put(ValueType.BLOB, BLOB_VALUE) - .put(ValueType.RAW_VALUE, RAW_VALUE) - .build(); + .put(ValueType.NULL, NULL_VALUE) + .put(ValueType.KEY, KEY_VALUE) + .put(ValueType.STRING, STRING_VALUE) + .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, + EMBEDDED_ENTITY_VALUE3) + .put(ValueType.LIST, LIST_VALUE) + .put(ValueType.LONG, LONG_VALUE) + .put(ValueType.DOUBLE, DOUBLE_VALUE) + .put(ValueType.BOOLEAN, BOOLEAN_VALUE) + .put(ValueType.DATE_TIME, DATE_AND_TIME_VALUE) + .put(ValueType.BLOB, BLOB_VALUE) + .put(ValueType.RAW_VALUE, RAW_VALUE) + .put(ValueType.GEO_POINT, GEO_POINT_VALUE) + .build(); @Test public void testServiceOptions() throws Exception { @@ -169,8 +169,8 @@ public void testValues() throws Exception { @Test public void testTypes() throws Exception { Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, GQL2, - QUERY1, QUERY2, QUERY3}; + ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, GEO_POINT, CURSOR1, GQL1, + GQL2, QUERY1, QUERY2, QUERY3}; for (Serializable obj : types) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java index 12908add4c8e..771b3c556a12 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java @@ -41,6 +41,7 @@ public class ValueTest { private static final NullValue NULL_VALUE = NullValue.of(); private static final StringValue STRING_VALUE = StringValue.of("hello"); private static final RawValue RAW_VALUE = RawValue.of(STRING_VALUE.toPb()); + private static final GeoPointValue GEO_POINT_VALUE = GeoPointValue.of(new GeoPoint(30.5, 40.5)); private static final ImmutableMap TYPES = ImmutableMap.builder() .put(ValueType.NULL, new Object[] {NullValue.class, NULL_VALUE.get()}) .put(ValueType.KEY, new Object[] {KeyValue.class, KEY}) @@ -53,6 +54,7 @@ public class ValueTest { new Object[] {ListValue.class, ImmutableList.of(NULL_VALUE, STRING_VALUE, RAW_VALUE)}) .put(ValueType.LONG, new Object[] {LongValue.class, 123L}) .put(ValueType.RAW_VALUE, new Object[] {RawValue.class, RAW_VALUE.get()}) + .put(ValueType.GEO_POINT, new Object[] {GeoPointValue.class, GEO_POINT_VALUE.get()}) .put(ValueType.STRING, new Object[] {StringValue.class, STRING_VALUE.get()}) .build(); From 3ccc7ed1660a1cc5eb0853bbdd2a38ba10e996e8 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 19 Oct 2015 17:01:57 -0700 Subject: [PATCH 16/29] Add getters, remove filtering --- .../java/com/google/gcloud/datastore/GeoPoint.java | 13 ++++++++++--- .../java/com/google/gcloud/datastore/GqlQuery.java | 10 ---------- .../google/gcloud/datastore/StructuredQuery.java | 5 ----- .../com/google/gcloud/datastore/BaseEntityTest.java | 2 +- .../com/google/gcloud/datastore/DatastoreTest.java | 3 ++- .../com/google/gcloud/datastore/GeoPointTest.java | 4 ++-- .../google/gcloud/datastore/SerializationTest.java | 2 +- 7 files changed, 16 insertions(+), 23 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java index 5d7d87ebc121..39dde9a9f85b 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java @@ -46,6 +46,14 @@ public final class GeoPoint extends Serializable { this.longitude = longitude; } + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + @Override public String toString() { return Double.toString(latitude) + ", " + Double.toString(longitude); @@ -58,9 +66,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj == this - || (obj instanceof GeoPoint && new Double(this.latitude).equals(((GeoPoint) obj).latitude)) - && new Double(this.longitude).equals(((GeoPoint) obj).longitude); + return obj == this || (obj instanceof GeoPoint && this.latitude == ((GeoPoint) obj).latitude + && this.longitude == ((GeoPoint) obj).longitude); } public static GeoPoint of(double latitude, double longitude) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 2205c7c270a3..7fcb562fea89 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -212,11 +212,6 @@ public Builder setBinding(String name, DateTime... value) { namedBindings.put(name, toBinding(DateTimeValue.MARSHALLER, Arrays.asList(value))); return this; } - - public Builder setBinding(String name, GeoPoint... value) { - namedBindings.put(name, toBinding(GeoPointValue.MARSHALLER, Arrays.asList(value))); - return this; - } public Builder setBinding(String name, Key... value) { namedBindings.put(name, toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); @@ -263,11 +258,6 @@ public Builder addBinding(DateTime... value) { return this; } - public Builder addBinding(GeoPoint... value) { - positionalBindings.add(toBinding(GeoPointValue.MARSHALLER, Arrays.asList(value))); - return this; - } - public Builder addBinding(Key... value) { positionalBindings.add(toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); return this; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 87f92f6d05b4..1b82991cb8c8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -21,7 +21,6 @@ import static com.google.gcloud.datastore.BooleanValue.of; import static com.google.gcloud.datastore.DateTimeValue.of; import static com.google.gcloud.datastore.DoubleValue.of; -import static com.google.gcloud.datastore.GeoPointValue.of; import static com.google.gcloud.datastore.KeyValue.of; import static com.google.gcloud.datastore.LongValue.of; import static com.google.gcloud.datastore.StringValue.of; @@ -421,10 +420,6 @@ public static PropertyFilter eq(String property, DateTime value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } - public static PropertyFilter eq(String property, GeoPoint value) { - return new PropertyFilter(property, Operator.EQUAL, of(value)); - } - public static PropertyFilter eq(String property, Key value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java index 8053b2d80b1d..5ca68bf848ce 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java @@ -35,7 +35,7 @@ public class BaseEntityTest { private static final Blob BLOB = Blob.copyFrom(new byte[]{1, 2}); private static final DateTime DATE_TIME = DateTime.now(); - private static final GeoPoint GEO_POINT = new GeoPoint(30.5, -40.5); + private static final GeoPoint GEO_POINT = new GeoPoint(37.422035, -122.084124); private static final Key KEY = Key.builder("ds1", "k1", "n1").build(); private static final Entity ENTITY = Entity.builder(KEY).set("name", "foo").build(); private static final IncompleteKey INCOMPLETE_KEY = IncompleteKey.builder("ds1", "k1").build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 320c4f3d67c8..c890a6b67aa8 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -74,7 +74,8 @@ public class DatastoreTest { .build(); private static final ListValue LIST_VALUE2 = ListValue.of(Collections.singletonList(KEY_VALUE)); private static final DateTimeValue DATE_TIME_VALUE = new DateTimeValue(DateTime.now()); - private static final GeoPointValue GEO_POINT_VALUE = new GeoPointValue(new GeoPoint(30.5, 40.5)); + private static final GeoPointValue GEO_POINT_VALUE = + new GeoPointValue(new GeoPoint(37.422035, -122.084124)); private static final FullEntity PARTIAL_ENTITY1 = FullEntity.builder(INCOMPLETE_KEY2).set("str", STR_VALUE).set("bool", BOOL_VALUE) .set("list", LIST_VALUE1).build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java index 61bcf0fd4f26..2f076d915c15 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java @@ -28,8 +28,8 @@ public class GeoPointTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private static GeoPoint gp1 = new GeoPoint(10.5, 20.5); - private static GeoPoint gp2 = new GeoPoint(10.5, 30.5); + private static GeoPoint gp1 = new GeoPoint(37.422035, -122.084124); + private static GeoPoint gp2 = new GeoPoint(0.0, 0.0); private static final String INVALID_LAT_MESSAGE = "latitude must be in the range [-90, 90] degrees"; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index fe2be0a04b76..b2ee24862688 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -45,7 +45,7 @@ public class SerializationTest { IncompleteKey.builder(KEY1, "v").ancestors(PathElement.of("p", 1)).build(); private static final Key KEY2 = Key.builder(KEY1, "v", 2).build(); private static final DateTime DATE_TIME1 = DateTime.now(); - private static final GeoPoint GEO_POINT = new GeoPoint(30.5, 40.5); + private static final GeoPoint GEO_POINT = new GeoPoint(37.422035, -122.084124); private static final Blob BLOB1 = Blob.copyFrom(UTF_8.encode("hello world")); private static final Cursor CURSOR1 = Cursor.copyFrom(new byte[] {1,2}); private static final Cursor CURSOR2 = Cursor.copyFrom(new byte[]{10}); From d75b0da95b0da4419423a56c437830e668ebbcc6 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 19 Oct 2015 19:43:47 -0700 Subject: [PATCH 17/29] rename accessors in geopoint --- .../src/main/java/com/google/gcloud/datastore/GeoPoint.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java index 39dde9a9f85b..34532a30d927 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java @@ -46,11 +46,11 @@ public final class GeoPoint extends Serializable { this.longitude = longitude; } - public double getLatitude() { + public double latitude() { return latitude; } - public double getLongitude() { + public double longitude() { return longitude; } From 241960f2a24d4dbec27288589ccf72f91c431816 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 20 Oct 2015 08:27:04 -0700 Subject: [PATCH 18/29] rename geopoint to latlng --- .../google/gcloud/datastore/BaseEntity.java | 12 +++---- .../datastore/{GeoPoint.java => LatLng.java} | 16 ++++----- .../{GeoPointValue.java => LatLngValue.java} | 32 ++++++++--------- .../google/gcloud/datastore/ValueType.java | 4 +-- .../gcloud/datastore/BaseEntityTest.java | 14 ++++---- .../gcloud/datastore/DatastoreTest.java | 12 +++---- .../{GeoPointTest.java => LatLngTest.java} | 22 ++++++------ ...intValueTest.java => LatLngValueTest.java} | 12 +++---- .../gcloud/datastore/SerializationTest.java | 8 ++--- .../google/gcloud/datastore/ValueTest.java | 34 ++++++++++--------- 10 files changed, 84 insertions(+), 82 deletions(-) rename gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/{GeoPoint.java => LatLng.java} (79%) rename gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/{GeoPointValue.java => LatLngValue.java} (63%) rename gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/{GeoPointTest.java => LatLngTest.java} (83%) rename gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/{GeoPointValueTest.java => LatLngValueTest.java} (78%) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 06ed0f419ac7..1846c2a0e7ae 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -21,7 +21,7 @@ import static com.google.gcloud.datastore.DateTimeValue.of; import static com.google.gcloud.datastore.DoubleValue.of; import static com.google.gcloud.datastore.EntityValue.of; -import static com.google.gcloud.datastore.GeoPointValue.of; +import static com.google.gcloud.datastore.LatLngValue.of; import static com.google.gcloud.datastore.KeyValue.of; import static com.google.gcloud.datastore.ListValue.of; import static com.google.gcloud.datastore.LongValue.of; @@ -160,7 +160,7 @@ public B set(String name, DateTime value) { return self(); } - public B set(String name, GeoPoint value) { + public B set(String name, LatLng value) { properties.put(name, of(value)); return self(); } @@ -327,14 +327,14 @@ public DateTime getDateTime(String name) { } /** - * Returns the property value as a GeoPoint. + * Returns the property value as a LatLng. * * @throws DatastoreException if not such property. - * @throws ClassCastException if value is not a GeoPoint. + * @throws ClassCastException if value is not a LatLng. */ @SuppressWarnings("unchecked") - public GeoPoint getGeoPoint(String name) { - return ((Value) getValue(name)).get(); + public LatLng getLatLng(String name) { + return ((Value) getValue(name)).get(); } /** diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java similarity index 79% rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java index 34532a30d927..7e2b42fac4d3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java @@ -23,20 +23,20 @@ import java.util.Objects; /** - * A Google Cloud Datastore GeoPoint (represented by latitude and longitude in degrees). + * A Google Cloud Datastore LatLng (represented by latitude and longitude in degrees). * This class is immutable. * * @see Google Cloud Datastore * Entities, Properties, and Keys */ -public final class GeoPoint extends Serializable { +public final class LatLng extends Serializable { private static final long serialVersionUID = 9077060962655752073L; private final transient double latitude; private final transient double longitude; - GeoPoint(double latitude, double longitude) { + LatLng(double latitude, double longitude) { checkArgument( latitude >= -90.0 && latitude <= 90.0, "latitude must be in the range [-90, 90] degrees"); checkArgument( @@ -66,12 +66,12 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj == this || (obj instanceof GeoPoint && this.latitude == ((GeoPoint) obj).latitude - && this.longitude == ((GeoPoint) obj).longitude); + return obj == this || (obj instanceof LatLng && this.latitude == ((LatLng) obj).latitude + && this.longitude == ((LatLng) obj).longitude); } - public static GeoPoint of(double latitude, double longitude) { - return new GeoPoint(latitude, longitude); + public static LatLng of(double latitude, double longitude) { + return new LatLng(latitude, longitude); } @Override @@ -85,6 +85,6 @@ protected com.google.type.LatLng toPb() { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { com.google.type.LatLng parsedLatLng = com.google.type.LatLng.parseFrom(bytesPb); - return new GeoPoint(parsedLatLng.getLatitude(), parsedLatLng.getLongitude()); + return new LatLng(parsedLatLng.getLatitude(), parsedLatLng.getLongitude()); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java similarity index 63% rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java index 0f6b5c2003e6..91723f710816 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java @@ -18,12 +18,12 @@ import static com.google.datastore.v1beta3.Value.GEO_POINT_VALUE_FIELD_NUMBER; -public final class GeoPointValue extends Value { +public final class LatLngValue extends Value { private static final long serialVersionUID = -5810614280642405898L; - static final BaseMarshaller MARSHALLER = - new BaseMarshaller() { + static final BaseMarshaller MARSHALLER = + new BaseMarshaller() { private static final long serialVersionUID = -3550567536035178649L; @@ -33,39 +33,39 @@ public int getProtoFieldId() { } @Override - public Builder newBuilder(GeoPoint value) { + public Builder newBuilder(LatLng value) { return builder(value); } @Override - protected GeoPoint getValue(com.google.datastore.v1beta3.Value from) { - return new GeoPoint( + protected LatLng getValue(com.google.datastore.v1beta3.Value from) { + return new LatLng( from.getGeoPointValue().getLatitude(), from.getGeoPointValue().getLongitude()); } @Override - protected void setValue(GeoPointValue from, com.google.datastore.v1beta3.Value.Builder to) { + protected void setValue(LatLngValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setGeoPointValue(from.get().toPb()); } }; - public static final class Builder extends Value.BaseBuilder { + public static final class Builder extends Value.BaseBuilder { private Builder() { - super(ValueType.GEO_POINT); + super(ValueType.LAT_LNG); } @Override - public GeoPointValue build() { - return new GeoPointValue(this); + public LatLngValue build() { + return new LatLngValue(this); } } - public GeoPointValue(GeoPoint value) { + public LatLngValue(LatLng value) { this(builder(value)); } - private GeoPointValue(Builder builder) { + private LatLngValue(Builder builder) { super(builder); } @@ -74,11 +74,11 @@ public Builder toBuilder() { return new Builder().mergeFrom(this); } - public static GeoPointValue of(GeoPoint value) { - return new GeoPointValue(value); + public static LatLngValue of(LatLng value) { + return new LatLngValue(value); } - public static Builder builder(GeoPoint value) { + public static Builder builder(LatLng value) { return new Builder().set(value); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java index 8326001c8fbc..ab16126336f5 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java @@ -81,9 +81,9 @@ public enum ValueType { RAW_VALUE(RawValue.MARSHALLER), /** - * Represents a {@link GeoPoint} value + * Represents a {@link LatLng} value */ - GEO_POINT(GeoPointValue.MARSHALLER); + LAT_LNG(LatLngValue.MARSHALLER); private static final ImmutableMap DESCRIPTOR_TO_TYPE_MAP; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java index 5ca68bf848ce..4be8b6c0d96a 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java @@ -35,7 +35,7 @@ public class BaseEntityTest { private static final Blob BLOB = Blob.copyFrom(new byte[]{1, 2}); private static final DateTime DATE_TIME = DateTime.now(); - private static final GeoPoint GEO_POINT = new GeoPoint(37.422035, -122.084124); + private static final LatLng LAT_LNG = new LatLng(37.422035, -122.084124); private static final Key KEY = Key.builder("ds1", "k1", "n1").build(); private static final Entity ENTITY = Entity.builder(KEY).set("name", "foo").build(); private static final IncompleteKey INCOMPLETE_KEY = IncompleteKey.builder("ds1", "k1").build(); @@ -63,9 +63,9 @@ public void setUp() { builder = new Builder(); builder.set("blob", BLOB).set("boolean", true).set("dateTime", DATE_TIME); builder.set("double", 1.25).set("key", KEY).set("string", "hello world"); - builder.set("long", 125).setNull("null").set("entity", ENTITY).set("geoPoint", GEO_POINT); + builder.set("long", 125).setNull("null").set("entity", ENTITY).set("latLng", LAT_LNG); builder.set("partialEntity", PARTIAL_ENTITY).set("stringValue", StringValue.of("bla")); - builder.set("list1", NullValue.of(), StringValue.of("foo"), GeoPointValue.of(GEO_POINT)); + builder.set("list1", NullValue.of(), StringValue.of("foo"), LatLngValue.of(LAT_LNG)); builder.set("list2", ImmutableList.of(LongValue.of(10), DoubleValue.of(2))); builder.set("list3", Collections.singletonList(BooleanValue.of(true))); } @@ -151,9 +151,9 @@ public void testGetDateTime() throws Exception { } @Test - public void testGetGeoPoint() throws Exception { + public void testGetLatLng() throws Exception { BaseEntity entity = builder.build(); - assertEquals(GEO_POINT, entity.getGeoPoint("geoPoint")); + assertEquals(LAT_LNG, entity.getLatLng("latLng")); } @Test @@ -181,7 +181,7 @@ public void testGetList() throws Exception { assertEquals(3, list.size()); assertEquals(NullValue.of(), list.get(0)); assertEquals("foo", list.get(1).get()); - assertEquals(GEO_POINT, list.get(2).get()); + assertEquals(LAT_LNG, list.get(2).get()); list = entity.getList("list2"); assertEquals(2, list.size()); assertEquals(Long.valueOf(10), list.get(0).get()); @@ -207,7 +207,7 @@ public void testNames() throws Exception { Set names = ImmutableSet.builder() .add("string", "stringValue", "boolean", "double", "long", "list1", "list2", "list3") - .add("entity", "partialEntity", "null", "dateTime", "geoPoint", "blob", "key") + .add("entity", "partialEntity", "null", "dateTime", "latLng", "blob", "key") .build(); BaseEntity entity = builder.build(); assertEquals(names, entity.names()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index c890a6b67aa8..152aeea0a75e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -74,8 +74,8 @@ public class DatastoreTest { .build(); private static final ListValue LIST_VALUE2 = ListValue.of(Collections.singletonList(KEY_VALUE)); private static final DateTimeValue DATE_TIME_VALUE = new DateTimeValue(DateTime.now()); - private static final GeoPointValue GEO_POINT_VALUE = - new GeoPointValue(new GeoPoint(37.422035, -122.084124)); + private static final LatLngValue LAT_LNG_VALUE = + new LatLngValue(new LatLng(37.422035, -122.084124)); private static final FullEntity PARTIAL_ENTITY1 = FullEntity.builder(INCOMPLETE_KEY2).set("str", STR_VALUE).set("bool", BOOL_VALUE) .set("list", LIST_VALUE1).build(); @@ -89,7 +89,7 @@ public class DatastoreTest { Entity.builder(KEY1) .set("str", STR_VALUE) .set("date", DATE_TIME_VALUE) - .set("geoPoint", GEO_POINT_VALUE) + .set("latLng", LAT_LNG_VALUE) .set("bool", BOOL_VALUE) .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) .set("list", LIST_VALUE2) @@ -508,8 +508,8 @@ public void testGet() { assertEquals(LIST_VALUE2, value3); DateTimeValue value4 = entity.getValue("date"); assertEquals(DATE_TIME_VALUE, value4); - GeoPointValue value5 = entity.getValue("geoPoint"); - assertEquals(GEO_POINT_VALUE, value5); + LatLngValue value5 = entity.getValue("latLng"); + assertEquals(LAT_LNG_VALUE, value5); FullEntity value6 = entity.getEntity("partial1"); assertEquals(PARTIAL_ENTITY1, value6); assertEquals(6, entity.names().size()); @@ -534,7 +534,7 @@ public void testGetArray() { assertEquals(PARTIAL_ENTITY2, partial1); assertEquals(ENTITY2, partial2); assertEquals(ValueType.BOOLEAN, entity3.getValue("bool").type()); - assertEquals(GEO_POINT_VALUE, entity3.getValue("geoPoint")); + assertEquals(LAT_LNG_VALUE, entity3.getValue("latLng")); assertEquals(7, entity3.names().size()); assertFalse(entity3.contains("bla")); try { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java similarity index 83% rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java index 2f076d915c15..1955ec236300 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java @@ -23,13 +23,13 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -public class GeoPointTest { +public class LatLngTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private static GeoPoint gp1 = new GeoPoint(37.422035, -122.084124); - private static GeoPoint gp2 = new GeoPoint(0.0, 0.0); + private static LatLng gp1 = new LatLng(37.422035, -122.084124); + private static LatLng gp2 = new LatLng(0.0, 0.0); private static final String INVALID_LAT_MESSAGE = "latitude must be in the range [-90, 90] degrees"; @@ -44,34 +44,34 @@ public void testEquals() { @Test public void testUpperLatRange() { - new GeoPoint(90, 0); + new LatLng(90, 0); thrown.expect(IllegalArgumentException.class); thrown.expectMessage(INVALID_LAT_MESSAGE); - new GeoPoint(91, 0); + new LatLng(91, 0); } @Test public void testLowerLatRange() { - new GeoPoint(-90, 0); + new LatLng(-90, 0); thrown.expect(IllegalArgumentException.class); thrown.expectMessage(INVALID_LAT_MESSAGE); - new GeoPoint(-91, 0); + new LatLng(-91, 0); } @Test public void testUpperLngRange() { - new GeoPoint(0, 180); + new LatLng(0, 180); thrown.expect(IllegalArgumentException.class); thrown.expectMessage(INVALID_LNG_MESSAGE); - new GeoPoint(0, 181); + new LatLng(0, 181); } @Test public void testLowerLngRange() { - new GeoPoint(0, 180); + new LatLng(0, 180); thrown.expect(IllegalArgumentException.class); thrown.expectMessage(INVALID_LNG_MESSAGE); - new GeoPoint(0, -181); + new LatLng(0, -181); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java similarity index 78% rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java index 82380efca8d3..3a25078237d4 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java @@ -22,20 +22,20 @@ import org.junit.Test; -public class GeoPointValueTest { +public class LatLngValueTest { -private static final GeoPoint CONTENT = new GeoPoint(37.4, -122.1); +private static final LatLng CONTENT = new LatLng(37.4, -122.1); @Test public void testToBuilder() throws Exception { - GeoPointValue value = GeoPointValue.of(CONTENT); + LatLngValue value = LatLngValue.of(CONTENT); assertEquals(value, value.toBuilder().build()); } @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { - GeoPointValue value = GeoPointValue.of(CONTENT); + LatLngValue value = LatLngValue.of(CONTENT); assertEquals(CONTENT, value.get()); assertFalse(value.excludeFromIndexes()); } @@ -43,8 +43,8 @@ public void testOf() throws Exception { @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { - GeoPointValue.Builder builder = GeoPointValue.builder(CONTENT); - GeoPointValue value = builder.meaning(1).excludeFromIndexes(true).build(); + LatLngValue.Builder builder = LatLngValue.builder(CONTENT); + LatLngValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); assertEquals(1, value.meaning()); assertTrue(value.excludeFromIndexes()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index b2ee24862688..a8cbcb294b39 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -45,7 +45,7 @@ public class SerializationTest { IncompleteKey.builder(KEY1, "v").ancestors(PathElement.of("p", 1)).build(); private static final Key KEY2 = Key.builder(KEY1, "v", 2).build(); private static final DateTime DATE_TIME1 = DateTime.now(); - private static final GeoPoint GEO_POINT = new GeoPoint(37.422035, -122.084124); + private static final LatLng LAT_LNG = new LatLng(37.422035, -122.084124); private static final Blob BLOB1 = Blob.copyFrom(UTF_8.encode("hello world")); private static final Cursor CURSOR1 = Cursor.copyFrom(new byte[] {1,2}); private static final Cursor CURSOR2 = Cursor.copyFrom(new byte[]{10}); @@ -91,7 +91,7 @@ public class SerializationTest { private static final BlobValue BLOB_VALUE = BlobValue.of(BLOB1); private static final RawValue RAW_VALUE = RawValue.of(com.google.datastore.v1beta3.Value.newBuilder().setMeaning(18).build()); - private static final GeoPointValue GEO_POINT_VALUE = GeoPointValue.of(GEO_POINT); + private static final LatLngValue LAT_LNG_VALUE = LatLngValue.of(LAT_LNG); private static final Entity ENTITY1 = Entity.builder(KEY1).build(); private static final Entity ENTITY2 = Entity.builder(KEY2).set("null", NullValue.of()).build(); @@ -130,7 +130,7 @@ public class SerializationTest { .put(ValueType.DATE_TIME, DATE_AND_TIME_VALUE) .put(ValueType.BLOB, BLOB_VALUE) .put(ValueType.RAW_VALUE, RAW_VALUE) - .put(ValueType.GEO_POINT, GEO_POINT_VALUE) + .put(ValueType.LAT_LNG, LAT_LNG_VALUE) .build(); @Test @@ -169,7 +169,7 @@ public void testValues() throws Exception { @Test public void testTypes() throws Exception { Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, GEO_POINT, CURSOR1, GQL1, + ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, LAT_LNG, CURSOR1, GQL1, GQL2, QUERY1, QUERY2, QUERY3}; for (Serializable obj : types) { Object copy = serializeAndDeserialize(obj); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java index 771b3c556a12..e433ca9a0666 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java @@ -41,22 +41,24 @@ public class ValueTest { private static final NullValue NULL_VALUE = NullValue.of(); private static final StringValue STRING_VALUE = StringValue.of("hello"); private static final RawValue RAW_VALUE = RawValue.of(STRING_VALUE.toPb()); - private static final GeoPointValue GEO_POINT_VALUE = GeoPointValue.of(new GeoPoint(30.5, 40.5)); - private static final ImmutableMap TYPES = ImmutableMap.builder() - .put(ValueType.NULL, new Object[] {NullValue.class, NULL_VALUE.get()}) - .put(ValueType.KEY, new Object[] {KeyValue.class, KEY}) - .put(ValueType.BLOB, new Object[] {BlobValue.class, BLOB}) - .put(ValueType.BOOLEAN, new Object[] {BooleanValue.class, Boolean.TRUE}) - .put(ValueType.DATE_TIME, new Object[] {DateTimeValue.class, DATE_TIME}) - .put(ValueType.DOUBLE, new Object[] {DoubleValue.class, 1.25D}) - .put(ValueType.ENTITY, new Object[] {EntityValue.class, ENTITY}) - .put(ValueType.LIST, - new Object[] {ListValue.class, ImmutableList.of(NULL_VALUE, STRING_VALUE, RAW_VALUE)}) - .put(ValueType.LONG, new Object[] {LongValue.class, 123L}) - .put(ValueType.RAW_VALUE, new Object[] {RawValue.class, RAW_VALUE.get()}) - .put(ValueType.GEO_POINT, new Object[] {GeoPointValue.class, GEO_POINT_VALUE.get()}) - .put(ValueType.STRING, new Object[] {StringValue.class, STRING_VALUE.get()}) - .build(); + private static final LatLngValue LAT_LNG_VALUE = + LatLngValue.of(new LatLng(37.422035, -122.084124)); + private static final ImmutableMap TYPES = + ImmutableMap.builder() + .put(ValueType.NULL, new Object[] {NullValue.class, NULL_VALUE.get()}) + .put(ValueType.KEY, new Object[] {KeyValue.class, KEY}) + .put(ValueType.BLOB, new Object[] {BlobValue.class, BLOB}) + .put(ValueType.BOOLEAN, new Object[] {BooleanValue.class, Boolean.TRUE}) + .put(ValueType.DATE_TIME, new Object[] {DateTimeValue.class, DATE_TIME}) + .put(ValueType.DOUBLE, new Object[] {DoubleValue.class, 1.25D}) + .put(ValueType.ENTITY, new Object[] {EntityValue.class, ENTITY}) + .put(ValueType.LIST, new Object[] { + ListValue.class, ImmutableList.of(NULL_VALUE, STRING_VALUE, RAW_VALUE)}) + .put(ValueType.LONG, new Object[] {LongValue.class, 123L}) + .put(ValueType.RAW_VALUE, new Object[] {RawValue.class, RAW_VALUE.get()}) + .put(ValueType.LAT_LNG, new Object[] {LatLngValue.class, LAT_LNG_VALUE.get()}) + .put(ValueType.STRING, new Object[] {StringValue.class, STRING_VALUE.get()}) + .build(); private ImmutableMap> typeToValue; From 50a5a66b851831ce50d17b04aea16f4c54c71f65 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 19 Oct 2015 15:50:24 -0700 Subject: [PATCH 19/29] Query continuation implemented for GqlQuery + tests --- .../com/google/gcloud/datastore/GqlQuery.java | 8 +- .../com/google/gcloud/datastore/Query.java | 2 +- .../gcloud/datastore/QueryResultsImpl.java | 18 ++- .../gcloud/datastore/StructuredQuery.java | 29 +++-- .../gcloud/datastore/DatastoreTest.java | 113 +++++++++++++++++- 5 files changed, 142 insertions(+), 28 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 7fcb562fea89..e6f713c76a1c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -379,9 +379,11 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r } @Override - protected GqlQuery nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb) { - // See issue #17 - throw new UnsupportedOperationException("paging for this query is not implemented yet"); + protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { + return new StructuredQuery.Builder<>(type()) + .mergeFrom(responsePb.getQuery()) + .prepareNext(responsePb.getBatch()) + .build(); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index c45efde3e30d..cd7d1015deda 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -192,7 +192,7 @@ protected abstract Object fromPb(ResultType resultType, String namespace, byt protected abstract void populatePb( com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb); - protected abstract Query nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb); + protected abstract Query nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb); /** * Returns a new {@link GqlQuery} builder. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index bb2b65fcc646..10f3eeda58ac 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -33,7 +33,7 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults private final ResultType queryResultType; private Query query; private ResultType actualResultType; - private com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb; + private com.google.datastore.v1beta3.RunQueryResponse runQueryResponsePb; private com.google.datastore.v1beta3.Query mostRecentQueryPb; private boolean lastBatch; private Iterator entityResultPbIter; @@ -56,8 +56,8 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults } partitionIdPb = pbBuilder.build(); sendRequest(); - if (queryResultBatchPb.getSkippedResults() > 0) { - cursor = queryResultBatchPb.getSkippedCursor(); + if (runQueryResponsePb.getBatch().getSkippedResults() > 0) { + cursor = runQueryResponsePb.getBatch().getSkippedCursor(); } else { cursor = mostRecentQueryPb.getStartCursor(); } @@ -71,16 +71,14 @@ private void sendRequest() { } requestPb.setPartitionId(partitionIdPb); query.populatePb(requestPb); - com.google.datastore.v1beta3.RunQueryResponse runQueryResponsePb = - datastore.runQuery(requestPb.build()); - queryResultBatchPb = runQueryResponsePb.getBatch(); + runQueryResponsePb = datastore.runQuery(requestPb.build()); mostRecentQueryPb = runQueryResponsePb.getQuery(); if (mostRecentQueryPb == null) { mostRecentQueryPb = requestPb.getQuery(); } - lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; - entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); - actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); + lastBatch = runQueryResponsePb.getBatch().getMoreResults() != MoreResultsType.NOT_FINISHED; + entityResultPbIter = runQueryResponsePb.getBatch().getEntityResultsList().iterator(); + actualResultType = ResultType.fromPb(runQueryResponsePb.getBatch().getEntityResultType()); if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) { // projection entity can represent all type of results actualResultType = ResultType.PROJECTION_ENTITY; @@ -92,7 +90,7 @@ private void sendRequest() { @Override protected T computeNext() { while (!entityResultPbIter.hasNext() && !lastBatch) { - query = query.nextQuery(queryResultBatchPb); + query = query.nextQuery(runQueryResponsePb); sendRequest(); } if (!entityResultPbIter.hasNext()) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 1b82991cb8c8..dcf4cef4721f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -669,9 +669,23 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { return self(); } + B prepareNext(com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb) { + startCursor(new Cursor(queryResultBatchPb.getEndCursor())); + if (offset > 0 && queryResultBatchPb.getSkippedResults() < offset) { + offset(offset - queryResultBatchPb.getSkippedResults()); + } else { + offset(0); + if (limit != null) { + limit(limit - queryResultBatchPb.getEntityResultsCount()); + } + } + return self(); + } + public StructuredQuery build() { return new StructuredQuery<>(this); } + } static final class Builder extends BaseBuilder> { @@ -844,19 +858,8 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r } @Override - protected StructuredQuery nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb) { - Builder builder = new Builder<>(type()); - builder.mergeFrom(toPb()); - builder.startCursor(new Cursor(responsePb.getEndCursor())); - if (offset > 0 && responsePb.getSkippedResults() < offset) { - builder.offset(offset - responsePb.getSkippedResults()); - } else { - builder.offset(0); - if (limit != null) { - builder.limit(limit - responsePb.getEntityResultsCount()); - } - } - return builder.build(); + protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { + return new Builder<>(type()).mergeFrom(toPb()).prepareNext(responsePb.getBatch()).build(); } @Override diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index f0fbd4ab96c0..6bf907422a0f 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -31,6 +31,7 @@ import com.google.gcloud.datastore.StructuredQuery.OrderBy; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; import com.google.gcloud.spi.DatastoreRpc; +import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; import com.google.gcloud.spi.DatastoreRpcFactory; @@ -43,6 +44,7 @@ import org.junit.runners.JUnit4; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -403,6 +405,42 @@ public void testRunGqlQueryWithCasting() { assertFalse(results3.hasNext()); } + @Test + public void testGqlQueryPagination() { + DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) + .andReturn(rpcMock); + List responses = + buildResponsesForQueryPagination(); + for (int i = 0; i < responses.size(); i++) { + try { + EasyMock + .expect(rpcMock.runQuery( + EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) + .andReturn(responses.get(i)); + } catch (DatastoreRpcException e) { + fail("Unexpected DatastoreRpcException"); + } + } + EasyMock.replay(rpcFactoryMock, rpcMock); + DatastoreOptions options = + this.options.toBuilder() + .retryParams(RetryParams.getDefaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build(); + Datastore mockDatastore = DatastoreFactory.instance().get(options); + QueryResults results = + mockDatastore.run(Query.gqlQueryBuilder(ResultType.KEY, "select __key__ from *").build()); + int count = 0; + while (results.hasNext()) { + count += 1; + results.next(); + } + assertEquals(count, responses.size()); + EasyMock.verify(rpcFactoryMock, rpcMock); + } + @Test public void testRunStructuredQuery() { Query query = @@ -445,7 +483,80 @@ public void testRunStructuredQuery() { assertEquals(20, entity.getLong("age")); assertEquals(1, entity.properties().size()); assertFalse(results4.hasNext()); - // TODO(ozarov): construct a test to verify nextQuery/pagination + } + + @Test + public void testStructuredQueryPagination() { + DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) + .andReturn(rpcMock); + List responses = + buildResponsesForQueryPagination(); + for (int i = 0; i < responses.size(); i++) { + try { + EasyMock + .expect(rpcMock.runQuery( + EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) + .andReturn(responses.get(i)); + } catch (DatastoreRpcException e) { + fail("Unexpected DatastoreRpcException"); + } + } + EasyMock.replay(rpcFactoryMock, rpcMock); + DatastoreOptions options = + this.options.toBuilder() + .retryParams(RetryParams.getDefaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build(); + Datastore mockDatastore = DatastoreFactory.instance().get(options); + QueryResults results = mockDatastore.run(Query.keyQueryBuilder().build()); + int count = 0; + while (results.hasNext()) { + count += 1; + results.next(); + } + assertEquals(count, responses.size()); + EasyMock.verify(rpcFactoryMock, rpcMock); + } + + private List buildResponsesForQueryPagination() { + List responses = new ArrayList<>(); + Query query = Query.keyQueryBuilder().build(); + com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = + com.google.datastore.v1beta3.RunQueryRequest.newBuilder(); + query.populatePb(requestPb); + com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb = + com.google.datastore.v1beta3.RunQueryResponse.newBuilder() + .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) + .getBatch(); + com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb1 = + com.google.datastore.v1beta3.QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults( + com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) + .build(); + responses.add( + com.google.datastore.v1beta3.RunQueryResponse.newBuilder() + .setBatch(queryResultBatchPb1) + .build()); + com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb2 = + com.google.datastore.v1beta3.QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults( + com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 2)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(1).getCursor()) + .build(); + responses.add( + com.google.datastore.v1beta3.RunQueryResponse.newBuilder() + .setBatch(queryResultBatchPb2) + .build()); + return responses; } @Test From b270c64f96c5cad1e07c717aab1120b10dd7025d Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 21 Oct 2015 13:08:18 -0700 Subject: [PATCH 20/29] Set namespace in Gql's nextQuery and add another batch to tests --- .../com/google/gcloud/datastore/GqlQuery.java | 1 + .../gcloud/datastore/DatastoreTest.java | 38 +++++++++++-------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index e6f713c76a1c..ecb0aef1e701 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -381,6 +381,7 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r @Override protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { return new StructuredQuery.Builder<>(type()) + .namespace(namespace()) .mergeFrom(responsePb.getQuery()) .prepareNext(responsePb.getBatch()) .build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 6bf907422a0f..6ea4e789ee34 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -406,7 +406,7 @@ public void testRunGqlQueryWithCasting() { } @Test - public void testGqlQueryPagination() { + public void testGqlQueryPagination() throws DatastoreRpcException { DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) @@ -414,14 +414,10 @@ public void testGqlQueryPagination() { List responses = buildResponsesForQueryPagination(); for (int i = 0; i < responses.size(); i++) { - try { EasyMock .expect(rpcMock.runQuery( EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) .andReturn(responses.get(i)); - } catch (DatastoreRpcException e) { - fail("Unexpected DatastoreRpcException"); - } } EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = @@ -437,7 +433,7 @@ public void testGqlQueryPagination() { count += 1; results.next(); } - assertEquals(count, responses.size()); + assertEquals(count, 5); EasyMock.verify(rpcFactoryMock, rpcMock); } @@ -486,7 +482,7 @@ public void testRunStructuredQuery() { } @Test - public void testStructuredQueryPagination() { + public void testStructuredQueryPagination() throws DatastoreRpcException { DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) @@ -494,14 +490,10 @@ public void testStructuredQueryPagination() { List responses = buildResponsesForQueryPagination(); for (int i = 0; i < responses.size(); i++) { - try { EasyMock .expect(rpcMock.runQuery( EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) .andReturn(responses.get(i)); - } catch (DatastoreRpcException e) { - fail("Unexpected DatastoreRpcException"); - } } EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = @@ -516,11 +508,14 @@ public void testStructuredQueryPagination() { count += 1; results.next(); } - assertEquals(count, responses.size()); + assertEquals(count, 5); EasyMock.verify(rpcFactoryMock, rpcMock); } private List buildResponsesForQueryPagination() { + Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); + Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); + datastore.add(ENTITY3, entity4, entity5); List responses = new ArrayList<>(); Query query = Query.keyQueryBuilder().build(); com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = @@ -547,15 +542,28 @@ private List buildResponsesForQue com.google.datastore.v1beta3.QueryResultBatch.newBuilder() .mergeFrom(queryResultBatchPb) .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 2)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(1).getCursor()) + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 3)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(2).getCursor()) .build(); responses.add( com.google.datastore.v1beta3.RunQueryResponse.newBuilder() .setBatch(queryResultBatchPb2) .build()); + com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb3 = + com.google.datastore.v1beta3.QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults( + com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(3, 5)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) + .build(); + responses.add( + com.google.datastore.v1beta3.RunQueryResponse.newBuilder() + .setBatch(queryResultBatchPb3) + .build()); return responses; } From 6ffe9273596c10d38cef62db73a77b38ac8b8c3c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 21 Oct 2015 15:47:34 -0700 Subject: [PATCH 21/29] remove changes to structured query's builder and instead use fromPb in GqlQuery's nextQuery --- .../com/google/gcloud/datastore/GqlQuery.java | 9 ++--- .../gcloud/datastore/StructuredQuery.java | 35 +++++++++---------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index ecb0aef1e701..6c746c7924d7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -379,12 +379,9 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r } @Override - protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { - return new StructuredQuery.Builder<>(type()) - .namespace(namespace()) - .mergeFrom(responsePb.getQuery()) - .prepareNext(responsePb.getBatch()) - .build(); + protected Query nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { + return StructuredQuery.fromPb(type(), namespace(), responsePb.getQuery()) + .nextQuery(responsePb); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index dcf4cef4721f..e519ce4fc3ff 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -669,23 +669,9 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { return self(); } - B prepareNext(com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb) { - startCursor(new Cursor(queryResultBatchPb.getEndCursor())); - if (offset > 0 && queryResultBatchPb.getSkippedResults() < offset) { - offset(offset - queryResultBatchPb.getSkippedResults()); - } else { - offset(0); - if (limit != null) { - limit(limit - queryResultBatchPb.getEntityResultsCount()); - } - } - return self(); - } - public StructuredQuery build() { return new StructuredQuery<>(this); } - } static final class Builder extends BaseBuilder> { @@ -858,8 +844,19 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r } @Override - protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { - return new Builder<>(type()).mergeFrom(toPb()).prepareNext(responsePb.getBatch()).build(); + protected Query nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { + Builder builder = new Builder<>(type()); + builder.mergeFrom(toPb()); + builder.startCursor(new Cursor(responsePb.getBatch().getEndCursor())); + if (offset > 0 && responsePb.getBatch().getSkippedResults() < offset) { + builder.offset(offset - responsePb.getBatch().getSkippedResults()); + } else { + builder.offset(0); + if (limit != null) { + builder.limit(limit - responsePb.getBatch().getEntityResultsCount()); + } + } + return builder.build(); } @Override @@ -907,7 +904,9 @@ protected Object fromPb(ResultType resultType, String namespace, byte[] bytes return fromPb(resultType, namespace, com.google.datastore.v1beta3.Query.parseFrom(bytesPb)); } - private static StructuredQuery fromPb(ResultType resultType, String namespace, + @SuppressWarnings("unchecked") + static StructuredQuery fromPb( + ResultType resultType, String namespace, com.google.datastore.v1beta3.Query queryPb) { BaseBuilder builder; if (resultType.equals(ResultType.ENTITY)) { @@ -917,6 +916,6 @@ private static StructuredQuery fromPb(ResultType resultType, String namesp } else { builder = new ProjectionEntityQueryBuilder(); } - return builder.namespace(namespace).mergeFrom(queryPb).build(); + return (StructuredQuery) builder.namespace(namespace).mergeFrom(queryPb).build(); } } From 3d7ea2c955bb4886ffc1954badd98ce0eff9a8a4 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 15 Jan 2016 15:26:57 -0800 Subject: [PATCH 22/29] update afterCursor javadoc --- .../google/gcloud/datastore/QueryResults.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java index 5b4f71da3963..110add0bbbe4 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java @@ -35,7 +35,21 @@ public interface QueryResults extends Iterator { Class resultClass(); /** - * Returns the Cursor for point after the value returned in the last {@link #next} call. + * Returns the Cursor for the point after the value returned in the last {@link #next} call. This + * cursor can be used to issue subsequent queries (with the same constraints) that may return + * additional results. + * + *

A simple use case: + *

 {@code
+   * Query query = Query.entityQueryBuilder()
+   *     .kind("Person")
+   *     .filter(PropertyFilter.eq("favoriteFood", "pizza"))
+   *     .build();
+   * QueryResults results = datastore.run(query);
+   * // Consume some results (using results.next()) and do any other actions as necessary.
+   * query = query.toBuilder().startCursor(results.cursorAfter()).build();
+   * results = datastore.run(query); // now we will iterate over all entities not yet consumed
+   * 
*/ Cursor cursorAfter(); } From 71d91aa5b6f603e02285207662e5faae5b1c8a7f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 28 Jan 2016 18:22:03 -0800 Subject: [PATCH 23/29] Fixed missed merge conflict --- .../java/com/google/gcloud/datastore/QueryResults.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java index cd851f690ca5..a6e5971936dd 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java @@ -36,7 +36,6 @@ public interface QueryResults extends Iterator { Class resultClass(); /** -<<<<<<< HEAD * Returns the Cursor for the point after the value returned in the last {@link #next} call. This * cursor can be used to issue subsequent queries (with the same constraints) that may return * additional results. @@ -51,11 +50,7 @@ public interface QueryResults extends Iterator { * // Consume some results (using results.next()) and do any other actions as necessary. * query = query.toBuilder().startCursor(results.cursorAfter()).build(); * results = datastore.run(query); // now we will iterate over all entities not yet consumed - * -======= - * Returns the Cursor for the point after the value returned in the last {@link #next} call. - * Currently, {@code cursorAfter} returns null in all cases but the last result. ->>>>>>> upstream/master + * } */ Cursor cursorAfter(); } From d27d567606f198822c5ec2b4a5e8c592e263abec Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 1 Feb 2016 17:35:06 -0800 Subject: [PATCH 24/29] Fix ServiceOptions merge bug, remove unnecessary protected modifier from DateTime, set cursorAfter to endCursor where appropriate, and fix error codes for retries. --- .../com/google/gcloud/ServiceOptions.java | 4 +--- .../gcloud/datastore/DatastoreException.java | 4 +--- .../com/google/gcloud/datastore/DateTime.java | 4 ++-- .../gcloud/datastore/QueryResultsImpl.java | 1 + .../datastore/DatastoreExceptionTest.java | 20 +++++++++---------- .../gcloud/datastore/DatastoreTest.java | 2 +- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 34280dbf92e5..31e543809464 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -18,7 +18,6 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.client.extensions.appengine.http.UrlFetchTransport; @@ -229,8 +228,7 @@ public B clock(Clock clock) { * @return the builder */ public B projectId(String projectId) { - this.projectId = - checkNotNull(projectId, "Project ID cannot be set to null. Leave unset for default."); + this.projectId = projectId; return self(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java index ecad69ac635b..a940fe573f93 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java @@ -34,9 +34,7 @@ public class DatastoreException extends BaseServiceException { // see https://cloud.google.com/datastore/docs/concepts/errors#Error_Codes" private static final Set RETRYABLE_ERRORS = ImmutableSet.of( - new Error(409, "ABORTED"), - new Error(403, "DEADLINE_EXCEEDED"), - new Error(503, "UNAVAILABLE")); + new Error(10, "ABORTED"), new Error(4, "DEADLINE_EXCEEDED"), new Error(14, "UNAVAILABLE")); private static final long serialVersionUID = 2663750991205874435L; public DatastoreException(int code, String message, String reason, Throwable cause) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java index 45347ed41dcb..5e8664395802 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java @@ -106,11 +106,11 @@ Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { com.google.protobuf.Timestamp.parseFrom(bytesPb))); } - protected static long timestampPbToMicroseconds(com.google.protobuf.Timestamp timestampPb) { + static long timestampPbToMicroseconds(com.google.protobuf.Timestamp timestampPb) { return timestampPb.getSeconds() * 1000000 + timestampPb.getNanos() / 1000; } - protected static com.google.protobuf.Timestamp microsecondsToTimestampPb(long microseconds) { + static com.google.protobuf.Timestamp microsecondsToTimestampPb(long microseconds) { long seconds = microseconds / 1000000; int nanos = (int) (microseconds % 1000000) * 1000; return com.google.protobuf.Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index 25dde18a1a1b..ec3a652c6131 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -93,6 +93,7 @@ protected T computeNext() { sendRequest(); } if (!entityResultPbIter.hasNext()) { + cursor = runQueryResponsePb.getBatch().getEndCursor(); return endOfData(); } com.google.datastore.v1beta3.EntityResult entityResultPb = entityResultPbIter.next(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java index 4d62224172f9..301a863476b6 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java @@ -38,29 +38,29 @@ public class DatastoreExceptionTest { @Test public void testDatastoreException() throws Exception { - DatastoreException exception = new DatastoreException(409, "message", "ABORTED"); - assertEquals(409, exception.code()); + DatastoreException exception = new DatastoreException(10, "message", "ABORTED"); + assertEquals(10, exception.code()); assertEquals("ABORTED", exception.reason()); assertEquals("message", exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - exception = new DatastoreException(403, "message", "DEADLINE_EXCEEDED"); - assertEquals(403, exception.code()); + exception = new DatastoreException(4, "message", "DEADLINE_EXCEEDED"); + assertEquals(4, exception.code()); assertEquals("DEADLINE_EXCEEDED", exception.reason()); assertEquals("message", exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - exception = new DatastoreException(503, "message", "UNAVAILABLE"); - assertEquals(503, exception.code()); + exception = new DatastoreException(14, "message", "UNAVAILABLE"); + assertEquals(14, exception.code()); assertEquals("UNAVAILABLE", exception.reason()); assertEquals("message", exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - exception = new DatastoreException(500, "message", "INTERNAL"); - assertEquals(500, exception.code()); + exception = new DatastoreException(2, "message", "INTERNAL"); + assertEquals(2, exception.code()); assertEquals("INTERNAL", exception.reason()); assertEquals("message", exception.getMessage()); assertFalse(exception.retryable()); @@ -77,14 +77,14 @@ public void testDatastoreException() throws Exception { @Test public void testTranslateAndThrow() throws Exception { - DatastoreException cause = new DatastoreException(503, "message", "UNAVAILABLE"); + DatastoreException cause = new DatastoreException(14, "message", "UNAVAILABLE"); RetryHelper.RetryHelperException exceptionMock = createMock(RetryHelper.RetryHelperException.class); expect(exceptionMock.getCause()).andReturn(cause).times(2); replay(exceptionMock); try { DatastoreException.translateAndThrow(exceptionMock); } catch (BaseServiceException ex) { - assertEquals(503, ex.code()); + assertEquals(14, ex.code()); assertEquals("message", ex.getMessage()); assertTrue(ex.retryable()); assertTrue(ex.idempotent()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index a39952c448eb..002e5f6df04f 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -986,7 +986,7 @@ public void testRetryableException() throws Exception { EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(rpcMock); EasyMock.expect(rpcMock.lookup(requestPb)) - .andThrow(new DatastoreException(503, "UNAVAILABLE", "UNAVAILABLE", null)) + .andThrow(new DatastoreException(14, "UNAVAILABLE", "UNAVAILABLE", null)) .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = this.options.toBuilder() From 7e498c1ef6ef00a29ba17714e732bf58e6cace83 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 29 Feb 2016 18:20:11 -0800 Subject: [PATCH 25/29] Remove userinfo scope from DatastoreOptions --- .../java/com/google/gcloud/datastore/DatastoreOptions.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 112d0e8d2602..d47aa5fa2915 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -35,8 +35,7 @@ public class DatastoreOptions extends ServiceOptions SCOPES = ImmutableSet.of(DATASTORE_SCOPE, USERINFO_SCOPE); + private static final Set SCOPES = ImmutableSet.of(DATASTORE_SCOPE); private final String namespace; private final boolean normalizeDataset; From c95e5e7dbecaeb613e77385f62258f9c43b32af2 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 18 Feb 2016 08:10:00 -0800 Subject: [PATCH 26/29] Allow eventual consistency for Datastore reads --- gcloud-java-datastore/pom.xml | 12 ---- .../google/gcloud/datastore/Datastore.java | 39 ++++++++++- .../gcloud/datastore/DatastoreHelper.java | 31 ++++++-- .../gcloud/datastore/DatastoreImpl.java | 39 +++++++++++ .../gcloud/datastore/DatastoreReader.java | 10 +-- .../google/gcloud/datastore/ReadOption.java | 66 +++++++++++++++++ .../gcloud/datastore/TransactionImpl.java | 8 +-- .../gcloud/datastore/DatastoreHelperTest.java | 65 ++++++++++++++--- .../gcloud/datastore/DatastoreTest.java | 70 +++++++++++++++++++ 9 files changed, 303 insertions(+), 37 deletions(-) create mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index b33f66a19682..ee633fd57883 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -42,18 +42,6 @@ datastore-v1beta3-proto-client 0.0.1-SNAPSHOT - - com.google.apis - google-api-services-datastore-protobuf - v1beta2-rev1-2.1.2 - compile - - - com.google.api-client - google-api-client - - - junit junit diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java index b49db1cacdfe..00b914a36678 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java @@ -18,6 +18,7 @@ import com.google.gcloud.Service; +import java.util.Iterator; import java.util.List; /** @@ -32,7 +33,6 @@ public interface Datastore extends Service, DatastoreReaderWri */ Transaction newTransaction(); - /** * A callback for running with a transactional * {@link com.google.gcloud.datastore.DatastoreReaderWriter}. @@ -45,7 +45,6 @@ interface TransactionCallable { T run(DatastoreReaderWriter readerWriter) throws Exception; } - /** * Invokes the callback's {@link Datastore.TransactionCallable#run} method with a * {@link DatastoreReaderWriter} that is associated with a new transaction. @@ -105,4 +104,40 @@ interface TransactionCallable { * Returns a new KeyFactory for this service */ KeyFactory newKeyFactory(); + + /** + * Returns an {@link Entity} for the given {@link Key} or {@code null} if it doesn't exist. + * {@link ReadOption}s can be specified if desired. + * + * @throws DatastoreException upon failure + */ + Entity get(Key key, ReadOption... options); + + /** + * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. + * The order of the result is unspecified. + * Results are loaded lazily, so it is possible to get a {@code DatastoreException} + * from the returned {@code Iterator}'s {@link Iterator#hasNext hasNext} or + * {@link Iterator#next next} methods. {@link ReadOption}s can be specified if desired. + * + * @throws DatastoreException upon failure + * @see #get(Key) + */ + Iterator get(Iterable keys, ReadOption... options); + + /** + * Returns a list with a value for each given key (ordered by input). + * {@code null} values are returned for nonexistent keys. + * When possible prefer using {@link #get(Key...)} to avoid eagerly loading the results. + * {@link ReadOption}s can be specified if desired. + */ + List fetch(Iterable keys, ReadOption... options); + + /** + * Submits a {@link Query} and returns its result. + * {@link ReadOption}s can be specified if desired. + * + * @throws DatastoreException upon failure + */ + QueryResults run(Query query, ReadOption... options); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java index 5ea0f755d2f8..2873e2f8aafa 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java @@ -20,6 +20,8 @@ import com.google.common.collect.Maps; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -33,13 +35,16 @@ class DatastoreHelper { private DatastoreHelper() { } - static Key allocateId(Datastore service, IncompleteKey key) { return service.allocateId(new IncompleteKey[]{key}).get(0); } - static Entity get(DatastoreReader reader, Key key) { - return Iterators.getNext(reader.get(new Key[]{key}), null); + static Entity get(Transaction reader, Key key) { + return Iterators.getNext(reader.get(new Key[] {key}), null); + } + + static Entity get(Datastore reader, Key key, ReadOption... options) { + return Iterators.getNext(reader.get(Collections.singletonList(key), options), null); } static Entity add(DatastoreWriter writer, FullEntity entity) { @@ -52,10 +57,24 @@ static KeyFactory newKeyFactory(DatastoreOptions options) { /** * Returns a list with a value for each given key (ordered by input). - * A {@code null} would be returned for non-existing keys. + * {@code null} values are returned for nonexistent keys. */ - static List fetch(DatastoreReader reader, Key... keys) { + static List fetch(Transaction reader, Key... keys) { Iterator entities = reader.get(keys); + return compileEntities(keys, entities); + } + + /** + * Returns a list with a value for each given key (ordered by input). + * {@code null} values are returned for nonexistent keys. + */ + static List fetch(Datastore reader, Key[] keys, ReadOption... options) { + Iterator entities; + entities = reader.get(Arrays.asList(keys), options); + return compileEntities(keys, entities); + } + + private static List compileEntities(Key[] keys, Iterator entities) { Map map = Maps.newHashMapWithExpectedSize(keys.length); while (entities.hasNext()) { Entity entity = entities.next(); @@ -63,7 +82,7 @@ static List fetch(DatastoreReader reader, Key... keys) { } List list = new ArrayList<>(keys.length); for (Key key : keys) { - // this will include nulls for non-existing keys + // this will include nulls for nonexistent keys list.add(map.get(key)); } return list; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index df4e22149fd5..73d25ab140d7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -20,11 +20,14 @@ import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; import com.google.gcloud.BaseService; import com.google.gcloud.RetryHelper; import com.google.gcloud.RetryHelper.RetryHelperException; import com.google.gcloud.RetryParams; +import com.google.gcloud.datastore.ReadOption.EventualConsistency; import com.google.gcloud.spi.DatastoreRpc; import com.google.protobuf.ByteString; @@ -70,6 +73,11 @@ public QueryResults run(Query query) { return run(null, query); } + @Override + public QueryResults run(Query query, ReadOption... options) { + return run(toReadOptionsPb(options), query); + } + QueryResults run(com.google.datastore.v1beta3.ReadOptions readOptionsPb, Query query) { return new QueryResultsImpl<>(this, readOptionsPb, query); } @@ -185,16 +193,47 @@ public Entity get(Key key) { return DatastoreHelper.get(this, key); } + @Override + public Entity get(Key key, ReadOption... options) { + return DatastoreHelper.get(this, key, options); + } + @Override public Iterator get(Key... keys) { return get(null, keys); } + @Override + public Iterator get(Iterable keys, ReadOption... options) { + return get(toReadOptionsPb(options), Iterables.toArray(keys, Key.class)); + } + + private static com.google.datastore.v1beta3.ReadOptions toReadOptionsPb(ReadOption... options) { + com.google.datastore.v1beta3.ReadOptions readOptionsPb = null; + if (options != null) { + Map, ReadOption> optionsMap = ReadOption.asImmutableMap(options); + EventualConsistency eventualConsistency = + (EventualConsistency) optionsMap.get(EventualConsistency.class); + if (eventualConsistency != null) { + readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.newBuilder() + .setReadConsistency(ReadConsistency.EVENTUAL) + .build(); + } + } + return readOptionsPb; + } + @Override public List fetch(Key... keys) { return DatastoreHelper.fetch(this, keys); } + @Override + public List fetch(Iterable keys, ReadOption... options) { + return DatastoreHelper.fetch(this, Iterables.toArray(keys, Key.class), options); + } + Iterator get(com.google.datastore.v1beta3.ReadOptions readOptionsPb, final Key... keys) { if (keys.length == 0) { return Collections.emptyIterator(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java index 4852dd53e16c..7ba5089ae4eb 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java @@ -25,7 +25,7 @@ public interface DatastoreReader { /** - * Returns an {@link Entity} for the given {@link Key} or {@code null} if does not exists. + * Returns an {@link Entity} for the given {@link Key} or {@code null} if it doesn't exist. * * @throws DatastoreException upon failure */ @@ -34,7 +34,7 @@ public interface DatastoreReader { /** * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. * The order of the result is unspecified. - * Results are loaded lazily therefore it is possible to get a {@code DatastoreException} + * Results are loaded lazily, so it is possible to get a {@code DatastoreException} * from the returned {@code Iterator}'s {@link Iterator#hasNext hasNext} or * {@link Iterator#next next} methods. * @@ -45,13 +45,13 @@ public interface DatastoreReader { /** * Returns a list with a value for each given key (ordered by input). - * A {@code null} would be returned for non-existing keys. - * When possible prefer using {@link #get(Key...)} which does not eagerly loads the results. + * {@code null} values are returned for nonexistent keys. + * When possible prefer using {@link #get(Key...)} to avoid eagerly loading the results. */ List fetch(Key... keys); /** - * Submit a {@link Query} and returns its result. + * Submits a {@link Query} and returns its result. * * @throws DatastoreException upon failure */ diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java new file mode 100644 index 000000000000..86214fddbf02 --- /dev/null +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.datastore; + +import com.google.common.collect.ImmutableMap; + +import java.io.Serializable; +import java.util.Map; + +/** + * Specifies options for read operations in Datastore, namely getting/fetching entities and running + * queries. + */ +public abstract class ReadOption implements Serializable { + + private static final long serialVersionUID = -4406964829189800528L; + + /** + * Specifies eventual consistency for reads from Datastore. + */ + public static final class EventualConsistency extends ReadOption { + + private static final long serialVersionUID = -6959530217724666172L; + + private final boolean eventualConsistency; + + private EventualConsistency(boolean eventualConsistency) { + this.eventualConsistency = eventualConsistency; + } + + public boolean isEventual() { + return eventualConsistency; + } + } + + ReadOption() {} + + /** + * Returns a {@code ReadOption} that specifies eventual consistency. + */ + public static EventualConsistency eventualConsistency() { + return new EventualConsistency(true); + } + + static Map, ReadOption> asImmutableMap(ReadOption... options) { + ImmutableMap.Builder, ReadOption> builder = ImmutableMap.builder(); + for (ReadOption option : options) { + builder.put(option.getClass(), option); + } + return builder.build(); + } +} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index 5a422927005a..469c14e1c78a 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -40,7 +40,7 @@ static class ResponseImpl implements Transaction.Response { @Override public List generatedKeys() { - Iterator results = + Iterator results = response.getMutationResultsList().iterator(); List generated = new ArrayList<>(numAutoAllocatedIds); for (int i = 0; i < numAutoAllocatedIds; i++) { @@ -66,7 +66,7 @@ public Entity get(Key key) { @Override public Iterator get(Key... keys) { validateActive(); - com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = com.google.datastore.v1beta3.ReadOptions.newBuilder(); readOptionsPb.setTransaction(transaction); return datastore.get(readOptionsPb.build(), keys); @@ -81,7 +81,7 @@ public List fetch(Key... keys) { @Override public QueryResults run(Query query) { validateActive(); - com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = com.google.datastore.v1beta3.ReadOptions.newBuilder(); readOptionsPb.setTransaction(transaction); return datastore.run(readOptionsPb.build(), query); @@ -91,7 +91,7 @@ public QueryResults run(Query query) { public Transaction.Response commit() { validateActive(); List mutationsPb = toMutationPbList(); - com.google.datastore.v1beta3.CommitRequest.Builder requestPb = + com.google.datastore.v1beta3.CommitRequest.Builder requestPb = com.google.datastore.v1beta3.CommitRequest.newBuilder(); requestPb.setMode(com.google.datastore.v1beta3.CommitRequest.Mode.TRANSACTIONAL); requestPb.setTransaction(transaction); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java index 55c8d0cf3ce6..61b266a9abc2 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; import com.google.gcloud.datastore.Datastore.TransactionCallable; @@ -66,52 +67,100 @@ public void testAllocateId() throws Exception { } @Test - public void testGet() throws Exception { + public void testGetWithDatastore() throws Exception { Datastore datastore = createStrictMock(Datastore.class); IncompleteKey pKey1 = IncompleteKey.builder("ds", "k").build(); Key key1 = Key.builder(pKey1, 1).build(); Entity entity1 = Entity.builder(key1).build(); Key key2 = Key.builder(pKey1, 2).build(); - expect(datastore.get(new Key[]{key1})) + ReadOption eventualConsistency = ReadOption.eventualConsistency(); + expect(datastore.get(Collections.singletonList(key1))) .andReturn(Collections.singletonList(entity1).iterator()); - expect(datastore.get(new Key[]{key2})) + expect(datastore.get(Collections.singletonList(key2))) .andReturn(Collections.emptyIterator()); + expect(datastore.get(Collections.singletonList(key1), eventualConsistency)) + .andReturn(Collections.singletonList(entity1).iterator()); replay(datastore); assertEquals(entity1, DatastoreHelper.get(datastore, key1)); assertNull(DatastoreHelper.get(datastore, key2)); + assertEquals(entity1, DatastoreHelper.get(datastore, key1, eventualConsistency)); verify(datastore); } + @Test + public void testGetWithTransaction() throws Exception { + Transaction transaction = createStrictMock(Transaction.class); + IncompleteKey pKey1 = IncompleteKey.builder("ds", "k").build(); + Key key1 = Key.builder(pKey1, 1).build(); + Entity entity1 = Entity.builder(key1).build(); + Key key2 = Key.builder(pKey1, 2).build(); + expect(transaction.get(new Key[] {key1})) + .andReturn(Collections.singletonList(entity1).iterator()); + expect(transaction.get(new Key[] {key2})).andReturn(Collections.emptyIterator()); + replay(transaction); + assertEquals(entity1, DatastoreHelper.get(transaction, key1)); + assertNull(DatastoreHelper.get(transaction, key2)); + verify(transaction); + } + @Test public void testAdd() throws Exception { Datastore datastore = createStrictMock(Datastore.class); IncompleteKey pKey = IncompleteKey.builder("ds", "k").build(); Key key = Key.builder(pKey, 1).build(); Entity entity = Entity.builder(key).build(); - expect(datastore.add(new Entity[]{entity})) - .andReturn(Collections.singletonList(entity)); + expect(datastore.add(new Entity[] {entity})).andReturn(Collections.singletonList(entity)); replay(datastore); assertEquals(entity, DatastoreHelper.add(datastore, entity)); verify(datastore); } @Test - public void testFetch() throws Exception { + public void testFetchWithDatastore() throws Exception { Datastore datastore = createStrictMock(Datastore.class); IncompleteKey pKey1 = IncompleteKey.builder("ds", "k").build(); Key key1 = Key.builder(pKey1, 1).build(); Key key2 = Key.builder(pKey1, "a").build(); Entity entity1 = Entity.builder(key1).build(); Entity entity2 = Entity.builder(key2).build(); - expect(datastore.get(key1, key2)).andReturn(Iterators.forArray(entity1, entity2)).once(); + ReadOption eventualConsistency = ReadOption.eventualConsistency(); + expect(datastore.get(ImmutableList.of(key1, key2))) + .andReturn(Iterators.forArray(entity1, entity2)) + .once(); + expect(datastore.get(ImmutableList.of(key1, key2), eventualConsistency)) + .andReturn(Iterators.forArray(entity1, entity2)) + .once(); replay(datastore); - List values = DatastoreHelper.fetch(datastore, key1, key2); + List values = DatastoreHelper.fetch(datastore, new Key[] {key1, key2}); + assertEquals(2, values.size()); + assertEquals(entity1, values.get(0)); + assertEquals(entity2, values.get(1)); + values = DatastoreHelper.fetch(datastore, new Key[] {key1, key2}, eventualConsistency); assertEquals(2, values.size()); assertEquals(entity1, values.get(0)); assertEquals(entity2, values.get(1)); verify(datastore); } + @Test + public void testFetchWithTransaction() throws Exception { + Transaction transaction = createStrictMock(Transaction.class); + IncompleteKey pKey1 = IncompleteKey.builder("ds", "k").build(); + Key key1 = Key.builder(pKey1, 1).build(); + Key key2 = Key.builder(pKey1, "a").build(); + Entity entity1 = Entity.builder(key1).build(); + Entity entity2 = Entity.builder(key2).build(); + expect(transaction.get(new Key[] {key1, key2})) + .andReturn(Iterators.forArray(entity1, entity2)) + .once(); + replay(transaction); + List values = DatastoreHelper.fetch(transaction, new Key[] {key1, key2}); + assertEquals(2, values.size()); + assertEquals(entity1, values.get(0)); + assertEquals(entity2, values.get(1)); + verify(transaction); + } + @Test public void testRunInTransaction() throws Exception { final Datastore datastore = createStrictMock(Datastore.class); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 002e5f6df04f..957ab881e7c4 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -25,7 +25,12 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; +import com.google.datastore.v1beta3.LookupResponse; +import com.google.datastore.v1beta3.PartitionId; +import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; +import com.google.datastore.v1beta3.RunQueryResponse; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; import com.google.gcloud.datastore.StructuredQuery.OrderBy; @@ -690,6 +695,37 @@ public void testQueryPaginationWithLimit() throws DatastoreException { return responses; } + @Test + public void testEventuallyConsistentQuery() { + DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) + .andReturn(rpcMock); + com.google.datastore.v1beta3.ReadOptions readOption = + com.google.datastore.v1beta3.ReadOptions.newBuilder() + .setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE) + .build(); + com.google.datastore.v1beta3.GqlQuery query = + com.google.datastore.v1beta3.GqlQuery.newBuilder() + .setQueryString("FROM * SELECT *") + .build(); + com.google.datastore.v1beta3.RunQueryRequest.Builder expectedRequest = + com.google.datastore.v1beta3.RunQueryRequest.newBuilder() + .setReadOptions(readOption) + .setGqlQuery(query) + .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID).build()); + EasyMock.expect(rpcMock.runQuery(expectedRequest.build())) + .andReturn(RunQueryResponse.newBuilder().build()); + EasyMock.replay(rpcFactoryMock, rpcMock); + Datastore mockDatastore = options.toBuilder() + .retryParams(RetryParams.defaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build() + .service(); + mockDatastore.run( + Query.gqlQueryBuilder("FROM * SELECT *").build(), ReadOption.eventualConsistency()); + } + @Test public void testToUrlSafe() { byte[][] invalidUtf8 = @@ -765,6 +801,40 @@ public void testGet() { assertFalse(entity.contains("bla")); } + @Test + public void testLookupEventualConsistency() { + DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) + .andReturn(rpcMock); + com.google.datastore.v1beta3.ReadOptions readOption = + com.google.datastore.v1beta3.ReadOptions.newBuilder() + .setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE) + .build(); + com.google.datastore.v1beta3.Key key = com.google.datastore.v1beta3.Key.newBuilder() + .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID).build()) + .addPath(com.google.datastore.v1beta3.Key.PathElement.newBuilder() + .setKind("kind1").setName("name").build()) + .build(); + com.google.datastore.v1beta3.LookupRequest lookupRequest = + com.google.datastore.v1beta3.LookupRequest.newBuilder() + .setReadOptions(readOption) + .addKeys(key) + .build(); + EasyMock.expect(rpcMock.lookup(lookupRequest)) + .andReturn(LookupResponse.newBuilder().build()) + .times(3); + EasyMock.replay(rpcFactoryMock, rpcMock); + Datastore mockDatastore = options.toBuilder() + .retryParams(RetryParams.defaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build() + .service(); + mockDatastore.get(KEY1, ReadOption.eventualConsistency()); + mockDatastore.get(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + mockDatastore.fetch(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + } + @Test public void testGetArrayNoDeferredResults() { datastore.put(ENTITY3); From 76e3b3ef5ead06e8741d887ca8c337451470692a Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Mar 2016 08:13:53 -0800 Subject: [PATCH 27/29] Clean up test code and javadoc formatting --- .../google/gcloud/datastore/Datastore.java | 21 +- .../gcloud/datastore/DatastoreHelper.java | 15 +- .../gcloud/datastore/DatastoreImpl.java | 15 +- .../gcloud/datastore/DatastoreReader.java | 15 +- .../google/gcloud/datastore/ReadOption.java | 2 +- .../gcloud/datastore/DatastoreTest.java | 452 +++++++----------- 6 files changed, 190 insertions(+), 330 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java index 00b914a36678..c0efaa52b4e8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java @@ -114,11 +114,11 @@ interface TransactionCallable { Entity get(Key key, ReadOption... options); /** - * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. - * The order of the result is unspecified. - * Results are loaded lazily, so it is possible to get a {@code DatastoreException} - * from the returned {@code Iterator}'s {@link Iterator#hasNext hasNext} or - * {@link Iterator#next next} methods. {@link ReadOption}s can be specified if desired. + * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. The order of + * the result is unspecified. Results are loaded lazily, so it is possible to get a + * {@code DatastoreException} from the returned {@code Iterator}'s + * {@link Iterator#hasNext hasNext} or {@link Iterator#next next} methods. {@link ReadOption}s can + * be specified if desired. * * @throws DatastoreException upon failure * @see #get(Key) @@ -126,16 +126,15 @@ interface TransactionCallable { Iterator get(Iterable keys, ReadOption... options); /** - * Returns a list with a value for each given key (ordered by input). - * {@code null} values are returned for nonexistent keys. - * When possible prefer using {@link #get(Key...)} to avoid eagerly loading the results. - * {@link ReadOption}s can be specified if desired. + * Returns a list with a value for each given key (ordered by input). {@code null} values are + * returned for nonexistent keys. When possible prefer using {@link #get(Key...)} to avoid eagerly + * loading the results. {@link ReadOption}s can be specified if desired. */ List fetch(Iterable keys, ReadOption... options); /** - * Submits a {@link Query} and returns its result. - * {@link ReadOption}s can be specified if desired. + * Submits a {@link Query} and returns its result. {@link ReadOption}s can be specified if + * desired. * * @throws DatastoreException upon failure */ diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java index 2873e2f8aafa..e3cf9c055576 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java @@ -56,22 +56,19 @@ static KeyFactory newKeyFactory(DatastoreOptions options) { } /** - * Returns a list with a value for each given key (ordered by input). - * {@code null} values are returned for nonexistent keys. + * Returns a list with a value for each given key (ordered by input). {@code null} values are + * returned for nonexistent keys. */ static List fetch(Transaction reader, Key... keys) { - Iterator entities = reader.get(keys); - return compileEntities(keys, entities); + return compileEntities(keys, reader.get(keys)); } /** - * Returns a list with a value for each given key (ordered by input). - * {@code null} values are returned for nonexistent keys. + * Returns a list with a value for each given key (ordered by input). {@code null} values are + * returned for nonexistent keys. */ static List fetch(Datastore reader, Key[] keys, ReadOption... options) { - Iterator entities; - entities = reader.get(Arrays.asList(keys), options); - return compileEntities(keys, entities); + return compileEntities(keys, reader.get(Arrays.asList(keys), options)); } private static List compileEntities(Key[] keys, Iterator entities) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 73d25ab140d7..80cf59980de1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -210,16 +210,11 @@ public Iterator get(Iterable keys, ReadOption... options) { private static com.google.datastore.v1beta3.ReadOptions toReadOptionsPb(ReadOption... options) { com.google.datastore.v1beta3.ReadOptions readOptionsPb = null; - if (options != null) { - Map, ReadOption> optionsMap = ReadOption.asImmutableMap(options); - EventualConsistency eventualConsistency = - (EventualConsistency) optionsMap.get(EventualConsistency.class); - if (eventualConsistency != null) { - readOptionsPb = - com.google.datastore.v1beta3.ReadOptions.newBuilder() - .setReadConsistency(ReadConsistency.EVENTUAL) - .build(); - } + if (options != null + && ReadOption.asImmutableMap(options).containsKey(EventualConsistency.class)) { + readOptionsPb = com.google.datastore.v1beta3.ReadOptions.newBuilder() + .setReadConsistency(ReadConsistency.EVENTUAL) + .build(); } return readOptionsPb; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java index 7ba5089ae4eb..3d6e5ec73243 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java @@ -32,11 +32,10 @@ public interface DatastoreReader { Entity get(Key key); /** - * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. - * The order of the result is unspecified. - * Results are loaded lazily, so it is possible to get a {@code DatastoreException} - * from the returned {@code Iterator}'s {@link Iterator#hasNext hasNext} or - * {@link Iterator#next next} methods. + * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. The order of + * the result is unspecified. Results are loaded lazily, so it is possible to get a + * {@code DatastoreException} from the returned {@code Iterator}'s + * {@link Iterator#hasNext hasNext} or {@link Iterator#next next} methods. * * @throws DatastoreException upon failure * @see #get(Key) @@ -44,9 +43,9 @@ public interface DatastoreReader { Iterator get(Key... key); /** - * Returns a list with a value for each given key (ordered by input). - * {@code null} values are returned for nonexistent keys. - * When possible prefer using {@link #get(Key...)} to avoid eagerly loading the results. + * Returns a list with a value for each given key (ordered by input). {@code null} values are + * returned for nonexistent keys. When possible prefer using {@link #get(Key...)} to avoid eagerly + * loading the results. */ List fetch(Key... keys); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java index 86214fddbf02..f8905716e564 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java @@ -47,7 +47,7 @@ public boolean isEventual() { } } - ReadOption() {} + private ReadOption() {} /** * Returns a {@code ReadOption} that specifies eventual consistency. diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 957ab881e7c4..23c22ac4f645 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -27,9 +27,14 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; +import com.google.datastore.v1beta3.EntityResult; +import com.google.datastore.v1beta3.LookupRequest; import com.google.datastore.v1beta3.LookupResponse; import com.google.datastore.v1beta3.PartitionId; +import com.google.datastore.v1beta3.QueryResultBatch; +import com.google.datastore.v1beta3.ReadOptions; import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; +import com.google.datastore.v1beta3.RunQueryRequest; import com.google.datastore.v1beta3.RunQueryResponse; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; @@ -96,22 +101,24 @@ public class DatastoreTest { private static final FullEntity PARTIAL_ENTITY3 = FullEntity.builder(PARTIAL_ENTITY1).key(IncompleteKey.builder(PROJECT_ID, KIND3).build()) .build(); - private static final Entity ENTITY1 = - Entity.builder(KEY1) - .set("str", STR_VALUE) - .set("date", DATE_TIME_VALUE) - .set("latLng", LAT_LNG_VALUE) - .set("bool", BOOL_VALUE) - .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) - .set("list", LIST_VALUE2) - .build(); + private static final Entity ENTITY1 = Entity.builder(KEY1) + .set("str", STR_VALUE) + .set("date", DATE_TIME_VALUE) + .set("latLng", LAT_LNG_VALUE) + .set("bool", BOOL_VALUE) + .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) + .set("list", LIST_VALUE2) + .build(); private static final Entity ENTITY2 = Entity.builder(ENTITY1).key(KEY2).remove("str") .set("name", "Dan").setNull("null").set("age", 20).build(); private static final Entity ENTITY3 = Entity.builder(ENTITY1).key(KEY3).remove("str") .set("null", NULL_VALUE).set("partial1", PARTIAL_ENTITY2).set("partial2", ENTITY2).build(); private DatastoreOptions options; + private DatastoreOptions rpcMockOptions; private Datastore datastore; + private DatastoreRpcFactory rpcFactoryMock; + private DatastoreRpc rpcMock; private static LocalGcdHelper gcdHelper; private static final int PORT = LocalGcdHelper.findAvailablePort(LocalGcdHelper.DEFAULT_PORT); @@ -134,6 +141,14 @@ public void setUp() { .retryParams(RetryParams.noRetries()) .build(); datastore = options.service(); + rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + rpcMockOptions = options + .toBuilder() + .retryParams(RetryParams.defaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build(); + EasyMock.expect(rpcFactoryMock.create(rpcMockOptions)).andReturn(rpcMock); StructuredQuery query = Query.keyQueryBuilder().build(); QueryResults result = datastore.run(query); datastore.delete(Iterators.toArray(result, Key.class)); @@ -426,24 +441,13 @@ public void testRunGqlQueryWithCasting() { @Test public void testGqlQueryPagination() throws DatastoreException { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - List responses = - buildResponsesForQueryPagination(); + List responses = buildResponsesForQueryPagination(); for (int i = 0; i < responses.size(); i++) { - EasyMock - .expect(rpcMock.runQuery( - EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) - .andReturn(responses.get(i)); + EasyMock.expect(rpcMock.runQuery(EasyMock.anyObject(RunQueryRequest.class))) + .andReturn(responses.get(i)); } EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore mockDatastore = options.service(); + Datastore mockDatastore = rpcMockOptions.service(); QueryResults results = mockDatastore.run(Query.gqlQueryBuilder(ResultType.KEY, "select __key__ from *").build()); int count = 0; @@ -480,15 +484,14 @@ public void testRunStructuredQuery() { assertTrue(projectionEntity.names().isEmpty()); assertFalse(results2.hasNext()); - StructuredQuery projectionQuery = - Query.projectionEntityQueryBuilder() - .kind(KIND2) - .projection("age") - .filter(PropertyFilter.gt("age", 18)) - .distinctOn("age") - .orderBy(OrderBy.asc("age")) - .limit(10) - .build(); + StructuredQuery projectionQuery = Query.projectionEntityQueryBuilder() + .kind(KIND2) + .projection("age") + .filter(PropertyFilter.gt("age", 18)) + .distinctOn("age") + .orderBy(OrderBy.asc("age")) + .limit(10) + .build(); QueryResults results4 = datastore.run(projectionQuery); assertTrue(results4.hasNext()); @@ -501,25 +504,14 @@ public void testRunStructuredQuery() { @Test public void testStructuredQueryPagination() throws DatastoreException { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - List responses = - buildResponsesForQueryPagination(); + List responses = buildResponsesForQueryPagination(); for (int i = 0; i < responses.size(); i++) { - EasyMock - .expect(rpcMock.runQuery( - EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) - .andReturn(responses.get(i)); + EasyMock.expect(rpcMock.runQuery(EasyMock.anyObject(RunQueryRequest.class))) + .andReturn(responses.get(i)); } EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore mockDatastore = options.service(); - QueryResults results = mockDatastore.run(Query.keyQueryBuilder().build()); + Datastore datastore = rpcMockOptions.service(); + QueryResults results = datastore.run(Query.keyQueryBuilder().build()); int count = 0; while (results.hasNext()) { count += 1; @@ -529,85 +521,57 @@ public void testStructuredQueryPagination() throws DatastoreException { EasyMock.verify(rpcFactoryMock, rpcMock); } - private List buildResponsesForQueryPagination() { + private List buildResponsesForQueryPagination() { Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); datastore.add(ENTITY3, entity4, entity5); - List responses = new ArrayList<>(); + List responses = new ArrayList<>(); Query query = Query.keyQueryBuilder().build(); - com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = - com.google.datastore.v1beta3.RunQueryRequest.newBuilder(); + RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); query.populatePb(requestPb); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb = - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) - .getBatch(); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb1 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb1) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb2 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 3)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(2).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb2) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb3 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(3, 5)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb3) - .build()); + QueryResultBatch queryResultBatchPb = RunQueryResponse.newBuilder() + .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) + .getBatch(); + QueryResultBatch queryResultBatchPb1 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NOT_FINISHED) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb1).build()); + QueryResultBatch queryResultBatchPb2 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NOT_FINISHED) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 3)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(2).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb2).build()); + QueryResultBatch queryResultBatchPb3 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(3, 5)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb3).build()); return responses; } public void testQueryPaginationWithLimit() throws DatastoreException { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - List responses = - buildResponsesForQueryPaginationWithLimit(); + List responses = buildResponsesForQueryPaginationWithLimit(); for (int i = 0; i < responses.size(); i++) { - EasyMock.expect( - rpcMock.runQuery( - EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) + EasyMock.expect(rpcMock.runQuery(EasyMock.anyObject(RunQueryRequest.class))) .andReturn(responses.get(i)); } EasyMock.replay(rpcFactoryMock, rpcMock); - Datastore mockDatastore = options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build() - .service(); + Datastore datastore = rpcMockOptions.service(); int limit = 2; int totalCount = 0; StructuredQuery query = Query.entityQueryBuilder().limit(limit).build(); while (true) { - QueryResults results = mockDatastore.run(query); + QueryResults results = datastore.run(query); int resultCount = 0; while (results.hasNext()) { results.next(); @@ -623,107 +587,72 @@ public void testQueryPaginationWithLimit() throws DatastoreException { EasyMock.verify(rpcFactoryMock, rpcMock); } - private List - buildResponsesForQueryPaginationWithLimit() { + private List buildResponsesForQueryPaginationWithLimit() { Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); datastore.add(ENTITY3, entity4, entity5); - List responses = new ArrayList<>(); + List responses = new ArrayList<>(); Query query = Query.entityQueryBuilder().build(); - com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = - com.google.datastore.v1beta3.RunQueryRequest.newBuilder(); + RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); query.populatePb(requestPb); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb = - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) - .getBatch(); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb1 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb1) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb2 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType - .MORE_RESULTS_AFTER_LIMIT) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 2)) - .setEndCursor( - ByteString.copyFrom(new byte[] {(byte) 0x80})) // test invalid UTF-8 string - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb2) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb3 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType - .MORE_RESULTS_AFTER_LIMIT) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(2, 4)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(3).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb3) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb4 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(4, 5)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb4) - .build()); + QueryResultBatch queryResultBatchPb = RunQueryResponse.newBuilder() + .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) + .getBatch(); + QueryResultBatch queryResultBatchPb1 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NOT_FINISHED) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb1).build()); + QueryResultBatch queryResultBatchPb2 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.MORE_RESULTS_AFTER_LIMIT) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 2)) + .setEndCursor( + ByteString.copyFrom(new byte[] {(byte) 0x80})) // test invalid UTF-8 string + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb2).build()); + QueryResultBatch queryResultBatchPb3 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.MORE_RESULTS_AFTER_LIMIT) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(2, 4)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(3).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb3).build()); + QueryResultBatch queryResultBatchPb4 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(4, 5)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb4).build()); return responses; } @Test - public void testEventuallyConsistentQuery() { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - com.google.datastore.v1beta3.ReadOptions readOption = - com.google.datastore.v1beta3.ReadOptions.newBuilder() - .setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE) - .build(); - com.google.datastore.v1beta3.GqlQuery query = - com.google.datastore.v1beta3.GqlQuery.newBuilder() - .setQueryString("FROM * SELECT *") - .build(); - com.google.datastore.v1beta3.RunQueryRequest.Builder expectedRequest = - com.google.datastore.v1beta3.RunQueryRequest.newBuilder() - .setReadOptions(readOption) - .setGqlQuery(query) - .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID).build()); + public void testEventualConsistencyQuery() { + ReadOptions readOption = + ReadOptions.newBuilder().setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE).build(); + com.google.datastore.v1beta3.GqlQuery query = com.google.datastore.v1beta3.GqlQuery.newBuilder() + .setQueryString("FROM * SELECT *") + .build(); + RunQueryRequest.Builder expectedRequest = RunQueryRequest.newBuilder() + .setReadOptions(readOption) + .setGqlQuery(query) + .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID) + .build()); EasyMock.expect(rpcMock.runQuery(expectedRequest.build())) .andReturn(RunQueryResponse.newBuilder().build()); EasyMock.replay(rpcFactoryMock, rpcMock); - Datastore mockDatastore = options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build() - .service(); - mockDatastore.run( + Datastore datastore = rpcMockOptions.service(); + datastore.run( Query.gqlQueryBuilder("FROM * SELECT *").build(), ReadOption.eventualConsistency()); + EasyMock.verify(rpcFactoryMock, rpcMock); } @Test @@ -803,36 +732,24 @@ public void testGet() { @Test public void testLookupEventualConsistency() { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - com.google.datastore.v1beta3.ReadOptions readOption = - com.google.datastore.v1beta3.ReadOptions.newBuilder() - .setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE) - .build(); + ReadOptions readOption = + ReadOptions.newBuilder().setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE).build(); com.google.datastore.v1beta3.Key key = com.google.datastore.v1beta3.Key.newBuilder() .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID).build()) .addPath(com.google.datastore.v1beta3.Key.PathElement.newBuilder() .setKind("kind1").setName("name").build()) .build(); - com.google.datastore.v1beta3.LookupRequest lookupRequest = - com.google.datastore.v1beta3.LookupRequest.newBuilder() - .setReadOptions(readOption) - .addKeys(key) - .build(); + LookupRequest lookupRequest = + LookupRequest.newBuilder().setReadOptions(readOption).addKeys(key).build(); EasyMock.expect(rpcMock.lookup(lookupRequest)) .andReturn(LookupResponse.newBuilder().build()) .times(3); EasyMock.replay(rpcFactoryMock, rpcMock); - Datastore mockDatastore = options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build() - .service(); - mockDatastore.get(KEY1, ReadOption.eventualConsistency()); - mockDatastore.get(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); - mockDatastore.fetch(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + Datastore datastore = rpcMockOptions.service(); + datastore.get(KEY1, ReadOption.eventualConsistency()); + datastore.get(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + datastore.fetch(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + EasyMock.verify(rpcFactoryMock, rpcMock); } @Test @@ -898,57 +815,41 @@ private Datastore createDatastoreForDeferredLookup() throws DatastoreException { keysPb.add(KEY3.toPb()); keysPb.add(KEY4.toPb()); keysPb.add(KEY5.toPb()); - List lookupRequests = new ArrayList<>(); + List lookupRequests = new ArrayList<>(); + lookupRequests.add(LookupRequest.newBuilder().addAllKeys(keysPb).build()); lookupRequests.add( - com.google.datastore.v1beta3.LookupRequest.newBuilder().addAllKeys(keysPb).build()); - lookupRequests.add( - com.google.datastore.v1beta3.LookupRequest.newBuilder() + LookupRequest.newBuilder() .addKeys(keysPb.get(2)) .addKeys(keysPb.get(3)) .addKeys(keysPb.get(5)) .build()); - lookupRequests.add( - com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(keysPb.get(5)).build()); + lookupRequests.add(LookupRequest.newBuilder().addKeys(keysPb.get(5)).build()); Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); - List lookupResponses = new ArrayList<>(); + List lookupResponses = new ArrayList<>(); lookupResponses.add( - com.google.datastore.v1beta3.LookupResponse.newBuilder() - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(ENTITY1.toPb())) - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(entity4.toPb())) + LookupResponse.newBuilder() + .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())) + .addFound(EntityResult.newBuilder().setEntity(entity4.toPb())) .addDeferred(keysPb.get(2)) .addDeferred(keysPb.get(3)) .addDeferred(keysPb.get(5)) .build()); lookupResponses.add( - com.google.datastore.v1beta3.LookupResponse.newBuilder() - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(ENTITY3.toPb())) - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(entity4.toPb())) + LookupResponse.newBuilder() + .addFound(EntityResult.newBuilder().setEntity(ENTITY3.toPb())) + .addFound(EntityResult.newBuilder().setEntity(entity4.toPb())) .addDeferred(keysPb.get(5)) .build()); lookupResponses.add( - com.google.datastore.v1beta3.LookupResponse.newBuilder() - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(entity5.toPb())) + LookupResponse.newBuilder() + .addFound(EntityResult.newBuilder().setEntity(entity5.toPb())) .build()); - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); for (int i = 0; i < lookupRequests.size(); i++) { EasyMock.expect(rpcMock.lookup(lookupRequests.get(i))).andReturn(lookupResponses.get(i)); } EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = - this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - return options.service(); + return rpcMockOptions.service(); } @Test @@ -1044,26 +945,15 @@ public void testKeyFactory() { @Test public void testRetryableException() throws Exception { - com.google.datastore.v1beta3.LookupRequest requestPb = - com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); - com.google.datastore.v1beta3.LookupResponse responsePb = - com.google.datastore.v1beta3.LookupResponse.newBuilder() - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(ENTITY1.toPb())) - .build(); - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); + LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); + LookupResponse responsePb = LookupResponse.newBuilder() + .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())) + .build(); EasyMock.expect(rpcMock.lookup(requestPb)) .andThrow(new DatastoreException(14, "UNAVAILABLE", "UNAVAILABLE", null)) .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore datastore = options.service(); + Datastore datastore = rpcMockOptions.service(); Entity entity = datastore.get(KEY1); assertEquals(ENTITY1, entity); EasyMock.verify(rpcFactoryMock, rpcMock); @@ -1071,23 +961,13 @@ public void testRetryableException() throws Exception { @Test public void testNonRetryableException() throws Exception { - com.google.datastore.v1beta3.LookupRequest requestPb = - com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); + LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); EasyMock.expect(rpcMock.lookup(requestPb)) .andThrow( new DatastoreException(DatastoreException.UNKNOWN_CODE, "denied", "PERMISSION_DENIED")) .times(1); EasyMock.replay(rpcFactoryMock, rpcMock); - RetryParams retryParams = RetryParams.builder().retryMinAttempts(2).build(); - DatastoreOptions options = this.options.toBuilder() - .retryParams(retryParams) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore datastore = options.service(); + Datastore datastore = rpcMockOptions.service(); thrown.expect(DatastoreException.class); thrown.expectMessage("denied"); datastore.get(KEY1); @@ -1096,21 +976,11 @@ public void testNonRetryableException() throws Exception { @Test public void testRuntimeException() throws Exception { - com.google.datastore.v1beta3.LookupRequest requestPb = - com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); + LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); String exceptionMessage = "Artificial runtime exception"; - EasyMock.expect(rpcMock.lookup(requestPb)) - .andThrow(new RuntimeException(exceptionMessage)); + EasyMock.expect(rpcMock.lookup(requestPb)).andThrow(new RuntimeException(exceptionMessage)); EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore datastore = options.service(); + Datastore datastore = rpcMockOptions.service(); thrown.expect(DatastoreException.class); thrown.expectMessage(exceptionMessage); datastore.get(KEY1); From 0d794eaf55f61ad3156d3ecbce9b64562e870868 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Mar 2016 10:08:37 -0800 Subject: [PATCH 28/29] Improve eventual consistency javadoc --- .../main/java/com/google/gcloud/datastore/ReadOption.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java index f8905716e564..f0de06d1651d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java @@ -30,7 +30,8 @@ public abstract class ReadOption implements Serializable { private static final long serialVersionUID = -4406964829189800528L; /** - * Specifies eventual consistency for reads from Datastore. + * Specifies eventual consistency for reads from Datastore. Lookups and ancestor queries using + * this option permit Datastore to return stale results. */ public static final class EventualConsistency extends ReadOption { @@ -50,7 +51,8 @@ public boolean isEventual() { private ReadOption() {} /** - * Returns a {@code ReadOption} that specifies eventual consistency. + * Returns a {@code ReadOption} that specifies eventual consistency, allowing Datastore to return + * stale results from gets, fetches, and ancestor queries. */ public static EventualConsistency eventualConsistency() { return new EventualConsistency(true); From 637860c6b7548c5aa8c118b2580a83bc837ef270 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 29 Mar 2016 17:25:05 -0700 Subject: [PATCH 29/29] Update dependencies --- gcloud-java-datastore/pom.xml | 14 ++------------ .../gcloud/datastore/testing/LocalGcdHelper.java | 4 ++-- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index e25144eec8a4..c640ab5a6d86 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -12,16 +12,6 @@ gcloud-java-pom 0.1.7-SNAPSHOT - - - sonatype-snapshots - sonatype-snapshots - https://oss.sonatype.org/content/repositories/snapshots/ - - true - - - gcloud-java-datastore @@ -34,12 +24,12 @@ com.google.cloud.datastore datastore-v1beta3-protos - 0.0.1-SNAPSHOT + 1.0.0-beta com.google.cloud.datastore datastore-v1beta3-proto-client - 0.0.1-SNAPSHOT + 1.0.0-beta ${project.groupId} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java index d5ce0efe0498..6f1a76b0a482 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java @@ -78,10 +78,10 @@ public class LocalGcdHelper { public static final String DEFAULT_PROJECT_ID = "projectid1"; public static final int DEFAULT_PORT = 8080; private static final String GCD_VERSION = "v1beta3"; - private static final String GCD_BUILD = "0.0.1"; + private static final String GCD_BUILD = "1.0.0"; private static final String GCD_BASENAME = "gcd-" + GCD_VERSION + "-" + GCD_BUILD; private static final String GCD_FILENAME = GCD_BASENAME + ".zip"; - private static final String MD5_CHECKSUM = "496b16f32473d0de0c7a974bd0ee1461"; + private static final String MD5_CHECKSUM = "72156cc993835c57f72789519b85249b"; private static final URL GCD_URL; private static final String GCLOUD = "gcloud"; private static final Path INSTALLED_GCD_PATH;