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  }