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 "golang.org/x/net/context" |
| 11 |
| 12 "infra/gae/libs/gae" |
| 13 "infra/gae/libs/gae/helper" |
| 14 ) |
| 15 |
| 16 //////////////////////////////////// public //////////////////////////////////// |
| 17 |
| 18 // useDS adds a gae.Datastore implementation to context, accessible |
| 19 // by gae.GetDS(c) |
| 20 func useDS(c context.Context) context.Context { |
| 21 return gae.SetRDSFactory(c, func(ic context.Context) gae.RawDatastore { |
| 22 dsd := cur(ic).Get(memContextDSIdx) |
| 23 |
| 24 switch x := dsd.(type) { |
| 25 case *dataStoreData: |
| 26 return &dsImpl{gae.DummyRDS(), x, curGID(ic).namespace,
ic} |
| 27 case *txnDataStoreData: |
| 28 return &txnDsImpl{gae.DummyRDS(), x, curGID(ic).namespac
e} |
| 29 default: |
| 30 panic(fmt.Errorf("DS: bad type: %v in context %v", dsd,
ic)) |
| 31 } |
| 32 }) |
| 33 } |
| 34 |
| 35 //////////////////////////////////// dsImpl //////////////////////////////////// |
| 36 |
| 37 // dsImpl exists solely to bind the current c to the datastore data. |
| 38 type dsImpl struct { |
| 39 gae.RawDatastore |
| 40 |
| 41 data *dataStoreData |
| 42 ns string |
| 43 c context.Context |
| 44 } |
| 45 |
| 46 var _ interface { |
| 47 gae.RawDatastore |
| 48 gae.Testable |
| 49 } = (*dsImpl)(nil) |
| 50 |
| 51 func (d *dsImpl) BreakFeatures(err error, features ...string) { |
| 52 d.data.BreakFeatures(err, features...) |
| 53 } |
| 54 func (d *dsImpl) UnbreakFeatures(features ...string) { |
| 55 d.data.UnbreakFeatures(features...) |
| 56 } |
| 57 |
| 58 func (d *dsImpl) NewKey(kind, stringID string, intID int64, parent gae.DSKey) ga
e.DSKey { |
| 59 return helper.NewDSKey(globalAppID, d.ns, kind, stringID, intID, parent) |
| 60 } |
| 61 |
| 62 func (d *dsImpl) Put(key gae.DSKey, src interface{}) (retKey gae.DSKey, err erro
r) { |
| 63 err = d.data.RunIfNotBroken(func() (err error) { |
| 64 retKey, err = d.data.put(d.ns, key, src) |
| 65 return |
| 66 }) |
| 67 return |
| 68 } |
| 69 |
| 70 func (d *dsImpl) Get(key gae.DSKey, dst interface{}) error { |
| 71 return d.data.RunIfNotBroken(func() error { |
| 72 return d.data.get(d.ns, key, dst) |
| 73 }) |
| 74 } |
| 75 |
| 76 func (d *dsImpl) Delete(key gae.DSKey) error { |
| 77 return d.data.RunIfNotBroken(func() error { |
| 78 return d.data.del(d.ns, key) |
| 79 }) |
| 80 } |
| 81 |
| 82 ////////////////////////////////// txnDsImpl /////////////////////////////////// |
| 83 |
| 84 type txnDsImpl struct { |
| 85 gae.RawDatastore |
| 86 |
| 87 data *txnDataStoreData |
| 88 ns string |
| 89 } |
| 90 |
| 91 var ( |
| 92 _ = gae.RawDatastore((*txnDsImpl)(nil)) |
| 93 _ = gae.Testable((*txnDsImpl)(nil)) |
| 94 ) |
| 95 |
| 96 func (d *dsImpl) NewQuery(kind string) gae.DSQuery { |
| 97 return &queryImpl{DSQuery: gae.DummyQY(), ns: d.ns, kind: kind} |
| 98 } |
| 99 |
| 100 func (d *dsImpl) Run(q gae.DSQuery) gae.DSIterator { |
| 101 rq := q.(*queryImpl) |
| 102 rq = rq.normalize().checkCorrectness(d.ns, false) |
| 103 return &queryIterImpl{rq} |
| 104 } |
| 105 |
| 106 func (d *dsImpl) GetAll(q gae.DSQuery, dst interface{}) ([]gae.DSKey, error) { |
| 107 // TODO(riannucci): assert that dst is a slice of structs |
| 108 return nil, nil |
| 109 } |
| 110 |
| 111 func (d *dsImpl) Count(q gae.DSQuery) (ret int, err error) { |
| 112 itr := d.Run(q.KeysOnly()) |
| 113 for _, err = itr.Next(nil); err != nil; _, err = itr.Next(nil) { |
| 114 ret++ |
| 115 } |
| 116 if err == gae.ErrDSQueryDone { |
| 117 err = nil |
| 118 } |
| 119 return |
| 120 } |
| 121 |
| 122 func (d *txnDsImpl) BreakFeatures(err error, features ...string) { |
| 123 d.data.BreakFeatures(err, features...) |
| 124 } |
| 125 func (d *txnDsImpl) UnbreakFeatures(features ...string) { |
| 126 d.data.UnbreakFeatures(features...) |
| 127 } |
| 128 |
| 129 func (d *txnDsImpl) NewKey(kind, stringID string, intID int64, parent gae.DSKey)
gae.DSKey { |
| 130 return helper.NewDSKey(globalAppID, d.ns, kind, stringID, intID, parent) |
| 131 } |
| 132 |
| 133 func (d *txnDsImpl) Put(key gae.DSKey, src interface{}) (retKey gae.DSKey, err e
rror) { |
| 134 err = d.data.RunIfNotBroken(func() (err error) { |
| 135 retKey, err = d.data.put(d.ns, key, src) |
| 136 return |
| 137 }) |
| 138 return |
| 139 } |
| 140 |
| 141 func (d *txnDsImpl) Get(key gae.DSKey, dst interface{}) error { |
| 142 return d.data.RunIfNotBroken(func() error { |
| 143 return d.data.get(d.ns, key, dst) |
| 144 }) |
| 145 } |
| 146 |
| 147 func (d *txnDsImpl) Delete(key gae.DSKey) error { |
| 148 return d.data.RunIfNotBroken(func() error { |
| 149 return d.data.del(d.ns, key) |
| 150 }) |
| 151 } |
| 152 |
| 153 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *gae.DSTransac
tionOptions) error { |
| 154 return errors.New("datastore: nested transactions are not supported") |
| 155 } |
OLD | NEW |