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

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

Issue 1270113002: Re-add metadata passthrough on Get operations (Closed) Base URL: https://github.com/luci/gae.git@fix_other_interfaces
Patch Set: add another test 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
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 "errors" 8 "errors"
9 "fmt" 9 "fmt"
10 "math" 10 "math"
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 } 307 }
308 p.propType = pt 308 p.propType = pt
309 p.value = value 309 p.value = value
310 p.indexSetting = is 310 p.indexSetting = is
311 if t == typeOfByteSlice { 311 if t == typeOfByteSlice {
312 p.indexSetting = NoIndex 312 p.indexSetting = NoIndex
313 } 313 }
314 return 314 return
315 } 315 }
316 316
317 // PropertyLoadSaver may be implemented by a user type, and Interface will 317 // MetaGetter is a subinterface of PropertyLoadSaver, but is also used to
318 // use this interface to serialize the type instead of trying to automatically 318 // abstract the meta argument for RawInterface.GetMulti.
319 // create a serialization codec for it with helper.GetPLS. 319 type MetaGetter interface {
320 type PropertyLoadSaver interface {
321 » // Load takes the values from the given map and attempts to save them in to
322 » // the underlying object (usually a struct or a PropertyMap). If a fatal
323 » // error occurs, it's returned via error. If non-fatal conversion errors
324 » // occur, error will be a MultiError containing one or more ErrFieldMism atch
325 » // objects.
326 » Load(PropertyMap) error
327
328 » // Save returns the current property as a PropertyMap. if withMeta is tr ue,
329 » // then the PropertyMap contains all the metadata (e.g. '$meta' fields)
330 » // which was held by this PropertyLoadSaver.
331 » Save(withMeta bool) (PropertyMap, error)
332
333 // GetMeta will get information about the field which has the struct tag in 320 // GetMeta will get information about the field which has the struct tag in
334 // the form of `gae:"$<key>[,<default>]?"`. 321 // the form of `gae:"$<key>[,<default>]?"`.
335 // 322 //
336 // Supported metadata types are: 323 // Supported metadata types are:
337 // int64 - may have default (ascii encoded base-10) 324 // int64 - may have default (ascii encoded base-10)
338 // string - may have default 325 // string - may have default
339 // Toggle - MUST have default ("true" or "false") 326 // Toggle - MUST have default ("true" or "false")
340 // Key - NO default allowed 327 // Key - NO default allowed
341 // 328 //
342 // Struct fields of type Toggle (which is an Auto/On/Off) require you to 329 // Struct fields of type Toggle (which is an Auto/On/Off) require you to
(...skipping 12 matching lines...) Expand all
355 // // val == 10 342 // // val == 10
356 // // err == nil 343 // // err == nil
357 // 344 //
358 // type MyStruct struct { 345 // type MyStruct struct {
359 // TFlag Toggle `gae:"$flag1,true"` // defaults to true 346 // TFlag Toggle `gae:"$flag1,true"` // defaults to true
360 // FFlag Toggle `gae:"$flag2,false"` // defaults to false 347 // FFlag Toggle `gae:"$flag2,false"` // defaults to false
361 // // BadFlag Toggle `gae:"$flag3"` // ILLEGAL 348 // // BadFlag Toggle `gae:"$flag3"` // ILLEGAL
362 // } 349 // }
363 GetMeta(key string) (interface{}, error) 350 GetMeta(key string) (interface{}, error)
364 351
352 // GetMetaDefault is GetMeta, but with a default.
353 //
354 // If the metadata key is not available, or its type doesn't equal the
355 // homogenized type of dflt, then dflt will be returned.
356 //
357 // Type homogenization:
358 // signed integer types -> int64
359 // bool -> Toggle fields (bool)
360 //
361 // Example:
362 // pls.GetMetaDefault("foo", 100).(int64)
363 GetMetaDefault(key string, dflt interface{}) interface{}
364 }
365
366 // PropertyLoadSaver may be implemented by a user type, and Interface will
367 // use this interface to serialize the type instead of trying to automatically
368 // create a serialization codec for it with helper.GetPLS.
369 type PropertyLoadSaver interface {
370 // Load takes the values from the given map and attempts to save them in to
371 // the underlying object (usually a struct or a PropertyMap). If a fatal
372 // error occurs, it's returned via error. If non-fatal conversion errors
373 // occur, error will be a MultiError containing one or more ErrFieldMism atch
374 // objects.
375 Load(PropertyMap) error
376
377 // Save returns the current property as a PropertyMap. if withMeta is tr ue,
378 // then the PropertyMap contains all the metadata (e.g. '$meta' fields)
379 // which was held by this PropertyLoadSaver.
380 Save(withMeta bool) (PropertyMap, error)
381
382 MetaGetter
383
365 // SetMeta allows you to set the current value of the meta-keyed field. 384 // SetMeta allows you to set the current value of the meta-keyed field.
366 SetMeta(key string, val interface{}) error 385 SetMeta(key string, val interface{}) error
367 386
368 // Problem indicates that this PLS has a fatal problem. Usually this is 387 // Problem indicates that this PLS has a fatal problem. Usually this is
369 // set when the underlying struct has recursion, invalid field types, ne sted 388 // set when the underlying struct has recursion, invalid field types, ne sted
370 // slices, etc. 389 // slices, etc.
371 Problem() error 390 Problem() error
372 } 391 }
373 392
374 // PropertyMap represents the contents of a datastore entity in a generic way. 393 // PropertyMap represents the contents of a datastore entity in a generic way.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 v, ok := pm["$"+key] 447 v, ok := pm["$"+key]
429 if !ok || len(v) == 0 { 448 if !ok || len(v) == 0 {
430 return nil, ErrMetaFieldUnset 449 return nil, ErrMetaFieldUnset
431 } 450 }
432 if len(v) > 1 { 451 if len(v) > 1 {
433 return nil, errors.New("gae: too many values for Meta key") 452 return nil, errors.New("gae: too many values for Meta key")
434 } 453 }
435 return v[0].Value(), nil 454 return v[0].Value(), nil
436 } 455 }
437 456
457 func (pm PropertyMap) GetMetaDefault(key string, dflt interface{}) interface{} {
458 return GetMetaDefaultImpl(pm.GetMeta, key, dflt)
459 }
460
438 // SetMeta implements PropertyLoadSaver.SetMeta. It will only return an error 461 // SetMeta implements PropertyLoadSaver.SetMeta. It will only return an error
439 // if `val` has an invalid type (e.g. not one supported by Property). 462 // if `val` has an invalid type (e.g. not one supported by Property).
440 func (pm PropertyMap) SetMeta(key string, val interface{}) error { 463 func (pm PropertyMap) SetMeta(key string, val interface{}) error {
441 prop := Property{} 464 prop := Property{}
442 if err := prop.SetValue(val, NoIndex); err != nil { 465 if err := prop.SetValue(val, NoIndex); err != nil {
443 return err 466 return err
444 } 467 }
445 pm["$"+key] = []Property{prop} 468 pm["$"+key] = []Property{prop}
446 return nil 469 return nil
447 } 470 }
448 471
449 // Problem implements PropertyLoadSaver.Problem. It ALWAYS returns nil. 472 // Problem implements PropertyLoadSaver.Problem. It ALWAYS returns nil.
450 func (pm PropertyMap) Problem() error { 473 func (pm PropertyMap) Problem() error {
451 return nil 474 return nil
452 } 475 }
476
477 // GetMetaDefaultImpl is the implementation of PropertyLoadSaver.GetMetaDefault.
478 //
479 // It takes the normal GetMeta function, the key and the default, and returns
480 // the value according to PropertyLoadSaver.GetMetaDefault.
481 func GetMetaDefaultImpl(gm func(string) (interface{}, error), key string, dflt i nterface{}) interface{} {
482 cur, err := gm(key)
483 if err != nil {
484 return dflt
485 }
486 dflt, typ := UpconvertUnderlyingType(dflt, reflect.TypeOf(dflt))
487 if reflect.TypeOf(cur) != typ {
488 return dflt
489 }
490 return cur
491 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698