| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |