Index: impl/memory/datastore_query_execution.go |
diff --git a/impl/memory/datastore_query_execution.go b/impl/memory/datastore_query_execution.go |
index 6fdd28bbf68fc7bcfee0c77429739309b7a770e5..9804898fc6cb82b0b93bedfe07454be87b7fecc8 100644 |
--- a/impl/memory/datastore_query_execution.go |
+++ b/impl/memory/datastore_query_execution.go |
@@ -6,7 +6,9 @@ package memory |
import ( |
"bytes" |
+ "errors" |
"fmt" |
+ "strings" |
ds "github.com/luci/gae/service/datastore" |
"github.com/luci/gae/service/datastore/serialize" |
@@ -178,6 +180,58 @@ func countQuery(fq *ds.FinalizedQuery, aid, ns string, isTxn bool, idx, head *me |
return |
} |
+func executeNamespaceQuery(fq *ds.FinalizedQuery, aid string, head *memStore, cb ds.RawRunCB) error { |
+ // these objects have no properties, so any filters on properties cause an |
+ // empty result. |
+ if len(fq.EqFilters()) > 0 || len(fq.Project()) > 0 || len(fq.Orders()) > 1 { |
+ return nil |
+ } |
+ if !(fq.IneqFilterProp() == "" || fq.IneqFilterProp() == "__key__") { |
+ return nil |
+ } |
+ colls := head.GetCollectionNames() |
+ foundEnts := false |
+ limit, hasLimit := fq.Limit() |
+ offset, hasOffset := fq.Offset() |
+ start, end := fq.Bounds() |
+ |
+ cursErr := errors.New("cursors not supported for __namespace__ query") |
+ cursFn := func() (ds.Cursor, error) { return nil, cursErr } |
+ if !(start == nil && end == nil) { |
+ return cursErr |
+ } |
+ for _, c := range colls { |
+ if !strings.HasPrefix(c, "ents:") { |
+ if foundEnts { |
+ break |
+ } |
+ continue |
+ } |
+ foundEnts = true |
+ if hasOffset && offset > 0 { |
+ offset-- |
+ continue |
+ } |
+ if hasLimit { |
+ if limit <= 0 { |
+ return ds.Stop |
+ } |
+ limit-- |
+ } |
+ k := (*ds.Key)(nil) |
+ ns := c[len("ents:"):] |
+ if ns == "" { |
dnj
2016/04/16 00:18:26
WDYT about adding a comment here about how datasto
iannucci
2016/04/16 00:51:52
Sure. Done.
|
+ k = ds.MakeKey(aid, "", "__namespace__", 1) |
+ } else { |
+ k = ds.MakeKey(aid, "", "__namespace__", ns) |
+ } |
+ if err := cb(k, nil, cursFn); err != nil { |
+ return err |
+ } |
+ } |
+ return nil |
+} |
+ |
func executeQuery(fq *ds.FinalizedQuery, aid, ns string, isTxn bool, idx, head *memStore, cb ds.RawRunCB) error { |
rq, err := reduce(fq, aid, ns, isTxn) |
if err == ds.ErrNullQuery { |
@@ -187,6 +241,10 @@ func executeQuery(fq *ds.FinalizedQuery, aid, ns string, isTxn bool, idx, head * |
return err |
} |
+ if rq.kind == "__namespace__" { |
+ return executeNamespaceQuery(fq, aid, head, cb) |
+ } |
+ |
idxs, err := getIndexes(rq, idx) |
if err == ds.ErrNullQuery { |
return nil |