go.mercari.io/datastore@v1.8.2/clouddatastore/bridge.go (about)

     1  package clouddatastore
     2  
     3  import (
     4  	"context"
     5  	"encoding/gob"
     6  	"errors"
     7  
     8  	"cloud.google.com/go/compute/metadata"
     9  	"cloud.google.com/go/datastore"
    10  	w "go.mercari.io/datastore"
    11  	"go.mercari.io/datastore/internal"
    12  	"go.mercari.io/datastore/internal/shared"
    13  	"google.golang.org/api/option"
    14  )
    15  
    16  func init() {
    17  	//lint:ignore SA1019 for backward compatible
    18  	w.FromContext = FromContext
    19  
    20  	gob.Register(&keyImpl{})
    21  }
    22  
    23  var projectID *string
    24  
    25  func newClientSettings(opts ...w.ClientOption) *internal.ClientSettings {
    26  	if projectID == nil {
    27  		pID, err := metadata.ProjectID()
    28  		if err != nil {
    29  			// don't check again even if it was failed...
    30  			pID = internal.GetProjectID()
    31  		}
    32  		projectID = &pID
    33  	}
    34  	settings := &internal.ClientSettings{
    35  		ProjectID: *projectID,
    36  	}
    37  	for _, opt := range opts {
    38  		opt.Apply(settings)
    39  	}
    40  	return settings
    41  }
    42  
    43  // FromContext make new Client by specified context.
    44  // Deprecated: use FromClient instead of FromContext. FromContext implicitly creates original datastore.Client.
    45  func FromContext(ctx context.Context, opts ...w.ClientOption) (w.Client, error) {
    46  	settings := newClientSettings(opts...)
    47  	origOpts := make([]option.ClientOption, 0, len(opts))
    48  	if len(settings.Scopes) != 0 {
    49  		origOpts = append(origOpts, option.WithScopes(settings.Scopes...))
    50  	}
    51  	if settings.TokenSource != nil {
    52  		origOpts = append(origOpts, option.WithTokenSource(settings.TokenSource))
    53  	}
    54  	if settings.CredentialsFile != "" {
    55  		origOpts = append(origOpts, option.WithCredentialsFile(settings.CredentialsFile))
    56  	}
    57  	if settings.HTTPClient != nil {
    58  		origOpts = append(origOpts, option.WithHTTPClient(settings.HTTPClient))
    59  	}
    60  	if len(settings.GRPCDialOpts) != 0 {
    61  		for _, dialOpt := range settings.GRPCDialOpts {
    62  			origOpts = append(origOpts, option.WithGRPCDialOption(dialOpt))
    63  		}
    64  	}
    65  
    66  	client, err := datastore.NewClient(ctx, settings.ProjectID, origOpts...)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	return &datastoreImpl{ctx: ctx, client: client}, nil
    72  }
    73  
    74  // FromClient make new Client by specified datastore.Client.
    75  func FromClient(ctx context.Context, client *datastore.Client) (w.Client, error) {
    76  	return &datastoreImpl{ctx: ctx, client: client}, nil
    77  }
    78  
    79  // IsCloudDatastoreClient returns check result that client is this package's client or not.
    80  func IsCloudDatastoreClient(client w.Client) bool {
    81  	_, ok := client.(*datastoreImpl)
    82  	return ok
    83  }
    84  
    85  var _ shared.OriginalClientBridge = &originalClientBridgeImpl{}
    86  var _ shared.OriginalTransactionBridge = &originalTransactionBridgeImpl{}
    87  var _ shared.OriginalIteratorBridge = &originalIteratorBridgeImpl{}
    88  
    89  type originalClientBridgeImpl struct {
    90  	d *datastoreImpl
    91  }
    92  
    93  func (ocb *originalClientBridgeImpl) AllocateIDs(ctx context.Context, keys []w.Key) ([]w.Key, error) {
    94  	origKeys := toOriginalKeys(keys)
    95  
    96  	origKeys, err := ocb.d.client.AllocateIDs(ctx, origKeys)
    97  	return toWrapperKeys(origKeys), toWrapperError(err)
    98  }
    99  
   100  func (ocb *originalClientBridgeImpl) PutMulti(ctx context.Context, keys []w.Key, psList []w.PropertyList) ([]w.Key, error) {
   101  	origKeys := toOriginalKeys(keys)
   102  	origPss := toOriginalPropertyListList(psList)
   103  
   104  	origKeys, err := ocb.d.client.PutMulti(ctx, origKeys, origPss)
   105  	return toWrapperKeys(origKeys), toWrapperError(err)
   106  }
   107  
   108  func (ocb *originalClientBridgeImpl) GetMulti(ctx context.Context, keys []w.Key, psList []w.PropertyList) error {
   109  	origKeys := toOriginalKeys(keys)
   110  	origPss := toOriginalPropertyListList(psList)
   111  
   112  	err := ocb.d.client.GetMulti(ctx, origKeys, origPss)
   113  	wPss := toWrapperPropertyListList(origPss)
   114  	copy(psList, wPss)
   115  	return toWrapperError(err)
   116  }
   117  
   118  func (ocb *originalClientBridgeImpl) DeleteMulti(ctx context.Context, keys []w.Key) error {
   119  	origKeys := toOriginalKeys(keys)
   120  
   121  	err := ocb.d.client.DeleteMulti(ctx, origKeys)
   122  	return toWrapperError(err)
   123  }
   124  
   125  func (ocb *originalClientBridgeImpl) Run(ctx context.Context, q w.Query, qDump *w.QueryDump) w.Iterator {
   126  	qImpl := q.(*queryImpl)
   127  	iter := ocb.d.client.Run(ctx, qImpl.q)
   128  
   129  	return &iteratorImpl{
   130  		client: ocb.d,
   131  		q:      qImpl,
   132  		qDump:  qDump,
   133  		t:      iter,
   134  		cacheInfo: &w.MiddlewareInfo{
   135  			Context:     ctx,
   136  			Client:      ocb.d,
   137  			Transaction: qDump.Transaction,
   138  		},
   139  		firstError: qImpl.firstError,
   140  	}
   141  }
   142  
   143  func (ocb *originalClientBridgeImpl) GetAll(ctx context.Context, q w.Query, qDump *w.QueryDump, psList *[]w.PropertyList) ([]w.Key, error) {
   144  	qImpl := q.(*queryImpl)
   145  
   146  	var origPss []datastore.PropertyList
   147  	if !qDump.KeysOnly {
   148  		origPss = toOriginalPropertyListList(*psList)
   149  	}
   150  	origKeys, err := ocb.d.client.GetAll(ctx, qImpl.q, &origPss)
   151  	if err != nil {
   152  		return nil, toWrapperError(err)
   153  	}
   154  
   155  	wKeys := toWrapperKeys(origKeys)
   156  
   157  	if !qDump.KeysOnly {
   158  		*psList = toWrapperPropertyListList(origPss)
   159  	}
   160  
   161  	return wKeys, nil
   162  }
   163  
   164  func (ocb *originalClientBridgeImpl) Count(ctx context.Context, q w.Query, qDump *w.QueryDump) (int, error) {
   165  	qImpl, ok := q.(*queryImpl)
   166  	if !ok {
   167  		return 0, errors.New("invalid query type")
   168  	}
   169  	if qImpl.firstError != nil {
   170  		return 0, qImpl.firstError
   171  	}
   172  
   173  	count, err := ocb.d.client.Count(ctx, qImpl.q)
   174  	if err != nil {
   175  		return 0, toWrapperError(err)
   176  	}
   177  
   178  	return count, nil
   179  }
   180  
   181  type originalTransactionBridgeImpl struct {
   182  	tx *transactionImpl
   183  }
   184  
   185  func (otb *originalTransactionBridgeImpl) PutMulti(keys []w.Key, psList []w.PropertyList) ([]w.PendingKey, error) {
   186  	baseTx := getTx(otb.tx.client.ctx)
   187  	if baseTx == nil {
   188  		return nil, errors.New("unexpected context")
   189  	}
   190  
   191  	origKeys := toOriginalKeys(keys)
   192  	origPss := toOriginalPropertyListList(psList)
   193  
   194  	origPKeys, err := baseTx.PutMulti(origKeys, origPss)
   195  	if err != nil {
   196  		return nil, toWrapperError(err)
   197  	}
   198  
   199  	wPKeys := toWrapperPendingKeys(origPKeys)
   200  
   201  	return wPKeys, nil
   202  }
   203  
   204  func (otb *originalTransactionBridgeImpl) GetMulti(keys []w.Key, psList []w.PropertyList) error {
   205  	baseTx := getTx(otb.tx.client.ctx)
   206  	if baseTx == nil {
   207  		return errors.New("unexpected context")
   208  	}
   209  
   210  	origKeys := toOriginalKeys(keys)
   211  	origPss := toOriginalPropertyListList(psList)
   212  
   213  	err := baseTx.GetMulti(origKeys, origPss)
   214  	wPss := toWrapperPropertyListList(origPss)
   215  	copy(psList, wPss)
   216  	if err != nil {
   217  		return toWrapperError(err)
   218  	}
   219  
   220  	return nil
   221  }
   222  
   223  func (otb *originalTransactionBridgeImpl) DeleteMulti(keys []w.Key) error {
   224  	baseTx := getTx(otb.tx.client.ctx)
   225  	if baseTx == nil {
   226  		return errors.New("unexpected context")
   227  	}
   228  
   229  	origKeys := toOriginalKeys(keys)
   230  
   231  	err := baseTx.DeleteMulti(origKeys)
   232  	return toWrapperError(err)
   233  }
   234  
   235  type originalIteratorBridgeImpl struct {
   236  	qDump *w.QueryDump
   237  }
   238  
   239  func (oib *originalIteratorBridgeImpl) Next(iter w.Iterator, ps *w.PropertyList) (w.Key, error) {
   240  	iterImpl := iter.(*iteratorImpl)
   241  
   242  	var origPsPtr *datastore.PropertyList
   243  	if !oib.qDump.KeysOnly {
   244  		origPs := toOriginalPropertyList(*ps)
   245  		origPsPtr = &origPs
   246  	}
   247  
   248  	origKey, err := iterImpl.t.Next(origPsPtr)
   249  	if err != nil {
   250  		return nil, toWrapperError(err)
   251  	}
   252  
   253  	if !oib.qDump.KeysOnly {
   254  		*ps = toWrapperPropertyList(*origPsPtr)
   255  	}
   256  
   257  	return toWrapperKey(origKey), nil
   258  }