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

Unified 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, 7 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 side-by-side diff with in-line comments
Download patch
Index: service/datastore/datastore.go
diff --git a/service/datastore/datastore.go b/service/datastore/datastore.go
index 5f9c64c8ce5c7d825bd91da3b03967fdec334ec5..e244c69f536f2ff0a741e1daada888744e88d39a 100644
--- a/service/datastore/datastore.go
+++ b/service/datastore/datastore.go
@@ -48,6 +48,16 @@ func (d *datastoreImpl) NewKey(kind, stringID string, intID int64, parent *Key)
return NewKey(d.aid, d.ns, kind, stringID, intID, parent)
}
+func (d *datastoreImpl) NewIncompleteKeys(count int, kind string, parent *Key) (keys []*Key) {
+ if count > 0 {
+ keys = make([]*Key, count)
+ for i := range keys {
+ keys[i] = d.NewKey(kind, "", 0, parent)
+ }
+ }
+ return
+}
+
func (d *datastoreImpl) NewKeyToks(toks []KeyTok) *Key {
return NewKeyToks(d.aid, d.ns, toks)
}
@@ -56,20 +66,28 @@ func (d *datastoreImpl) NewKeyToks(toks []KeyTok) *Key {
//
// obj is any object that Interface.Get is able to accept.
//
-// This method will panic if obj is an invalid datastore model. If the key could
-// not be applied to the object, nothing will happen.
-func PopulateKey(obj interface{}, key *Key) {
+// Upon successful application, this method will return true. If the key could
+// not be applied to the object, this method will return false. It will panic if
+// obj is an invalid datastore model.
+func PopulateKey(obj interface{}, key *Key) bool {
pls := getMGS(obj)
- if !pls.SetMeta("key", key) {
- lst := key.LastTok()
- if lst.StringID != "" {
- pls.SetMeta("id", lst.StringID)
- } else {
- pls.SetMeta("id", lst.IntID)
+ if pls.SetMeta("key", key) {
+ return true
+ }
+
+ lst := key.LastTok()
+ if lst.StringID != "" {
+ if !pls.SetMeta("id", lst.StringID) {
+ return false
+ }
+ } else {
+ if !pls.SetMeta("id", lst.IntID) {
+ return false
}
- pls.SetMeta("kind", lst.Kind)
- pls.SetMeta("parent", key.Parent())
}
+ pls.SetMeta("kind", lst.Kind)
+ pls.SetMeta("parent", key.Parent())
+ return true
}
func checkMultiSliceType(v interface{}) error {
@@ -129,6 +147,57 @@ func runParseCallback(cbIface interface{}) (isKey, hasErr, hasCursorCB bool, mat
return
}
+func (d *datastoreImpl) AllocateIDs(ent ...interface{}) error {
+ if len(ent) == 0 {
+ return nil
+ }
+
+ mma, err := makeMetaMultiArg(ent, true)
+ if err != nil {
+ panic(err)
+ }
+
+ keys, _, err := mma.getKeysPMs(d.aid, d.ns, false)
+ if err != nil {
+ return err
+ }
+ if len(keys) == 0 {
+ return nil
+ }
+
+ // Convert each key to be partial valid, assigning an integer ID of 0. Confirm
+ // that each object can be populated with such a key.
+ for i, key := range keys {
+ keys[i] = key.Partial()
+ }
+
+ var et errorTracker
+ it := mma.iterator(et.init(mma))
+ err = filterStop(d.RawInterface.AllocateIDs(keys, func(key *Key, err error) error {
+ it.next(func(mat *multiArgType, v reflect.Value) error {
+ if err != nil {
+ return err
+ }
+
+ if !mat.setKey(v, key) {
+ return ErrInvalidKey
+ }
+ return nil
+ })
+
+ return nil
+ }))
+ if err == nil {
+ err = et.error()
+
+ if err != nil && len(ent) == 1 {
+ // Single-argument Exists will return a single error.
+ err = errors.SingleError(err)
+ }
+ }
+ return err
+}
+
func (d *datastoreImpl) Run(q *Query, cbIface interface{}) error {
isKey, hasErr, hasCursorCB, mat := runParseCallback(cbIface)
@@ -257,6 +326,10 @@ func (d *datastoreImpl) GetAll(q *Query, dst interface{}) error {
}
func (d *datastoreImpl) Exists(ent ...interface{}) (*ExistsResult, error) {
+ if len(ent) == 0 {
+ return nil, nil
+ }
+
mma, err := makeMetaMultiArg(ent, true)
if err != nil {
panic(err)
@@ -266,15 +339,16 @@ func (d *datastoreImpl) Exists(ent ...interface{}) (*ExistsResult, error) {
if err != nil {
return nil, err
}
+ if len(keys) == 0 {
+ return nil, nil
+ }
- i := 0
var bt boolTracker
it := mma.iterator(bt.init(mma))
err = filterStop(d.RawInterface.GetMulti(keys, nil, func(_ PropertyMap, err error) error {
it.next(func(*multiArgType, reflect.Value) error {
return err
})
- i++
return nil
}))
if err == nil {
@@ -297,6 +371,10 @@ func (d *datastoreImpl) ExistsMulti(keys []*Key) (BoolList, error) {
}
func (d *datastoreImpl) Get(dst ...interface{}) (err error) {
+ if len(dst) == 0 {
+ return nil
+ }
+
mma, err := makeMetaMultiArg(dst, false)
if err != nil {
panic(err)
@@ -306,8 +384,10 @@ func (d *datastoreImpl) Get(dst ...interface{}) (err error) {
if err != nil {
return err
}
+ if len(keys) == 0 {
+ return nil
+ }
- i := 0
var et errorTracker
it := mma.iterator(et.init(mma))
meta := NewMultiMetaGetter(pms)
@@ -318,8 +398,6 @@ func (d *datastoreImpl) Get(dst ...interface{}) (err error) {
}
return mat.setPM(slot, pm)
})
-
- i++
return nil
}))
@@ -342,6 +420,10 @@ func (d *datastoreImpl) GetMulti(dst interface{}) error {
}
func (d *datastoreImpl) Put(src ...interface{}) (err error) {
+ if len(src) == 0 {
+ return nil
+ }
+
mma, err := makeMetaMultiArg(src, false)
if err != nil {
panic(err)
@@ -351,6 +433,9 @@ func (d *datastoreImpl) Put(src ...interface{}) (err error) {
if err != nil {
return err
}
+ if len(keys) == 0 {
+ return nil
+ }
i := 0
var et errorTracker
@@ -389,6 +474,10 @@ func (d *datastoreImpl) PutMulti(src interface{}) error {
}
func (d *datastoreImpl) Delete(ent ...interface{}) error {
+ if len(ent) == 0 {
+ return nil
+ }
+
mma, err := makeMetaMultiArg(ent, true)
if err != nil {
panic(err)
@@ -398,15 +487,16 @@ func (d *datastoreImpl) Delete(ent ...interface{}) error {
if err != nil {
return err
}
+ if len(keys) == 0 {
+ return nil
+ }
- i := 0
var et errorTracker
it := mma.iterator(et.init(mma))
err = filterStop(d.RawInterface.DeleteMulti(keys, func(err error) error {
it.next(func(*multiArgType, reflect.Value) error {
return err
})
- i++
return nil
}))

Powered by Google App Engine
This is Rietveld 408576698