aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/google.golang.org/appengine/datastore/doc.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/google.golang.org/appengine/datastore/doc.go')
-rw-r--r--vendor/google.golang.org/appengine/datastore/doc.go361
1 files changed, 361 insertions, 0 deletions
diff --git a/vendor/google.golang.org/appengine/datastore/doc.go b/vendor/google.golang.org/appengine/datastore/doc.go
new file mode 100644
index 0000000..85616cf
--- /dev/null
+++ b/vendor/google.golang.org/appengine/datastore/doc.go
@@ -0,0 +1,361 @@
1// Copyright 2011 Google Inc. All rights reserved.
2// Use of this source code is governed by the Apache 2.0
3// license that can be found in the LICENSE file.
4
5/*
6Package datastore provides a client for App Engine's datastore service.
7
8
9Basic Operations
10
11Entities are the unit of storage and are associated with a key. A key
12consists of an optional parent key, a string application ID, a string kind
13(also known as an entity type), and either a StringID or an IntID. A
14StringID is also known as an entity name or key name.
15
16It is valid to create a key with a zero StringID and a zero IntID; this is
17called an incomplete key, and does not refer to any saved entity. Putting an
18entity into the datastore under an incomplete key will cause a unique key
19to be generated for that entity, with a non-zero IntID.
20
21An entity's contents are a mapping from case-sensitive field names to values.
22Valid value types are:
23 - signed integers (int, int8, int16, int32 and int64),
24 - bool,
25 - string,
26 - float32 and float64,
27 - []byte (up to 1 megabyte in length),
28 - any type whose underlying type is one of the above predeclared types,
29 - ByteString,
30 - *Key,
31 - time.Time (stored with microsecond precision),
32 - appengine.BlobKey,
33 - appengine.GeoPoint,
34 - structs whose fields are all valid value types,
35 - slices of any of the above.
36
37Slices of structs are valid, as are structs that contain slices. However, if
38one struct contains another, then at most one of those can be repeated. This
39disqualifies recursively defined struct types: any struct T that (directly or
40indirectly) contains a []T.
41
42The Get and Put functions load and save an entity's contents. An entity's
43contents are typically represented by a struct pointer.
44
45Example code:
46
47 type Entity struct {
48 Value string
49 }
50
51 func handle(w http.ResponseWriter, r *http.Request) {
52 ctx := appengine.NewContext(r)
53
54 k := datastore.NewKey(ctx, "Entity", "stringID", 0, nil)
55 e := new(Entity)
56 if err := datastore.Get(ctx, k, e); err != nil {
57 http.Error(w, err.Error(), 500)
58 return
59 }
60
61 old := e.Value
62 e.Value = r.URL.Path
63
64 if _, err := datastore.Put(ctx, k, e); err != nil {
65 http.Error(w, err.Error(), 500)
66 return
67 }
68
69 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
70 fmt.Fprintf(w, "old=%q\nnew=%q\n", old, e.Value)
71 }
72
73GetMulti, PutMulti and DeleteMulti are batch versions of the Get, Put and
74Delete functions. They take a []*Key instead of a *Key, and may return an
75appengine.MultiError when encountering partial failure.
76
77
78Properties
79
80An entity's contents can be represented by a variety of types. These are
81typically struct pointers, but can also be any type that implements the
82PropertyLoadSaver interface. If using a struct pointer, you do not have to
83explicitly implement the PropertyLoadSaver interface; the datastore will
84automatically convert via reflection. If a struct pointer does implement that
85interface then those methods will be used in preference to the default
86behavior for struct pointers. Struct pointers are more strongly typed and are
87easier to use; PropertyLoadSavers are more flexible.
88
89The actual types passed do not have to match between Get and Put calls or even
90across different calls to datastore. It is valid to put a *PropertyList and
91get that same entity as a *myStruct, or put a *myStruct0 and get a *myStruct1.
92Conceptually, any entity is saved as a sequence of properties, and is loaded
93into the destination value on a property-by-property basis. When loading into
94a struct pointer, an entity that cannot be completely represented (such as a
95missing field) will result in an ErrFieldMismatch error but it is up to the
96caller whether this error is fatal, recoverable or ignorable.
97
98By default, for struct pointers, all properties are potentially indexed, and
99the property name is the same as the field name (and hence must start with an
100upper case letter).
101
102Fields may have a `datastore:"name,options"` tag. The tag name is the
103property name, which must be one or more valid Go identifiers joined by ".",
104but may start with a lower case letter. An empty tag name means to just use the
105field name. A "-" tag name means that the datastore will ignore that field.
106
107The only valid options are "omitempty" and "noindex".
108
109If the options include "omitempty" and the value of the field is empty, then the field will be omitted on Save.
110The empty values are false, 0, any nil interface value, and any array, slice, map, or string of length zero.
111Struct field values will never be empty.
112
113If options include "noindex" then the field will not be indexed. All fields are indexed
114by default. Strings or byte slices longer than 1500 bytes cannot be indexed;
115fields used to store long strings and byte slices must be tagged with "noindex"
116or they will cause Put operations to fail.
117
118To use multiple options together, separate them by a comma.
119The order does not matter.
120
121If the options is "" then the comma may be omitted.
122
123Example code:
124
125 // A and B are renamed to a and b.
126 // A, C and J are not indexed.
127 // D's tag is equivalent to having no tag at all (E).
128 // I is ignored entirely by the datastore.
129 // J has tag information for both the datastore and json packages.
130 type TaggedStruct struct {
131 A int `datastore:"a,noindex"`
132 B int `datastore:"b"`
133 C int `datastore:",noindex"`
134 D int `datastore:""`
135 E int
136 I int `datastore:"-"`
137 J int `datastore:",noindex" json:"j"`
138 }
139
140
141Structured Properties
142
143If the struct pointed to contains other structs, then the nested or embedded
144structs are flattened. For example, given these definitions:
145
146 type Inner1 struct {
147 W int32
148 X string
149 }
150
151 type Inner2 struct {
152 Y float64
153 }
154
155 type Inner3 struct {
156 Z bool
157 }
158
159 type Outer struct {
160 A int16
161 I []Inner1
162 J Inner2
163 Inner3
164 }
165
166then an Outer's properties would be equivalent to those of:
167
168 type OuterEquivalent struct {
169 A int16
170 IDotW []int32 `datastore:"I.W"`
171 IDotX []string `datastore:"I.X"`
172 JDotY float64 `datastore:"J.Y"`
173 Z bool
174 }
175
176If Outer's embedded Inner3 field was tagged as `datastore:"Foo"` then the
177equivalent field would instead be: FooDotZ bool `datastore:"Foo.Z"`.
178
179If an outer struct is tagged "noindex" then all of its implicit flattened
180fields are effectively "noindex".
181
182
183The PropertyLoadSaver Interface
184
185An entity's contents can also be represented by any type that implements the
186PropertyLoadSaver interface. This type may be a struct pointer, but it does
187not have to be. The datastore package will call Load when getting the entity's
188contents, and Save when putting the entity's contents.
189Possible uses include deriving non-stored fields, verifying fields, or indexing
190a field only if its value is positive.
191
192Example code:
193
194 type CustomPropsExample struct {
195 I, J int
196 // Sum is not stored, but should always be equal to I + J.
197 Sum int `datastore:"-"`
198 }
199
200 func (x *CustomPropsExample) Load(ps []datastore.Property) error {
201 // Load I and J as usual.
202 if err := datastore.LoadStruct(x, ps); err != nil {
203 return err
204 }
205 // Derive the Sum field.
206 x.Sum = x.I + x.J
207 return nil
208 }
209
210 func (x *CustomPropsExample) Save() ([]datastore.Property, error) {
211 // Validate the Sum field.
212 if x.Sum != x.I + x.J {
213 return nil, errors.New("CustomPropsExample has inconsistent sum")
214 }
215 // Save I and J as usual. The code below is equivalent to calling
216 // "return datastore.SaveStruct(x)", but is done manually for
217 // demonstration purposes.
218 return []datastore.Property{
219 {
220 Name: "I",
221 Value: int64(x.I),
222 },
223 {
224 Name: "J",
225 Value: int64(x.J),
226 },
227 }, nil
228 }
229
230The *PropertyList type implements PropertyLoadSaver, and can therefore hold an
231arbitrary entity's contents.
232
233
234Queries
235
236Queries retrieve entities based on their properties or key's ancestry. Running
237a query yields an iterator of results: either keys or (key, entity) pairs.
238Queries are re-usable and it is safe to call Query.Run from concurrent
239goroutines. Iterators are not safe for concurrent use.
240
241Queries are immutable, and are either created by calling NewQuery, or derived
242from an existing query by calling a method like Filter or Order that returns a
243new query value. A query is typically constructed by calling NewQuery followed
244by a chain of zero or more such methods. These methods are:
245 - Ancestor and Filter constrain the entities returned by running a query.
246 - Order affects the order in which they are returned.
247 - Project constrains the fields returned.
248 - Distinct de-duplicates projected entities.
249 - KeysOnly makes the iterator return only keys, not (key, entity) pairs.
250 - Start, End, Offset and Limit define which sub-sequence of matching entities
251 to return. Start and End take cursors, Offset and Limit take integers. Start
252 and Offset affect the first result, End and Limit affect the last result.
253 If both Start and Offset are set, then the offset is relative to Start.
254 If both End and Limit are set, then the earliest constraint wins. Limit is
255 relative to Start+Offset, not relative to End. As a special case, a
256 negative limit means unlimited.
257
258Example code:
259
260 type Widget struct {
261 Description string
262 Price int
263 }
264
265 func handle(w http.ResponseWriter, r *http.Request) {
266 ctx := appengine.NewContext(r)
267 q := datastore.NewQuery("Widget").
268 Filter("Price <", 1000).
269 Order("-Price")
270 b := new(bytes.Buffer)
271 for t := q.Run(ctx); ; {
272 var x Widget
273 key, err := t.Next(&x)
274 if err == datastore.Done {
275 break
276 }
277 if err != nil {
278 serveError(ctx, w, err)
279 return
280 }
281 fmt.Fprintf(b, "Key=%v\nWidget=%#v\n\n", key, x)
282 }
283 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
284 io.Copy(w, b)
285 }
286
287
288Transactions
289
290RunInTransaction runs a function in a transaction.
291
292Example code:
293
294 type Counter struct {
295 Count int
296 }
297
298 func inc(ctx context.Context, key *datastore.Key) (int, error) {
299 var x Counter
300 if err := datastore.Get(ctx, key, &x); err != nil && err != datastore.ErrNoSuchEntity {
301 return 0, err
302 }
303 x.Count++
304 if _, err := datastore.Put(ctx, key, &x); err != nil {
305 return 0, err
306 }
307 return x.Count, nil
308 }
309
310 func handle(w http.ResponseWriter, r *http.Request) {
311 ctx := appengine.NewContext(r)
312 var count int
313 err := datastore.RunInTransaction(ctx, func(ctx context.Context) error {
314 var err1 error
315 count, err1 = inc(ctx, datastore.NewKey(ctx, "Counter", "singleton", 0, nil))
316 return err1
317 }, nil)
318 if err != nil {
319 serveError(ctx, w, err)
320 return
321 }
322 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
323 fmt.Fprintf(w, "Count=%d", count)
324 }
325
326
327Metadata
328
329The datastore package provides access to some of App Engine's datastore
330metadata. This metadata includes information about the entity groups,
331namespaces, entity kinds, and properties in the datastore, as well as the
332property representations for each property.
333
334Example code:
335
336 func handle(w http.ResponseWriter, r *http.Request) {
337 // Print all the kinds in the datastore, with all the indexed
338 // properties (and their representations) for each.
339 ctx := appengine.NewContext(r)
340
341 kinds, err := datastore.Kinds(ctx)
342 if err != nil {
343 serveError(ctx, w, err)
344 return
345 }
346
347 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
348 for _, kind := range kinds {
349 fmt.Fprintf(w, "%s:\n", kind)
350 props, err := datastore.KindProperties(ctx, kind)
351 if err != nil {
352 fmt.Fprintln(w, "\t(unable to retrieve properties)")
353 continue
354 }
355 for p, rep := range props {
356 fmt.Fprintf(w, "\t-%s (%s)\n", p, strings.Join(rep, ", "))
357 }
358 }
359 }
360*/
361package datastore // import "google.golang.org/appengine/datastore"