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

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

Issue 1355783002: Refactor keys and queries in datastore service and implementation. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: appease errcheck Created 5 years, 3 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/key_test.go ('k') | service/datastore/pls_impl.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 multiArgType struct { 14 type multiArgType struct {
15 valid bool 15 valid bool
16 16
17 » getKey func(nk newKeyFunc, slot reflect.Value) (Key, error) 17 » getKey func(aid, ns string, slot reflect.Value) (*Key, error)
18 getPM func(slot reflect.Value) (PropertyMap, error) 18 getPM func(slot reflect.Value) (PropertyMap, error)
19 setPM func(slot reflect.Value, pm PropertyMap) error 19 setPM func(slot reflect.Value, pm PropertyMap) error
20 » setKey func(slot reflect.Value, k Key) 20 » setKey func(slot reflect.Value, k *Key)
21 newElem func() reflect.Value 21 newElem func() reflect.Value
22 } 22 }
23 23
24 func (mat *multiArgType) GetKeysPMs(nk newKeyFunc, slice reflect.Value) ([]Key, []PropertyMap, error) { 24 func (mat *multiArgType) GetKeysPMs(aid, ns string, slice reflect.Value) ([]*Key , []PropertyMap, error) {
25 » retKey := make([]Key, slice.Len()) 25 » retKey := make([]*Key, slice.Len())
26 retPM := make([]PropertyMap, slice.Len()) 26 retPM := make([]PropertyMap, slice.Len())
27 lme := errors.NewLazyMultiError(len(retKey)) 27 lme := errors.NewLazyMultiError(len(retKey))
28 for i := range retKey { 28 for i := range retKey {
29 » » key, err := mat.getKey(nk, slice.Index(i)) 29 » » key, err := mat.getKey(aid, ns, slice.Index(i))
30 if !lme.Assign(i, err) { 30 if !lme.Assign(i, err) {
31 retKey[i] = key 31 retKey[i] = key
32 pm, err := mat.getPM(slice.Index(i)) 32 pm, err := mat.getPM(slice.Index(i))
33 if !lme.Assign(i, err) { 33 if !lme.Assign(i, err) {
34 retPM[i] = pm 34 retPM[i] = pm
35 } 35 }
36 } 36 }
37 } 37 }
38 return retKey, retPM, lme.Get() 38 return retKey, retPM, lme.Get()
39 } 39 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 func multiArgTypeInvalid() multiArgType { 77 func multiArgTypeInvalid() multiArgType {
78 return multiArgType{} 78 return multiArgType{}
79 } 79 }
80 80
81 // multiArgTypePLS == []P 81 // multiArgTypePLS == []P
82 // *P implements PropertyLoadSaver 82 // *P implements PropertyLoadSaver
83 func multiArgTypePLS(et reflect.Type) multiArgType { 83 func multiArgTypePLS(et reflect.Type) multiArgType {
84 ret := multiArgType{ 84 ret := multiArgType{
85 valid: true, 85 valid: true,
86 86
87 » » getKey: func(nk newKeyFunc, slot reflect.Value) (Key, error) { 87 » » getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
88 » » » return newKeyObjErr(nk, slot.Addr().Interface()) 88 » » » return newKeyObjErr(aid, ns, slot.Addr().Interface())
89 }, 89 },
90 getPM: func(slot reflect.Value) (PropertyMap, error) { 90 getPM: func(slot reflect.Value) (PropertyMap, error) {
91 return slot.Addr().Interface().(PropertyLoadSaver).Save( true) 91 return slot.Addr().Interface().(PropertyLoadSaver).Save( true)
92 }, 92 },
93 setPM: func(slot reflect.Value, pm PropertyMap) error { 93 setPM: func(slot reflect.Value, pm PropertyMap) error {
94 return slot.Addr().Interface().(PropertyLoadSaver).Load( pm) 94 return slot.Addr().Interface().(PropertyLoadSaver).Load( pm)
95 }, 95 },
96 » » setKey: func(slot reflect.Value, k Key) { 96 » » setKey: func(slot reflect.Value, k *Key) {
97 setKey(slot.Addr().Interface(), k) 97 setKey(slot.Addr().Interface(), k)
98 }, 98 },
99 } 99 }
100 if et.Kind() == reflect.Map { 100 if et.Kind() == reflect.Map {
101 ret.newElem = func() reflect.Value { 101 ret.newElem = func() reflect.Value {
102 // Create a *map so that way slot.Addr() works above whe n this is 102 // Create a *map so that way slot.Addr() works above whe n this is
103 // called from Run(). Otherwise the map is 'unaddressabl e' according 103 // called from Run(). Otherwise the map is 'unaddressabl e' according
104 // to reflect. ¯\_(ツ)_/¯ 104 // to reflect. ¯\_(ツ)_/¯
105 ptr := reflect.New(et) 105 ptr := reflect.New(et)
106 ptr.Elem().Set(reflect.MakeMap(et)) 106 ptr.Elem().Set(reflect.MakeMap(et))
107 return ptr.Elem() 107 return ptr.Elem()
108 } 108 }
109 } else { 109 } else {
110 ret.newElem = func() reflect.Value { 110 ret.newElem = func() reflect.Value {
111 return reflect.New(et).Elem() 111 return reflect.New(et).Elem()
112 } 112 }
113 } 113 }
114 return ret 114 return ret
115 } 115 }
116 116
117 // multiArgTypePLSPtr == []*P 117 // multiArgTypePLSPtr == []*P
118 // *P implements PropertyLoadSaver 118 // *P implements PropertyLoadSaver
119 func multiArgTypePLSPtr(et reflect.Type) multiArgType { 119 func multiArgTypePLSPtr(et reflect.Type) multiArgType {
120 ret := multiArgType{ 120 ret := multiArgType{
121 valid: true, 121 valid: true,
122 122
123 » » getKey: func(nk newKeyFunc, slot reflect.Value) (Key, error) { 123 » » getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
124 » » » return newKeyObjErr(nk, slot.Interface()) 124 » » » return newKeyObjErr(aid, ns, slot.Interface())
125 }, 125 },
126 getPM: func(slot reflect.Value) (PropertyMap, error) { 126 getPM: func(slot reflect.Value) (PropertyMap, error) {
127 return slot.Interface().(PropertyLoadSaver).Save(true) 127 return slot.Interface().(PropertyLoadSaver).Save(true)
128 }, 128 },
129 setPM: func(slot reflect.Value, pm PropertyMap) error { 129 setPM: func(slot reflect.Value, pm PropertyMap) error {
130 return slot.Interface().(PropertyLoadSaver).Load(pm) 130 return slot.Interface().(PropertyLoadSaver).Load(pm)
131 }, 131 },
132 » » setKey: func(slot reflect.Value, k Key) { 132 » » setKey: func(slot reflect.Value, k *Key) {
133 setKey(slot.Interface(), k) 133 setKey(slot.Interface(), k)
134 }, 134 },
135 } 135 }
136 if et.Kind() == reflect.Map { 136 if et.Kind() == reflect.Map {
137 ret.newElem = func() reflect.Value { 137 ret.newElem = func() reflect.Value {
138 ptr := reflect.New(et) 138 ptr := reflect.New(et)
139 ptr.Elem().Set(reflect.MakeMap(et)) 139 ptr.Elem().Set(reflect.MakeMap(et))
140 return ptr 140 return ptr
141 } 141 }
142 } else { 142 } else {
143 ret.newElem = func() reflect.Value { return reflect.New(et) } 143 ret.newElem = func() reflect.Value { return reflect.New(et) }
144 } 144 }
145 return ret 145 return ret
146 } 146 }
147 147
148 // multiArgTypeStruct == []S 148 // multiArgTypeStruct == []S
149 func multiArgTypeStruct(et reflect.Type) multiArgType { 149 func multiArgTypeStruct(et reflect.Type) multiArgType {
150 cdc := getCodec(et) 150 cdc := getCodec(et)
151 if cdc.problem != nil { 151 if cdc.problem != nil {
152 return multiArgTypeInvalid() 152 return multiArgTypeInvalid()
153 } 153 }
154 toPLS := func(slot reflect.Value) PropertyLoadSaver { 154 toPLS := func(slot reflect.Value) PropertyLoadSaver {
155 return &structPLS{slot, cdc} 155 return &structPLS{slot, cdc}
156 } 156 }
157 return multiArgType{ 157 return multiArgType{
158 valid: true, 158 valid: true,
159 159
160 » » getKey: func(nk newKeyFunc, slot reflect.Value) (Key, error) { 160 » » getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
161 » » » return newKeyObjErr(nk, toPLS(slot)) 161 » » » return newKeyObjErr(aid, ns, toPLS(slot))
162 }, 162 },
163 getPM: func(slot reflect.Value) (PropertyMap, error) { 163 getPM: func(slot reflect.Value) (PropertyMap, error) {
164 return toPLS(slot).(PropertyLoadSaver).Save(true) 164 return toPLS(slot).(PropertyLoadSaver).Save(true)
165 }, 165 },
166 setPM: func(slot reflect.Value, pm PropertyMap) error { 166 setPM: func(slot reflect.Value, pm PropertyMap) error {
167 return toPLS(slot).(PropertyLoadSaver).Load(pm) 167 return toPLS(slot).(PropertyLoadSaver).Load(pm)
168 }, 168 },
169 » » setKey: func(slot reflect.Value, k Key) { 169 » » setKey: func(slot reflect.Value, k *Key) {
170 setKey(toPLS(slot), k) 170 setKey(toPLS(slot), k)
171 }, 171 },
172 newElem: func() reflect.Value { 172 newElem: func() reflect.Value {
173 return reflect.New(et).Elem() 173 return reflect.New(et).Elem()
174 }, 174 },
175 } 175 }
176 } 176 }
177 177
178 // multiArgTypeStructPtr == []*S 178 // multiArgTypeStructPtr == []*S
179 func multiArgTypeStructPtr(et reflect.Type) multiArgType { 179 func multiArgTypeStructPtr(et reflect.Type) multiArgType {
180 cdc := getCodec(et) 180 cdc := getCodec(et)
181 if cdc.problem != nil { 181 if cdc.problem != nil {
182 return multiArgTypeInvalid() 182 return multiArgTypeInvalid()
183 } 183 }
184 toPLS := func(slot reflect.Value) PropertyLoadSaver { 184 toPLS := func(slot reflect.Value) PropertyLoadSaver {
185 return &structPLS{slot.Elem(), cdc} 185 return &structPLS{slot.Elem(), cdc}
186 } 186 }
187 return multiArgType{ 187 return multiArgType{
188 valid: true, 188 valid: true,
189 189
190 » » getKey: func(nk newKeyFunc, slot reflect.Value) (Key, error) { 190 » » getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
191 » » » return newKeyObjErr(nk, toPLS(slot)) 191 » » » return newKeyObjErr(aid, ns, toPLS(slot))
192 }, 192 },
193 getPM: func(slot reflect.Value) (PropertyMap, error) { 193 getPM: func(slot reflect.Value) (PropertyMap, error) {
194 return toPLS(slot).(PropertyLoadSaver).Save(true) 194 return toPLS(slot).(PropertyLoadSaver).Save(true)
195 }, 195 },
196 setPM: func(slot reflect.Value, pm PropertyMap) error { 196 setPM: func(slot reflect.Value, pm PropertyMap) error {
197 return toPLS(slot).(PropertyLoadSaver).Load(pm) 197 return toPLS(slot).(PropertyLoadSaver).Load(pm)
198 }, 198 },
199 » » setKey: func(slot reflect.Value, k Key) { 199 » » setKey: func(slot reflect.Value, k *Key) {
200 setKey(toPLS(slot), k) 200 setKey(toPLS(slot), k)
201 }, 201 },
202 newElem: func() reflect.Value { 202 newElem: func() reflect.Value {
203 return reflect.New(et) 203 return reflect.New(et)
204 }, 204 },
205 } 205 }
206 } 206 }
207 207
208 // multiArgTypeInterface == []I 208 // multiArgTypeInterface == []I
209 func multiArgTypeInterface() multiArgType { 209 func multiArgTypeInterface() multiArgType {
210 return multiArgType{ 210 return multiArgType{
211 valid: true, 211 valid: true,
212 212
213 » » getKey: func(nk newKeyFunc, slot reflect.Value) (Key, error) { 213 » » getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
214 » » » return newKeyObjErr(nk, slot.Elem().Interface()) 214 » » » return newKeyObjErr(aid, ns, slot.Elem().Interface())
215 }, 215 },
216 getPM: func(slot reflect.Value) (PropertyMap, error) { 216 getPM: func(slot reflect.Value) (PropertyMap, error) {
217 pls := mkPLS(slot.Elem().Interface()) 217 pls := mkPLS(slot.Elem().Interface())
218 return pls.Save(true) 218 return pls.Save(true)
219 }, 219 },
220 setPM: func(slot reflect.Value, pm PropertyMap) error { 220 setPM: func(slot reflect.Value, pm PropertyMap) error {
221 pls := mkPLS(slot.Elem().Interface()) 221 pls := mkPLS(slot.Elem().Interface())
222 return pls.Load(pm) 222 return pls.Load(pm)
223 }, 223 },
224 » » setKey: func(slot reflect.Value, k Key) { 224 » » setKey: func(slot reflect.Value, k *Key) {
225 setKey(slot.Elem().Interface(), k) 225 setKey(slot.Elem().Interface(), k)
226 }, 226 },
227 } 227 }
228 } 228 }
229 229
230 func newKeyObjErr(nk newKeyFunc, src interface{}) (Key, error) { 230 func newKeyObjErr(aid, ns string, src interface{}) (*Key, error) {
231 pls := mkPLS(src) 231 pls := mkPLS(src)
232 » if key, _ := pls.GetMetaDefault("key", nil).(Key); key != nil { 232 » if key, _ := pls.GetMetaDefault("key", nil).(*Key); key != nil {
233 return key, nil 233 return key, nil
234 } 234 }
235 235
236 // get kind 236 // get kind
237 kind := pls.GetMetaDefault("kind", "").(string) 237 kind := pls.GetMetaDefault("kind", "").(string)
238 if kind == "" { 238 if kind == "" {
239 return nil, fmt.Errorf("unable to extract $kind from %T", src) 239 return nil, fmt.Errorf("unable to extract $kind from %T", src)
240 } 240 }
241 241
242 // get id - allow both to be default for default keys 242 // get id - allow both to be default for default keys
243 sid := pls.GetMetaDefault("id", "").(string) 243 sid := pls.GetMetaDefault("id", "").(string)
244 iid := pls.GetMetaDefault("id", 0).(int64) 244 iid := pls.GetMetaDefault("id", 0).(int64)
245 245
246 // get parent 246 // get parent
247 » par, _ := pls.GetMetaDefault("parent", nil).(Key) 247 » par, _ := pls.GetMetaDefault("parent", nil).(*Key)
248 248
249 » return nk(kind, sid, iid, par), nil 249 » return NewKey(aid, ns, kind, sid, iid, par), nil
250 } 250 }
251 251
252 func setKey(src interface{}, key Key) { 252 func setKey(src interface{}, key *Key) {
253 pls := mkPLS(src) 253 pls := mkPLS(src)
254 if pls.SetMeta("key", key) == ErrMetaFieldUnset { 254 if pls.SetMeta("key", key) == ErrMetaFieldUnset {
255 » » if key.StringID() != "" { 255 » » lst := key.Last()
256 » » » pls.SetMeta("id", key.StringID()) 256 » » if lst.StringID != "" {
257 » » » _ = pls.SetMeta("id", lst.StringID)
257 } else { 258 } else {
258 » » » pls.SetMeta("id", key.IntID()) 259 » » » _ = pls.SetMeta("id", lst.IntID)
259 } 260 }
260 » » pls.SetMeta("kind", key.Kind()) 261 » » _ = pls.SetMeta("kind", lst.Kind)
261 » » pls.SetMeta("parent", key.Parent()) 262 » » _ = pls.SetMeta("parent", key.Parent())
262 } 263 }
263 } 264 }
264 265
265 func mkPLS(o interface{}) PropertyLoadSaver { 266 func mkPLS(o interface{}) PropertyLoadSaver {
266 if pls, ok := o.(PropertyLoadSaver); ok { 267 if pls, ok := o.(PropertyLoadSaver); ok {
267 return pls 268 return pls
268 } 269 }
269 return GetPLS(o) 270 return GetPLS(o)
270 } 271 }
OLDNEW
« no previous file with comments | « service/datastore/key_test.go ('k') | service/datastore/pls_impl.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698