Chromium Code Reviews| 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 |