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

     1  package aedatastore
     2  
     3  import (
     4  	"context"
     5  	"encoding/gob"
     6  	"errors"
     7  
     8  	w "go.mercari.io/datastore"
     9  	"go.mercari.io/datastore/internal/shared"
    10  	"google.golang.org/appengine"
    11  	"google.golang.org/appengine/datastore"
    12  )
    13  
    14  func init() {
    15  	//lint:ignore SA1019 for backward compatible
    16  	w.FromContext = FromContext
    17  
    18  	gob.Register(&keyImpl{})
    19  }
    20  
    21  // FromContext make new Client by specified context.
    22  func FromContext(ctx context.Context, opts ...w.ClientOption) (w.Client, error) {
    23  	if ctx == nil {
    24  		panic("unexpected")
    25  	}
    26  	return &datastoreImpl{ctx: ctx}, nil
    27  }
    28  
    29  // IsAEDatastoreClient returns check result that client is this package's client or not.
    30  func IsAEDatastoreClient(client w.Client) bool {
    31  	_, ok := client.(*datastoreImpl)
    32  	return ok
    33  }
    34  
    35  var _ shared.OriginalClientBridge = &originalClientBridgeImpl{}
    36  var _ shared.OriginalTransactionBridge = &originalTransactionBridgeImpl{}
    37  var _ shared.OriginalIteratorBridge = &originalIteratorBridgeImpl{}
    38  
    39  type originalClientBridgeImpl struct {
    40  	d *datastoreImpl
    41  }
    42  
    43  func (ocb *originalClientBridgeImpl) AllocateIDs(ctx context.Context, keys []w.Key) ([]w.Key, error) {
    44  	// TODO 可能な限りバッチ化する
    45  	var resultKeys []w.Key
    46  	for _, key := range keys {
    47  		pK := toOriginalKey(key.ParentKey())
    48  		low, _, err := datastore.AllocateIDs(ctx, key.Kind(), pK, 1)
    49  		if err != nil {
    50  			return nil, toWrapperError(err)
    51  		}
    52  		origKey := datastore.NewKey(ctx, key.Kind(), "", low, pK)
    53  		resultKeys = append(resultKeys, toWrapperKey(ctx, origKey))
    54  	}
    55  
    56  	return resultKeys, nil
    57  }
    58  
    59  func (ocb *originalClientBridgeImpl) PutMulti(ctx context.Context, keys []w.Key, psList []w.PropertyList) ([]w.Key, error) {
    60  	origKeys := toOriginalKeys(keys)
    61  	origPss, err := toOriginalPropertyListList(psList)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	origKeys, err = datastore.PutMulti(ctx, origKeys, origPss)
    67  	return toWrapperKeys(ctx, origKeys), toWrapperError(err)
    68  }
    69  
    70  func (ocb *originalClientBridgeImpl) GetMulti(ctx context.Context, keys []w.Key, psList []w.PropertyList) error {
    71  	origKeys := toOriginalKeys(keys)
    72  	origPss, err := toOriginalPropertyListList(psList)
    73  	if err != nil {
    74  		return err
    75  	}
    76  
    77  	err = datastore.GetMulti(ctx, origKeys, origPss)
    78  	wPss := toWrapperPropertyListList(ctx, origPss)
    79  	copy(psList, wPss)
    80  	return toWrapperError(err)
    81  }
    82  
    83  func (ocb *originalClientBridgeImpl) DeleteMulti(ctx context.Context, keys []w.Key) error {
    84  	origKeys := toOriginalKeys(keys)
    85  
    86  	err := datastore.DeleteMulti(ctx, origKeys)
    87  	return toWrapperError(err)
    88  }
    89  
    90  func (ocb *originalClientBridgeImpl) Run(ctx context.Context, q w.Query, qDump *w.QueryDump) w.Iterator {
    91  	qImpl := q.(*queryImpl)
    92  
    93  	baseCtx := ctx
    94  
    95  	if qImpl.dump.Transaction != nil {
    96  		// replace ctx to tx ctx
    97  		ctx = TransactionContext(qImpl.dump.Transaction)
    98  	}
    99  
   100  	ctx, err := appengine.Namespace(ctx, qImpl.dump.Namespace)
   101  	if err != nil && qImpl.firstError == nil {
   102  		qImpl.firstError = err
   103  	}
   104  
   105  	iter := qImpl.q.Run(ctx)
   106  	return &iteratorImpl{
   107  		client: ocb.d,
   108  		q:      qImpl,
   109  		qDump:  qDump,
   110  		t:      iter,
   111  		cacheInfo: &w.MiddlewareInfo{
   112  			Context:     baseCtx,
   113  			Client:      ocb.d,
   114  			Transaction: qDump.Transaction,
   115  		},
   116  		firstError: qImpl.firstError,
   117  	}
   118  }
   119  
   120  func (ocb *originalClientBridgeImpl) GetAll(ctx context.Context, q w.Query, qDump *w.QueryDump, psList *[]w.PropertyList) ([]w.Key, error) {
   121  	qImpl, ok := q.(*queryImpl)
   122  	if !ok {
   123  		return nil, errors.New("invalid query type")
   124  	}
   125  
   126  	if qImpl.firstError != nil {
   127  		return nil, qImpl.firstError
   128  	}
   129  
   130  	if qDump.Transaction != nil {
   131  		// replace ctx to tx ctx
   132  		ctx = TransactionContext(qImpl.dump.Transaction)
   133  	}
   134  
   135  	var err error
   136  	ctx, err = appengine.Namespace(ctx, qDump.Namespace)
   137  	if err != nil {
   138  		return nil, toWrapperError(err)
   139  	}
   140  
   141  	var origPss []datastore.PropertyList
   142  	if !qDump.KeysOnly {
   143  		origPss, err = toOriginalPropertyListList(*psList)
   144  		if err != nil {
   145  			return nil, err
   146  		}
   147  	}
   148  	origKeys, err := qImpl.q.GetAll(ctx, &origPss)
   149  	if err != nil {
   150  		return nil, toWrapperError(err)
   151  	}
   152  
   153  	wKeys := toWrapperKeys(ctx, origKeys)
   154  
   155  	if !qDump.KeysOnly {
   156  		*psList = toWrapperPropertyListList(ctx, origPss)
   157  	}
   158  
   159  	return wKeys, nil
   160  }
   161  
   162  func (ocb *originalClientBridgeImpl) Count(ctx context.Context, q w.Query, qDump *w.QueryDump) (int, error) {
   163  	qImpl, ok := q.(*queryImpl)
   164  	if !ok {
   165  		return 0, errors.New("invalid query type")
   166  	}
   167  	if qImpl.firstError != nil {
   168  		return 0, qImpl.firstError
   169  	}
   170  
   171  	if qImpl.dump.Transaction != nil {
   172  		// replace ctx to tx ctx
   173  		txImpl, ok := qImpl.dump.Transaction.(*transactionImpl)
   174  		if !ok {
   175  			return 0, errors.New("unexpected context")
   176  		}
   177  		ctx = txImpl.client.ctx
   178  	}
   179  
   180  	var err error
   181  	ctx, err = appengine.Namespace(ctx, qImpl.dump.Namespace)
   182  	if err != nil {
   183  		return 0, toWrapperError(err)
   184  	}
   185  	count, err := qImpl.q.Count(ctx)
   186  	if err != nil {
   187  		return 0, toWrapperError(err)
   188  	}
   189  
   190  	return count, nil
   191  }
   192  
   193  type originalTransactionBridgeImpl struct {
   194  	tx *transactionImpl
   195  }
   196  
   197  func (otb *originalTransactionBridgeImpl) PutMulti(keys []w.Key, psList []w.PropertyList) ([]w.PendingKey, error) {
   198  	ext := getTxExtractor(otb.tx.client.ctx)
   199  	if ext == nil {
   200  		return nil, errors.New("unexpected context")
   201  	}
   202  
   203  	origKeys := toOriginalKeys(keys)
   204  	origPss, err := toOriginalPropertyListList(psList)
   205  	if err != nil {
   206  		return nil, err
   207  	}
   208  
   209  	origKeys, err = datastore.PutMulti(ext.txCtx, origKeys, origPss)
   210  	if err != nil {
   211  		return nil, toWrapperError(err)
   212  	}
   213  
   214  	wPKeys := toWrapperPendingKeys(ext.txCtx, origKeys)
   215  
   216  	return wPKeys, nil
   217  }
   218  
   219  func (otb *originalTransactionBridgeImpl) GetMulti(keys []w.Key, psList []w.PropertyList) error {
   220  	ext := getTxExtractor(otb.tx.client.ctx)
   221  	if ext == nil {
   222  		return errors.New("unexpected context")
   223  	}
   224  
   225  	origKeys := toOriginalKeys(keys)
   226  	origPss, err := toOriginalPropertyListList(psList)
   227  	if err != nil {
   228  		return err
   229  	}
   230  
   231  	err = datastore.GetMulti(ext.txCtx, origKeys, origPss)
   232  	wPss := toWrapperPropertyListList(ext.txCtx, origPss)
   233  	copy(psList, wPss)
   234  	if err != nil {
   235  		return toWrapperError(err)
   236  	}
   237  
   238  	return nil
   239  }
   240  
   241  func (otb *originalTransactionBridgeImpl) DeleteMulti(keys []w.Key) error {
   242  	ext := getTxExtractor(otb.tx.client.ctx)
   243  	if ext == nil {
   244  		return errors.New("unexpected context")
   245  	}
   246  
   247  	origKeys := toOriginalKeys(keys)
   248  
   249  	err := datastore.DeleteMulti(ext.txCtx, origKeys)
   250  	return toWrapperError(err)
   251  }
   252  
   253  type originalIteratorBridgeImpl struct {
   254  	qDump *w.QueryDump
   255  }
   256  
   257  func (oib *originalIteratorBridgeImpl) Next(iter w.Iterator, ps *w.PropertyList) (w.Key, error) {
   258  	iterImpl := iter.(*iteratorImpl)
   259  
   260  	var origPsPtr *datastore.PropertyList
   261  	if !oib.qDump.KeysOnly {
   262  		origPs, err := toOriginalPropertyList(*ps)
   263  		if err != nil {
   264  			return nil, err
   265  		}
   266  		origPsPtr = &origPs
   267  	}
   268  
   269  	origKey, err := iterImpl.t.Next(origPsPtr)
   270  	if err != nil {
   271  		return nil, toWrapperError(err)
   272  	}
   273  
   274  	if !oib.qDump.KeysOnly {
   275  		*ps = toWrapperPropertyList(iterImpl.client.ctx, *origPsPtr)
   276  	}
   277  
   278  	return toWrapperKey(iterImpl.client.ctx, origKey), nil
   279  }