| 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 "fmt" | |
| 10 "infra/gae/libs/wrapper" | |
| 11 "strings" | |
| 12 | |
| 13 "github.com/mjibson/goon" | |
| 14 "golang.org/x/net/context" | |
| 15 | |
| 16 "appengine/datastore" | |
| 17 "appengine_internal" | |
| 18 pb "appengine_internal/datastore" | |
| 19 ) | |
| 20 | |
| 21 //////////////////////////////////// public //////////////////////////////////// | |
| 22 | |
| 23 // useDS adds a wrapper.Datastore implementation to context, accessible | |
| 24 // by wrapper.GetDS(c) | |
| 25 func useDS(c context.Context) context.Context { | |
| 26 return wrapper.SetDSFactory(c, func(ic context.Context) wrapper.Datastor
e { | |
| 27 dsd := cur(ic).Get(memContextDSIdx) | |
| 28 | |
| 29 switch x := dsd.(type) { | |
| 30 case *dataStoreData: | |
| 31 return &dsImpl{wrapper.DummyDS(), x, curGID(ic).namespac
e, ic} | |
| 32 case *txnDataStoreData: | |
| 33 return &txnDsImpl{wrapper.DummyDS(), x, curGID(ic).names
pace} | |
| 34 default: | |
| 35 panic(fmt.Errorf("DS: bad type: %v in context %v", dsd,
ic)) | |
| 36 } | |
| 37 }) | |
| 38 } | |
| 39 | |
| 40 //////////////////////////////////// dsImpl //////////////////////////////////// | |
| 41 | |
| 42 // dsImpl exists solely to bind the current c to the datastore data. | |
| 43 type dsImpl struct { | |
| 44 wrapper.Datastore | |
| 45 | |
| 46 data *dataStoreData | |
| 47 ns string | |
| 48 c context.Context | |
| 49 } | |
| 50 | |
| 51 var ( | |
| 52 _ = wrapper.Datastore((*dsImpl)(nil)) | |
| 53 _ = wrapper.Testable((*dsImpl)(nil)) | |
| 54 ) | |
| 55 | |
| 56 func (d *dsImpl) BreakFeatures(err error, features ...string) { | |
| 57 d.data.BreakFeatures(err, features...) | |
| 58 } | |
| 59 func (d *dsImpl) UnbreakFeatures(features ...string) { | |
| 60 d.data.UnbreakFeatures(features...) | |
| 61 } | |
| 62 | |
| 63 func (d *dsImpl) Kind(src interface{}) string { | |
| 64 return kind(d.ns, d.KindNameResolver(), src) | |
| 65 } | |
| 66 | |
| 67 func (d *dsImpl) KindNameResolver() goon.KindNameResolver { | |
| 68 return d.data.KindNameResolver() | |
| 69 } | |
| 70 func (d *dsImpl) SetKindNameResolver(knr goon.KindNameResolver) { | |
| 71 d.data.SetKindNameResolver(knr) | |
| 72 } | |
| 73 | |
| 74 func (d *dsImpl) NewKey(kind, stringID string, intID int64, parent *datastore.Ke
y) *datastore.Key { | |
| 75 return newKey(d.ns, kind, stringID, intID, parent) | |
| 76 } | |
| 77 func (d *dsImpl) NewKeyObj(src interface{}) *datastore.Key { | |
| 78 return newKeyObj(d.ns, d.KindNameResolver(), src) | |
| 79 } | |
| 80 func (d *dsImpl) NewKeyObjError(src interface{}) (*datastore.Key, error) { | |
| 81 return newKeyObjError(d.ns, d.KindNameResolver(), src) | |
| 82 } | |
| 83 | |
| 84 func (d *dsImpl) Put(src interface{}) (*datastore.Key, error) { | |
| 85 if err := d.data.IsBroken(); err != nil { | |
| 86 return nil, err | |
| 87 } | |
| 88 return d.data.put(d.ns, src) | |
| 89 } | |
| 90 | |
| 91 func (d *dsImpl) Get(dst interface{}) error { | |
| 92 if err := d.data.IsBroken(); err != nil { | |
| 93 return err | |
| 94 } | |
| 95 return d.data.get(d.ns, dst) | |
| 96 } | |
| 97 | |
| 98 func (d *dsImpl) Delete(key *datastore.Key) error { | |
| 99 if err := d.data.IsBroken(); err != nil { | |
| 100 return err | |
| 101 } | |
| 102 return d.data.del(d.ns, key) | |
| 103 } | |
| 104 | |
| 105 ////////////////////////////////// txnDsImpl /////////////////////////////////// | |
| 106 | |
| 107 type txnDsImpl struct { | |
| 108 wrapper.Datastore | |
| 109 | |
| 110 data *txnDataStoreData | |
| 111 ns string | |
| 112 } | |
| 113 | |
| 114 var ( | |
| 115 _ = wrapper.Datastore((*txnDsImpl)(nil)) | |
| 116 _ = wrapper.Testable((*txnDsImpl)(nil)) | |
| 117 ) | |
| 118 | |
| 119 func (d *dsImpl) NewQuery(kind string) wrapper.DSQuery { | |
| 120 return &queryImpl{DSQuery: wrapper.DummyQY(), ns: d.ns, kind: kind} | |
| 121 } | |
| 122 | |
| 123 func (d *dsImpl) Run(q wrapper.DSQuery) wrapper.DSIterator { | |
| 124 rq := q.(*queryImpl) | |
| 125 rq = rq.normalize().checkCorrectness(d.ns, false) | |
| 126 return &queryIterImpl{rq} | |
| 127 } | |
| 128 | |
| 129 func (d *dsImpl) GetAll(q wrapper.DSQuery, dst interface{}) ([]*datastore.Key, e
rror) { | |
| 130 // TODO(riannucci): assert that dst is a slice of structs | |
| 131 return nil, nil | |
| 132 } | |
| 133 | |
| 134 func (d *dsImpl) Count(q wrapper.DSQuery) (ret int, err error) { | |
| 135 itr := d.Run(q.KeysOnly()) | |
| 136 for _, err = itr.Next(nil); err != nil; _, err = itr.Next(nil) { | |
| 137 ret++ | |
| 138 } | |
| 139 if err == datastore.Done { | |
| 140 err = nil | |
| 141 } | |
| 142 return | |
| 143 } | |
| 144 | |
| 145 func (d *txnDsImpl) BreakFeatures(err error, features ...string) { | |
| 146 d.data.BreakFeatures(err, features...) | |
| 147 } | |
| 148 func (d *txnDsImpl) UnbreakFeatures(features ...string) { | |
| 149 d.data.UnbreakFeatures(features...) | |
| 150 } | |
| 151 | |
| 152 func (d *txnDsImpl) Kind(src interface{}) string { | |
| 153 return kind(d.ns, d.KindNameResolver(), src) | |
| 154 } | |
| 155 | |
| 156 func (d *txnDsImpl) KindNameResolver() goon.KindNameResolver { | |
| 157 return d.data.KindNameResolver() | |
| 158 } | |
| 159 func (d *txnDsImpl) SetKindNameResolver(knr goon.KindNameResolver) { | |
| 160 d.data.SetKindNameResolver(knr) | |
| 161 } | |
| 162 | |
| 163 func (d *txnDsImpl) NewKey(kind, stringID string, intID int64, parent *datastore
.Key) *datastore.Key { | |
| 164 return newKey(d.ns, kind, stringID, intID, parent) | |
| 165 } | |
| 166 func (d *txnDsImpl) NewKeyObj(src interface{}) *datastore.Key { | |
| 167 return newKeyObj(d.ns, d.KindNameResolver(), src) | |
| 168 } | |
| 169 func (d *txnDsImpl) NewKeyObjError(src interface{}) (*datastore.Key, error) { | |
| 170 return newKeyObjError(d.ns, d.KindNameResolver(), src) | |
| 171 } | |
| 172 | |
| 173 func (d *txnDsImpl) Put(src interface{}) (*datastore.Key, error) { | |
| 174 if err := d.data.IsBroken(); err != nil { | |
| 175 return nil, err | |
| 176 } | |
| 177 return d.data.put(d.ns, src) | |
| 178 } | |
| 179 | |
| 180 func (d *txnDsImpl) Get(dst interface{}) error { | |
| 181 if err := d.data.IsBroken(); err != nil { | |
| 182 return err | |
| 183 } | |
| 184 return d.data.get(d.ns, dst) | |
| 185 } | |
| 186 | |
| 187 func (d *txnDsImpl) Delete(key *datastore.Key) error { | |
| 188 if err := d.data.IsBroken(); err != nil { | |
| 189 return err | |
| 190 } | |
| 191 return d.data.del(d.ns, key) | |
| 192 } | |
| 193 | |
| 194 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *datastore.Tra
nsactionOptions) error { | |
| 195 return errors.New("datastore: nested transactions are not supported") | |
| 196 } | |
| 197 | |
| 198 ////////////////////////////// private functions /////////////////////////////// | |
| 199 | |
| 200 func newDSError(code pb.Error_ErrorCode, message ...string) *appengine_internal.
APIError { | |
| 201 return &appengine_internal.APIError{ | |
| 202 Detail: strings.Join(message, ""), | |
| 203 Service: "datastore_v3", | |
| 204 Code: int32(code), | |
| 205 } | |
| 206 } | |
| OLD | NEW |