Skip to content

Commit 0cb15cd

Browse files
author
Ajay Kannan
committed
fix distinct and cursor code
1 parent c029c37 commit 0cb15cd

File tree

6 files changed

+73
-110
lines changed

6 files changed

+73
-110
lines changed

gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static com.google.gcloud.datastore.Validator.validateNamespace;
2121

2222
import com.google.common.base.MoreObjects;
23+
import com.google.common.base.Preconditions;
2324
import com.google.common.collect.ImmutableList;
2425
import com.google.common.collect.ImmutableMap;
2526
import com.google.common.collect.ImmutableSortedMap;
@@ -137,10 +138,8 @@ static Binding fromPb(com.google.datastore.v1beta3.GqlQueryParameter argPb) {
137138
switch (argPb.getParameterTypeCase()) {
138139
case CURSOR:
139140
return new Binding(new Cursor(argPb.getCursor()));
140-
case VALUE:
141-
return new Binding(Value.fromPb(argPb.getValue()));
142141
default:
143-
return null;
142+
return new Binding(Value.fromPb(argPb.getValue()));
144143
}
145144
}
146145
}
@@ -398,16 +397,14 @@ private static <V> GqlQuery<V> fromPb(
398397
for (Map.Entry<String, com.google.datastore.v1beta3.GqlQueryParameter> nameArg
399398
: queryPb.getNamedBindings().entrySet()) {
400399
Binding currBinding = Binding.fromPb(nameArg.getValue());
401-
if (currBinding != null) {
402-
builder.namedBindings.put(nameArg.getKey(), currBinding);
403-
}
400+
Preconditions.checkState(currBinding != null);
401+
builder.namedBindings.put(nameArg.getKey(), currBinding);
404402
}
405403
for (com.google.datastore.v1beta3.GqlQueryParameter numberArg
406404
: queryPb.getPositionalBindingsList()) {
407405
Binding currBinding = Binding.fromPb(numberArg);
408-
if (currBinding != null) {
409-
builder.positionalBindings.add(currBinding);
410-
}
406+
Preconditions.checkState(currBinding != null);
407+
builder.positionalBindings.add(currBinding);
411408
}
412409
return builder.build();
413410
}

gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public abstract static class ResultType<V> implements java.io.Serializable {
6262
private static final long serialVersionUID = 1602329532153860907L;
6363

6464
@Override protected Object convert(com.google.datastore.v1beta3.Entity entityPb) {
65-
if (entityPb.getProperties().size() == 0) {
65+
if (entityPb.getProperties().isEmpty()) {
6666
if (!entityPb.hasKey()) {
6767
return null;
6868
}

gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ private void sendRequest() {
7070
entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator();
7171
if (queryResultBatchPb.getSkippedResults() > 0) {
7272
cursor = queryResultBatchPb.getSkippedCursor();
73+
} else if (entityResultPbIter.hasNext()) {
74+
cursor = queryResultBatchPb.getEntityResults(0).getCursor();
75+
} else {
76+
cursor = queryResultBatchPb.getEndCursor();
7377
}
7478
actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType());
7579
if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) {

gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java

Lines changed: 57 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
* .kind(kind)
6969
* .projection(Projection.property("age"), Projection.first("name"))
7070
* .filter(PropertyFilter.gt("age", 18))
71-
* .groupBy("age")
71+
* .distinct("age")
7272
* .orderBy(OrderBy.asc("age"))
7373
* .limit(10)
7474
* .build();
@@ -86,9 +86,9 @@ public class StructuredQuery<V> extends Query<V> {
8686
private static final String KEY_PROPERTY_NAME = "__key__";
8787

8888
private final transient String kind;
89-
private final ImmutableList<Projection> projection;
89+
private final ImmutableList<String> projection;
9090
private final transient Filter filter;
91-
private final ImmutableList<String> groupBy;
91+
private final ImmutableList<String> distinctOn;
9292
private final transient ImmutableList<OrderBy> orderBy;
9393
private final transient Cursor startCursor;
9494
private final transient Cursor endCursor;
@@ -108,10 +108,8 @@ static Filter fromPb(com.google.datastore.v1beta3.Filter filterPb) {
108108
switch (filterPb.getFilterTypeCase()) {
109109
case COMPOSITE_FILTER:
110110
return CompositeFilter.fromPb(filterPb.getCompositeFilter());
111-
case PROPERTY_FILTER:
112-
return PropertyFilter.fromPb(filterPb.getPropertyFilter());
113111
default:
114-
return null;
112+
return PropertyFilter.fromPb(filterPb.getPropertyFilter());
115113
}
116114
}
117115
}
@@ -525,65 +523,15 @@ static OrderBy fromPb(com.google.datastore.v1beta3.PropertyOrder propertyOrderPb
525523
}
526524
}
527525

528-
public static final class Projection implements Serializable {
529-
530-
private static final long serialVersionUID = 3083707957256279470L;
531-
532-
private final String property;
533-
534-
private Projection(String property) {
535-
this.property = property;
536-
}
537-
538-
@Override
539-
public int hashCode() {
540-
return Objects.hash(property);
541-
}
542-
543-
@Override
544-
public boolean equals(Object obj) {
545-
if (obj == this) {
546-
return true;
547-
}
548-
if (!(obj instanceof Projection)) {
549-
return false;
550-
}
551-
return Objects.equals(property, ((Projection) obj).property);
552-
}
553-
554-
@Override
555-
public String toString() {
556-
ToStringHelper toStringHelper = MoreObjects.toStringHelper(this);
557-
toStringHelper.add("property", property);
558-
return toStringHelper.toString();
559-
}
560-
561-
com.google.datastore.v1beta3.Projection toPb() {
562-
com.google.datastore.v1beta3.Projection.Builder expressionPb =
563-
com.google.datastore.v1beta3.Projection.newBuilder();
564-
expressionPb.setProperty(
565-
com.google.datastore.v1beta3.PropertyReference.newBuilder().setName(property).build());
566-
return expressionPb.build();
567-
}
568-
569-
public static Projection fromPb(
570-
com.google.datastore.v1beta3.Projection projectionPb) {
571-
return new Projection(projectionPb.getProperty().getName());
572-
}
573-
574-
public static Projection property(String property) {
575-
return new Projection(property);
576-
}
577-
}
578-
579526
static class BaseBuilder<V, B extends BaseBuilder<V, B>> {
580527

581528
private final ResultType<V> resultType;
582529
private String namespace;
583530
private String kind;
584-
private final List<Projection> projection = new LinkedList<>();
531+
private final List<String> projection = new LinkedList<>();
585532
private Filter filter;
586-
private final List<String> groupBy = new LinkedList<>();
533+
private boolean distinctOnAll = false;
534+
private final List<String> distinctOn = new LinkedList<>();
587535
private final List<OrderBy> orderBy = new LinkedList<>();
588536
private Cursor startCursor;
589537
private Cursor endCursor;
@@ -658,32 +606,39 @@ B clearProjection() {
658606
return self();
659607
}
660608

661-
B projection(Projection projection, Projection... others) {
609+
B projection(String projection, String... others) {
662610
clearProjection();
663611
addProjection(projection, others);
664612
return self();
665613
}
666614

667-
B addProjection(Projection projection, Projection... others) {
615+
B addProjection(String projection, String... others) {
668616
this.projection.add(projection);
669617
Collections.addAll(this.projection, others);
670618
return self();
671619
}
672620

673-
B clearGroupBy() {
674-
groupBy.clear();
621+
B clearDistinct() {
622+
distinctOn.clear();
623+
distinctOnAll = false;
675624
return self();
676625
}
677626

678-
B groupBy(String property, String... others) {
679-
clearGroupBy();
680-
addGroupBy(property, others);
627+
B distinct(String... properties) {
628+
clearDistinct();
629+
if (properties.length == 0) {
630+
this.distinctOnAll = true;
631+
} else if (properties.length == 1) {
632+
addDistinct(properties[0]);
633+
} else {
634+
addDistinct(properties[0], Arrays.copyOfRange(properties, 1, properties.length));
635+
}
681636
return self();
682637
}
683638

684-
B addGroupBy(String property, String... others) {
685-
this.groupBy.add(property);
686-
Collections.addAll(this.groupBy, others);
639+
B addDistinct(String property, String... others) {
640+
this.distinctOn.add(property);
641+
Collections.addAll(this.distinctOn, others);
687642
return self();
688643
}
689644

@@ -712,15 +667,20 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) {
712667
}
713668
for (com.google.datastore.v1beta3.Projection projectionPb
714669
: queryPb.getProjectionList()) {
715-
addProjection(Projection.fromPb(projectionPb));
670+
addProjection(projectionPb.getProperty().getName());
716671
}
717-
for (com.google.datastore.v1beta3.PropertyReference groupByPb : queryPb.getDistinctOnList()) {
718-
addGroupBy(groupByPb.getName());
672+
for (com.google.datastore.v1beta3.PropertyReference distinctOnPb : queryPb.getDistinctOnList()) {
673+
addDistinct(distinctOnPb.getName());
719674
}
675+
distinctOnAll = false;
720676
return self();
721677
}
722678

723679
public StructuredQuery<V> build() {
680+
if (distinctOnAll) {
681+
clearDistinct();
682+
this.distinctOn.addAll(this.projection);
683+
}
724684
return new StructuredQuery<>(this);
725685
}
726686
}
@@ -748,14 +708,14 @@ public static final class KeyQueryBuilder extends BaseBuilder<Key, KeyQueryBuild
748708

749709
KeyQueryBuilder() {
750710
super(ResultType.KEY);
751-
projection(Projection.property(KEY_PROPERTY_NAME));
711+
projection(KEY_PROPERTY_NAME);
752712
}
753713

754714
@Override
755715
protected KeyQueryBuilder mergeFrom(com.google.datastore.v1beta3.Query queryPb) {
756716
super.mergeFrom(queryPb);
757-
projection(Projection.property(KEY_PROPERTY_NAME));
758-
clearGroupBy();
717+
projection(KEY_PROPERTY_NAME);
718+
clearDistinct();
759719
return this;
760720
}
761721

@@ -783,28 +743,28 @@ public ProjectionEntityQueryBuilder clearProjection() {
783743
}
784744

785745
@Override
786-
public ProjectionEntityQueryBuilder projection(Projection projection, Projection... others) {
746+
public ProjectionEntityQueryBuilder projection(String projection, String... others) {
787747
return super.projection(projection, others);
788748
}
789749

790750
@Override
791-
public ProjectionEntityQueryBuilder addProjection(Projection projection, Projection... others) {
751+
public ProjectionEntityQueryBuilder addProjection(String projection, String... others) {
792752
return super.addProjection(projection, others);
793753
}
794754

795755
@Override
796-
public ProjectionEntityQueryBuilder clearGroupBy() {
797-
return super.clearGroupBy();
756+
public ProjectionEntityQueryBuilder clearDistinct() {
757+
return super.clearDistinct();
798758
}
799759

800760
@Override
801-
public ProjectionEntityQueryBuilder groupBy(String property, String... others) {
802-
return super.groupBy(property, others);
761+
public ProjectionEntityQueryBuilder distinct(String... properties) {
762+
return super.distinct(properties);
803763
}
804764

805765
@Override
806-
public ProjectionEntityQueryBuilder addGroupBy(String property, String... others) {
807-
return super.addGroupBy(property, others);
766+
public ProjectionEntityQueryBuilder addDistinct(String property, String... others) {
767+
return super.addDistinct(property, others);
808768
}
809769
}
810770

@@ -813,7 +773,7 @@ public ProjectionEntityQueryBuilder addGroupBy(String property, String... others
813773
kind = builder.kind;
814774
projection = ImmutableList.copyOf(builder.projection);
815775
filter = builder.filter;
816-
groupBy = ImmutableList.copyOf(builder.groupBy);
776+
distinctOn = ImmutableList.copyOf(builder.distinctOn);
817777
orderBy = ImmutableList.copyOf(builder.orderBy);
818778
startCursor = builder.startCursor;
819779
endCursor = builder.endCursor;
@@ -824,7 +784,7 @@ public ProjectionEntityQueryBuilder addGroupBy(String property, String... others
824784
@Override
825785
public int hashCode() {
826786
return Objects.hash(namespace(), kind, startCursor, endCursor, offset, limit, filter, orderBy,
827-
projection(), groupBy());
787+
groupBy());
828788
}
829789

830790
@Override
@@ -845,7 +805,7 @@ public boolean equals(Object obj) {
845805
&& Objects.equals(filter, other.filter)
846806
&& Objects.equals(orderBy, other.orderBy)
847807
&& Objects.equals(projection, other.projection)
848-
&& Objects.equals(groupBy, other.groupBy);
808+
&& Objects.equals(distinctOn, other.distinctOn);
849809

850810
}
851811

@@ -854,19 +814,19 @@ public String kind() {
854814
}
855815

856816
boolean keyOnly() {
857-
return projection.size() == 1 && KEY_PROPERTY_NAME.equals(projection.get(0).property);
817+
return projection.size() == 1 && KEY_PROPERTY_NAME.equals(projection.get(0));
858818
}
859819

860-
public List<Projection> projection() {
820+
public List<String> projection() {
861821
return projection;
862822
}
863823

864824
public Filter filter() {
865825
return filter;
866826
}
867827

868-
public List<String> groupBy() {
869-
return groupBy;
828+
public List<String> distinct() {
829+
return distinctOn;
870830
}
871831

872832
public ImmutableList<OrderBy> orderBy() {
@@ -935,12 +895,16 @@ protected com.google.datastore.v1beta3.Query toPb() {
935895
for (OrderBy value : orderBy) {
936896
queryPb.addOrder(value.toPb());
937897
}
938-
for (String value : groupBy) {
898+
for (String value : distinctOn) {
939899
queryPb.addDistinctOn(com.google.datastore.v1beta3.PropertyReference.newBuilder()
940900
.setName(value).build());
941901
}
942-
for (Projection value : projection) {
943-
queryPb.addProjection(value.toPb());
902+
for (String value : projection) {
903+
com.google.datastore.v1beta3.Projection.Builder expressionPb =
904+
com.google.datastore.v1beta3.Projection.newBuilder();
905+
expressionPb.setProperty(
906+
com.google.datastore.v1beta3.PropertyReference.newBuilder().setName(value).build());
907+
queryPb.addProjection(expressionPb.build());
944908
}
945909
return queryPb.build();
946910
}

gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import com.google.gcloud.RetryParams;
3030
import com.google.gcloud.datastore.Query.ResultType;
3131
import com.google.gcloud.datastore.StructuredQuery.OrderBy;
32-
import com.google.gcloud.datastore.StructuredQuery.Projection;
3332
import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
3433
import com.google.gcloud.spi.DatastoreRpc;
3534
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason;
@@ -421,7 +420,7 @@ public void testRunStructuredQuery() {
421420

422421
StructuredQuery<ProjectionEntity> keyOnlyProjectionQuery =
423422
Query.projectionEntityQueryBuilder()
424-
.kind(KIND1).projection(Projection.property("__key__")).build();
423+
.kind(KIND1).projection("__key__").build();
425424
QueryResults<ProjectionEntity> results3 = datastore.run(keyOnlyProjectionQuery);
426425
assertTrue(results3.hasNext());
427426
ProjectionEntity projectionEntity = results3.next();
@@ -431,9 +430,9 @@ public void testRunStructuredQuery() {
431430

432431
StructuredQuery<ProjectionEntity> projectionQuery = Query.projectionEntityQueryBuilder()
433432
.kind(KIND2)
434-
.projection(Projection.property("age"))
433+
.projection("age")
435434
.filter(PropertyFilter.gt("age", 18))
436-
.groupBy("age")
435+
.distinct("age")
437436
.orderBy(OrderBy.asc("age"))
438437
.limit(10)
439438
.build();

0 commit comments

Comments
 (0)