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

Side by Side Diff: service/datastore/datastore.go

Issue 1279703003: Get rid of awkward proto argument to Interface.Run (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: rename test helper Created 5 years, 4 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 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 "reflect" 9 "reflect"
10 10
11 "github.com/luci/luci-go/common/errors" 11 "github.com/luci/luci-go/common/errors"
12 ) 12 )
13 13
14 type datastoreImpl struct{ RawInterface } 14 type datastoreImpl struct{ RawInterface }
15 15
16 var _ Interface = (*datastoreImpl)(nil) 16 var _ Interface = (*datastoreImpl)(nil)
17 17
18 func (d *datastoreImpl) KeyForObj(src interface{}) Key { 18 func (d *datastoreImpl) KeyForObj(src interface{}) Key {
19 ret, err := d.KeyForObjErr(src) 19 ret, err := d.KeyForObjErr(src)
20 if err != nil { 20 if err != nil {
21 panic(err) 21 panic(err)
22 } 22 }
23 return ret 23 return ret
24 } 24 }
25 25
26 func (d *datastoreImpl) KeyForObjErr(src interface{}) (Key, error) { 26 func (d *datastoreImpl) KeyForObjErr(src interface{}) (Key, error) {
27 return newKeyObjErr(d.NewKey, src) 27 return newKeyObjErr(d.NewKey, src)
28 } 28 }
29 29
30 func (d *datastoreImpl) Run(q Query, proto interface{}, cb RunCB) error { 30 func (d *datastoreImpl) Run(q Query, cbIface interface{}) error {
31 » if _, ok := proto.(*Key); ok { 31 » // TODO(riannucci): Profile and determine if any of this is causing a re al
32 » » return d.RawInterface.Run(q.KeysOnly(), func(k Key, _ PropertyMa p, gc func() (Cursor, error)) bool { 32 » // slowdown. Could potentially cache reflection stuff by cbType?
33 » cbTyp := reflect.TypeOf(cbIface)
34
35 » badSig := false
36 » mat := multiArgType{}
37 » isKey := false
38
39 » if cbTyp.Kind() == reflect.Func && cbTyp.NumIn() == 2 && cbTyp.NumOut() == 1 {
40 » » firstArg := cbTyp.In(0)
41 » » if firstArg == typeOfKey {
42 » » » isKey = true
43 » » } else {
44 » » » mat = parseArg(firstArg)
45 » » » badSig = !mat.valid || mat.newElem == nil
46 » » }
47 » } else {
48 » » badSig = true
49 » }
50
51 » if badSig || cbTyp.Out(0) != typeOfBool || cbTyp.In(1) != typeOfCursorCB {
52 » » panic(fmt.Errorf(
53 » » » "cb does not match the required callback signature: `%T` != `func(TYPE, CursorCB) bool`",
54 » » » cbIface))
55 » }
56
57 » if isKey {
58 » » cb := cbIface.(func(Key, CursorCB) bool)
59 » » return d.RawInterface.Run(q.KeysOnly(), func(k Key, _ PropertyMa p, gc CursorCB) bool {
33 return cb(k, gc) 60 return cb(k, gc)
34 }) 61 })
35 } 62 }
36 63
37 » mat := parseArg(reflect.TypeOf(proto)) 64 » cbVal := reflect.ValueOf(cbIface)
38 » if !mat.valid || mat.newElem == nil {
39 » » return fmt.Errorf("invalid Run proto type: %T", proto)
40 » }
41 65
42 innerErr := error(nil) 66 innerErr := error(nil)
43 » err := d.RawInterface.Run(q, func(k Key, pm PropertyMap, gc func() (Curs or, error)) bool { 67 » err := d.RawInterface.Run(q, func(k Key, pm PropertyMap, gc CursorCB) bo ol {
44 itm := mat.newElem() 68 itm := mat.newElem()
45 if innerErr = mat.setPM(itm, pm); innerErr != nil { 69 if innerErr = mat.setPM(itm, pm); innerErr != nil {
46 return false 70 return false
47 } 71 }
48 mat.setKey(itm, k) 72 mat.setKey(itm, k)
49 » » return cb(itm.Interface(), gc) 73 » » return cbVal.Call([]reflect.Value{itm, reflect.ValueOf(gc)})[0]. Bool()
50 }) 74 })
51 if err == nil { 75 if err == nil {
52 err = innerErr 76 err = innerErr
53 } 77 }
54 return err 78 return err
55 } 79 }
56 80
57 func (d *datastoreImpl) GetAll(q Query, dst interface{}) error { 81 func (d *datastoreImpl) GetAll(q Query, dst interface{}) error {
58 v := reflect.ValueOf(dst) 82 v := reflect.ValueOf(dst)
59 if v.Kind() != reflect.Ptr { 83 if v.Kind() != reflect.Ptr {
60 return fmt.Errorf("invalid GetAll dst: must have a ptr-to-slice: %T", dst) 84 return fmt.Errorf("invalid GetAll dst: must have a ptr-to-slice: %T", dst)
61 } 85 }
62 if !v.IsValid() || v.IsNil() { 86 if !v.IsValid() || v.IsNil() {
63 return errors.New("invalid GetAll dst: <nil>") 87 return errors.New("invalid GetAll dst: <nil>")
64 } 88 }
65 89
66 if keys, ok := dst.(*[]Key); ok { 90 if keys, ok := dst.(*[]Key); ok {
67 » » return d.RawInterface.Run(q.KeysOnly(), func(k Key, _ PropertyMa p, _ func() (Cursor, error)) bool { 91 » » return d.RawInterface.Run(q.KeysOnly(), func(k Key, _ PropertyMa p, _ CursorCB) bool {
68 *keys = append(*keys, k) 92 *keys = append(*keys, k)
69 return true 93 return true
70 }) 94 })
71 } 95 }
72 96
73 slice := v.Elem() 97 slice := v.Elem()
74 mat := parseMultiArg(slice.Type()) 98 mat := parseMultiArg(slice.Type())
75 if !mat.valid || mat.newElem == nil { 99 if !mat.valid || mat.newElem == nil {
76 return fmt.Errorf("invalid GetAll input type: %T", dst) 100 return fmt.Errorf("invalid GetAll input type: %T", dst)
77 } 101 }
78 102
79 lme := errors.LazyMultiError{Size: slice.Len()} 103 lme := errors.LazyMultiError{Size: slice.Len()}
80 i := 0 104 i := 0
81 » err := d.RawInterface.Run(q, func(k Key, pm PropertyMap, _ func() (Curso r, error)) bool { 105 » err := d.RawInterface.Run(q, func(k Key, pm PropertyMap, _ CursorCB) boo l {
82 slice.Set(reflect.Append(slice, mat.newElem())) 106 slice.Set(reflect.Append(slice, mat.newElem()))
83 itm := slice.Index(i) 107 itm := slice.Index(i)
84 mat.setKey(itm, k) 108 mat.setKey(itm, k)
85 lme.Assign(i, mat.setPM(itm, pm)) 109 lme.Assign(i, mat.setPM(itm, pm))
86 i++ 110 i++
87 return true 111 return true
88 }) 112 })
89 if err == nil { 113 if err == nil {
90 err = lme.Get() 114 err = lme.Get()
91 } 115 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 err = lme.Get() 210 err = lme.Get()
187 if err == nil { 211 if err == nil {
188 err = extErr 212 err = extErr
189 } 213 }
190 return 214 return
191 } 215 }
192 216
193 func (d *datastoreImpl) Raw() RawInterface { 217 func (d *datastoreImpl) Raw() RawInterface {
194 return d.RawInterface 218 return d.RawInterface
195 } 219 }
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