OLD | NEW |
---|---|
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 "reflect" | 8 "reflect" |
9 ) | 9 ) |
10 | 10 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 // if err != nil { | 118 // if err != nil { |
119 // return nil, err | 119 // return nil, err |
120 // } | 120 // } |
121 // props["foo"] = []Property{MkProperty(s.foo)} | 121 // props["foo"] = []Property{MkProperty(s.foo)} |
122 // return props, nil | 122 // return props, nil |
123 // } | 123 // } |
124 // | 124 // |
125 // func (s *Special) Problem() error { | 125 // func (s *Special) Problem() error { |
126 // return GetPLS(s).Problem() | 126 // return GetPLS(s).Problem() |
127 // } | 127 // } |
128 // | |
129 // Additionally, any field ptr-to-type may implement the PropertyConverter | |
130 // interface to allow a single field to, for example, implement some alternate | |
131 // encoding (json, gzip), or even just serialize to/from a simple string field. | |
132 // This applies to normal fields, as well as metadata fields. It can be useful | |
133 // for storing struct '$id's which have multi-field meanings. For example, the | |
134 // Person struct below could be initialized in go as `&Person{Name{"Jane", | |
135 // "Doe"}}`, retaining Jane's name as manipulable go fields. However, in the | |
dnj
2015/11/03 03:11:25
nit: capitalize Go.
iannucci
2015/11/03 20:29:33
done
| |
136 // datastore, it would have a key of `/Person,"Jane|Doe"`, and loading the | |
137 // struct from the datastore as part of a Query, for example, would correct | |
dnj
2015/11/03 03:11:25
nit: correctly*
iannucci
2015/11/03 20:29:33
done
| |
138 // populate Person.Name.First and Person.Name.Last. | |
139 // | |
140 // type Name struct { | |
141 // First string | |
142 // Last string | |
143 // } | |
144 // | |
145 // func (n *Name) ToProperty() (Property, error) { | |
146 // return fmt.Sprintf("%s|%s", n.First, n.Last) | |
147 // } | |
148 // | |
149 // func (n *Name) FromProperty(p Property) error { | |
150 // // check p to be a PTString | |
151 // // split on "|" | |
152 // // assign to n.First, n.Last | |
153 // } | |
154 // | |
155 // type Person struct { | |
156 // Name `gae:"$id"` | |
157 // } | |
128 func GetPLS(obj interface{}) interface { | 158 func GetPLS(obj interface{}) interface { |
129 PropertyLoadSaver | 159 PropertyLoadSaver |
130 MetaGetterSetter | 160 MetaGetterSetter |
131 } { | 161 } { |
132 v := reflect.ValueOf(obj) | 162 v := reflect.ValueOf(obj) |
133 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { | 163 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { |
134 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } | 164 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } |
135 } | 165 } |
136 if v.IsNil() { | 166 if v.IsNil() { |
137 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } | 167 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } |
(...skipping 15 matching lines...) Expand all Loading... | |
153 c, ok := structCodecs[structType] | 183 c, ok := structCodecs[structType] |
154 structCodecsMutex.RUnlock() | 184 structCodecsMutex.RUnlock() |
155 if ok { | 185 if ok { |
156 return c | 186 return c |
157 } | 187 } |
158 | 188 |
159 structCodecsMutex.Lock() | 189 structCodecsMutex.Lock() |
160 defer structCodecsMutex.Unlock() | 190 defer structCodecsMutex.Unlock() |
161 return getStructCodecLocked(structType) | 191 return getStructCodecLocked(structType) |
162 } | 192 } |
OLD | NEW |