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

Unified Diff: service/datastore/datastore.go

Issue 2011773002: datastore: variadic Get, Put, Exists, Delete. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/gae@master
Patch Set: 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 752c99c55779e02a2f97cced14b351645f18a6af..cb0a0bb77f9baa39f647725c92685b27f0e42492 100644
--- a/service/datastore/datastore.go
+++ b/service/datastore/datastore.go
@@ -37,7 +37,7 @@ func (d *datastoreImpl) KeyForObj(src interface{}) *Key {
}
func (d *datastoreImpl) KeyForObjErr(src interface{}) (*Key, error) {
- return newKeyObjErr(d.aid, d.ns, src)
+ return newKeyObjErr(d.aid, d.ns, getMGS(src))
}
func (d *datastoreImpl) MakeKey(elems ...interface{}) *Key {
@@ -72,7 +72,15 @@ func PopulateKey(obj interface{}, key *Key) {
}
}
-func runParseCallback(cbIface interface{}) (isKey, hasErr, hasCursorCB bool, mat multiArgType) {
+func checkMultiSliceType(v interface{}) error {
+ if reflect.TypeOf(v).Kind() == reflect.Slice {
+ return nil
+ }
+ return fmt.Errorf("argument must be a slice, not %T", v)
+
+}
+
+func runParseCallback(cbIface interface{}) (isKey, hasErr, hasCursorCB bool, mat *multiArgType) {
badSig := func() {
panic(fmt.Errorf(
"cb does not match the required callback signature: `%T` != `func(TYPE, [CursorCB]) [error]`",
@@ -100,7 +108,7 @@ func runParseCallback(cbIface interface{}) (isKey, hasErr, hasCursorCB bool, mat
if firstArg == typeOfKey {
isKey = true
} else {
- mat = parseArg(firstArg, false)
+ mat = mustParseArg(firstArg)
if mat.newElem == nil {
badSig()
}
@@ -218,7 +226,7 @@ func (d *datastoreImpl) GetAll(q *Query, dst interface{}) error {
}
slice := v.Elem()
- mat := parseMultiArg(slice.Type())
+ mat := mustParseMultiArg(slice.Type())
if mat.newElem == nil {
panic(fmt.Errorf("invalid GetAll dst (non-concrete element type): %T", dst))
}
@@ -248,26 +256,7 @@ func (d *datastoreImpl) GetAll(q *Query, dst interface{}) error {
return err
}
-func isOkType(t reflect.Type) error {
dnj 2016/05/25 05:27:15 This check is moved into "multiarg.go".
- if t == nil {
- return errors.New("no type information")
- }
- if t.Implements(typeOfPropertyLoadSaver) {
- return nil
- }
- if t == typeOfKey {
- return errors.New("not user datatype")
- }
- if t.Kind() != reflect.Ptr {
- return errors.New("not a pointer")
- }
- if t.Elem().Kind() != reflect.Struct {
- return errors.New("does not point to a struct")
- }
- return nil
-}
-
-func (d *datastoreImpl) ExistsMulti(keys []*Key) (BoolList, error) {
+func (d *datastoreImpl) ExistsMulti(keys ...*Key) (BoolList, error) {
lme := errors.NewLazyMultiError(len(keys))
ret := make(BoolList, len(keys))
i := 0
@@ -287,80 +276,105 @@ func (d *datastoreImpl) ExistsMulti(keys []*Key) (BoolList, error) {
}
func (d *datastoreImpl) Exists(k *Key) (bool, error) {
- ret, err := d.ExistsMulti([]*Key{k})
+ ret, err := d.ExistsMulti(k)
return ret[0], errors.SingleError(err)
}
-func (d *datastoreImpl) Get(dst interface{}) (err error) {
- if err := isOkType(reflect.TypeOf(dst)); err != nil {
- panic(fmt.Errorf("invalid Get input type (%T): %s", dst, err))
- }
- return errors.SingleError(d.GetMulti([]interface{}{dst}))
-}
-
-func (d *datastoreImpl) Put(src interface{}) (err error) {
- if err := isOkType(reflect.TypeOf(src)); err != nil {
- panic(fmt.Errorf("invalid Put input type (%T): %s", src, err))
+func (d *datastoreImpl) Get(dst ...interface{}) (err error) {
+ mma, err := makeMetaMultiArg(dst)
+ if err != nil {
+ panic(err)
}
- return errors.SingleError(d.PutMulti([]interface{}{src}))
-}
-
-func (d *datastoreImpl) Delete(key *Key) (err error) {
- return errors.SingleError(d.DeleteMulti([]*Key{key}))
-}
-
-func (d *datastoreImpl) GetMulti(dst interface{}) error {
- slice := reflect.ValueOf(dst)
- mat := parseMultiArg(slice.Type())
- keys, pms, err := mat.GetKeysPMs(d.aid, d.ns, slice, true)
+ keys, pms, err := mma.getKeysPMs(d.aid, d.ns, true)
if err != nil {
return err
}
- lme := errors.NewLazyMultiError(len(keys))
i := 0
+ it := mma.iterator()
meta := NewMultiMetaGetter(pms)
err = filterStop(d.RawInterface.GetMulti(keys, meta, func(pm PropertyMap, err error) error {
- if !lme.Assign(i, err) {
- lme.Assign(i, mat.setPM(slice.Index(i), pm))
- }
+ it.next(func(mat *multiArgType, slot reflect.Value) error {
dnj 2016/05/25 05:27:15 Just a quick explanation, since Rietveld sorted th
+ if err != nil {
+ return err
+ }
+ return mat.setPM(slot, pm)
+ })
+
i++
return nil
}))
if err == nil {
- err = lme.Get()
+ err = it.error()
dnj 2016/05/25 05:27:15 (This returns the MultiError accumulated by "it").
+
+ if err != nil && len(dst) == 1 {
+ // Single-argument Get will return a single error.
+ err = errors.SingleError(err)
+ }
}
return err
}
-func (d *datastoreImpl) PutMulti(src interface{}) error {
- slice := reflect.ValueOf(src)
- mat := parseMultiArg(slice.Type())
+func (d *datastoreImpl) GetMulti(dst interface{}) error {
+ if err := checkMultiSliceType(dst); err != nil {
+ panic(err)
+ }
+ return d.Get(dst)
+}
- keys, vals, err := mat.GetKeysPMs(d.aid, d.ns, slice, false)
+func (d *datastoreImpl) Put(src ...interface{}) (err error) {
+ mma, err := makeMetaMultiArg(src)
+ if err != nil {
+ panic(err)
+ }
+
+ keys, vals, err := mma.getKeysPMs(d.aid, d.ns, false)
if err != nil {
return err
}
- lme := errors.NewLazyMultiError(len(keys))
i := 0
+ it := mma.iterator()
err = filterStop(d.RawInterface.PutMulti(keys, vals, func(key *Key, err error) error {
- if !lme.Assign(i, err) && key != keys[i] {
- mat.setKey(slice.Index(i), key)
- }
+ it.next(func(mat *multiArgType, slot reflect.Value) error {
+ if err != nil {
+ return err
+ }
+ if key != keys[i] {
+ mat.setKey(slot, key)
+ }
+ return nil
+ })
+
i++
return nil
}))
if err == nil {
- err = lme.Get()
+ err = it.error()
+
+ if err != nil && len(src) == 1 {
+ // Single-argument Get will return a single error.
+ err = errors.SingleError(err)
+ }
}
return err
}
-func (d *datastoreImpl) DeleteMulti(keys []*Key) (err error) {
+func (d *datastoreImpl) PutMulti(src interface{}) error {
+ if err := checkMultiSliceType(src); err != nil {
+ panic(err)
+ }
+ return d.Put(src)
+}
+
+func (d *datastoreImpl) Delete(key *Key) (err error) {
+ return errors.SingleError(d.DeleteMulti(key))
+}
+
+func (d *datastoreImpl) DeleteMulti(keys ...*Key) (err error) {
lme := errors.NewLazyMultiError(len(keys))
i := 0
extErr := filterStop(d.RawInterface.DeleteMulti(keys, func(internalErr error) error {

Powered by Google App Engine
This is Rietveld 408576698