OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 package memory | |
6 | |
7 import ( | |
8 "errors" | |
9 | |
10 "golang.org/x/net/context" | |
11 | |
12 "github.com/luci/gae" | |
13 "github.com/luci/gae/helper" | |
14 ) | |
15 | |
16 //////////////////////////////////// public //////////////////////////////////// | |
17 | |
18 // useRDS adds a gae.Datastore implementation to context, accessible | |
19 // by gae.GetDS(c) | |
20 func useRDS(c context.Context) context.Context { | |
21 return gae.SetRDSFactory(c, func(ic context.Context) gae.RawDatastore { | |
22 dsd := cur(ic).Get(memContextDSIdx) | |
23 | |
24 ns := curGID(ic).namespace | |
25 if x, ok := dsd.(*dataStoreData); ok { | |
26 return &dsImpl{x, ns, ic} | |
27 } | |
28 return &txnDsImpl{dsd.(*txnDataStoreData), ns} | |
29 }) | |
30 } | |
31 | |
32 //////////////////////////////////// dsImpl //////////////////////////////////// | |
33 | |
34 // dsImpl exists solely to bind the current c to the datastore data. | |
35 type dsImpl struct { | |
36 data *dataStoreData | |
37 ns string | |
38 c context.Context | |
39 } | |
40 | |
41 var _ gae.RawDatastore = (*dsImpl)(nil) | |
42 | |
43 func (d *dsImpl) DecodeKey(encoded string) (gae.DSKey, error) { | |
44 return helper.NewDSKeyFromEncoded(encoded) | |
45 } | |
46 | |
47 func (d *dsImpl) NewKey(kind, stringID string, intID int64, parent gae.DSKey) ga
e.DSKey { | |
48 return helper.NewDSKey(globalAppID, d.ns, kind, stringID, intID, parent) | |
49 } | |
50 | |
51 func (d *dsImpl) Put(key gae.DSKey, pls gae.DSPropertyLoadSaver) (gae.DSKey, err
or) { | |
52 return d.data.put(d.ns, key, pls) | |
53 } | |
54 | |
55 func (d *dsImpl) PutMulti(keys []gae.DSKey, plss []gae.DSPropertyLoadSaver) ([]g
ae.DSKey, error) { | |
56 return d.data.putMulti(d.ns, keys, plss) | |
57 } | |
58 | |
59 func (d *dsImpl) Get(key gae.DSKey, pls gae.DSPropertyLoadSaver) error { | |
60 return d.data.get(d.ns, key, pls) | |
61 } | |
62 | |
63 func (d *dsImpl) GetMulti(keys []gae.DSKey, plss []gae.DSPropertyLoadSaver) erro
r { | |
64 return d.data.getMulti(d.ns, keys, plss) | |
65 } | |
66 | |
67 func (d *dsImpl) Delete(key gae.DSKey) error { | |
68 return d.data.del(d.ns, key) | |
69 } | |
70 | |
71 func (d *dsImpl) DeleteMulti(keys []gae.DSKey) error { | |
72 return d.data.delMulti(d.ns, keys) | |
73 } | |
74 | |
75 func (d *dsImpl) NewQuery(kind string) gae.DSQuery { | |
76 return &queryImpl{ns: d.ns, kind: kind} | |
77 } | |
78 | |
79 func (d *dsImpl) Run(q gae.DSQuery) gae.RDSIterator { | |
80 rq := q.(*queryImpl) | |
81 rq = rq.normalize().checkCorrectness(d.ns, false) | |
82 return &queryIterImpl{rq} | |
83 } | |
84 | |
85 func (d *dsImpl) GetAll(q gae.DSQuery, dst *[]gae.DSPropertyMap) ([]gae.DSKey, e
rror) { | |
86 // TODO(riannucci): assert that dst is a slice of structs | |
87 panic("NOT IMPLEMENTED") | |
88 } | |
89 | |
90 func (d *dsImpl) Count(q gae.DSQuery) (int, error) { | |
91 return count(d.Run(q.KeysOnly())) | |
92 } | |
93 | |
94 ////////////////////////////////// txnDsImpl /////////////////////////////////// | |
95 | |
96 type txnDsImpl struct { | |
97 data *txnDataStoreData | |
98 ns string | |
99 } | |
100 | |
101 var _ gae.RawDatastore = (*txnDsImpl)(nil) | |
102 | |
103 func (d *txnDsImpl) DecodeKey(encoded string) (gae.DSKey, error) { | |
104 return helper.NewDSKeyFromEncoded(encoded) | |
105 } | |
106 | |
107 func (d *txnDsImpl) NewKey(kind, stringID string, intID int64, parent gae.DSKey)
gae.DSKey { | |
108 return helper.NewDSKey(globalAppID, d.ns, kind, stringID, intID, parent) | |
109 } | |
110 | |
111 func (d *txnDsImpl) Put(key gae.DSKey, pls gae.DSPropertyLoadSaver) (retKey gae.
DSKey, err error) { | |
112 err = d.data.run(func() (err error) { | |
113 retKey, err = d.data.put(d.ns, key, pls) | |
114 return | |
115 }) | |
116 return | |
117 } | |
118 | |
119 func (d *txnDsImpl) PutMulti(keys []gae.DSKey, plss []gae.DSPropertyLoadSaver) (
retKeys []gae.DSKey, err error) { | |
120 err = d.data.run(func() (err error) { | |
121 retKeys, err = d.data.putMulti(d.ns, keys, plss) | |
122 return | |
123 }) | |
124 return | |
125 } | |
126 | |
127 func (d *txnDsImpl) Get(key gae.DSKey, pls gae.DSPropertyLoadSaver) error { | |
128 return d.data.run(func() error { | |
129 return d.data.get(d.ns, key, pls) | |
130 }) | |
131 } | |
132 | |
133 func (d *txnDsImpl) GetMulti(keys []gae.DSKey, plss []gae.DSPropertyLoadSaver) e
rror { | |
134 return d.data.run(func() error { | |
135 return d.data.getMulti(d.ns, keys, plss) | |
136 }) | |
137 } | |
138 | |
139 func (d *txnDsImpl) Delete(key gae.DSKey) error { | |
140 return d.data.run(func() error { | |
141 return d.data.del(d.ns, key) | |
142 }) | |
143 } | |
144 | |
145 func (d *txnDsImpl) DeleteMulti(keys []gae.DSKey) error { | |
146 return d.data.run(func() error { | |
147 return d.data.delMulti(d.ns, keys) | |
148 }) | |
149 } | |
150 | |
151 func (d *txnDsImpl) Run(q gae.DSQuery) gae.RDSIterator { | |
152 rq := q.(*queryImpl) | |
153 if rq.ancestor == nil { | |
154 rq.err = errors.New("memory: queries in transactions only suppor
t ancestor queries") | |
155 return &queryIterImpl{rq} | |
156 } | |
157 panic("NOT IMPLEMENTED") | |
158 } | |
159 | |
160 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *gae.DSTransac
tionOptions) error { | |
161 return errors.New("datastore: nested transactions are not supported") | |
162 } | |
163 | |
164 func (d *txnDsImpl) NewQuery(kind string) gae.DSQuery { | |
165 return &queryImpl{ns: d.ns, kind: kind} | |
166 } | |
167 | |
168 func (d *txnDsImpl) GetAll(q gae.DSQuery, dst *[]gae.DSPropertyMap) ([]gae.DSKey
, error) { | |
169 // TODO(riannucci): assert that dst is a slice of structs | |
170 panic("NOT IMPLEMENTED") | |
171 } | |
172 | |
173 func (d *txnDsImpl) Count(q gae.DSQuery) (int, error) { | |
174 return count(d.Run(q.KeysOnly())) | |
175 } | |
176 | |
177 func count(itr gae.RDSIterator) (ret int, err error) { | |
178 for _, err = itr.Next(nil); err != nil; _, err = itr.Next(nil) { | |
179 ret++ | |
180 } | |
181 if err == gae.ErrDSQueryDone { | |
182 err = nil | |
183 } | |
184 return | |
185 } | |
OLD | NEW |