OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 // HEAVILY adapted from github.com/golang/appengine/datastore | |
6 | |
7 package helper | |
8 | |
9 import ( | |
10 "fmt" | |
11 "infra/gae/libs/gae" | |
Vadim Sh.
2015/07/13 21:17:11
nit: group non-stdlib imports separately
iannucci
2015/07/13 22:39:51
blargh I thought I got all these
| |
12 "reflect" | |
13 ) | |
14 | |
15 // GetStructPLS resolves o into a gae.DSStructPLS. o must be a pointer to a | |
16 // struct of some sort. | |
17 func GetStructPLS(o interface{}) gae.DSStructPLS { | |
18 v := reflect.ValueOf(o) | |
19 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { | |
20 return &structPLS{c: &structCodec{problem: gae.ErrDSInvalidEntit yType}} | |
21 } | |
22 v = v.Elem() | |
23 t := v.Type() | |
24 | |
25 structCodecsMutex.RLock() | |
26 if c, ok := structCodecs[t]; ok { | |
27 structCodecsMutex.RUnlock() | |
28 return &structPLS{v, c} | |
29 } | |
30 structCodecsMutex.RUnlock() | |
31 | |
32 structCodecsMutex.Lock() | |
33 defer structCodecsMutex.Unlock() | |
34 return &structPLS{v, getStructCodecLocked(t)} | |
35 } | |
36 | |
37 // GetPLS resolves o into a gae.DSPropertyLoadSaver. If o implements the | |
38 // gae.DSPropertyLoadSaver interface already, it's returned unchanged. Otherwise | |
39 // this calls GetStructPLS and returns the result. | |
40 func GetPLS(o interface{}) (gae.DSPropertyLoadSaver, error) { | |
41 if pls, ok := o.(gae.DSPropertyLoadSaver); ok { | |
42 return pls, nil | |
43 } | |
44 pls := GetStructPLS(o) | |
45 if err := pls.Problem(); err != nil { | |
46 return nil, err | |
47 } | |
48 return pls, nil | |
49 } | |
50 | |
51 // MultiGetPLS resolves os to a []gae.DSPropertyLoadSaver. os must be a slice of | |
52 // something. If os is already a []gae.DSPropertyLoadSaver, it's returned | |
53 // unchanged. Otherwise this calls GetPLS on each item, and composes the | |
54 // resulting slice that way. | |
55 func MultiGetPLS(os interface{}) ([]gae.DSPropertyLoadSaver, error) { | |
56 if plss, ok := os.([]gae.DSPropertyLoadSaver); ok { | |
57 return plss, nil | |
58 } | |
59 | |
60 v := reflect.ValueOf(os) | |
61 if v.Kind() != reflect.Slice { | |
62 return nil, fmt.Errorf("gae/helper: bad type in MultiObjToPLS: % T", os) | |
63 } | |
64 | |
65 // TODO(riannucci): define a higher-level type DSMultiPropertyLoadSaver | |
66 // to avoid this slice? | |
67 ret := make([]gae.DSPropertyLoadSaver, v.Len()) | |
68 for i := 0; i < v.Len(); i++ { | |
69 pls, err := GetPLS(v.Index(i).Interface()) | |
70 if err != nil { | |
71 return nil, err | |
72 } | |
73 ret[i] = pls | |
74 } | |
75 return ret, nil | |
76 } | |
OLD | NEW |