go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/gae/impl/prod/datastore_key.go (about) 1 // Copyright 2015 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package prod 16 17 import ( 18 "context" 19 20 "google.golang.org/appengine" 21 "google.golang.org/appengine/datastore" 22 23 "go.chromium.org/luci/common/errors" 24 25 ds "go.chromium.org/luci/gae/service/datastore" 26 ) 27 28 // dsR2F (DS real-to-fake) converts an SDK Key to a ds.Key 29 func dsR2F(k *datastore.Key) *ds.Key { 30 if k == nil { 31 return nil 32 } 33 kc := ds.MkKeyContext(k.AppID(), k.Namespace()) 34 35 count := 0 36 for nk := k; nk != nil; nk = nk.Parent() { 37 count++ 38 } 39 40 toks := make([]ds.KeyTok, count) 41 42 for ; k != nil; k = k.Parent() { 43 count-- 44 toks[count].Kind = k.Kind() 45 toks[count].StringID = k.StringID() 46 toks[count].IntID = k.IntID() 47 } 48 return kc.NewKeyToks(toks) 49 } 50 51 // dsF2R (DS fake-to-real) converts a DSKey back to an SDK *Key. 52 func dsF2R(aeCtx context.Context, k *ds.Key) (*datastore.Key, error) { 53 if k == nil { 54 return nil, nil 55 } 56 57 // drop aid. 58 _, ns, toks := k.Split() 59 err := error(nil) 60 aeCtx, err = appengine.Namespace(aeCtx, ns) 61 if err != nil { 62 return nil, err 63 } 64 65 ret := datastore.NewKey(aeCtx, toks[0].Kind, toks[0].StringID, toks[0].IntID, nil) 66 for _, t := range toks[1:] { 67 ret = datastore.NewKey(aeCtx, t.Kind, t.StringID, t.IntID, ret) 68 } 69 70 return ret, nil 71 } 72 73 // dsMF2R (DS multi-fake-to-fake) converts a slice of wrapped keys to SDK keys. 74 func dsMF2R(aeCtx context.Context, ks []*ds.Key) ([]*datastore.Key, error) { 75 lme := errors.NewLazyMultiError(len(ks)) 76 ret := make([]*datastore.Key, len(ks)) 77 err := error(nil) 78 for i, k := range ks { 79 ret[i], err = dsF2R(aeCtx, k) 80 lme.Assign(i, err) 81 } 82 return ret, lme.Get() 83 }