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

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

Issue 2342063003: Differentiate between single- and multi- props. (Closed)
Patch Set: Created 4 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
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 // HEAVILY adapted from github.com/golang/appengine/datastore 5 // HEAVILY adapted from github.com/golang/appengine/datastore
6 6
7 package datastore 7 package datastore
8 8
9 import ( 9 import (
10 "fmt" 10 "fmt"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 useExtra := false 62 useExtra := false
63 extra := (*PropertyMap)(nil) 63 extra := (*PropertyMap)(nil)
64 if i, ok := p.c.bySpecial["extra"]; ok { 64 if i, ok := p.c.bySpecial["extra"]; ok {
65 useExtra = true 65 useExtra = true
66 f := p.c.byIndex[i] 66 f := p.c.byIndex[i]
67 if f.canSet { 67 if f.canSet {
68 extra = p.o.Field(i).Addr().Interface().(*PropertyMap) 68 extra = p.o.Field(i).Addr().Interface().(*PropertyMap)
69 } 69 }
70 } 70 }
71 t := reflect.Type(nil) 71 t := reflect.Type(nil)
72 » for name, props := range propMap { 72 » for name, pdata := range propMap {
73 » » multiple := len(props) > 1 73 » » var props PropertySlice
74 » » switch prop := pdata.(type) {
75 » » case Property:
76 » » » props = []Property{prop}
77
78 » » case PropertySlice:
79 » » » props = prop
80
81 » » default:
82 » » » panic(fmt.Errorf("unknown PropertyData type %T", prop))
83 » » }
84
85 » » requireSlice := len(props) > 1
74 for i, prop := range props { 86 for i, prop := range props {
75 » » » if reason := loadInner(p.c, p.o, i, name, prop, multiple ); reason != "" { 87 » » » if reason := loadInner(p.c, p.o, i, name, prop, requireS lice); reason != "" {
76 if useExtra { 88 if useExtra {
77 if extra != nil { 89 if extra != nil {
78 if *extra == nil { 90 if *extra == nil {
79 *extra = make(PropertyMa p, 1) 91 *extra = make(PropertyMa p, 1)
80 } 92 }
81 (*extra)[name] = props 93 (*extra)[name] = props
82 } 94 }
83 break // go to the next property in prop Map 95 break // go to the next property in prop Map
84 } else { 96 } else {
85 if t == nil { 97 if t == nil {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 ret := PropertyMap(nil) 246 ret := PropertyMap(nil)
235 if withMeta { 247 if withMeta {
236 if p.mgs != nil { 248 if p.mgs != nil {
237 ret = p.mgs.GetAllMeta() 249 ret = p.mgs.GetAllMeta()
238 } else { 250 } else {
239 ret = p.GetAllMeta() 251 ret = p.GetAllMeta()
240 } 252 }
241 } else { 253 } else {
242 ret = make(PropertyMap, len(p.c.byName)) 254 ret = make(PropertyMap, len(p.c.byName))
243 } 255 }
244 » if _, err := p.save(ret, "", ShouldIndex); err != nil { 256 » if _, err := p.save(ret, "", nil, ShouldIndex); err != nil {
245 return nil, err 257 return nil, err
246 } 258 }
247 return ret, nil 259 return ret, nil
248 } 260 }
249 261
250 func (p *structPLS) getDefaultKind() string { 262 func (p *structPLS) getDefaultKind() string {
251 if !p.o.IsValid() { 263 if !p.o.IsValid() {
252 return "" 264 return ""
253 } 265 }
254 return p.o.Type().Name() 266 return p.o.Type().Name()
255 } 267 }
256 268
257 func (p *structPLS) save(propMap PropertyMap, prefix string, is IndexSetting) (i dxCount int, err error) { 269 func (p *structPLS) save(propMap PropertyMap, prefix string, parentST *structTag , is IndexSetting) (idxCount int, err error) {
258 saveProp := func(name string, si IndexSetting, v reflect.Value, st *stru ctTag) (err error) { 270 saveProp := func(name string, si IndexSetting, v reflect.Value, st *stru ctTag) (err error) {
259 if st.substructCodec != nil { 271 if st.substructCodec != nil {
260 » » » count, err := (&structPLS{v, st.substructCodec, nil}).sa ve(propMap, name, si) 272 » » » count, err := (&structPLS{v, st.substructCodec, nil}).sa ve(propMap, name, st, si)
261 if err == nil { 273 if err == nil {
262 idxCount += count 274 idxCount += count
263 if idxCount > maxIndexedProperties { 275 if idxCount > maxIndexedProperties {
264 err = errors.New("gae: too many indexed properties") 276 err = errors.New("gae: too many indexed properties")
265 } 277 }
266 } 278 }
267 return err 279 return err
268 } 280 }
269 281
270 prop := Property{} 282 prop := Property{}
271 if st.convert { 283 if st.convert {
272 prop, err = v.Addr().Interface().(PropertyConverter).ToP roperty() 284 prop, err = v.Addr().Interface().(PropertyConverter).ToP roperty()
273 } else { 285 } else {
274 err = prop.SetValue(v.Interface(), si) 286 err = prop.SetValue(v.Interface(), si)
275 } 287 }
276 if err != nil { 288 if err != nil {
277 return err 289 return err
278 } 290 }
279 » » propMap[name] = append(propMap[name], prop) 291
292 » » // If we're a slice, or we are members in a slice, then use a Pr opertySlice.
293 » » if st.isSlice || (parentST != nil && parentST.isSlice) {
294 » » » var pslice PropertySlice
295 » » » if pdata := propMap[name]; pdata != nil {
296 » » » » pslice = pdata.(PropertySlice)
297 » » » }
298 » » » propMap[name] = append(pslice, prop)
299 » » } else {
300 » » » if _, ok := propMap[name]; ok {
301 » » » » return errors.New("non-slice property adding mul tiple PropertyMap entries")
302 » » » }
303 » » » propMap[name] = prop
304 » » }
305
280 if prop.IndexSetting() == ShouldIndex { 306 if prop.IndexSetting() == ShouldIndex {
281 idxCount++ 307 idxCount++
282 if idxCount > maxIndexedProperties { 308 if idxCount > maxIndexedProperties {
283 return errors.New("gae: too many indexed propert ies") 309 return errors.New("gae: too many indexed propert ies")
284 } 310 }
285 } 311 }
286 return nil 312 return nil
287 } 313 }
288 314
289 for i, st := range p.c.byIndex { 315 for i, st := range p.c.byIndex {
290 if st.name == "-" || st.isExtra { 316 if st.name == "-" || st.isExtra {
291 continue 317 continue
292 } 318 }
293 name := st.name 319 name := st.name
294 if prefix != "" { 320 if prefix != "" {
295 name = prefix + name 321 name = prefix + name
296 } 322 }
297 v := p.o.Field(i) 323 v := p.o.Field(i)
298 is1 := is 324 is1 := is
299 if st.idxSetting == NoIndex { 325 if st.idxSetting == NoIndex {
300 is1 = NoIndex 326 is1 = NoIndex
301 } 327 }
302 if st.isSlice { 328 if st.isSlice {
303 for j := 0; j < v.Len(); j++ { 329 for j := 0; j < v.Len(); j++ {
304 if err = saveProp(name, is1, v.Index(j), &st); e rr != nil { 330 if err = saveProp(name, is1, v.Index(j), &st); e rr != nil {
331 err = fmt.Errorf("gae: failed to save sl ice field %q: %v", name, err)
305 return 332 return
306 } 333 }
307 } 334 }
308 } else { 335 } else {
309 if err = saveProp(name, is1, v, &st); err != nil { 336 if err = saveProp(name, is1, v, &st); err != nil {
337 err = fmt.Errorf("gae: failed to save single fie ld %q: %v", name, err)
310 return 338 return
311 } 339 }
312 } 340 }
313 } 341 }
314 342
315 if i, ok := p.c.bySpecial["extra"]; ok { 343 if i, ok := p.c.bySpecial["extra"]; ok {
316 if p.c.byIndex[i].name != "-" { 344 if p.c.byIndex[i].name != "-" {
317 for fullName, vals := range p.o.Field(i).Interface().(Pr opertyMap) { 345 for fullName, vals := range p.o.Field(i).Interface().(Pr opertyMap) {
318 if _, ok := propMap[fullName]; !ok { 346 if _, ok := propMap[fullName]; !ok {
319 propMap[fullName] = vals 347 propMap[fullName] = vals
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 391
364 func (p *structPLS) GetAllMeta() PropertyMap { 392 func (p *structPLS) GetAllMeta() PropertyMap {
365 needKind := true 393 needKind := true
366 ret := make(PropertyMap, len(p.c.byMeta)+1) 394 ret := make(PropertyMap, len(p.c.byMeta)+1)
367 for k, idx := range p.c.byMeta { 395 for k, idx := range p.c.byMeta {
368 if val, ok := p.getMetaFor(idx); ok { 396 if val, ok := p.getMetaFor(idx); ok {
369 p := Property{} 397 p := Property{}
370 if err := p.SetValue(val, NoIndex); err != nil { 398 if err := p.SetValue(val, NoIndex); err != nil {
371 continue 399 continue
372 } 400 }
373 » » » ret["$"+k] = []Property{p} 401 » » » ret["$"+k] = p
374 } 402 }
375 } 403 }
376 if needKind { 404 if needKind {
377 if _, ok := p.c.byMeta["kind"]; !ok { 405 if _, ok := p.c.byMeta["kind"]; !ok {
378 » » » ret["$kind"] = []Property{MkPropertyNI(p.getDefaultKind( ))} 406 » » » ret["$kind"] = MkPropertyNI(p.getDefaultKind())
379 } 407 }
380 } 408 }
381 return ret 409 return ret
382 } 410 }
383 411
384 func (p *structPLS) SetMeta(key string, val interface{}) bool { 412 func (p *structPLS) SetMeta(key string, val interface{}) bool {
385 idx, ok := p.c.byMeta[key] 413 idx, ok := p.c.byMeta[key]
386 if !ok { 414 if !ok {
387 return false 415 return false
388 } 416 }
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 switch val { 705 switch val {
678 case "on", "On", "true": 706 case "on", "On", "true":
679 return true, nil 707 return true, nil
680 case "off", "Off", "false": 708 case "off", "Off", "false":
681 return false, nil 709 return false, nil
682 } 710 }
683 return nil, fmt.Errorf("Toggle field has bad/missing default, go t %q", val) 711 return nil, fmt.Errorf("Toggle field has bad/missing default, go t %q", val)
684 } 712 }
685 return nil, fmt.Errorf("helper: meta field with bad type/value %s/%q", t , val) 713 return nil, fmt.Errorf("helper: meta field with bad type/value %s/%q", t , val)
686 } 714 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698