load.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. // Copyright 2014 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package datastore
  15. import (
  16. "fmt"
  17. "reflect"
  18. "strings"
  19. "time"
  20. "cloud.google.com/go/internal/fields"
  21. pb "google.golang.org/genproto/googleapis/datastore/v1"
  22. )
  23. var (
  24. typeOfByteSlice = reflect.TypeOf([]byte(nil))
  25. typeOfTime = reflect.TypeOf(time.Time{})
  26. typeOfGeoPoint = reflect.TypeOf(GeoPoint{})
  27. typeOfKeyPtr = reflect.TypeOf(&Key{})
  28. )
  29. // typeMismatchReason returns a string explaining why the property p could not
  30. // be stored in an entity field of type v.Type().
  31. func typeMismatchReason(p Property, v reflect.Value) string {
  32. entityType := "empty"
  33. switch p.Value.(type) {
  34. case int64:
  35. entityType = "int"
  36. case bool:
  37. entityType = "bool"
  38. case string:
  39. entityType = "string"
  40. case float64:
  41. entityType = "float"
  42. case *Key:
  43. entityType = "*datastore.Key"
  44. case *Entity:
  45. entityType = "*datastore.Entity"
  46. case GeoPoint:
  47. entityType = "GeoPoint"
  48. case time.Time:
  49. entityType = "time.Time"
  50. case []byte:
  51. entityType = "[]byte"
  52. }
  53. return fmt.Sprintf("type mismatch: %s versus %v", entityType, v.Type())
  54. }
  55. func overflowReason(x interface{}, v reflect.Value) string {
  56. return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
  57. }
  58. type propertyLoader struct {
  59. // m holds the number of times a substruct field like "Foo.Bar.Baz" has
  60. // been seen so far. The map is constructed lazily.
  61. m map[string]int
  62. }
  63. func (l *propertyLoader) load(codec fields.List, structValue reflect.Value, p Property, prev map[string]struct{}) string {
  64. sl, ok := p.Value.([]interface{})
  65. if !ok {
  66. return l.loadOneElement(codec, structValue, p, prev)
  67. }
  68. for _, val := range sl {
  69. p.Value = val
  70. if errStr := l.loadOneElement(codec, structValue, p, prev); errStr != "" {
  71. return errStr
  72. }
  73. }
  74. return ""
  75. }
  76. // loadOneElement loads the value of Property p into structValue based on the provided
  77. // codec. codec is used to find the field in structValue into which p should be loaded.
  78. // prev is the set of property names already seen for structValue.
  79. func (l *propertyLoader) loadOneElement(codec fields.List, structValue reflect.Value, p Property, prev map[string]struct{}) string {
  80. var sliceOk bool
  81. var sliceIndex int
  82. var v reflect.Value
  83. name := p.Name
  84. fieldNames := strings.Split(name, ".")
  85. for len(fieldNames) > 0 {
  86. var field *fields.Field
  87. // Start by trying to find a field with name. If none found,
  88. // cut off the last field (delimited by ".") and find its parent
  89. // in the codec.
  90. // eg. for name "A.B.C.D", split off "A.B.C" and try to
  91. // find a field in the codec with this name.
  92. // Loop again with "A.B", etc.
  93. for i := len(fieldNames); i > 0; i-- {
  94. parent := strings.Join(fieldNames[:i], ".")
  95. field = codec.Match(parent)
  96. if field != nil {
  97. fieldNames = fieldNames[i:]
  98. break
  99. }
  100. }
  101. // If we never found a matching field in the codec, return
  102. // error message.
  103. if field == nil {
  104. return "no such struct field"
  105. }
  106. v = initField(structValue, field.Index)
  107. if !v.IsValid() {
  108. return "no such struct field"
  109. }
  110. if !v.CanSet() {
  111. return "cannot set struct field"
  112. }
  113. // If field implements PLS, we delegate loading to the PLS's Load early,
  114. // and stop iterating through fields.
  115. ok, err := plsFieldLoad(v, p, fieldNames)
  116. if err != nil {
  117. return err.Error()
  118. }
  119. if ok {
  120. return ""
  121. }
  122. if field.Type.Kind() == reflect.Struct {
  123. codec, err = structCache.Fields(field.Type)
  124. if err != nil {
  125. return err.Error()
  126. }
  127. structValue = v
  128. }
  129. // If the element is a slice, we need to accommodate it.
  130. if v.Kind() == reflect.Slice && v.Type() != typeOfByteSlice {
  131. if l.m == nil {
  132. l.m = make(map[string]int)
  133. }
  134. sliceIndex = l.m[p.Name]
  135. l.m[p.Name] = sliceIndex + 1
  136. for v.Len() <= sliceIndex {
  137. v.Set(reflect.Append(v, reflect.New(v.Type().Elem()).Elem()))
  138. }
  139. structValue = v.Index(sliceIndex)
  140. // If structValue implements PLS, we delegate loading to the PLS's
  141. // Load early, and stop iterating through fields.
  142. ok, err := plsFieldLoad(structValue, p, fieldNames)
  143. if err != nil {
  144. return err.Error()
  145. }
  146. if ok {
  147. return ""
  148. }
  149. if structValue.Type().Kind() == reflect.Struct {
  150. codec, err = structCache.Fields(structValue.Type())
  151. if err != nil {
  152. return err.Error()
  153. }
  154. }
  155. sliceOk = true
  156. }
  157. }
  158. var slice reflect.Value
  159. if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 {
  160. slice = v
  161. v = reflect.New(v.Type().Elem()).Elem()
  162. } else if _, ok := prev[p.Name]; ok && !sliceOk {
  163. // Zero the field back out that was set previously, turns out
  164. // it's a slice and we don't know what to do with it
  165. v.Set(reflect.Zero(v.Type()))
  166. return "multiple-valued property requires a slice field type"
  167. }
  168. prev[p.Name] = struct{}{}
  169. if errReason := setVal(v, p); errReason != "" {
  170. // Set the slice back to its zero value.
  171. if slice.IsValid() {
  172. slice.Set(reflect.Zero(slice.Type()))
  173. }
  174. return errReason
  175. }
  176. if slice.IsValid() {
  177. slice.Index(sliceIndex).Set(v)
  178. }
  179. return ""
  180. }
  181. // plsFieldLoad first tries to converts v's value to a PLS, then v's addressed
  182. // value to a PLS. If neither succeeds, plsFieldLoad returns false for first return
  183. // value. Otherwise, the first return value will be true.
  184. // If v is successfully converted to a PLS, plsFieldLoad will then try to Load
  185. // the property p into v (by way of the PLS's Load method).
  186. //
  187. // If the field v has been flattened, the Property's name must be altered
  188. // before calling Load to reflect the field v.
  189. // For example, if our original field name was "A.B.C.D",
  190. // and at this point in iteration we had initialized the field
  191. // corresponding to "A" and have moved into the struct, so that now
  192. // v corresponds to the field named "B", then we want to let the
  193. // PLS handle this field (B)'s subfields ("C", "D"),
  194. // so we send the property to the PLS's Load, renamed to "C.D".
  195. //
  196. // If subfields are present, the field v has been flattened.
  197. func plsFieldLoad(v reflect.Value, p Property, subfields []string) (ok bool, err error) {
  198. vpls, err := plsForLoad(v)
  199. if err != nil {
  200. return false, err
  201. }
  202. if vpls == nil {
  203. return false, nil
  204. }
  205. // If Entity, load properties as well as key.
  206. if e, ok := p.Value.(*Entity); ok {
  207. err = loadEntity(vpls, e)
  208. return true, err
  209. }
  210. // If flattened, we must alter the property's name to reflect
  211. // the field v.
  212. if len(subfields) > 0 {
  213. p.Name = strings.Join(subfields, ".")
  214. }
  215. return true, vpls.Load([]Property{p})
  216. }
  217. // setVal sets 'v' to the value of the Property 'p'.
  218. func setVal(v reflect.Value, p Property) (s string) {
  219. pValue := p.Value
  220. switch v.Kind() {
  221. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  222. x, ok := pValue.(int64)
  223. if !ok && pValue != nil {
  224. return typeMismatchReason(p, v)
  225. }
  226. if v.OverflowInt(x) {
  227. return overflowReason(x, v)
  228. }
  229. v.SetInt(x)
  230. case reflect.Bool:
  231. x, ok := pValue.(bool)
  232. if !ok && pValue != nil {
  233. return typeMismatchReason(p, v)
  234. }
  235. v.SetBool(x)
  236. case reflect.String:
  237. x, ok := pValue.(string)
  238. if !ok && pValue != nil {
  239. return typeMismatchReason(p, v)
  240. }
  241. v.SetString(x)
  242. case reflect.Float32, reflect.Float64:
  243. x, ok := pValue.(float64)
  244. if !ok && pValue != nil {
  245. return typeMismatchReason(p, v)
  246. }
  247. if v.OverflowFloat(x) {
  248. return overflowReason(x, v)
  249. }
  250. v.SetFloat(x)
  251. case reflect.Ptr:
  252. // v must be a pointer to either a Key, an Entity, or one of the supported basic types.
  253. if v.Type() != typeOfKeyPtr && v.Type().Elem().Kind() != reflect.Struct && !isValidPointerType(v.Type().Elem()) {
  254. return typeMismatchReason(p, v)
  255. }
  256. if pValue == nil {
  257. // If v is populated already, set it to nil.
  258. if !v.IsNil() {
  259. v.Set(reflect.New(v.Type()).Elem())
  260. }
  261. return ""
  262. }
  263. if x, ok := p.Value.(*Key); ok {
  264. if _, ok := v.Interface().(*Key); !ok {
  265. return typeMismatchReason(p, v)
  266. }
  267. v.Set(reflect.ValueOf(x))
  268. return ""
  269. }
  270. if v.IsNil() {
  271. v.Set(reflect.New(v.Type().Elem()))
  272. }
  273. switch x := pValue.(type) {
  274. case *Entity:
  275. err := loadEntity(v.Interface(), x)
  276. if err != nil {
  277. return err.Error()
  278. }
  279. case int64:
  280. if v.Elem().OverflowInt(x) {
  281. return overflowReason(x, v.Elem())
  282. }
  283. v.Elem().SetInt(x)
  284. case float64:
  285. if v.Elem().OverflowFloat(x) {
  286. return overflowReason(x, v.Elem())
  287. }
  288. v.Elem().SetFloat(x)
  289. case bool:
  290. v.Elem().SetBool(x)
  291. case string:
  292. v.Elem().SetString(x)
  293. case GeoPoint, time.Time:
  294. v.Elem().Set(reflect.ValueOf(x))
  295. default:
  296. return typeMismatchReason(p, v)
  297. }
  298. case reflect.Struct:
  299. switch v.Type() {
  300. case typeOfTime:
  301. x, ok := pValue.(time.Time)
  302. if !ok && pValue != nil {
  303. return typeMismatchReason(p, v)
  304. }
  305. v.Set(reflect.ValueOf(x))
  306. case typeOfGeoPoint:
  307. x, ok := pValue.(GeoPoint)
  308. if !ok && pValue != nil {
  309. return typeMismatchReason(p, v)
  310. }
  311. v.Set(reflect.ValueOf(x))
  312. default:
  313. ent, ok := pValue.(*Entity)
  314. if !ok {
  315. return typeMismatchReason(p, v)
  316. }
  317. err := loadEntity(v.Addr().Interface(), ent)
  318. if err != nil {
  319. return err.Error()
  320. }
  321. }
  322. case reflect.Slice:
  323. x, ok := pValue.([]byte)
  324. if !ok && pValue != nil {
  325. return typeMismatchReason(p, v)
  326. }
  327. if v.Type().Elem().Kind() != reflect.Uint8 {
  328. return typeMismatchReason(p, v)
  329. }
  330. v.SetBytes(x)
  331. default:
  332. return typeMismatchReason(p, v)
  333. }
  334. return ""
  335. }
  336. // initField is similar to reflect's Value.FieldByIndex, in that it
  337. // returns the nested struct field corresponding to index, but it
  338. // initialises any nil pointers encountered when traversing the structure.
  339. func initField(val reflect.Value, index []int) reflect.Value {
  340. for _, i := range index[:len(index)-1] {
  341. val = val.Field(i)
  342. if val.Kind() == reflect.Ptr {
  343. if val.IsNil() {
  344. val.Set(reflect.New(val.Type().Elem()))
  345. }
  346. val = val.Elem()
  347. }
  348. }
  349. return val.Field(index[len(index)-1])
  350. }
  351. // loadEntityProto loads an EntityProto into PropertyLoadSaver or struct pointer.
  352. func loadEntityProto(dst interface{}, src *pb.Entity) error {
  353. ent, err := protoToEntity(src)
  354. if err != nil {
  355. return err
  356. }
  357. return loadEntity(dst, ent)
  358. }
  359. func loadEntity(dst interface{}, ent *Entity) error {
  360. if pls, ok := dst.(PropertyLoadSaver); ok {
  361. err := pls.Load(ent.Properties)
  362. if err != nil {
  363. return err
  364. }
  365. if e, ok := dst.(KeyLoader); ok {
  366. err = e.LoadKey(ent.Key)
  367. }
  368. return err
  369. }
  370. return loadEntityToStruct(dst, ent)
  371. }
  372. func loadEntityToStruct(dst interface{}, ent *Entity) error {
  373. pls, err := newStructPLS(dst)
  374. if err != nil {
  375. return err
  376. }
  377. // Try and load key.
  378. keyField := pls.codec.Match(keyFieldName)
  379. if keyField != nil && ent.Key != nil {
  380. pls.v.FieldByIndex(keyField.Index).Set(reflect.ValueOf(ent.Key))
  381. }
  382. // Load properties.
  383. return pls.Load(ent.Properties)
  384. }
  385. func (s structPLS) Load(props []Property) error {
  386. var fieldName, errReason string
  387. var l propertyLoader
  388. prev := make(map[string]struct{})
  389. for _, p := range props {
  390. if errStr := l.load(s.codec, s.v, p, prev); errStr != "" {
  391. // We don't return early, as we try to load as many properties as possible.
  392. // It is valid to load an entity into a struct that cannot fully represent it.
  393. // That case returns an error, but the caller is free to ignore it.
  394. fieldName, errReason = p.Name, errStr
  395. }
  396. }
  397. if errReason != "" {
  398. return &ErrFieldMismatch{
  399. StructType: s.v.Type(),
  400. FieldName: fieldName,
  401. Reason: errReason,
  402. }
  403. }
  404. return nil
  405. }
  406. func protoToEntity(src *pb.Entity) (*Entity, error) {
  407. props := make([]Property, 0, len(src.Properties))
  408. for name, val := range src.Properties {
  409. v, err := propToValue(val)
  410. if err != nil {
  411. return nil, err
  412. }
  413. props = append(props, Property{
  414. Name: name,
  415. Value: v,
  416. NoIndex: val.ExcludeFromIndexes,
  417. })
  418. }
  419. var key *Key
  420. if src.Key != nil {
  421. // Ignore any error, since nested entity values
  422. // are allowed to have an invalid key.
  423. key, _ = protoToKey(src.Key)
  424. }
  425. return &Entity{key, props}, nil
  426. }
  427. // propToValue returns a Go value that represents the PropertyValue. For
  428. // example, a TimestampValue becomes a time.Time.
  429. func propToValue(v *pb.Value) (interface{}, error) {
  430. switch v := v.ValueType.(type) {
  431. case *pb.Value_NullValue:
  432. return nil, nil
  433. case *pb.Value_BooleanValue:
  434. return v.BooleanValue, nil
  435. case *pb.Value_IntegerValue:
  436. return v.IntegerValue, nil
  437. case *pb.Value_DoubleValue:
  438. return v.DoubleValue, nil
  439. case *pb.Value_TimestampValue:
  440. return time.Unix(v.TimestampValue.Seconds, int64(v.TimestampValue.Nanos)), nil
  441. case *pb.Value_KeyValue:
  442. return protoToKey(v.KeyValue)
  443. case *pb.Value_StringValue:
  444. return v.StringValue, nil
  445. case *pb.Value_BlobValue:
  446. return []byte(v.BlobValue), nil
  447. case *pb.Value_GeoPointValue:
  448. return GeoPoint{Lat: v.GeoPointValue.Latitude, Lng: v.GeoPointValue.Longitude}, nil
  449. case *pb.Value_EntityValue:
  450. return protoToEntity(v.EntityValue)
  451. case *pb.Value_ArrayValue:
  452. arr := make([]interface{}, 0, len(v.ArrayValue.Values))
  453. for _, v := range v.ArrayValue.Values {
  454. vv, err := propToValue(v)
  455. if err != nil {
  456. return nil, err
  457. }
  458. arr = append(arr, vv)
  459. }
  460. return arr, nil
  461. default:
  462. return nil, nil
  463. }
  464. }