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

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

Issue 1259593005: Add 'user friendly' datastore API. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: more docs Created 5 years, 4 months 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 o into a PropertyLoadSaver. o must be a pointer to a 11 // GetPLS resolves obj into a PropertyLoadSaver.
12 // struct of some sort. 12 //
13 func GetPLS(o interface{}) PropertyLoadSaver { 13 // obj must be a non-nil pointer to a struct of some sort.
14 » v := reflect.ValueOf(o) 14 //
15 // 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 //
18 // 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 // Problem(). Other problems include duplicate field names (due to tagging),
21 // recursively defined structs, nested structures with multiple slices (e.g.
22 // slices of slices, either directly `[][]type` or indirectly `[]Embedded` where
23 // Embedded contains a slice.)
24 //
25 // GetPLS supports the following struct tag syntax:
26 // `gae:"fieldName[,noindex]"` -- an alternate fieldname for an exportable
27 //» field. When the struct is serialized or deserialized, fieldName wil l be
28 // associated with the struct field instead of the field's Go name. This is
29 // useful when writing Go code which interfaces with appengine code written
30 // in other languages (like python) which use lowercase as their default
31 //» » datastore field names.
32 //
33 // A fieldName of "-" means that gae will ignore the field for all
34 // serialization/deserialization.
35 //
36 // if noindex is specified, then this field will not be indexed in the
37 // datastore, even if it was an otherwise indexable type. If fieldName is
38 // blank, and noindex is specifed, then fieldName will default to the
39 // field's actual name. Note that by default, all fields (with indexable
40 // types) are indexed.
41 //
42 // `gae:"$metaKey[,<value>]` -- indicates a field is metadata. Metadata
43 // can be used to control filter behavior, or to store key data when using
44 // the Interface.KeyForObj* methods. The supported field types are:
45 // - Key
46 // - int64
47 // - string
48 // - Toggle (GetMeta and SetMeta treat the field as if it were bool)
49 // Additionally, int64, string and Toggle allow setting a default value
50 // in the struct field tag (the "<value>" portion).
51 //
52 // Only exported fields allow SetMeta, but all fields of appropriate type
53 // allow tagged defaults. See Examples.
54 //
55 // Example "special" structure. This is supposed to be some sort of datastore
56 // singleton object.
57 // struct secretFoo {
58 // // _id and _kind are not exported, so setting their values will not be
59 // // reflected by GetMeta.
60 // _id int64 `gae:"$id,1"`
61 // _kind string `gae:"$kind,InternalFooSingleton"`
62 //
63 // // Value is exported, so can be read and written by the PropertyLoadSaver ,
64 // // but secretFoo is shared with a python appengine module which has
65 // // stored this field as 'value' instead of 'Value'.
66 // Value int64 `gae:"value"`
67 // }
68 //
69 // Example "normal" structure that you might use in a go-only appengine app.
70 // struct User {
71 // ID string `gae:"$id"`
72 // // "kind" is automatically implied by the struct name: "User"
73 // // "parent" is nil... Users are root entities
74 //
75 // // 'Name' will serialized to the datastore in the field 'Name'
76 // Name string
77 // }
78 //
79 // struct Comment {
80 // ID int64 `gae:"$id"`
81 // // "kind" is automatically implied by the struct name: "Comment"
82 //
83 // // Parent will be enforced by the application to be a User key.
84 // Parent Key `gae:"$parent"`
85 //
86 // // 'Lines' will serialized to the datastore in the field 'Lines'
87 // Lines []string
88 // }
89 func GetPLS(obj interface{}) PropertyLoadSaver {
90 » v := reflect.ValueOf(obj)
15 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { 91 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
16 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } 92 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} }
17 } 93 }
94 if v.IsNil() {
95 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} }
96 }
18 v = v.Elem() 97 v = v.Elem()
19 » t := v.Type() 98 » c := getCodec(v.Type())
99 » return &structPLS{v, c}
100 }
20 101
102 func getCodec(structType reflect.Type) *structCodec {
21 structCodecsMutex.RLock() 103 structCodecsMutex.RLock()
22 » if c, ok := structCodecs[t]; ok { 104 » c, ok := structCodecs[structType]
23 » » structCodecsMutex.RUnlock() 105 » structCodecsMutex.RUnlock()
24 » » return &structPLS{v, c} 106 » if ok {
107 » » return c
25 } 108 }
26 structCodecsMutex.RUnlock()
27 109
28 structCodecsMutex.Lock() 110 structCodecsMutex.Lock()
29 defer structCodecsMutex.Unlock() 111 defer structCodecsMutex.Unlock()
30 » return &structPLS{v, getStructCodecLocked(t)} 112 » return getStructCodecLocked(structType)
31 } 113 }
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