Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: service/datastore/datastore.go

Issue 2007123002: datastore: Update AllocateIDs to take keys. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/gae@master
Patch Set: Add empty arg/key short-circuits for other varidic methods. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 datastore 5 package datastore
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "io" 9 "io"
10 "io/ioutil" 10 "io/ioutil"
(...skipping 30 matching lines...) Expand all
41 } 41 }
42 42
43 func (d *datastoreImpl) MakeKey(elems ...interface{}) *Key { 43 func (d *datastoreImpl) MakeKey(elems ...interface{}) *Key {
44 return MakeKey(d.aid, d.ns, elems...) 44 return MakeKey(d.aid, d.ns, elems...)
45 } 45 }
46 46
47 func (d *datastoreImpl) NewKey(kind, stringID string, intID int64, parent *Key) *Key { 47 func (d *datastoreImpl) NewKey(kind, stringID string, intID int64, parent *Key) *Key {
48 return NewKey(d.aid, d.ns, kind, stringID, intID, parent) 48 return NewKey(d.aid, d.ns, kind, stringID, intID, parent)
49 } 49 }
50 50
51 func (d *datastoreImpl) NewIncompleteKeys(count int, kind string, parent *Key) ( keys []*Key) {
52 if count > 0 {
53 keys = make([]*Key, count)
54 for i := range keys {
55 keys[i] = d.NewKey(kind, "", 0, parent)
56 }
57 }
58 return
59 }
60
51 func (d *datastoreImpl) NewKeyToks(toks []KeyTok) *Key { 61 func (d *datastoreImpl) NewKeyToks(toks []KeyTok) *Key {
52 return NewKeyToks(d.aid, d.ns, toks) 62 return NewKeyToks(d.aid, d.ns, toks)
53 } 63 }
54 64
55 // PopulateKey loads key into obj. 65 // PopulateKey loads key into obj.
56 // 66 //
57 // obj is any object that Interface.Get is able to accept. 67 // obj is any object that Interface.Get is able to accept.
58 // 68 //
59 // This method will panic if obj is an invalid datastore model. If the key could 69 // Upon successful application, this method will return true. If the key could
60 // not be applied to the object, nothing will happen. 70 // not be applied to the object, this method will return false. It will panic if
61 func PopulateKey(obj interface{}, key *Key) { 71 // obj is an invalid datastore model.
72 func PopulateKey(obj interface{}, key *Key) bool {
62 pls := getMGS(obj) 73 pls := getMGS(obj)
63 » if !pls.SetMeta("key", key) { 74 » if pls.SetMeta("key", key) {
64 » » lst := key.LastTok() 75 » » return true
65 » » if lst.StringID != "" { 76 » }
66 » » » pls.SetMeta("id", lst.StringID) 77
67 » » } else { 78 » lst := key.LastTok()
68 » » » pls.SetMeta("id", lst.IntID) 79 » if lst.StringID != "" {
80 » » if !pls.SetMeta("id", lst.StringID) {
81 » » » return false
69 } 82 }
70 » » pls.SetMeta("kind", lst.Kind) 83 » } else {
71 » » pls.SetMeta("parent", key.Parent()) 84 » » if !pls.SetMeta("id", lst.IntID) {
85 » » » return false
86 » » }
72 } 87 }
88 pls.SetMeta("kind", lst.Kind)
89 pls.SetMeta("parent", key.Parent())
90 return true
73 } 91 }
74 92
75 func checkMultiSliceType(v interface{}) error { 93 func checkMultiSliceType(v interface{}) error {
76 if reflect.TypeOf(v).Kind() == reflect.Slice { 94 if reflect.TypeOf(v).Kind() == reflect.Slice {
77 return nil 95 return nil
78 } 96 }
79 return fmt.Errorf("argument must be a slice, not %T", v) 97 return fmt.Errorf("argument must be a slice, not %T", v)
80 98
81 } 99 }
82 100
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 if cbTyp.NumOut() > 1 { 140 if cbTyp.NumOut() > 1 {
123 badSig() 141 badSig()
124 } else if cbTyp.NumOut() == 1 && cbTyp.Out(0) != typeOfError { 142 } else if cbTyp.NumOut() == 1 && cbTyp.Out(0) != typeOfError {
125 badSig() 143 badSig()
126 } 144 }
127 hasErr = cbTyp.NumOut() == 1 145 hasErr = cbTyp.NumOut() == 1
128 146
129 return 147 return
130 } 148 }
131 149
150 func (d *datastoreImpl) AllocateIDs(ent ...interface{}) error {
151 if len(ent) == 0 {
152 return nil
153 }
154
155 mma, err := makeMetaMultiArg(ent, true)
156 if err != nil {
157 panic(err)
158 }
159
160 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false)
161 if err != nil {
162 return err
163 }
164 if len(keys) == 0 {
165 return nil
166 }
167
168 // Convert each key to be partial valid, assigning an integer ID of 0. C onfirm
169 // that each object can be populated with such a key.
170 for i, key := range keys {
171 keys[i] = key.Partial()
172 }
173
174 var et errorTracker
175 it := mma.iterator(et.init(mma))
176 err = filterStop(d.RawInterface.AllocateIDs(keys, func(key *Key, err err or) error {
177 it.next(func(mat *multiArgType, v reflect.Value) error {
178 if err != nil {
179 return err
180 }
181
182 if !mat.setKey(v, key) {
183 return ErrInvalidKey
184 }
185 return nil
186 })
187
188 return nil
189 }))
190 if err == nil {
191 err = et.error()
192
193 if err != nil && len(ent) == 1 {
194 // Single-argument Exists will return a single error.
195 err = errors.SingleError(err)
196 }
197 }
198 return err
199 }
200
132 func (d *datastoreImpl) Run(q *Query, cbIface interface{}) error { 201 func (d *datastoreImpl) Run(q *Query, cbIface interface{}) error {
133 isKey, hasErr, hasCursorCB, mat := runParseCallback(cbIface) 202 isKey, hasErr, hasCursorCB, mat := runParseCallback(cbIface)
134 203
135 if isKey { 204 if isKey {
136 q = q.KeysOnly(true) 205 q = q.KeysOnly(true)
137 } 206 }
138 fq, err := q.Finalize() 207 fq, err := q.Finalize()
139 if err != nil { 208 if err != nil {
140 return err 209 return err
141 } 210 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 for i, e := range errs { 319 for i, e := range errs {
251 me[i] = e 320 me[i] = e
252 } 321 }
253 err = me 322 err = me
254 } 323 }
255 } 324 }
256 return err 325 return err
257 } 326 }
258 327
259 func (d *datastoreImpl) Exists(ent ...interface{}) (*ExistsResult, error) { 328 func (d *datastoreImpl) Exists(ent ...interface{}) (*ExistsResult, error) {
329 if len(ent) == 0 {
330 return nil, nil
331 }
332
260 mma, err := makeMetaMultiArg(ent, true) 333 mma, err := makeMetaMultiArg(ent, true)
261 if err != nil { 334 if err != nil {
262 panic(err) 335 panic(err)
263 } 336 }
264 337
265 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false) 338 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false)
266 if err != nil { 339 if err != nil {
267 return nil, err 340 return nil, err
268 } 341 }
342 if len(keys) == 0 {
343 return nil, nil
344 }
269 345
270 i := 0
271 var bt boolTracker 346 var bt boolTracker
272 it := mma.iterator(bt.init(mma)) 347 it := mma.iterator(bt.init(mma))
273 err = filterStop(d.RawInterface.GetMulti(keys, nil, func(_ PropertyMap, err error) error { 348 err = filterStop(d.RawInterface.GetMulti(keys, nil, func(_ PropertyMap, err error) error {
274 it.next(func(*multiArgType, reflect.Value) error { 349 it.next(func(*multiArgType, reflect.Value) error {
275 return err 350 return err
276 }) 351 })
277 i++
278 return nil 352 return nil
279 })) 353 }))
280 if err == nil { 354 if err == nil {
281 err = bt.error() 355 err = bt.error()
282 356
283 if err != nil && len(ent) == 1 { 357 if err != nil && len(ent) == 1 {
284 // Single-argument Exists will return a single error. 358 // Single-argument Exists will return a single error.
285 err = errors.SingleError(err) 359 err = errors.SingleError(err)
286 } 360 }
287 } 361 }
288 return bt.result(), err 362 return bt.result(), err
289 } 363 }
290 364
291 func (d *datastoreImpl) ExistsMulti(keys []*Key) (BoolList, error) { 365 func (d *datastoreImpl) ExistsMulti(keys []*Key) (BoolList, error) {
292 v, err := d.Exists(keys) 366 v, err := d.Exists(keys)
293 if err != nil { 367 if err != nil {
294 return nil, err 368 return nil, err
295 } 369 }
296 return v.List(0), nil 370 return v.List(0), nil
297 } 371 }
298 372
299 func (d *datastoreImpl) Get(dst ...interface{}) (err error) { 373 func (d *datastoreImpl) Get(dst ...interface{}) (err error) {
374 if len(dst) == 0 {
375 return nil
376 }
377
300 mma, err := makeMetaMultiArg(dst, false) 378 mma, err := makeMetaMultiArg(dst, false)
301 if err != nil { 379 if err != nil {
302 panic(err) 380 panic(err)
303 } 381 }
304 382
305 keys, pms, err := mma.getKeysPMs(d.aid, d.ns, true) 383 keys, pms, err := mma.getKeysPMs(d.aid, d.ns, true)
306 if err != nil { 384 if err != nil {
307 return err 385 return err
308 } 386 }
387 if len(keys) == 0 {
388 return nil
389 }
309 390
310 i := 0
311 var et errorTracker 391 var et errorTracker
312 it := mma.iterator(et.init(mma)) 392 it := mma.iterator(et.init(mma))
313 meta := NewMultiMetaGetter(pms) 393 meta := NewMultiMetaGetter(pms)
314 err = filterStop(d.RawInterface.GetMulti(keys, meta, func(pm PropertyMap , err error) error { 394 err = filterStop(d.RawInterface.GetMulti(keys, meta, func(pm PropertyMap , err error) error {
315 it.next(func(mat *multiArgType, slot reflect.Value) error { 395 it.next(func(mat *multiArgType, slot reflect.Value) error {
316 if err != nil { 396 if err != nil {
317 return err 397 return err
318 } 398 }
319 return mat.setPM(slot, pm) 399 return mat.setPM(slot, pm)
320 }) 400 })
321
322 i++
323 return nil 401 return nil
324 })) 402 }))
325 403
326 if err == nil { 404 if err == nil {
327 err = et.error() 405 err = et.error()
328 406
329 if err != nil && len(dst) == 1 { 407 if err != nil && len(dst) == 1 {
330 // Single-argument Get will return a single error. 408 // Single-argument Get will return a single error.
331 err = errors.SingleError(err) 409 err = errors.SingleError(err)
332 } 410 }
333 } 411 }
334 return err 412 return err
335 } 413 }
336 414
337 func (d *datastoreImpl) GetMulti(dst interface{}) error { 415 func (d *datastoreImpl) GetMulti(dst interface{}) error {
338 if err := checkMultiSliceType(dst); err != nil { 416 if err := checkMultiSliceType(dst); err != nil {
339 panic(err) 417 panic(err)
340 } 418 }
341 return d.Get(dst) 419 return d.Get(dst)
342 } 420 }
343 421
344 func (d *datastoreImpl) Put(src ...interface{}) (err error) { 422 func (d *datastoreImpl) Put(src ...interface{}) (err error) {
423 if len(src) == 0 {
424 return nil
425 }
426
345 mma, err := makeMetaMultiArg(src, false) 427 mma, err := makeMetaMultiArg(src, false)
346 if err != nil { 428 if err != nil {
347 panic(err) 429 panic(err)
348 } 430 }
349 431
350 keys, vals, err := mma.getKeysPMs(d.aid, d.ns, false) 432 keys, vals, err := mma.getKeysPMs(d.aid, d.ns, false)
351 if err != nil { 433 if err != nil {
352 return err 434 return err
353 } 435 }
436 if len(keys) == 0 {
437 return nil
438 }
354 439
355 i := 0 440 i := 0
356 var et errorTracker 441 var et errorTracker
357 it := mma.iterator(et.init(mma)) 442 it := mma.iterator(et.init(mma))
358 err = filterStop(d.RawInterface.PutMulti(keys, vals, func(key *Key, err error) error { 443 err = filterStop(d.RawInterface.PutMulti(keys, vals, func(key *Key, err error) error {
359 it.next(func(mat *multiArgType, slot reflect.Value) error { 444 it.next(func(mat *multiArgType, slot reflect.Value) error {
360 if err != nil { 445 if err != nil {
361 return err 446 return err
362 } 447 }
363 if key != keys[i] { 448 if key != keys[i] {
(...skipping 18 matching lines...) Expand all
382 } 467 }
383 468
384 func (d *datastoreImpl) PutMulti(src interface{}) error { 469 func (d *datastoreImpl) PutMulti(src interface{}) error {
385 if err := checkMultiSliceType(src); err != nil { 470 if err := checkMultiSliceType(src); err != nil {
386 panic(err) 471 panic(err)
387 } 472 }
388 return d.Put(src) 473 return d.Put(src)
389 } 474 }
390 475
391 func (d *datastoreImpl) Delete(ent ...interface{}) error { 476 func (d *datastoreImpl) Delete(ent ...interface{}) error {
477 if len(ent) == 0 {
478 return nil
479 }
480
392 mma, err := makeMetaMultiArg(ent, true) 481 mma, err := makeMetaMultiArg(ent, true)
393 if err != nil { 482 if err != nil {
394 panic(err) 483 panic(err)
395 } 484 }
396 485
397 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false) 486 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false)
398 if err != nil { 487 if err != nil {
399 return err 488 return err
400 } 489 }
490 if len(keys) == 0 {
491 return nil
492 }
401 493
402 i := 0
403 var et errorTracker 494 var et errorTracker
404 it := mma.iterator(et.init(mma)) 495 it := mma.iterator(et.init(mma))
405 err = filterStop(d.RawInterface.DeleteMulti(keys, func(err error) error { 496 err = filterStop(d.RawInterface.DeleteMulti(keys, func(err error) error {
406 it.next(func(*multiArgType, reflect.Value) error { 497 it.next(func(*multiArgType, reflect.Value) error {
407 return err 498 return err
408 }) 499 })
409 i++
410 500
411 return nil 501 return nil
412 })) 502 }))
413 if err == nil { 503 if err == nil {
414 err = et.error() 504 err = et.error()
415 505
416 if err != nil && len(ent) == 1 { 506 if err != nil && len(ent) == 1 {
417 // Single-argument Delete will return a single error. 507 // Single-argument Delete will return a single error.
418 err = errors.SingleError(err) 508 err = errors.SingleError(err)
419 } 509 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 currentDir = filepath.Dir(currentDir) 601 currentDir = filepath.Dir(currentDir)
512 } 602 }
513 } 603 }
514 604
515 func filterStop(err error) error { 605 func filterStop(err error) error {
516 if err == Stop { 606 if err == Stop {
517 err = nil 607 err = nil
518 } 608 }
519 return err 609 return err
520 } 610 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698