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

Side by Side Diff: service/datastore/pls.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: more simplification 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 "fmt"
8 "reflect" 9 "reflect"
9 ) 10 )
10 11
11 // GetPLS resolves obj into default struct PropertyLoadSaver and 12 // GetPLS resolves obj into default struct PropertyLoadSaver and
12 // MetaGetterSetter implementation. 13 // MetaGetterSetter implementation.
13 // 14 //
14 // obj must be a non-nil pointer to a struct of some sort. 15 // obj must be a non-nil pointer to a struct of some sort.
15 // 16 //
16 // By default, exported fields will be serialized to/from the datastore. If the 17 // By default, exported fields will be serialized to/from the datastore. If the
17 // field is not exported, it will be skipped by the serialization routines. 18 // field is not exported, it will be skipped by the serialization routines.
18 // 19 //
19 // If a field is of a non-supported type (see Property for the list of supported 20 // If a field is of a non-supported type (see Property for the list of supported
20 // property types), the resulting PropertyLoadSaver will have a non-nil 21 // property types), this function will panic Other problems include duplicate
dnj 2015/12/12 02:47:50 nit: panic<period>.
iannucci 2015/12/12 03:52:22 done
21 // Problem(). Other problems include duplicate field names (due to tagging), 22 // field names (due to tagging), recursively defined structs, nested structures
22 // recursively defined structs, nested structures with multiple slices (e.g. 23 // with multiple slices (e.g. slices of slices, either directly `[][]type` or
23 // slices of slices, either directly `[][]type` or indirectly `[]Embedded` where 24 // indirectly `[]Embedded` where Embedded contains a slice.)
24 // Embedded contains a slice.)
25 // 25 //
26 // GetPLS supports the following struct tag syntax: 26 // GetPLS supports the following struct tag syntax:
27 // `gae:"fieldName[,noindex]"` -- an alternate fieldname for an exportable 27 // `gae:"fieldName[,noindex]"` -- an alternate fieldname for an exportable
28 // field. When the struct is serialized or deserialized, fieldName will be 28 // field. When the struct is serialized or deserialized, fieldName will be
29 // associated with the struct field instead of the field's Go name. This is 29 // associated with the struct field instead of the field's Go name. This is
30 // useful when writing Go code which interfaces with appengine code written 30 // useful when writing Go code which interfaces with appengine code written
31 // in other languages (like python) which use lowercase as their default 31 // in other languages (like python) which use lowercase as their default
32 // datastore field names. 32 // datastore field names.
33 // 33 //
34 // A fieldName of "-" means that gae will ignore the field for all 34 // A fieldName of "-" means that gae will ignore the field for all
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // } 153 // }
154 // 154 //
155 // type Person struct { 155 // type Person struct {
156 // Name `gae:"$id"` 156 // Name `gae:"$id"`
157 // } 157 // }
158 func GetPLS(obj interface{}) interface { 158 func GetPLS(obj interface{}) interface {
159 PropertyLoadSaver 159 PropertyLoadSaver
160 MetaGetterSetter 160 MetaGetterSetter
161 } { 161 } {
162 v := reflect.ValueOf(obj) 162 v := reflect.ValueOf(obj)
163 if !v.IsValid() {
164 panic(fmt.Errorf("cannot GetPLS(%T): failed to reflect", obj))
165 }
163 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { 166 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
164 » » return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } 167 » » panic(fmt.Errorf("cannot GetPLS(%T): not a pointer-to-struct", o bj))
165 } 168 }
166 if v.IsNil() { 169 if v.IsNil() {
167 » » return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } 170 » » panic(fmt.Errorf("cannot GetPLS(%T): pointer-to-struct is nil", obj))
168 } 171 }
169 v = v.Elem() 172 v = v.Elem()
170 c := getCodec(v.Type()) 173 c := getCodec(v.Type())
174 if c.problem != nil {
175 panic(c.problem)
176 }
171 return &structPLS{v, c} 177 return &structPLS{v, c}
172 } 178 }
173 179
174 func getMGS(obj interface{}) MetaGetterSetter { 180 func getMGS(obj interface{}) MetaGetterSetter {
175 if mgs, ok := obj.(MetaGetterSetter); ok { 181 if mgs, ok := obj.(MetaGetterSetter); ok {
176 return mgs 182 return mgs
177 } 183 }
178 return GetPLS(obj) 184 return GetPLS(obj)
179 } 185 }
180 186
181 func getCodec(structType reflect.Type) *structCodec { 187 func getCodec(structType reflect.Type) *structCodec {
182 structCodecsMutex.RLock() 188 structCodecsMutex.RLock()
183 c, ok := structCodecs[structType] 189 c, ok := structCodecs[structType]
184 structCodecsMutex.RUnlock() 190 structCodecsMutex.RUnlock()
185 if ok { 191 if ok {
186 return c 192 return c
187 } 193 }
188 194
189 structCodecsMutex.Lock() 195 structCodecsMutex.Lock()
190 defer structCodecsMutex.Unlock() 196 defer structCodecsMutex.Unlock()
191 return getStructCodecLocked(structType) 197 return getStructCodecLocked(structType)
192 } 198 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698