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

     1  package clouddatastore
     2  
     3  import (
     4  	"context"
     5  
     6  	"cloud.google.com/go/datastore"
     7  	w "go.mercari.io/datastore"
     8  	"go.mercari.io/datastore/internal/shared"
     9  )
    10  
    11  var _ w.Transaction = (*transactionImpl)(nil)
    12  var _ w.Commit = (*commitImpl)(nil)
    13  
    14  type contextTransaction struct{}
    15  
    16  func getTx(ctx context.Context) *datastore.Transaction {
    17  	tx := ctx.Value(contextTransaction{})
    18  	if tx != nil {
    19  		return tx.(*datastore.Transaction)
    20  	}
    21  
    22  	return nil
    23  }
    24  
    25  type transactionImpl struct {
    26  	client    *datastoreImpl
    27  	cacheInfo *w.MiddlewareInfo
    28  }
    29  
    30  type commitImpl struct {
    31  	commit *datastore.Commit
    32  }
    33  
    34  func (tx *transactionImpl) Get(key w.Key, dst interface{}) error {
    35  	err := tx.GetMulti([]w.Key{key}, []interface{}{dst})
    36  	if merr, ok := err.(w.MultiError); ok {
    37  		return merr[0]
    38  	} else if err != nil {
    39  		return err
    40  	}
    41  
    42  	return nil
    43  }
    44  
    45  func (tx *transactionImpl) GetMulti(keys []w.Key, dst interface{}) error {
    46  	cb := shared.NewCacheBridge(tx.cacheInfo, &originalClientBridgeImpl{tx.client}, &originalTransactionBridgeImpl{tx: tx}, nil, tx.client.middlewares)
    47  
    48  	err := shared.GetMultiOps(tx.client.ctx, keys, dst, func(keys []w.Key, dst []w.PropertyList) error {
    49  		return cb.GetMultiWithTx(tx.cacheInfo, keys, dst)
    50  	})
    51  
    52  	return err
    53  }
    54  
    55  func (tx *transactionImpl) Put(key w.Key, src interface{}) (w.PendingKey, error) {
    56  	pKeys, err := tx.PutMulti([]w.Key{key}, []interface{}{src})
    57  	if merr, ok := err.(w.MultiError); ok {
    58  		return nil, merr[0]
    59  	} else if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	return pKeys[0], nil
    64  }
    65  
    66  func (tx *transactionImpl) PutMulti(keys []w.Key, src interface{}) ([]w.PendingKey, error) {
    67  	cb := shared.NewCacheBridge(tx.cacheInfo, &originalClientBridgeImpl{tx.client}, &originalTransactionBridgeImpl{tx: tx}, nil, tx.client.middlewares)
    68  
    69  	_, pKeys, err := shared.PutMultiOps(tx.client.ctx, keys, src, func(keys []w.Key, src []w.PropertyList) ([]w.Key, []w.PendingKey, error) {
    70  		pKeys, err := cb.PutMultiWithTx(tx.cacheInfo, keys, src)
    71  		return nil, pKeys, err
    72  	})
    73  
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	return pKeys, nil
    79  }
    80  
    81  func (tx *transactionImpl) Delete(key w.Key) error {
    82  	err := tx.DeleteMulti([]w.Key{key})
    83  	if merr, ok := err.(w.MultiError); ok {
    84  		return merr[0]
    85  	} else if err != nil {
    86  		return err
    87  	}
    88  
    89  	return nil
    90  }
    91  
    92  func (tx *transactionImpl) DeleteMulti(keys []w.Key) error {
    93  	cb := shared.NewCacheBridge(tx.cacheInfo, &originalClientBridgeImpl{tx.client}, &originalTransactionBridgeImpl{tx: tx}, nil, tx.client.middlewares)
    94  
    95  	err := shared.DeleteMultiOps(tx.client.ctx, keys, func(keys []w.Key) error {
    96  		return cb.DeleteMultiWithTx(tx.cacheInfo, keys)
    97  	})
    98  
    99  	return err
   100  }
   101  
   102  func (tx *transactionImpl) Commit() (w.Commit, error) {
   103  	baseTx := getTx(tx.client.ctx)
   104  	if baseTx == nil {
   105  		return nil, nil
   106  	}
   107  
   108  	commit, err := baseTx.Commit()
   109  	if err != nil {
   110  		return nil, toWrapperError(err)
   111  	}
   112  
   113  	cb := shared.NewCacheBridge(tx.cacheInfo, &originalClientBridgeImpl{tx.client}, &originalTransactionBridgeImpl{tx: tx}, nil, tx.client.middlewares)
   114  	commitImpl := &commitImpl{commit}
   115  	err = cb.PostCommit(tx.cacheInfo, tx, commitImpl)
   116  
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	return commitImpl, nil
   122  }
   123  
   124  func (tx *transactionImpl) Rollback() error {
   125  	baseTx := getTx(tx.client.ctx)
   126  	if tx == nil {
   127  		return nil
   128  	}
   129  
   130  	err := baseTx.Rollback()
   131  	if err != nil {
   132  		return toWrapperError(err)
   133  	}
   134  
   135  	cb := shared.NewCacheBridge(tx.cacheInfo, &originalClientBridgeImpl{tx.client}, &originalTransactionBridgeImpl{tx: tx}, nil, tx.client.middlewares)
   136  	return cb.PostRollback(tx.cacheInfo, tx)
   137  }
   138  
   139  func (tx *transactionImpl) Batch() *w.TransactionBatch {
   140  	return &w.TransactionBatch{Transaction: tx}
   141  }
   142  
   143  func (c *commitImpl) Key(p w.PendingKey) w.Key {
   144  	pk := toOriginalPendingKey(p)
   145  	key := c.commit.Key(pk)
   146  	return toWrapperKey(key)
   147  }