OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "errors" | 9 "errors" |
10 "fmt" | 10 "fmt" |
11 "strings" | |
12 | 11 |
13 ds "github.com/luci/gae/service/datastore" | 12 ds "github.com/luci/gae/service/datastore" |
14 "github.com/luci/gae/service/datastore/serialize" | 13 "github.com/luci/gae/service/datastore/serialize" |
15 "github.com/luci/luci-go/common/cmpbin" | 14 "github.com/luci/luci-go/common/cmpbin" |
16 "github.com/luci/luci-go/common/stringset" | 15 "github.com/luci/luci-go/common/stringset" |
17 ) | 16 ) |
18 | 17 |
19 type queryStrategy interface { | 18 type queryStrategy interface { |
20 // handle applies the strategy to the embedded user callback. | 19 // handle applies the strategy to the embedded user callback. |
21 // - rawData is the slice of encoded Properties from the index row | 20 // - rawData is the slice of encoded Properties from the index row |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 | 181 |
183 func executeNamespaceQuery(fq *ds.FinalizedQuery, aid string, head *memStore, cb
ds.RawRunCB) error { | 182 func executeNamespaceQuery(fq *ds.FinalizedQuery, aid string, head *memStore, cb
ds.RawRunCB) error { |
184 // these objects have no properties, so any filters on properties cause
an | 183 // these objects have no properties, so any filters on properties cause
an |
185 // empty result. | 184 // empty result. |
186 if len(fq.EqFilters()) > 0 || len(fq.Project()) > 0 || len(fq.Orders())
> 1 { | 185 if len(fq.EqFilters()) > 0 || len(fq.Project()) > 0 || len(fq.Orders())
> 1 { |
187 return nil | 186 return nil |
188 } | 187 } |
189 if !(fq.IneqFilterProp() == "" || fq.IneqFilterProp() == "__key__") { | 188 if !(fq.IneqFilterProp() == "" || fq.IneqFilterProp() == "__key__") { |
190 return nil | 189 return nil |
191 } | 190 } |
192 colls := head.GetCollectionNames() | |
193 foundEnts := false | |
194 limit, hasLimit := fq.Limit() | 191 limit, hasLimit := fq.Limit() |
195 offset, hasOffset := fq.Offset() | 192 offset, hasOffset := fq.Offset() |
196 start, end := fq.Bounds() | 193 start, end := fq.Bounds() |
197 | 194 |
198 cursErr := errors.New("cursors not supported for __namespace__ query") | 195 cursErr := errors.New("cursors not supported for __namespace__ query") |
199 cursFn := func() (ds.Cursor, error) { return nil, cursErr } | 196 cursFn := func() (ds.Cursor, error) { return nil, cursErr } |
200 if !(start == nil && end == nil) { | 197 if !(start == nil && end == nil) { |
201 return cursErr | 198 return cursErr |
202 } | 199 } |
203 » for _, c := range colls { | 200 » for _, ns := range namespaces(head) { |
204 » » if !strings.HasPrefix(c, "ents:") { | |
205 » » » if foundEnts { | |
206 » » » » break | |
207 » » » } | |
208 » » » continue | |
209 » » } | |
210 » » foundEnts = true | |
211 if hasOffset && offset > 0 { | 201 if hasOffset && offset > 0 { |
212 offset-- | 202 offset-- |
213 continue | 203 continue |
214 } | 204 } |
215 if hasLimit { | 205 if hasLimit { |
216 if limit <= 0 { | 206 if limit <= 0 { |
217 return ds.Stop | 207 return ds.Stop |
218 } | 208 } |
219 limit-- | 209 limit-- |
220 } | 210 } |
221 k := (*ds.Key)(nil) | 211 k := (*ds.Key)(nil) |
222 ns := c[len("ents:"):] | |
223 if ns == "" { | 212 if ns == "" { |
224 // Datastore uses an id of 1 to indicate the default nam
espace in its | 213 // Datastore uses an id of 1 to indicate the default nam
espace in its |
225 // metadata API. | 214 // metadata API. |
226 k = ds.MakeKey(aid, "", "__namespace__", 1) | 215 k = ds.MakeKey(aid, "", "__namespace__", 1) |
227 } else { | 216 } else { |
228 k = ds.MakeKey(aid, "", "__namespace__", ns) | 217 k = ds.MakeKey(aid, "", "__namespace__", ns) |
229 } | 218 } |
230 if err := cb(k, nil, cursFn); err != nil { | 219 if err := cb(k, nil, cursFn); err != nil { |
231 return err | 220 return err |
232 } | 221 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 keyProp := decodedProps[len(decodedProps)-1] | 291 keyProp := decodedProps[len(decodedProps)-1] |
303 if keyProp.Type() != ds.PTKey { | 292 if keyProp.Type() != ds.PTKey { |
304 impossible(fmt.Errorf("decoded index row doesn't end wit
h a Key: %#v", keyProp)) | 293 impossible(fmt.Errorf("decoded index row doesn't end wit
h a Key: %#v", keyProp)) |
305 } | 294 } |
306 | 295 |
307 return strategy.handle( | 296 return strategy.handle( |
308 rawData, decodedProps, keyProp.Value().(*ds.Key), | 297 rawData, decodedProps, keyProp.Value().(*ds.Key), |
309 getCursorFn(suffix)) | 298 getCursorFn(suffix)) |
310 }) | 299 }) |
311 } | 300 } |
OLD | NEW |