go.mercari.io/datastore@v1.8.2/aedatastore/bridge.go (about) 1 package aedatastore 2 3 import ( 4 "context" 5 "encoding/gob" 6 "errors" 7 8 w "go.mercari.io/datastore" 9 "go.mercari.io/datastore/internal/shared" 10 "google.golang.org/appengine" 11 "google.golang.org/appengine/datastore" 12 ) 13 14 func init() { 15 //lint:ignore SA1019 for backward compatible 16 w.FromContext = FromContext 17 18 gob.Register(&keyImpl{}) 19 } 20 21 // FromContext make new Client by specified context. 22 func FromContext(ctx context.Context, opts ...w.ClientOption) (w.Client, error) { 23 if ctx == nil { 24 panic("unexpected") 25 } 26 return &datastoreImpl{ctx: ctx}, nil 27 } 28 29 // IsAEDatastoreClient returns check result that client is this package's client or not. 30 func IsAEDatastoreClient(client w.Client) bool { 31 _, ok := client.(*datastoreImpl) 32 return ok 33 } 34 35 var _ shared.OriginalClientBridge = &originalClientBridgeImpl{} 36 var _ shared.OriginalTransactionBridge = &originalTransactionBridgeImpl{} 37 var _ shared.OriginalIteratorBridge = &originalIteratorBridgeImpl{} 38 39 type originalClientBridgeImpl struct { 40 d *datastoreImpl 41 } 42 43 func (ocb *originalClientBridgeImpl) AllocateIDs(ctx context.Context, keys []w.Key) ([]w.Key, error) { 44 // TODO 可能な限りバッチ化する 45 var resultKeys []w.Key 46 for _, key := range keys { 47 pK := toOriginalKey(key.ParentKey()) 48 low, _, err := datastore.AllocateIDs(ctx, key.Kind(), pK, 1) 49 if err != nil { 50 return nil, toWrapperError(err) 51 } 52 origKey := datastore.NewKey(ctx, key.Kind(), "", low, pK) 53 resultKeys = append(resultKeys, toWrapperKey(ctx, origKey)) 54 } 55 56 return resultKeys, nil 57 } 58 59 func (ocb *originalClientBridgeImpl) PutMulti(ctx context.Context, keys []w.Key, psList []w.PropertyList) ([]w.Key, error) { 60 origKeys := toOriginalKeys(keys) 61 origPss, err := toOriginalPropertyListList(psList) 62 if err != nil { 63 return nil, err 64 } 65 66 origKeys, err = datastore.PutMulti(ctx, origKeys, origPss) 67 return toWrapperKeys(ctx, origKeys), toWrapperError(err) 68 } 69 70 func (ocb *originalClientBridgeImpl) GetMulti(ctx context.Context, keys []w.Key, psList []w.PropertyList) error { 71 origKeys := toOriginalKeys(keys) 72 origPss, err := toOriginalPropertyListList(psList) 73 if err != nil { 74 return err 75 } 76 77 err = datastore.GetMulti(ctx, origKeys, origPss) 78 wPss := toWrapperPropertyListList(ctx, origPss) 79 copy(psList, wPss) 80 return toWrapperError(err) 81 } 82 83 func (ocb *originalClientBridgeImpl) DeleteMulti(ctx context.Context, keys []w.Key) error { 84 origKeys := toOriginalKeys(keys) 85 86 err := datastore.DeleteMulti(ctx, origKeys) 87 return toWrapperError(err) 88 } 89 90 func (ocb *originalClientBridgeImpl) Run(ctx context.Context, q w.Query, qDump *w.QueryDump) w.Iterator { 91 qImpl := q.(*queryImpl) 92 93 baseCtx := ctx 94 95 if qImpl.dump.Transaction != nil { 96 // replace ctx to tx ctx 97 ctx = TransactionContext(qImpl.dump.Transaction) 98 } 99 100 ctx, err := appengine.Namespace(ctx, qImpl.dump.Namespace) 101 if err != nil && qImpl.firstError == nil { 102 qImpl.firstError = err 103 } 104 105 iter := qImpl.q.Run(ctx) 106 return &iteratorImpl{ 107 client: ocb.d, 108 q: qImpl, 109 qDump: qDump, 110 t: iter, 111 cacheInfo: &w.MiddlewareInfo{ 112 Context: baseCtx, 113 Client: ocb.d, 114 Transaction: qDump.Transaction, 115 }, 116 firstError: qImpl.firstError, 117 } 118 } 119 120 func (ocb *originalClientBridgeImpl) GetAll(ctx context.Context, q w.Query, qDump *w.QueryDump, psList *[]w.PropertyList) ([]w.Key, error) { 121 qImpl, ok := q.(*queryImpl) 122 if !ok { 123 return nil, errors.New("invalid query type") 124 } 125 126 if qImpl.firstError != nil { 127 return nil, qImpl.firstError 128 } 129 130 if qDump.Transaction != nil { 131 // replace ctx to tx ctx 132 ctx = TransactionContext(qImpl.dump.Transaction) 133 } 134 135 var err error 136 ctx, err = appengine.Namespace(ctx, qDump.Namespace) 137 if err != nil { 138 return nil, toWrapperError(err) 139 } 140 141 var origPss []datastore.PropertyList 142 if !qDump.KeysOnly { 143 origPss, err = toOriginalPropertyListList(*psList) 144 if err != nil { 145 return nil, err 146 } 147 } 148 origKeys, err := qImpl.q.GetAll(ctx, &origPss) 149 if err != nil { 150 return nil, toWrapperError(err) 151 } 152 153 wKeys := toWrapperKeys(ctx, origKeys) 154 155 if !qDump.KeysOnly { 156 *psList = toWrapperPropertyListList(ctx, origPss) 157 } 158 159 return wKeys, nil 160 } 161 162 func (ocb *originalClientBridgeImpl) Count(ctx context.Context, q w.Query, qDump *w.QueryDump) (int, error) { 163 qImpl, ok := q.(*queryImpl) 164 if !ok { 165 return 0, errors.New("invalid query type") 166 } 167 if qImpl.firstError != nil { 168 return 0, qImpl.firstError 169 } 170 171 if qImpl.dump.Transaction != nil { 172 // replace ctx to tx ctx 173 txImpl, ok := qImpl.dump.Transaction.(*transactionImpl) 174 if !ok { 175 return 0, errors.New("unexpected context") 176 } 177 ctx = txImpl.client.ctx 178 } 179 180 var err error 181 ctx, err = appengine.Namespace(ctx, qImpl.dump.Namespace) 182 if err != nil { 183 return 0, toWrapperError(err) 184 } 185 count, err := qImpl.q.Count(ctx) 186 if err != nil { 187 return 0, toWrapperError(err) 188 } 189 190 return count, nil 191 } 192 193 type originalTransactionBridgeImpl struct { 194 tx *transactionImpl 195 } 196 197 func (otb *originalTransactionBridgeImpl) PutMulti(keys []w.Key, psList []w.PropertyList) ([]w.PendingKey, error) { 198 ext := getTxExtractor(otb.tx.client.ctx) 199 if ext == nil { 200 return nil, errors.New("unexpected context") 201 } 202 203 origKeys := toOriginalKeys(keys) 204 origPss, err := toOriginalPropertyListList(psList) 205 if err != nil { 206 return nil, err 207 } 208 209 origKeys, err = datastore.PutMulti(ext.txCtx, origKeys, origPss) 210 if err != nil { 211 return nil, toWrapperError(err) 212 } 213 214 wPKeys := toWrapperPendingKeys(ext.txCtx, origKeys) 215 216 return wPKeys, nil 217 } 218 219 func (otb *originalTransactionBridgeImpl) GetMulti(keys []w.Key, psList []w.PropertyList) error { 220 ext := getTxExtractor(otb.tx.client.ctx) 221 if ext == nil { 222 return errors.New("unexpected context") 223 } 224 225 origKeys := toOriginalKeys(keys) 226 origPss, err := toOriginalPropertyListList(psList) 227 if err != nil { 228 return err 229 } 230 231 err = datastore.GetMulti(ext.txCtx, origKeys, origPss) 232 wPss := toWrapperPropertyListList(ext.txCtx, origPss) 233 copy(psList, wPss) 234 if err != nil { 235 return toWrapperError(err) 236 } 237 238 return nil 239 } 240 241 func (otb *originalTransactionBridgeImpl) DeleteMulti(keys []w.Key) error { 242 ext := getTxExtractor(otb.tx.client.ctx) 243 if ext == nil { 244 return errors.New("unexpected context") 245 } 246 247 origKeys := toOriginalKeys(keys) 248 249 err := datastore.DeleteMulti(ext.txCtx, origKeys) 250 return toWrapperError(err) 251 } 252 253 type originalIteratorBridgeImpl struct { 254 qDump *w.QueryDump 255 } 256 257 func (oib *originalIteratorBridgeImpl) Next(iter w.Iterator, ps *w.PropertyList) (w.Key, error) { 258 iterImpl := iter.(*iteratorImpl) 259 260 var origPsPtr *datastore.PropertyList 261 if !oib.qDump.KeysOnly { 262 origPs, err := toOriginalPropertyList(*ps) 263 if err != nil { 264 return nil, err 265 } 266 origPsPtr = &origPs 267 } 268 269 origKey, err := iterImpl.t.Next(origPsPtr) 270 if err != nil { 271 return nil, toWrapperError(err) 272 } 273 274 if !oib.qDump.KeysOnly { 275 *ps = toWrapperPropertyList(iterImpl.client.ctx, *origPsPtr) 276 } 277 278 return toWrapperKey(iterImpl.client.ctx, origKey), nil 279 }