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

Unified 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: cleanup 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « service/datastore/pls_test.go ('k') | service/datastore/properties_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: service/datastore/properties.go
diff --git a/service/datastore/properties.go b/service/datastore/properties.go
index dfa91515cca6432f38b102d2a119ca230e3655b5..11f62dc2939334b7581ee453aa541365b1c518cd 100644
--- a/service/datastore/properties.go
+++ b/service/datastore/properties.go
@@ -224,27 +224,27 @@ func PropertyTypeOf(v interface{}, checkValid bool) (PropertyType, error) {
// UpconvertUnderlyingType takes an object o, and attempts to convert it to
// its native datastore-compatible type. e.g. int16 will convert to int64, and
// `type Foo string` will convert to `string`.
-func UpconvertUnderlyingType(o interface{}, t reflect.Type) (interface{}, reflect.Type) {
+func UpconvertUnderlyingType(o interface{}) interface{} {
+ if o == nil {
+ return o
+ }
+
v := reflect.ValueOf(o)
- switch t.Kind() {
+ t := v.Type()
+ switch v.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
o = v.Int()
- t = typeOfInt64
case reflect.Bool:
o = v.Bool()
- t = typeOfBool
case reflect.String:
if t != typeOfBSKey {
o = v.String()
- t = typeOfString
}
case reflect.Float32, reflect.Float64:
o = v.Float()
- t = typeOfFloat64
case reflect.Slice:
if t != typeOfByteString && t.Elem().Kind() == reflect.Uint8 {
o = v.Bytes()
- t = typeOfByteSlice
}
case reflect.Struct:
if t == typeOfTime {
@@ -252,7 +252,7 @@ func UpconvertUnderlyingType(o interface{}, t reflect.Type) (interface{}, reflec
o = v.Interface().(time.Time).Round(time.Microsecond)
}
}
- return o, t
+ return o
}
// Value returns the current value held by this property. It's guaranteed to
@@ -296,11 +296,9 @@ func (p *Property) Type() PropertyType { return p.propType }
// a nil-valued property into a struct will set that field to the zero
// value.
func (p *Property) SetValue(value interface{}, is IndexSetting) (err error) {
- t := reflect.Type(nil)
pt := PTNull
if value != nil {
- t = reflect.TypeOf(value)
- value, t = UpconvertUnderlyingType(value, t)
+ value = UpconvertUnderlyingType(value)
if pt, err = PropertyTypeOf(value, true); err != nil {
return
}
@@ -308,28 +306,15 @@ func (p *Property) SetValue(value interface{}, is IndexSetting) (err error) {
p.propType = pt
p.value = value
p.indexSetting = is
- if t == typeOfByteSlice {
+ if _, ok := value.([]byte); ok {
p.indexSetting = NoIndex
}
return
}
-// PropertyLoadSaver may be implemented by a user type, and Interface will
-// use this interface to serialize the type instead of trying to automatically
-// create a serialization codec for it with helper.GetPLS.
-type PropertyLoadSaver interface {
- // Load takes the values from the given map and attempts to save them into
- // the underlying object (usually a struct or a PropertyMap). If a fatal
- // error occurs, it's returned via error. If non-fatal conversion errors
- // occur, error will be a MultiError containing one or more ErrFieldMismatch
- // objects.
- Load(PropertyMap) error
-
- // Save returns the current property as a PropertyMap. if withMeta is true,
- // then the PropertyMap contains all the metadata (e.g. '$meta' fields)
- // which was held by this PropertyLoadSaver.
- Save(withMeta bool) (PropertyMap, error)
-
+// MetaGetter is a subinterface of PropertyLoadSaver, but is also used to
+// abstract the meta argument for RawInterface.GetMulti.
+type MetaGetter interface {
// GetMeta will get information about the field which has the struct tag in
// the form of `gae:"$<key>[,<default>]?"`.
//
@@ -362,6 +347,38 @@ type PropertyLoadSaver interface {
// }
GetMeta(key string) (interface{}, error)
+ // GetMetaDefault is GetMeta, but with a default.
+ //
+ // If the metadata key is not available, or its type doesn't equal the
+ // homogenized type of dflt, then dflt will be returned.
+ //
+ // Type homogenization:
+ // signed integer types -> int64
+ // bool -> Toggle fields (bool)
+ //
+ // Example:
+ // pls.GetMetaDefault("foo", 100).(int64)
+ GetMetaDefault(key string, dflt interface{}) interface{}
+}
+
+// PropertyLoadSaver may be implemented by a user type, and Interface will
+// use this interface to serialize the type instead of trying to automatically
+// create a serialization codec for it with helper.GetPLS.
+type PropertyLoadSaver interface {
+ // Load takes the values from the given map and attempts to save them into
+ // the underlying object (usually a struct or a PropertyMap). If a fatal
+ // error occurs, it's returned via error. If non-fatal conversion errors
+ // occur, error will be a MultiError containing one or more ErrFieldMismatch
+ // objects.
+ Load(PropertyMap) error
+
+ // Save returns the current property as a PropertyMap. if withMeta is true,
+ // then the PropertyMap contains all the metadata (e.g. '$meta' fields)
+ // which was held by this PropertyLoadSaver.
+ Save(withMeta bool) (PropertyMap, error)
+
+ MetaGetter
+
// SetMeta allows you to set the current value of the meta-keyed field.
SetMeta(key string, val interface{}) error
@@ -435,6 +452,10 @@ func (pm PropertyMap) GetMeta(key string) (interface{}, error) {
return v[0].Value(), nil
}
+func (pm PropertyMap) GetMetaDefault(key string, dflt interface{}) interface{} {
+ return GetMetaDefaultImpl(pm.GetMeta, key, dflt)
+}
+
// SetMeta implements PropertyLoadSaver.SetMeta. It will only return an error
// if `val` has an invalid type (e.g. not one supported by Property).
func (pm PropertyMap) SetMeta(key string, val interface{}) error {
@@ -450,3 +471,19 @@ func (pm PropertyMap) SetMeta(key string, val interface{}) error {
func (pm PropertyMap) Problem() error {
return nil
}
+
+// GetMetaDefaultImpl is the implementation of PropertyLoadSaver.GetMetaDefault.
+//
+// It takes the normal GetMeta function, the key and the default, and returns
+// the value according to PropertyLoadSaver.GetMetaDefault.
+func GetMetaDefaultImpl(gm func(string) (interface{}, error), key string, dflt interface{}) interface{} {
+ dflt = UpconvertUnderlyingType(dflt)
+ cur, err := gm(key)
+ if err != nil {
+ return dflt
+ }
+ if dflt != nil && reflect.TypeOf(cur) != reflect.TypeOf(dflt) {
+ return dflt
+ }
+ return cur
+}
« no previous file with comments | « service/datastore/pls_test.go ('k') | service/datastore/properties_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698