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

Side by Side Diff: service/datastore/pls.go

Issue 1427933002: Decouple PLS from MGS. (Closed) Base URL: https://github.com/luci/gae@master
Patch Set: Cleaner code for test. Created 5 years, 1 month 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
« no previous file with comments | « service/datastore/multiarg.go ('k') | service/datastore/pls_impl.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "reflect" 8 "reflect"
9 ) 9 )
10 10
11 // GetPLS resolves obj into a PropertyLoadSaver. 11 // GetPLS resolves obj into default struct PropertyLoadSaver and
12 // MetaGetterSetter implementation.
12 // 13 //
13 // obj must be a non-nil pointer to a struct of some sort. 14 // obj must be a non-nil pointer to a struct of some sort.
14 // 15 //
15 // By default, exported fields will be serialized to/from the datastore. If the 16 // By default, exported fields will be serialized to/from the datastore. If the
16 // field is not exported, it will be skipped by the serialization routines. 17 // field is not exported, it will be skipped by the serialization routines.
17 // 18 //
18 // If a field is of a non-supported type (see Property for the list of supported 19 // If a field is of a non-supported type (see Property for the list of supported
19 // property types), the resulting PropertyLoadSaver will have a non-nil 20 // property types), the resulting PropertyLoadSaver will have a non-nil
20 // Problem(). Other problems include duplicate field names (due to tagging), 21 // Problem(). Other problems include duplicate field names (due to tagging),
21 // recursively defined structs, nested structures with multiple slices (e.g. 22 // recursively defined structs, nested structures with multiple slices (e.g.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 // // 'Lines' will serialized to the datastore in the field 'Lines' 87 // // 'Lines' will serialized to the datastore in the field 'Lines'
87 // Lines []string 88 // Lines []string
88 // } 89 // }
89 // 90 //
90 // A pointer-to-struct may also implement MetaGetterSetter to provide more 91 // A pointer-to-struct may also implement MetaGetterSetter to provide more
91 // sophistocated metadata values. Explicitly defined fields (as shown above) 92 // sophistocated metadata values. Explicitly defined fields (as shown above)
92 // always take precedence over fields manipulated by the MetaGetterSetter 93 // always take precedence over fields manipulated by the MetaGetterSetter
93 // methods. So if your GetMeta handles "kind", but you explicitly have a 94 // methods. So if your GetMeta handles "kind", but you explicitly have a
94 // $kind field, the $kind field will take precedence and your GetMeta 95 // $kind field, the $kind field will take precedence and your GetMeta
95 // implementation will not be called for "kind". 96 // implementation will not be called for "kind".
96 func GetPLS(obj interface{}) PropertyLoadSaver { 97 //
98 // A struct overloading any of the PropertyLoadSaver or MetaGetterSetter
99 // interfaces may evoke the default struct behavior by using GetPLS on itself.
100 // For example:
101 //
102 // struct Special {
103 // Name string
104 //
105 // foo string
106 // }
107 //
108 // func (s *Special) Load(props PropertyMap) error {
109 // if foo, ok := props["foo"]; ok && len(foo) == 1 {
110 // s.foo = foo
111 // delete(props, "foo")
112 // }
113 // return GetPLS(props)
iannucci 2015/10/30 22:02:54 I think this should be `GetPLS(s).Load(props)`
114 // }
115 //
116 // func (s *Special) Save(withMeta bool) (PropertyMap, error) {
117 // props, err := GetPLS(withMeta)
iannucci 2015/10/30 22:02:54 GetPLS(s).Save(withMeta)
118 // if err != nil {
119 // return nil, err
120 // }
121 // props["foo"] = []Property{MkProperty(s.foo)}
122 // return props, nil
123 // }
124 //
125 // func (s *Special) Problem() error {
126 // return GetPLS(s).Problem()
127 // }
128 func GetPLS(obj interface{}) interface {
129 » PropertyLoadSaver
130 » MetaGetterSetter
131 } {
97 v := reflect.ValueOf(obj) 132 v := reflect.ValueOf(obj)
98 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { 133 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
99 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } 134 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} }
100 } 135 }
101 if v.IsNil() { 136 if v.IsNil() {
102 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } 137 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} }
103 } 138 }
104 v = v.Elem() 139 v = v.Elem()
105 c := getCodec(v.Type()) 140 c := getCodec(v.Type())
106 return &structPLS{v, c} 141 return &structPLS{v, c}
107 } 142 }
108 143
144 func getMGS(obj interface{}) MetaGetterSetter {
145 if mgs, ok := obj.(MetaGetterSetter); ok {
146 return mgs
147 }
148 return GetPLS(obj)
149 }
150
109 func getCodec(structType reflect.Type) *structCodec { 151 func getCodec(structType reflect.Type) *structCodec {
110 structCodecsMutex.RLock() 152 structCodecsMutex.RLock()
111 c, ok := structCodecs[structType] 153 c, ok := structCodecs[structType]
112 structCodecsMutex.RUnlock() 154 structCodecsMutex.RUnlock()
113 if ok { 155 if ok {
114 return c 156 return c
115 } 157 }
116 158
117 structCodecsMutex.Lock() 159 structCodecsMutex.Lock()
118 defer structCodecsMutex.Unlock() 160 defer structCodecsMutex.Unlock()
119 return getStructCodecLocked(structType) 161 return getStructCodecLocked(structType)
120 } 162 }
OLDNEW
« no previous file with comments | « service/datastore/multiarg.go ('k') | service/datastore/pls_impl.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698