| OLD | NEW |
| 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 Loading... |
| 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 » » pslice := pdata.Slice() |
| 74 » » for i, prop := range props { | 74 » » requireSlice := len(pslice) > 1 |
| 75 » » » if reason := loadInner(p.c, p.o, i, name, prop, multiple
); reason != "" { | 75 » » for i, prop := range pslice { |
| 76 » » » if reason := loadInner(p.c, p.o, i, name, prop, requireS
lice); reason != "" { |
| 76 if useExtra { | 77 if useExtra { |
| 77 if extra != nil { | 78 if extra != nil { |
| 78 if *extra == nil { | 79 if *extra == nil { |
| 79 *extra = make(PropertyMa
p, 1) | 80 *extra = make(PropertyMa
p, 1) |
| 80 } | 81 } |
| 81 » » » » » » (*extra)[name] = props | 82 » » » » » » (*extra)[name] = pslice |
| 82 } | 83 } |
| 83 break // go to the next property in prop
Map | 84 break // go to the next property in prop
Map |
| 84 } else { | 85 } else { |
| 85 if t == nil { | 86 if t == nil { |
| 86 t = p.o.Type() | 87 t = p.o.Type() |
| 87 } | 88 } |
| 88 convFailures = append(convFailures, &Err
FieldMismatch{ | 89 convFailures = append(convFailures, &Err
FieldMismatch{ |
| 89 StructType: t, | 90 StructType: t, |
| 90 FieldName: name, | 91 FieldName: name, |
| 91 Reason: reason, | 92 Reason: reason, |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 ret := PropertyMap(nil) | 235 ret := PropertyMap(nil) |
| 235 if withMeta { | 236 if withMeta { |
| 236 if p.mgs != nil { | 237 if p.mgs != nil { |
| 237 ret = p.mgs.GetAllMeta() | 238 ret = p.mgs.GetAllMeta() |
| 238 } else { | 239 } else { |
| 239 ret = p.GetAllMeta() | 240 ret = p.GetAllMeta() |
| 240 } | 241 } |
| 241 } else { | 242 } else { |
| 242 ret = make(PropertyMap, len(p.c.byName)) | 243 ret = make(PropertyMap, len(p.c.byName)) |
| 243 } | 244 } |
| 244 » if _, err := p.save(ret, "", ShouldIndex); err != nil { | 245 » if _, err := p.save(ret, "", nil, ShouldIndex); err != nil { |
| 245 return nil, err | 246 return nil, err |
| 246 } | 247 } |
| 247 return ret, nil | 248 return ret, nil |
| 248 } | 249 } |
| 249 | 250 |
| 250 func (p *structPLS) getDefaultKind() string { | 251 func (p *structPLS) getDefaultKind() string { |
| 251 if !p.o.IsValid() { | 252 if !p.o.IsValid() { |
| 252 return "" | 253 return "" |
| 253 } | 254 } |
| 254 return p.o.Type().Name() | 255 return p.o.Type().Name() |
| 255 } | 256 } |
| 256 | 257 |
| 257 func (p *structPLS) save(propMap PropertyMap, prefix string, is IndexSetting) (i
dxCount int, err error) { | 258 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) { | 259 saveProp := func(name string, si IndexSetting, v reflect.Value, st *stru
ctTag) (err error) { |
| 259 if st.substructCodec != nil { | 260 if st.substructCodec != nil { |
| 260 » » » count, err := (&structPLS{v, st.substructCodec, nil}).sa
ve(propMap, name, si) | 261 » » » count, err := (&structPLS{v, st.substructCodec, nil}).sa
ve(propMap, name, st, si) |
| 261 if err == nil { | 262 if err == nil { |
| 262 idxCount += count | 263 idxCount += count |
| 263 if idxCount > maxIndexedProperties { | 264 if idxCount > maxIndexedProperties { |
| 264 err = errors.New("gae: too many indexed
properties") | 265 err = errors.New("gae: too many indexed
properties") |
| 265 } | 266 } |
| 266 } | 267 } |
| 267 return err | 268 return err |
| 268 } | 269 } |
| 269 | 270 |
| 270 prop := Property{} | 271 prop := Property{} |
| 271 if st.convert { | 272 if st.convert { |
| 272 prop, err = v.Addr().Interface().(PropertyConverter).ToP
roperty() | 273 prop, err = v.Addr().Interface().(PropertyConverter).ToP
roperty() |
| 273 } else { | 274 } else { |
| 274 err = prop.SetValue(v.Interface(), si) | 275 err = prop.SetValue(v.Interface(), si) |
| 275 } | 276 } |
| 276 if err != nil { | 277 if err != nil { |
| 277 return err | 278 return err |
| 278 } | 279 } |
| 279 » » propMap[name] = append(propMap[name], prop) | 280 |
| 281 » » // If we're a slice, or we are members in a slice, then use a Pr
opertySlice. |
| 282 » » if st.isSlice || (parentST != nil && parentST.isSlice) { |
| 283 » » » var pslice PropertySlice |
| 284 » » » if pdata := propMap[name]; pdata != nil { |
| 285 » » » » pslice = pdata.(PropertySlice) |
| 286 » » » } |
| 287 » » » propMap[name] = append(pslice, prop) |
| 288 » » } else { |
| 289 » » » if _, ok := propMap[name]; ok { |
| 290 » » » » return errors.New("non-slice property adding mul
tiple PropertyMap entries") |
| 291 » » » } |
| 292 » » » propMap[name] = prop |
| 293 » » } |
| 294 |
| 280 if prop.IndexSetting() == ShouldIndex { | 295 if prop.IndexSetting() == ShouldIndex { |
| 281 idxCount++ | 296 idxCount++ |
| 282 if idxCount > maxIndexedProperties { | 297 if idxCount > maxIndexedProperties { |
| 283 return errors.New("gae: too many indexed propert
ies") | 298 return errors.New("gae: too many indexed propert
ies") |
| 284 } | 299 } |
| 285 } | 300 } |
| 286 return nil | 301 return nil |
| 287 } | 302 } |
| 288 | 303 |
| 289 for i, st := range p.c.byIndex { | 304 for i, st := range p.c.byIndex { |
| 290 if st.name == "-" || st.isExtra { | 305 if st.name == "-" || st.isExtra { |
| 291 continue | 306 continue |
| 292 } | 307 } |
| 293 name := st.name | 308 name := st.name |
| 294 if prefix != "" { | 309 if prefix != "" { |
| 295 name = prefix + name | 310 name = prefix + name |
| 296 } | 311 } |
| 297 v := p.o.Field(i) | 312 v := p.o.Field(i) |
| 298 is1 := is | 313 is1 := is |
| 299 if st.idxSetting == NoIndex { | 314 if st.idxSetting == NoIndex { |
| 300 is1 = NoIndex | 315 is1 = NoIndex |
| 301 } | 316 } |
| 302 if st.isSlice { | 317 if st.isSlice { |
| 303 for j := 0; j < v.Len(); j++ { | 318 for j := 0; j < v.Len(); j++ { |
| 304 if err = saveProp(name, is1, v.Index(j), &st); e
rr != nil { | 319 if err = saveProp(name, is1, v.Index(j), &st); e
rr != nil { |
| 320 err = fmt.Errorf("gae: failed to save sl
ice field %q: %v", name, err) |
| 305 return | 321 return |
| 306 } | 322 } |
| 307 } | 323 } |
| 308 } else { | 324 } else { |
| 309 if err = saveProp(name, is1, v, &st); err != nil { | 325 if err = saveProp(name, is1, v, &st); err != nil { |
| 326 err = fmt.Errorf("gae: failed to save single fie
ld %q: %v", name, err) |
| 310 return | 327 return |
| 311 } | 328 } |
| 312 } | 329 } |
| 313 } | 330 } |
| 314 | 331 |
| 315 if i, ok := p.c.bySpecial["extra"]; ok { | 332 if i, ok := p.c.bySpecial["extra"]; ok { |
| 316 if p.c.byIndex[i].name != "-" { | 333 if p.c.byIndex[i].name != "-" { |
| 317 for fullName, vals := range p.o.Field(i).Interface().(Pr
opertyMap) { | 334 for fullName, vals := range p.o.Field(i).Interface().(Pr
opertyMap) { |
| 318 if _, ok := propMap[fullName]; !ok { | 335 if _, ok := propMap[fullName]; !ok { |
| 319 propMap[fullName] = vals | 336 propMap[fullName] = vals |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 380 |
| 364 func (p *structPLS) GetAllMeta() PropertyMap { | 381 func (p *structPLS) GetAllMeta() PropertyMap { |
| 365 needKind := true | 382 needKind := true |
| 366 ret := make(PropertyMap, len(p.c.byMeta)+1) | 383 ret := make(PropertyMap, len(p.c.byMeta)+1) |
| 367 for k, idx := range p.c.byMeta { | 384 for k, idx := range p.c.byMeta { |
| 368 if val, ok := p.getMetaFor(idx); ok { | 385 if val, ok := p.getMetaFor(idx); ok { |
| 369 p := Property{} | 386 p := Property{} |
| 370 if err := p.SetValue(val, NoIndex); err != nil { | 387 if err := p.SetValue(val, NoIndex); err != nil { |
| 371 continue | 388 continue |
| 372 } | 389 } |
| 373 » » » ret["$"+k] = []Property{p} | 390 » » » ret["$"+k] = p |
| 374 } | 391 } |
| 375 } | 392 } |
| 376 if needKind { | 393 if needKind { |
| 377 if _, ok := p.c.byMeta["kind"]; !ok { | 394 if _, ok := p.c.byMeta["kind"]; !ok { |
| 378 » » » ret["$kind"] = []Property{MkPropertyNI(p.getDefaultKind(
))} | 395 » » » ret["$kind"] = MkPropertyNI(p.getDefaultKind()) |
| 379 } | 396 } |
| 380 } | 397 } |
| 381 return ret | 398 return ret |
| 382 } | 399 } |
| 383 | 400 |
| 384 func (p *structPLS) SetMeta(key string, val interface{}) bool { | 401 func (p *structPLS) SetMeta(key string, val interface{}) bool { |
| 385 idx, ok := p.c.byMeta[key] | 402 idx, ok := p.c.byMeta[key] |
| 386 if !ok { | 403 if !ok { |
| 387 return false | 404 return false |
| 388 } | 405 } |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 switch val { | 694 switch val { |
| 678 case "on", "On", "true": | 695 case "on", "On", "true": |
| 679 return true, nil | 696 return true, nil |
| 680 case "off", "Off", "false": | 697 case "off", "Off", "false": |
| 681 return false, nil | 698 return false, nil |
| 682 } | 699 } |
| 683 return nil, fmt.Errorf("Toggle field has bad/missing default, go
t %q", val) | 700 return nil, fmt.Errorf("Toggle field has bad/missing default, go
t %q", val) |
| 684 } | 701 } |
| 685 return nil, fmt.Errorf("helper: meta field with bad type/value %s/%q", t
, val) | 702 return nil, fmt.Errorf("helper: meta field with bad type/value %s/%q", t
, val) |
| 686 } | 703 } |
| OLD | NEW |