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

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

Issue 1516173002: Fix error message from KeyForObj when passing an invalid struct. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: Fix GetMetaDefault silliness Created 5 years 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 "encoding/base64" 8 "encoding/base64"
9 "errors" 9 "errors"
10 "fmt" 10 "fmt"
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 // val, err := helper.GetPLS(&MyStruct{10}).GetMeta("id") 642 // val, err := helper.GetPLS(&MyStruct{10}).GetMeta("id")
643 // // val == 10 643 // // val == 10
644 // // err == nil 644 // // err == nil
645 // 645 //
646 // type MyStruct struct { 646 // type MyStruct struct {
647 // TFlag Toggle `gae:"$flag1,true"` // defaults to true 647 // TFlag Toggle `gae:"$flag1,true"` // defaults to true
648 // FFlag Toggle `gae:"$flag2,false"` // defaults to false 648 // FFlag Toggle `gae:"$flag2,false"` // defaults to false
649 // // BadFlag Toggle `gae:"$flag3"` // ILLEGAL 649 // // BadFlag Toggle `gae:"$flag3"` // ILLEGAL
650 // } 650 // }
651 GetMeta(key string) (interface{}, error) 651 GetMeta(key string) (interface{}, error)
652
653 // GetMetaDefault is GetMeta, but with a default.
654 //
655 // If the metadata key is not available, or its type doesn't equal the
656 // homogenized type of dflt, then dflt will be returned.
657 //
658 // Type homogenization:
659 // signed integer types -> int64
660 // bool -> Toggle fields (bool)
661 //
662 // Example:
663 // pls.GetMetaDefault("foo", 100).(int64)
664 GetMetaDefault(key string, dflt interface{}) interface{}
665 } 652 }
666 653
667 // PropertyLoadSaver may be implemented by a user type, and Interface will 654 // PropertyLoadSaver may be implemented by a user type, and Interface will
668 // use this interface to serialize the type instead of trying to automatically 655 // use this interface to serialize the type instead of trying to automatically
669 // create a serialization codec for it with helper.GetPLS. 656 // create a serialization codec for it with helper.GetPLS.
670 type PropertyLoadSaver interface { 657 type PropertyLoadSaver interface {
671 // Load takes the values from the given map and attempts to save them in to 658 // Load takes the values from the given map and attempts to save them in to
672 // the underlying object (usually a struct or a PropertyMap). If a fatal 659 // the underlying object (usually a struct or a PropertyMap). If a fatal
673 // error occurs, it's returned via error. If non-fatal conversion errors 660 // error occurs, it's returned via error. If non-fatal conversion errors
674 // occur, error will be a MultiError containing one or more ErrFieldMism atch 661 // occur, error will be a MultiError containing one or more ErrFieldMism atch
675 // objects. 662 // objects.
676 Load(PropertyMap) error 663 Load(PropertyMap) error
677 664
678 // Save returns the current property as a PropertyMap. if withMeta is tr ue, 665 // Save returns the current property as a PropertyMap. if withMeta is tr ue,
679 // then the PropertyMap contains all the metadata (e.g. '$meta' fields) 666 // then the PropertyMap contains all the metadata (e.g. '$meta' fields)
680 // which was held by this PropertyLoadSaver. 667 // which was held by this PropertyLoadSaver.
681 Save(withMeta bool) (PropertyMap, error) 668 Save(withMeta bool) (PropertyMap, error)
682
683 // Problem indicates that this PLS has a fatal problem. Usually this is
684 // set when the underlying struct has recursion, invalid field types, ne sted
685 // slices, etc.
686 Problem() error
687 } 669 }
688 670
689 // MetaGetterSetter is the subset of PropertyLoadSaver which pertains to 671 // MetaGetterSetter is the subset of PropertyLoadSaver which pertains to
690 // getting and saving metadata. 672 // getting and saving metadata.
691 // 673 //
692 // A *struct may implement this interface to provide metadata which is 674 // A *struct may implement this interface to provide metadata which is
693 // supplimental to the variety described by GetPLS. For example, this could be 675 // supplimental to the variety described by GetPLS. For example, this could be
694 // used to implement a parsed-out $kind or $id. 676 // used to implement a parsed-out $kind or $id.
695 type MetaGetterSetter interface { 677 type MetaGetterSetter interface {
696 MetaGetter 678 MetaGetter
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 for k, v := range pm { 762 for k, v := range pm {
781 if isMetaKey(k) { 763 if isMetaKey(k) {
782 newV := make([]Property, len(v)) 764 newV := make([]Property, len(v))
783 copy(newV, v) 765 copy(newV, v)
784 ret[k] = newV 766 ret[k] = newV
785 } 767 }
786 } 768 }
787 return ret 769 return ret
788 } 770 }
789 771
790 // GetMetaDefault is the implementation of PropertyLoadSaver.GetMetaDefault.
791 func (pm PropertyMap) GetMetaDefault(key string, dflt interface{}) interface{} {
792 return GetMetaDefaultImpl(pm.GetMeta, key, dflt)
793 }
794
795 // SetMeta implements PropertyLoadSaver.SetMeta. It will only return an error 772 // SetMeta implements PropertyLoadSaver.SetMeta. It will only return an error
796 // if `val` has an invalid type (e.g. not one supported by Property). 773 // if `val` has an invalid type (e.g. not one supported by Property).
797 func (pm PropertyMap) SetMeta(key string, val interface{}) error { 774 func (pm PropertyMap) SetMeta(key string, val interface{}) error {
798 prop := Property{} 775 prop := Property{}
799 if err := prop.SetValue(val, NoIndex); err != nil { 776 if err := prop.SetValue(val, NoIndex); err != nil {
800 return err 777 return err
801 } 778 }
802 pm["$"+key] = []Property{prop} 779 pm["$"+key] = []Property{prop}
803 return nil 780 return nil
804 } 781 }
(...skipping 21 matching lines...) Expand all
826 } 803 }
827 return ret 804 return ret
828 } 805 }
829 806
830 func isMetaKey(k string) bool { 807 func isMetaKey(k string) bool {
831 // empty counts as a metakey since it's not a valid data key, but it's 808 // empty counts as a metakey since it's not a valid data key, but it's
832 // not really a valid metakey either. 809 // not really a valid metakey either.
833 return k == "" || k[0] == '$' 810 return k == "" || k[0] == '$'
834 } 811 }
835 812
836 // GetMetaDefaultImpl is the implementation of PropertyLoadSaver.GetMetaDefault. 813 // GetMetaDefault is a helper for GetMeta, allowing a default value.
837 // 814 //
838 // It takes the normal GetMeta function, the key and the default, and returns 815 // If the metadata key is not available, or its type doesn't equal the
839 // the value according to PropertyLoadSaver.GetMetaDefault. 816 // homogenized type of dflt, then dflt will be returned.
840 func GetMetaDefaultImpl(gm func(string) (interface{}, error), key string, dflt i nterface{}) interface{} { 817 //
818 // Type homogenization:
819 // signed integer types -> int64
820 // bool -> Toggle fields (bool)
821 //
822 // Example:
823 // pls.GetMetaDefault("foo", 100).(int64)
824 func GetMetaDefault(getter MetaGetter, key string, dflt interface{}) (interface{ }, error) {
841 dflt = UpconvertUnderlyingType(dflt) 825 dflt = UpconvertUnderlyingType(dflt)
842 » cur, err := gm(key) 826 » cur, err := getter.GetMeta(key)
843 if err != nil { 827 if err != nil {
844 » » return dflt 828 » » if err == ErrMetaFieldUnset {
829 » » » return dflt, nil
830 » » }
831 » » return nil, err
845 } 832 }
846 if dflt != nil && reflect.TypeOf(cur) != reflect.TypeOf(dflt) { 833 if dflt != nil && reflect.TypeOf(cur) != reflect.TypeOf(dflt) {
847 » » return dflt 834 » » return dflt, nil
848 } 835 }
849 » return cur 836 » return cur, nil
850 } 837 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698