-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathboth.go
More file actions
94 lines (87 loc) · 3.28 KB
/
both.go
File metadata and controls
94 lines (87 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Package retrievable handles interaction between
// Google appengine's datastore and memcache using
// a very simple to implement interface.
//
// A trivial example of implementing Retrievable is:
//
// package main
//
// import (
// "github.com/Esseh/retrievable"
// "golang.org/x/net/context"
// "google.golang.org/appengine"
// "google.golang.org/appengine/datastore"
// )
//
// type A struct { // A is an example structure implementing KeyRetrievable
// Value string
// StringID `datastore:"-" json:"-"` // We will mark the ID as not to be stored in either Datastore or Memcache
// // KeyRetrievable is implemented by one of the helper types useful for the most common cases
// }
//
// func (a *A) Key(ctx context.Context, key interface{}) *datastore.Key {
// return datastore.NewKey(ctx, "tableA", key.(string), 0, nil) // This is the function to implement Retrievable, A in this context knows the Kind it is a part of and that it's key is a string.
// }
//
// func Example(w http.ResponseWriter, r *http.Request) {
// ctx := appengine.NewContext(req)
//
// a := A{}
// a.Value = "Example Information"
// // Now that A implements KeyRetrievable, we may use the associated functions.
// retrievable.PlaceInDatastore(ctx, "Key Value", &a)
// }
//
// Retrievable structs will follow the properties of datastore.
// If a struct does not implement Serializable, it will also follow the properties of json.
// Information regarding this can be found at:
// https://godoc.org/google.golang.org/appengine/datastore#hdr-Properties
// and
// https://godoc.org/encoding/json#Marshal
//
// More complex and in depth examples can be found in our wiki page at: https://github.com/Esseh/retrievable/wiki
//
package retrievable
import (
"golang.org/x/net/context"
"google.golang.org/appengine/datastore"
)
// GetEntity preforms a get action from first memcache then datastore.
//
// If there is no value in memcache but there is in datastore, this
// function will attempt to place the value in memcache for future
// retrieval.
//
// If found, value is placed into output (Retrievable).
// An error may be returned if datastore cannot find the entity.
func GetEntity(ctx context.Context, key interface{}, output Retrievable) error {
DSKey := output.Key(ctx, key)
if cacheErr := GetFromMemcache(ctx, DSKey.Encode(), output); cacheErr == nil {
if i, ok := output.(KeyRetrievable); ok {
i.StoreKey(DSKey)
}
return nil
}
if getErr := GetFromDatastore(ctx, key, output); getErr != nil {
return getErr
}
return nil
}
// PlaceEntity will place the input Retrievable into first memcache and
// then datastore.
//
// Returns a datastore.Key on successful placement.
// An error may be returned if datastore throws an error.
func PlaceEntity(ctx context.Context, key interface{}, input Retrievable) (*datastore.Key, error) {
mck := input.Key(ctx, key).Encode()
PlaceInMemcache(ctx, mck, input, 0)
return PlaceInDatastore(ctx, key, input)
}
// DeleteEntity will attempt to delete the memory pointed to by key
// first from memcache then datastore.
//
// An error may be returned if datastore throws an error.
func DeleteEntity(ctx context.Context, key *datastore.Key) error {
DeleteFromMemcache(ctx, key.Encode())
return datastore.Delete(ctx, key)
}