go.mercari.io/datastore@v1.8.2/aedatastore/client.go (about) 1 package aedatastore 2 3 import ( 4 "context" 5 6 w "go.mercari.io/datastore" 7 "go.mercari.io/datastore/internal/shared" 8 "google.golang.org/appengine/datastore" 9 ) 10 11 var _ w.Client = (*datastoreImpl)(nil) 12 13 type datastoreImpl struct { 14 ctx context.Context 15 middlewares []w.Middleware 16 } 17 18 func (d *datastoreImpl) Get(ctx context.Context, key w.Key, dst interface{}) error { 19 err := d.GetMulti(ctx, []w.Key{key}, []interface{}{dst}) 20 if merr, ok := err.(w.MultiError); ok { 21 return merr[0] 22 } else if err != nil { 23 return err 24 } 25 26 return nil 27 } 28 29 func (d *datastoreImpl) GetMulti(ctx context.Context, keys []w.Key, dst interface{}) error { 30 cacheInfo := &w.MiddlewareInfo{ 31 Context: ctx, 32 Client: d, 33 } 34 cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares) 35 36 return shared.GetMultiOps(ctx, keys, dst, func(keys []w.Key, dst []w.PropertyList) error { 37 return cb.GetMultiWithoutTx(cacheInfo, keys, dst) 38 }) 39 } 40 41 func (d *datastoreImpl) Put(ctx context.Context, key w.Key, src interface{}) (w.Key, error) { 42 keys, err := d.PutMulti(ctx, []w.Key{key}, []interface{}{src}) 43 if merr, ok := err.(w.MultiError); ok { 44 return nil, merr[0] 45 } else if err != nil { 46 return nil, err 47 } 48 49 return keys[0], nil 50 } 51 52 func (d *datastoreImpl) PutMulti(ctx context.Context, keys []w.Key, src interface{}) ([]w.Key, error) { 53 cacheInfo := &w.MiddlewareInfo{ 54 Context: ctx, 55 Client: d, 56 } 57 cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares) 58 59 keys, _, err := shared.PutMultiOps(ctx, keys, src, func(keys []w.Key, src []w.PropertyList) ([]w.Key, []w.PendingKey, error) { 60 keys, err := cb.PutMultiWithoutTx(cacheInfo, keys, src) 61 return keys, nil, err 62 }) 63 if err != nil { 64 return nil, err 65 } 66 67 return keys, nil 68 } 69 70 func (d *datastoreImpl) Delete(ctx context.Context, key w.Key) error { 71 err := d.DeleteMulti(ctx, []w.Key{key}) 72 if merr, ok := err.(w.MultiError); ok { 73 return merr[0] 74 } else if err != nil { 75 return err 76 } 77 78 return nil 79 } 80 81 func (d *datastoreImpl) DeleteMulti(ctx context.Context, keys []w.Key) error { 82 cacheInfo := &w.MiddlewareInfo{ 83 Context: ctx, 84 Client: d, 85 } 86 cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares) 87 88 return shared.DeleteMultiOps(ctx, keys, func(keys []w.Key) error { 89 return cb.DeleteMultiWithoutTx(cacheInfo, keys) 90 }) 91 } 92 93 func (d *datastoreImpl) NewTransaction(ctx context.Context) (w.Transaction, error) { 94 ext, err := newTxExtractor(ctx) 95 if err != nil { 96 return nil, err 97 } 98 99 txCtx := context.WithValue(ext.txCtx, contextTransaction{}, ext) 100 txImpl := &transactionImpl{ 101 client: &datastoreImpl{ 102 ctx: txCtx, 103 middlewares: d.middlewares, 104 }, 105 } 106 txImpl.cacheInfo = &w.MiddlewareInfo{ 107 Context: txCtx, 108 Client: d, 109 Transaction: txImpl, 110 } 111 112 return txImpl, nil 113 } 114 115 func (d *datastoreImpl) RunInTransaction(ctx context.Context, f func(tx w.Transaction) error) (w.Commit, error) { 116 ext, err := newTxExtractor(ctx) 117 if err != nil { 118 return nil, err 119 } 120 121 txCtx := context.WithValue(ext.txCtx, contextTransaction{}, ext) 122 txImpl := &transactionImpl{ 123 client: &datastoreImpl{ 124 ctx: txCtx, 125 middlewares: d.middlewares, 126 }, 127 } 128 txImpl.cacheInfo = &w.MiddlewareInfo{ 129 Context: txCtx, 130 Client: d, 131 Transaction: txImpl, 132 } 133 134 err = f(txImpl) 135 if err != nil { 136 rollbackErr := txImpl.Rollback() 137 if rollbackErr != nil { 138 return nil, rollbackErr 139 } 140 return nil, err 141 } 142 143 commit, err := txImpl.Commit() 144 if err != nil { 145 return nil, err 146 } 147 return commit, nil 148 } 149 150 func (d *datastoreImpl) Run(ctx context.Context, q w.Query) w.Iterator { 151 cacheInfo := &w.MiddlewareInfo{ 152 Context: ctx, 153 Client: d, 154 } 155 cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares) 156 157 return cb.Run(cb.Info, q, q.Dump()) 158 } 159 160 func (d *datastoreImpl) AllocateIDs(ctx context.Context, keys []w.Key) ([]w.Key, error) { 161 cacheInfo := &w.MiddlewareInfo{ 162 Context: ctx, 163 Client: d, 164 } 165 cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares) 166 167 return cb.AllocateIDs(cb.Info, keys) 168 } 169 170 func (d *datastoreImpl) Count(ctx context.Context, q w.Query) (int, error) { 171 cacheInfo := &w.MiddlewareInfo{ 172 Context: ctx, 173 Client: d, 174 } 175 cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares) 176 177 return cb.Count(cb.Info, q, q.Dump()) 178 } 179 180 func (d *datastoreImpl) GetAll(ctx context.Context, q w.Query, dst interface{}) ([]w.Key, error) { 181 qDump := q.Dump() 182 cacheInfo := &w.MiddlewareInfo{ 183 Context: ctx, 184 Client: d, 185 Transaction: qDump.Transaction, 186 } 187 cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares) 188 return shared.GetAllOps(ctx, qDump, dst, func(dst *[]w.PropertyList) ([]w.Key, error) { 189 return cb.GetAll(cacheInfo, q, qDump, dst) 190 }) 191 } 192 193 func (d *datastoreImpl) IncompleteKey(kind string, parent w.Key) w.Key { 194 key := &keyImpl{ 195 ctx: d.ctx, 196 kind: kind, 197 id: 0, 198 name: "", 199 } 200 if parent != nil { 201 parentImpl := parent.(*keyImpl) 202 key.parent = parentImpl 203 } 204 205 return key 206 } 207 208 func (d *datastoreImpl) NameKey(kind, name string, parent w.Key) w.Key { 209 key := &keyImpl{ 210 ctx: d.ctx, 211 kind: kind, 212 id: 0, 213 name: name, 214 } 215 if parent != nil { 216 parentImpl := parent.(*keyImpl) 217 key.parent = parentImpl 218 } 219 220 return key 221 } 222 223 func (d *datastoreImpl) IDKey(kind string, id int64, parent w.Key) w.Key { 224 key := &keyImpl{ 225 ctx: d.ctx, 226 kind: kind, 227 id: id, 228 name: "", 229 } 230 if parent != nil { 231 parentImpl := parent.(*keyImpl) 232 key.parent = parentImpl 233 } 234 235 return key 236 } 237 238 func (d *datastoreImpl) NewQuery(kind string) w.Query { 239 q := datastore.NewQuery(kind) 240 return &queryImpl{ctx: d.ctx, q: q, dump: &w.QueryDump{Kind: kind}} 241 } 242 243 func (d *datastoreImpl) Close() error { 244 // TODO closeした後に呼んだら殺したほうが ae <-> cloud の移行が楽になりそう 245 return nil 246 } 247 248 func (d *datastoreImpl) DecodeKey(encoded string) (w.Key, error) { 249 key, err := datastore.DecodeKey(encoded) 250 if err != nil { 251 return nil, toWrapperError(err) 252 } 253 254 return toWrapperKey(d.ctx, key), nil 255 } 256 257 func (d *datastoreImpl) DecodeCursor(s string) (w.Cursor, error) { 258 cur, err := datastore.DecodeCursor(s) 259 if err != nil { 260 return nil, toWrapperError(err) 261 } 262 263 return &cursorImpl{cursor: cur}, nil 264 } 265 266 func (d *datastoreImpl) Batch() *w.Batch { 267 return &w.Batch{Client: d} 268 } 269 270 func (d *datastoreImpl) AppendMiddleware(mw w.Middleware) { 271 d.middlewares = append(d.middlewares, mw) 272 } 273 274 func (d *datastoreImpl) RemoveMiddleware(md w.Middleware) bool { 275 list := make([]w.Middleware, 0, len(d.middlewares)) 276 found := false 277 for _, old := range d.middlewares { 278 if old == md { 279 found = true 280 continue 281 } 282 list = append(list, old) 283 } 284 d.middlewares = list 285 286 return found 287 } 288 289 func (d *datastoreImpl) Context() context.Context { 290 return d.ctx 291 } 292 293 func (d *datastoreImpl) SetContext(ctx context.Context) { 294 if ctx == nil { 295 panic("ctx can't be nil") 296 } 297 d.ctx = ctx 298 }