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 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |