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

Unified Diff: service/datastore/pls_impl.go

Issue 1336443003: Implement projection queries correctly. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: fix comments Created 5 years, 3 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 | « impl/prod/raw_datastore_type_converter_test.go ('k') | service/datastore/pls_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: service/datastore/pls_impl.go
diff --git a/service/datastore/pls_impl.go b/service/datastore/pls_impl.go
index f6656d3ad92bfe021d460f83a18c7ac7e6e76695..6e2f2b651ec749616584736db01a8d46078831e7 100644
--- a/service/datastore/pls_impl.go
+++ b/service/datastore/pls_impl.go
@@ -12,10 +12,8 @@ import (
"strconv"
"strings"
"sync"
- "time"
"unicode"
- "github.com/luci/gae/service/blobstore"
"github.com/luci/luci-go/common/errors"
)
@@ -138,8 +136,6 @@ func loadInner(codec *structCodec, structValue reflect.Value, index int, name st
return "multiple-valued property requires a slice field type"
}
- pVal := p.Value()
-
if ret, ok := doConversion(v); ok {
if ret != "" {
return ret
@@ -149,79 +145,61 @@ func loadInner(codec *structCodec, structValue reflect.Value, index int, name st
if v.Type().Implements(typeOfKey) {
knd = reflect.Interface
}
+
+ project := PTNull
+ overflow := (func(interface{}) bool)(nil)
+ set := (func(interface{}))(nil)
+
switch knd {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- x, ok := pVal.(int64)
- if !ok && pVal != nil {
- return typeMismatchReason(pVal, v)
- }
- if v.OverflowInt(x) {
- return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
- }
- v.SetInt(x)
+ project = PTInt
+ overflow = func(x interface{}) bool { return v.OverflowInt(x.(int64)) }
+ set = func(x interface{}) { v.SetInt(x.(int64)) }
case reflect.Bool:
- x, ok := pVal.(bool)
- if !ok && pVal != nil {
- return typeMismatchReason(pVal, v)
- }
- v.SetBool(x)
+ project = PTBool
+ set = func(x interface{}) { v.SetBool(x.(bool)) }
case reflect.String:
- switch x := pVal.(type) {
- case blobstore.Key:
- v.SetString(string(x))
- case string:
- v.SetString(x)
- default:
- if pVal != nil {
- return typeMismatchReason(pVal, v)
- }
- }
+ project = PTString
+ set = func(x interface{}) { v.SetString(x.(string)) }
case reflect.Float32, reflect.Float64:
- x, ok := pVal.(float64)
- if !ok && pVal != nil {
- return typeMismatchReason(pVal, v)
- }
- if v.OverflowFloat(x) {
- return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
- }
- v.SetFloat(x)
+ project = PTFloat
+ overflow = func(x interface{}) bool { return v.OverflowFloat(x.(float64)) }
+ set = func(x interface{}) { v.SetFloat(x.(float64)) }
case reflect.Interface:
- x, ok := pVal.(Key)
- if !ok && pVal != nil {
- return typeMismatchReason(pVal, v)
- }
- if x != nil {
- v.Set(reflect.ValueOf(x))
+ project = PTKey
+ set = func(x interface{}) {
+ if k, ok := x.(Key); ok {
+ v.Set(reflect.ValueOf(k))
+ }
}
case reflect.Struct:
switch v.Type() {
case typeOfTime:
- x, ok := pVal.(time.Time)
- if !ok && pVal != nil {
- return typeMismatchReason(pVal, v)
- }
- v.Set(reflect.ValueOf(x))
+ project = PTTime
+ set = func(x interface{}) { v.Set(reflect.ValueOf(x)) }
case typeOfGeoPoint:
- x, ok := pVal.(GeoPoint)
- if !ok && pVal != nil {
- return typeMismatchReason(pVal, v)
- }
- v.Set(reflect.ValueOf(x))
+ project = PTGeoPoint
+ set = func(x interface{}) { v.Set(reflect.ValueOf(x)) }
default:
- panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(pVal, v)))
+ panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(p.value, v)))
}
case reflect.Slice:
- switch x := pVal.(type) {
- case []byte:
- v.SetBytes(x)
- case ByteString:
- v.SetBytes([]byte(x))
- default:
- panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(pVal, v)))
+ project = PTBytes
+ set = func(x interface{}) {
+ v.SetBytes(reflect.ValueOf(x).Bytes())
}
default:
- panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(pVal, v)))
+ panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(p.value, v)))
+ }
+
+ pVal, err := p.Project(project)
+ if err != nil {
+ return typeMismatchReason(p.value, v)
+ }
+ if overflow != nil && overflow(pVal) {
+ return fmt.Sprintf("value %v overflows struct field of type %v", pVal, v.Type())
}
+ set(pVal)
}
if slice.IsValid() {
slice.Set(reflect.Append(slice, v))
« no previous file with comments | « impl/prod/raw_datastore_type_converter_test.go ('k') | service/datastore/pls_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698