golang.org/x/build@v0.0.0-20240506185731-218518f32b70/internal/datastore/fake/client.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package fake provides a fake implementation of a Datastore client 6 // to use in testing. 7 package fake 8 9 import ( 10 "bytes" 11 "context" 12 "encoding/gob" 13 "log" 14 "reflect" 15 "sync" 16 17 "cloud.google.com/go/datastore" 18 "github.com/googleapis/google-cloud-go-testing/datastore/dsiface" 19 ) 20 21 // Client is a fake implementation of dsiface.Client to use in 22 // testing. 23 type Client struct { 24 dsiface.Client 25 26 m sync.Mutex 27 db map[string]map[string][]byte 28 } 29 30 var _ dsiface.Client = &Client{} 31 32 // Close is unimplemented and panics. 33 func (f *Client) Close() error { 34 panic("unimplemented") 35 } 36 37 // AllocateIDs is unimplemented and panics. 38 func (f *Client) AllocateIDs(context.Context, []*datastore.Key) ([]*datastore.Key, error) { 39 panic("unimplemented") 40 } 41 42 // Count is unimplemented and panics. 43 func (f *Client) Count(context.Context, *datastore.Query) (n int, err error) { 44 panic("unimplemented") 45 } 46 47 // Delete is unimplemented and panics. 48 func (f *Client) Delete(context.Context, *datastore.Key) error { 49 panic("unimplemented") 50 } 51 52 // DeleteMulti is unimplemented and panics. 53 func (f *Client) DeleteMulti(context.Context, []*datastore.Key) (err error) { 54 panic("unimplemented") 55 } 56 57 // Get loads the entity stored for key into dst, which must be a 58 // struct pointer. 59 func (f *Client) Get(_ context.Context, key *datastore.Key, dst interface{}) (err error) { 60 f.m.Lock() 61 defer f.m.Unlock() 62 // get catches nil interfaces; we need to catch nil ptr here 63 if dst == nil { 64 return datastore.ErrInvalidEntityType 65 } 66 if key == nil { 67 return datastore.ErrInvalidKey 68 } 69 kdb := f.db[key.Kind] 70 if kdb == nil { 71 return datastore.ErrNoSuchEntity 72 } 73 rv := reflect.ValueOf(dst) 74 if rv.Kind() != reflect.Ptr { 75 return datastore.ErrInvalidEntityType 76 } 77 v := kdb[key.Encode()] 78 if v == nil { 79 return datastore.ErrNoSuchEntity 80 } 81 d := gob.NewDecoder(bytes.NewReader(v)) 82 return d.Decode(dst) 83 } 84 85 // GetAll runs the provided query in the given context and returns all 86 // keys that match that query, as well as appending the values to dst. 87 // 88 // GetAll currently only supports a query of all entities of a given 89 // Kind, and a dst of a slice of pointers to structs. 90 func (f *Client) GetAll(_ context.Context, q *datastore.Query, dst interface{}) (keys []*datastore.Key, err error) { 91 f.m.Lock() 92 defer f.m.Unlock() 93 fv := reflect.ValueOf(q).Elem().FieldByName("kind") 94 kdb := f.db[fv.String()] 95 if kdb == nil { 96 return 97 } 98 s := reflect.ValueOf(dst).Elem() 99 for k, v := range kdb { 100 dk, err := datastore.DecodeKey(k) 101 if err != nil { 102 log.Printf("f.GetAll() failed to decode key %q: %v", k, err) 103 continue 104 } 105 keys = append(keys, dk) 106 // This value is expected to represent a slice of pointers to structs. 107 ev := reflect.New(s.Type().Elem().Elem()) 108 d := gob.NewDecoder(bytes.NewReader(v)) 109 if err := d.DecodeValue(ev); err != nil { 110 return nil, err 111 } 112 s.Set(reflect.Append(s, ev)) 113 } 114 return 115 } 116 117 // GetMulti is unimplemented and panics. 118 func (f *Client) GetMulti(context.Context, []*datastore.Key, interface{}) (err error) { 119 panic("unimplemented") 120 } 121 122 // Mutate is unimplemented and panics. 123 func (f *Client) Mutate(context.Context, ...*datastore.Mutation) (ret []*datastore.Key, err error) { 124 panic("unimplemented") 125 } 126 127 // NewTransaction is unimplemented and panics. 128 func (f *Client) NewTransaction(context.Context, ...datastore.TransactionOption) (t dsiface.Transaction, err error) { 129 panic("unimplemented") 130 } 131 132 // Put saves the entity src into the datastore with the given key. src 133 // must be a struct pointer. 134 func (f *Client) Put(_ context.Context, key *datastore.Key, src interface{}) (*datastore.Key, error) { 135 f.m.Lock() 136 defer f.m.Unlock() 137 if f.db == nil { 138 f.db = make(map[string]map[string][]byte) 139 } 140 kdb := f.db[key.Kind] 141 if kdb == nil { 142 f.db[key.Kind] = make(map[string][]byte) 143 kdb = f.db[key.Kind] 144 } 145 dst := bytes.Buffer{} 146 e := gob.NewEncoder(&dst) 147 if err := e.Encode(src); err != nil { 148 return nil, err 149 } 150 kdb[key.Encode()] = dst.Bytes() 151 return key, nil 152 } 153 154 // PutMulti is unimplemented and panics. 155 func (f *Client) PutMulti(context.Context, []*datastore.Key, interface{}) (ret []*datastore.Key, err error) { 156 panic("unimplemented") 157 } 158 159 // Run is unimplemented and panics. 160 func (f *Client) Run(context.Context, *datastore.Query) dsiface.Iterator { 161 panic("unimplemented") 162 } 163 164 // RunInTransaction is unimplemented and panics. 165 func (f *Client) RunInTransaction(context.Context, func(tx dsiface.Transaction) error, ...datastore.TransactionOption) (cmt dsiface.Commit, err error) { 166 panic("unimplemented") 167 }