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

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: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « service/datastore/checkfilter_test.go ('k') | service/datastore/datastore_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: service/datastore/datastore.go
diff --git a/service/datastore/datastore.go b/service/datastore/datastore.go
index 375066276565ad044864079f33f66b109ebd82ec..3c328c966efcdb947d03c131ed839ce5620a0571 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,23 +66,35 @@ func (d *datastoreImpl) NewKeyToks(toks []KeyTok) *Key {
//
// obj is any object that Interface.Get is able to accept.
//
+// 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.
+//
// 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) {
- populateKeyMGS(getMGS(obj), key)
+func PopulateKey(obj interface{}, key *Key) bool {
+ return populateKeyMGS(getMGS(obj), key)
}
-func populateKeyMGS(mgs MetaGetterSetter, key *Key) {
- if !mgs.SetMeta("key", key) {
- lst := key.LastTok()
- if lst.StringID != "" {
- mgs.SetMeta("id", lst.StringID)
- } else {
- mgs.SetMeta("id", lst.IntID)
+func populateKeyMGS(mgs MetaGetterSetter, key *Key) bool {
+ if mgs.SetMeta("key", key) {
+ return true
+ }
+
+ lst := key.LastTok()
+ if lst.StringID != "" {
+ if !mgs.SetMeta("id", lst.StringID) {
+ return false
+ }
+ } else {
+ if !mgs.SetMeta("id", lst.IntID) {
+ return false
}
- mgs.SetMeta("kind", lst.Kind)
- mgs.SetMeta("parent", key.Parent())
}
+
+ mgs.SetMeta("kind", lst.Kind)
+ mgs.SetMeta("parent", key.Parent())
+ return true
}
func checkMultiSliceType(v interface{}) error {
@@ -111,7 +133,7 @@ func runParseCallback(cbIface interface{}) (isKey, hasErr, hasCursorCB bool, mat
if firstArg == typeOfKey {
isKey = true
} else {
- mat = mustParseArg(firstArg)
+ mat = mustParseArg(firstArg, false)
if mat.newElem == nil {
badSig()
}
@@ -132,6 +154,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, mmaWriteKeys)
+ 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.Incomplete()
+ }
+
+ 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)
@@ -260,7 +333,11 @@ func (d *datastoreImpl) GetAll(q *Query, dst interface{}) error {
}
func (d *datastoreImpl) Exists(ent ...interface{}) (*ExistsResult, error) {
- mma, err := makeMetaMultiArg(ent, true)
+ if len(ent) == 0 {
+ return nil, nil
+ }
+
+ mma, err := makeMetaMultiArg(ent, mmaKeysOnly)
if err != nil {
panic(err)
}
@@ -269,15 +346,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 {
@@ -300,7 +378,11 @@ func (d *datastoreImpl) ExistsMulti(keys []*Key) (BoolList, error) {
}
func (d *datastoreImpl) Get(dst ...interface{}) (err error) {
- mma, err := makeMetaMultiArg(dst, false)
+ if len(dst) == 0 {
+ return nil
+ }
+
+ mma, err := makeMetaMultiArg(dst, mmaReadWrite)
if err != nil {
panic(err)
}
@@ -309,8 +391,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)
@@ -321,8 +405,6 @@ func (d *datastoreImpl) Get(dst ...interface{}) (err error) {
}
return mat.setPM(slot, pm)
})
-
- i++
return nil
}))
@@ -345,7 +427,11 @@ func (d *datastoreImpl) GetMulti(dst interface{}) error {
}
func (d *datastoreImpl) Put(src ...interface{}) (err error) {
- mma, err := makeMetaMultiArg(src, false)
+ if len(src) == 0 {
+ return nil
+ }
+
+ mma, err := makeMetaMultiArg(src, mmaReadWrite)
if err != nil {
panic(err)
}
@@ -354,6 +440,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
@@ -392,7 +481,11 @@ func (d *datastoreImpl) PutMulti(src interface{}) error {
}
func (d *datastoreImpl) Delete(ent ...interface{}) error {
- mma, err := makeMetaMultiArg(ent, true)
+ if len(ent) == 0 {
+ return nil
+ }
+
+ mma, err := makeMetaMultiArg(ent, mmaKeysOnly)
if err != nil {
panic(err)
}
@@ -401,15 +494,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
}))
« 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