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

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: Rebase, comments. 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
« no previous file with comments | « service/datastore/checkfilter_test.go ('k') | service/datastore/datastore_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be 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 //
69 // Upon successful application, this method will return true. If the key could
70 // not be applied to the object, this method will return false. It will panic if
71 // obj is an invalid datastore model.
72 //
59 // This method will panic if obj is an invalid datastore model. If the key could 73 // This method will panic if obj is an invalid datastore model. If the key could
60 // not be applied to the object, nothing will happen. 74 // not be applied to the object, nothing will happen.
61 func PopulateKey(obj interface{}, key *Key) { 75 func PopulateKey(obj interface{}, key *Key) bool {
62 » populateKeyMGS(getMGS(obj), key) 76 » return populateKeyMGS(getMGS(obj), key)
63 } 77 }
64 78
65 func populateKeyMGS(mgs MetaGetterSetter, key *Key) { 79 func populateKeyMGS(mgs MetaGetterSetter, key *Key) bool {
66 » if !mgs.SetMeta("key", key) { 80 » if mgs.SetMeta("key", key) {
67 » » lst := key.LastTok() 81 » » return true
68 » » if lst.StringID != "" { 82 » }
69 » » » mgs.SetMeta("id", lst.StringID) 83
70 » » } else { 84 » lst := key.LastTok()
71 » » » mgs.SetMeta("id", lst.IntID) 85 » if lst.StringID != "" {
86 » » if !mgs.SetMeta("id", lst.StringID) {
87 » » » return false
72 } 88 }
73 » » mgs.SetMeta("kind", lst.Kind) 89 » } else {
74 » » mgs.SetMeta("parent", key.Parent()) 90 » » if !mgs.SetMeta("id", lst.IntID) {
91 » » » return false
92 » » }
75 } 93 }
94
95 mgs.SetMeta("kind", lst.Kind)
96 mgs.SetMeta("parent", key.Parent())
97 return true
76 } 98 }
77 99
78 func checkMultiSliceType(v interface{}) error { 100 func checkMultiSliceType(v interface{}) error {
79 if reflect.TypeOf(v).Kind() == reflect.Slice { 101 if reflect.TypeOf(v).Kind() == reflect.Slice {
80 return nil 102 return nil
81 } 103 }
82 return fmt.Errorf("argument must be a slice, not %T", v) 104 return fmt.Errorf("argument must be a slice, not %T", v)
83 105
84 } 106 }
85 107
(...skipping 18 matching lines...) Expand all
104 126
105 numIn := cbTyp.NumIn() 127 numIn := cbTyp.NumIn()
106 if numIn != 1 && numIn != 2 { 128 if numIn != 1 && numIn != 2 {
107 badSig() 129 badSig()
108 } 130 }
109 131
110 firstArg := cbTyp.In(0) 132 firstArg := cbTyp.In(0)
111 if firstArg == typeOfKey { 133 if firstArg == typeOfKey {
112 isKey = true 134 isKey = true
113 } else { 135 } else {
114 » » mat = mustParseArg(firstArg) 136 » » mat = mustParseArg(firstArg, false)
115 if mat.newElem == nil { 137 if mat.newElem == nil {
116 badSig() 138 badSig()
117 } 139 }
118 } 140 }
119 141
120 hasCursorCB = numIn == 2 142 hasCursorCB = numIn == 2
121 if hasCursorCB && cbTyp.In(1) != typeOfCursorCB { 143 if hasCursorCB && cbTyp.In(1) != typeOfCursorCB {
122 badSig() 144 badSig()
123 } 145 }
124 146
125 if cbTyp.NumOut() > 1 { 147 if cbTyp.NumOut() > 1 {
126 badSig() 148 badSig()
127 } else if cbTyp.NumOut() == 1 && cbTyp.Out(0) != typeOfError { 149 } else if cbTyp.NumOut() == 1 && cbTyp.Out(0) != typeOfError {
128 badSig() 150 badSig()
129 } 151 }
130 hasErr = cbTyp.NumOut() == 1 152 hasErr = cbTyp.NumOut() == 1
131 153
132 return 154 return
133 } 155 }
134 156
157 func (d *datastoreImpl) AllocateIDs(ent ...interface{}) error {
158 if len(ent) == 0 {
159 return nil
160 }
161
162 mma, err := makeMetaMultiArg(ent, mmaWriteKeys)
163 if err != nil {
164 panic(err)
165 }
166
167 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false)
168 if err != nil {
169 return err
170 }
171 if len(keys) == 0 {
172 return nil
173 }
174
175 // Convert each key to be partial valid, assigning an integer ID of 0. C onfirm
176 // that each object can be populated with such a key.
177 for i, key := range keys {
178 keys[i] = key.Incomplete()
179 }
180
181 var et errorTracker
182 it := mma.iterator(et.init(mma))
183 err = filterStop(d.RawInterface.AllocateIDs(keys, func(key *Key, err err or) error {
184 it.next(func(mat *multiArgType, v reflect.Value) error {
185 if err != nil {
186 return err
187 }
188
189 if !mat.setKey(v, key) {
190 return ErrInvalidKey
191 }
192 return nil
193 })
194
195 return nil
196 }))
197 if err == nil {
198 err = et.error()
199
200 if err != nil && len(ent) == 1 {
201 // Single-argument Exists will return a single error.
202 err = errors.SingleError(err)
203 }
204 }
205 return err
206 }
207
135 func (d *datastoreImpl) Run(q *Query, cbIface interface{}) error { 208 func (d *datastoreImpl) Run(q *Query, cbIface interface{}) error {
136 isKey, hasErr, hasCursorCB, mat := runParseCallback(cbIface) 209 isKey, hasErr, hasCursorCB, mat := runParseCallback(cbIface)
137 210
138 if isKey { 211 if isKey {
139 q = q.KeysOnly(true) 212 q = q.KeysOnly(true)
140 } 213 }
141 fq, err := q.Finalize() 214 fq, err := q.Finalize()
142 if err != nil { 215 if err != nil {
143 return err 216 return err
144 } 217 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 for i, e := range errs { 326 for i, e := range errs {
254 me[i] = e 327 me[i] = e
255 } 328 }
256 err = me 329 err = me
257 } 330 }
258 } 331 }
259 return err 332 return err
260 } 333 }
261 334
262 func (d *datastoreImpl) Exists(ent ...interface{}) (*ExistsResult, error) { 335 func (d *datastoreImpl) Exists(ent ...interface{}) (*ExistsResult, error) {
263 » mma, err := makeMetaMultiArg(ent, true) 336 » if len(ent) == 0 {
337 » » return nil, nil
338 » }
339
340 » mma, err := makeMetaMultiArg(ent, mmaKeysOnly)
264 if err != nil { 341 if err != nil {
265 panic(err) 342 panic(err)
266 } 343 }
267 344
268 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false) 345 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false)
269 if err != nil { 346 if err != nil {
270 return nil, err 347 return nil, err
271 } 348 }
349 if len(keys) == 0 {
350 return nil, nil
351 }
272 352
273 i := 0
274 var bt boolTracker 353 var bt boolTracker
275 it := mma.iterator(bt.init(mma)) 354 it := mma.iterator(bt.init(mma))
276 err = filterStop(d.RawInterface.GetMulti(keys, nil, func(_ PropertyMap, err error) error { 355 err = filterStop(d.RawInterface.GetMulti(keys, nil, func(_ PropertyMap, err error) error {
277 it.next(func(*multiArgType, reflect.Value) error { 356 it.next(func(*multiArgType, reflect.Value) error {
278 return err 357 return err
279 }) 358 })
280 i++
281 return nil 359 return nil
282 })) 360 }))
283 if err == nil { 361 if err == nil {
284 err = bt.error() 362 err = bt.error()
285 363
286 if err != nil && len(ent) == 1 { 364 if err != nil && len(ent) == 1 {
287 // Single-argument Exists will return a single error. 365 // Single-argument Exists will return a single error.
288 err = errors.SingleError(err) 366 err = errors.SingleError(err)
289 } 367 }
290 } 368 }
291 return bt.result(), err 369 return bt.result(), err
292 } 370 }
293 371
294 func (d *datastoreImpl) ExistsMulti(keys []*Key) (BoolList, error) { 372 func (d *datastoreImpl) ExistsMulti(keys []*Key) (BoolList, error) {
295 v, err := d.Exists(keys) 373 v, err := d.Exists(keys)
296 if err != nil { 374 if err != nil {
297 return nil, err 375 return nil, err
298 } 376 }
299 return v.List(0), nil 377 return v.List(0), nil
300 } 378 }
301 379
302 func (d *datastoreImpl) Get(dst ...interface{}) (err error) { 380 func (d *datastoreImpl) Get(dst ...interface{}) (err error) {
303 » mma, err := makeMetaMultiArg(dst, false) 381 » if len(dst) == 0 {
382 » » return nil
383 » }
384
385 » mma, err := makeMetaMultiArg(dst, mmaReadWrite)
304 if err != nil { 386 if err != nil {
305 panic(err) 387 panic(err)
306 } 388 }
307 389
308 keys, pms, err := mma.getKeysPMs(d.aid, d.ns, true) 390 keys, pms, err := mma.getKeysPMs(d.aid, d.ns, true)
309 if err != nil { 391 if err != nil {
310 return err 392 return err
311 } 393 }
394 if len(keys) == 0 {
395 return nil
396 }
312 397
313 i := 0
314 var et errorTracker 398 var et errorTracker
315 it := mma.iterator(et.init(mma)) 399 it := mma.iterator(et.init(mma))
316 meta := NewMultiMetaGetter(pms) 400 meta := NewMultiMetaGetter(pms)
317 err = filterStop(d.RawInterface.GetMulti(keys, meta, func(pm PropertyMap , err error) error { 401 err = filterStop(d.RawInterface.GetMulti(keys, meta, func(pm PropertyMap , err error) error {
318 it.next(func(mat *multiArgType, slot reflect.Value) error { 402 it.next(func(mat *multiArgType, slot reflect.Value) error {
319 if err != nil { 403 if err != nil {
320 return err 404 return err
321 } 405 }
322 return mat.setPM(slot, pm) 406 return mat.setPM(slot, pm)
323 }) 407 })
324
325 i++
326 return nil 408 return nil
327 })) 409 }))
328 410
329 if err == nil { 411 if err == nil {
330 err = et.error() 412 err = et.error()
331 413
332 if err != nil && len(dst) == 1 { 414 if err != nil && len(dst) == 1 {
333 // Single-argument Get will return a single error. 415 // Single-argument Get will return a single error.
334 err = errors.SingleError(err) 416 err = errors.SingleError(err)
335 } 417 }
336 } 418 }
337 return err 419 return err
338 } 420 }
339 421
340 func (d *datastoreImpl) GetMulti(dst interface{}) error { 422 func (d *datastoreImpl) GetMulti(dst interface{}) error {
341 if err := checkMultiSliceType(dst); err != nil { 423 if err := checkMultiSliceType(dst); err != nil {
342 panic(err) 424 panic(err)
343 } 425 }
344 return d.Get(dst) 426 return d.Get(dst)
345 } 427 }
346 428
347 func (d *datastoreImpl) Put(src ...interface{}) (err error) { 429 func (d *datastoreImpl) Put(src ...interface{}) (err error) {
348 » mma, err := makeMetaMultiArg(src, false) 430 » if len(src) == 0 {
431 » » return nil
432 » }
433
434 » mma, err := makeMetaMultiArg(src, mmaReadWrite)
349 if err != nil { 435 if err != nil {
350 panic(err) 436 panic(err)
351 } 437 }
352 438
353 keys, vals, err := mma.getKeysPMs(d.aid, d.ns, false) 439 keys, vals, err := mma.getKeysPMs(d.aid, d.ns, false)
354 if err != nil { 440 if err != nil {
355 return err 441 return err
356 } 442 }
443 if len(keys) == 0 {
444 return nil
445 }
357 446
358 i := 0 447 i := 0
359 var et errorTracker 448 var et errorTracker
360 it := mma.iterator(et.init(mma)) 449 it := mma.iterator(et.init(mma))
361 err = filterStop(d.RawInterface.PutMulti(keys, vals, func(key *Key, err error) error { 450 err = filterStop(d.RawInterface.PutMulti(keys, vals, func(key *Key, err error) error {
362 it.next(func(mat *multiArgType, slot reflect.Value) error { 451 it.next(func(mat *multiArgType, slot reflect.Value) error {
363 if err != nil { 452 if err != nil {
364 return err 453 return err
365 } 454 }
366 if key != keys[i] { 455 if key != keys[i] {
(...skipping 18 matching lines...) Expand all
385 } 474 }
386 475
387 func (d *datastoreImpl) PutMulti(src interface{}) error { 476 func (d *datastoreImpl) PutMulti(src interface{}) error {
388 if err := checkMultiSliceType(src); err != nil { 477 if err := checkMultiSliceType(src); err != nil {
389 panic(err) 478 panic(err)
390 } 479 }
391 return d.Put(src) 480 return d.Put(src)
392 } 481 }
393 482
394 func (d *datastoreImpl) Delete(ent ...interface{}) error { 483 func (d *datastoreImpl) Delete(ent ...interface{}) error {
395 » mma, err := makeMetaMultiArg(ent, true) 484 » if len(ent) == 0 {
485 » » return nil
486 » }
487
488 » mma, err := makeMetaMultiArg(ent, mmaKeysOnly)
396 if err != nil { 489 if err != nil {
397 panic(err) 490 panic(err)
398 } 491 }
399 492
400 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false) 493 keys, _, err := mma.getKeysPMs(d.aid, d.ns, false)
401 if err != nil { 494 if err != nil {
402 return err 495 return err
403 } 496 }
497 if len(keys) == 0 {
498 return nil
499 }
404 500
405 i := 0
406 var et errorTracker 501 var et errorTracker
407 it := mma.iterator(et.init(mma)) 502 it := mma.iterator(et.init(mma))
408 err = filterStop(d.RawInterface.DeleteMulti(keys, func(err error) error { 503 err = filterStop(d.RawInterface.DeleteMulti(keys, func(err error) error {
409 it.next(func(*multiArgType, reflect.Value) error { 504 it.next(func(*multiArgType, reflect.Value) error {
410 return err 505 return err
411 }) 506 })
412 i++
413 507
414 return nil 508 return nil
415 })) 509 }))
416 if err == nil { 510 if err == nil {
417 err = et.error() 511 err = et.error()
418 512
419 if err != nil && len(ent) == 1 { 513 if err != nil && len(ent) == 1 {
420 // Single-argument Delete will return a single error. 514 // Single-argument Delete will return a single error.
421 err = errors.SingleError(err) 515 err = errors.SingleError(err)
422 } 516 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 currentDir = filepath.Dir(currentDir) 608 currentDir = filepath.Dir(currentDir)
515 } 609 }
516 } 610 }
517 611
518 func filterStop(err error) error { 612 func filterStop(err error) error {
519 if err == Stop { 613 if err == Stop {
520 err = nil 614 err = nil
521 } 615 }
522 return err 616 return err
523 } 617 }
OLDNEW
« no previous file with comments | « service/datastore/checkfilter_test.go ('k') | service/datastore/datastore_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698