datastore: adds DistinctOn support (#189)
This is a port of the change in the Cloud Datastore package https://github.com/googleapis/google-cloud-go/commit/a370663b6dbaadb2ba5d7737f0b0471a0b41032e
diff --git a/datastore/query.go b/datastore/query.go
index c1ea4ad..4124534 100644
--- a/datastore/query.go
+++ b/datastore/query.go
@@ -82,14 +82,15 @@
order []order
projection []string
- distinct bool
- keysOnly bool
- eventual bool
- limit int32
- offset int32
- count int32
- start *pb.CompiledCursor
- end *pb.CompiledCursor
+ distinct bool
+ distinctOn []string
+ keysOnly bool
+ eventual bool
+ limit int32
+ offset int32
+ count int32
+ start *pb.CompiledCursor
+ end *pb.CompiledCursor
err error
}
@@ -199,13 +200,23 @@
// Distinct returns a derivative query that yields de-duplicated entities with
// respect to the set of projected fields. It is only used for projection
-// queries.
+// queries. Distinct cannot be used with DistinctOn.
func (q *Query) Distinct() *Query {
q = q.clone()
q.distinct = true
return q
}
+// DistinctOn returns a derivative query that yields de-duplicated entities with
+// respect to the set of the specified fields. It is only used for projection
+// queries. The field list should be a subset of the projected field list.
+// DistinctOn cannot be used with Distinct.
+func (q *Query) DistinctOn(fieldNames ...string) *Query {
+ q = q.clone()
+ q.distinctOn = fieldNames
+ return q
+}
+
// KeysOnly returns a derivative query that yields only keys, not keys and
// entities. It cannot be used with projection queries.
func (q *Query) KeysOnly() *Query {
@@ -282,6 +293,9 @@
if len(q.projection) != 0 && q.keysOnly {
return errors.New("datastore: query cannot both project and be keys-only")
}
+ if len(q.distinctOn) != 0 && q.distinct {
+ return errors.New("datastore: query cannot be both distinct and distinct-on")
+ }
dst.Reset()
dst.App = proto.String(appID)
if q.kind != "" {
@@ -295,6 +309,9 @@
}
if q.projection != nil {
dst.PropertyName = q.projection
+ if len(q.distinctOn) != 0 {
+ dst.GroupByPropertyName = q.distinctOn
+ }
if q.distinct {
dst.GroupByPropertyName = q.projection
}
diff --git a/datastore/query_test.go b/datastore/query_test.go
index 45e5313..ab96823 100644
--- a/datastore/query_test.go
+++ b/datastore/query_test.go
@@ -528,6 +528,14 @@
},
},
{
+ desc: "distinct on",
+ query: NewQuery("").Project("A", "B").DistinctOn("A"),
+ want: &pb.Query{
+ PropertyName: []string{"A", "B"},
+ GroupByPropertyName: []string{"A"},
+ },
+ },
+ {
desc: "keys only",
query: NewQuery("").KeysOnly(),
want: &pb.Query{