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

     1  package clouddatastore
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"cloud.google.com/go/datastore"
     8  	w "go.mercari.io/datastore"
     9  	"go.mercari.io/datastore/internal/shared"
    10  )
    11  
    12  var _ w.Client = (*datastoreImpl)(nil)
    13  
    14  type datastoreImpl struct {
    15  	ctx         context.Context
    16  	client      *datastore.Client
    17  	middlewares []w.Middleware
    18  }
    19  
    20  func (d *datastoreImpl) Get(ctx context.Context, key w.Key, dst interface{}) error {
    21  	err := d.GetMulti(ctx, []w.Key{key}, []interface{}{dst})
    22  	if merr, ok := err.(w.MultiError); ok {
    23  		return merr[0]
    24  	} else if err != nil {
    25  		return err
    26  	}
    27  
    28  	return nil
    29  }
    30  
    31  func (d *datastoreImpl) GetMulti(ctx context.Context, keys []w.Key, dst interface{}) error {
    32  	cacheInfo := &w.MiddlewareInfo{
    33  		Context: ctx,
    34  		Client:  d,
    35  	}
    36  	cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares)
    37  
    38  	return shared.GetMultiOps(ctx, keys, dst, func(keys []w.Key, dst []w.PropertyList) error {
    39  		return cb.GetMultiWithoutTx(cacheInfo, keys, dst)
    40  	})
    41  }
    42  
    43  func (d *datastoreImpl) Put(ctx context.Context, key w.Key, src interface{}) (w.Key, error) {
    44  	keys, err := d.PutMulti(ctx, []w.Key{key}, []interface{}{src})
    45  	if merr, ok := err.(w.MultiError); ok {
    46  		return nil, merr[0]
    47  	} else if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	return keys[0], nil
    52  }
    53  
    54  func (d *datastoreImpl) PutMulti(ctx context.Context, keys []w.Key, src interface{}) ([]w.Key, error) {
    55  	cacheInfo := &w.MiddlewareInfo{
    56  		Context: ctx,
    57  		Client:  d,
    58  	}
    59  	cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares)
    60  
    61  	keys, _, err := shared.PutMultiOps(ctx, keys, src, func(keys []w.Key, src []w.PropertyList) ([]w.Key, []w.PendingKey, error) {
    62  		keys, err := cb.PutMultiWithoutTx(cacheInfo, keys, src)
    63  		return keys, nil, err
    64  	})
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	return keys, nil
    70  }
    71  
    72  func (d *datastoreImpl) Delete(ctx context.Context, key w.Key) error {
    73  	err := d.DeleteMulti(ctx, []w.Key{key})
    74  	if merr, ok := err.(w.MultiError); ok {
    75  		return merr[0]
    76  	} else if err != nil {
    77  		return err
    78  	}
    79  
    80  	return nil
    81  }
    82  
    83  func (d *datastoreImpl) DeleteMulti(ctx context.Context, keys []w.Key) error {
    84  	cacheInfo := &w.MiddlewareInfo{
    85  		Context: ctx,
    86  		Client:  d,
    87  	}
    88  	cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares)
    89  
    90  	return shared.DeleteMultiOps(ctx, keys, func(keys []w.Key) error {
    91  		return cb.DeleteMultiWithoutTx(cacheInfo, keys)
    92  	})
    93  }
    94  
    95  func (d *datastoreImpl) NewTransaction(ctx context.Context) (w.Transaction, error) {
    96  	tx, err := d.client.NewTransaction(ctx)
    97  	if err != nil {
    98  		return nil, toWrapperError(err)
    99  	}
   100  
   101  	txCtx := context.WithValue(ctx, contextTransaction{}, tx)
   102  	txImpl := &transactionImpl{
   103  		client: &datastoreImpl{
   104  			ctx:         txCtx,
   105  			client:      d.client,
   106  			middlewares: d.middlewares,
   107  		},
   108  	}
   109  	txImpl.cacheInfo = &w.MiddlewareInfo{
   110  		Context:     txCtx,
   111  		Client:      d,
   112  		Transaction: txImpl,
   113  	}
   114  
   115  	return txImpl, nil
   116  }
   117  
   118  func (d *datastoreImpl) RunInTransaction(ctx context.Context, f func(tx w.Transaction) error) (w.Commit, error) {
   119  	var txImpl *transactionImpl
   120  	commit, err := d.client.RunInTransaction(ctx, func(baseTx *datastore.Transaction) error {
   121  		txCtx := context.WithValue(ctx, contextTransaction{}, baseTx)
   122  		txImpl = &transactionImpl{
   123  			client: &datastoreImpl{
   124  				ctx:         txCtx,
   125  				client:      d.client,
   126  				middlewares: d.middlewares,
   127  			},
   128  		}
   129  		txImpl.cacheInfo = &w.MiddlewareInfo{
   130  			Context:     txCtx,
   131  			Client:      d,
   132  			Transaction: txImpl,
   133  		}
   134  		return f(txImpl)
   135  	}, datastore.MaxAttempts(1))
   136  	if err != nil {
   137  		return nil, toWrapperError(err)
   138  	}
   139  
   140  	cb := shared.NewCacheBridge(txImpl.cacheInfo, &originalClientBridgeImpl{txImpl.client}, &originalTransactionBridgeImpl{tx: txImpl}, nil, txImpl.client.middlewares)
   141  	commitImpl := &commitImpl{commit}
   142  	err = cb.PostCommit(txImpl.cacheInfo, txImpl, commitImpl)
   143  
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	return commitImpl, nil
   149  }
   150  
   151  func (d *datastoreImpl) Run(ctx context.Context, q w.Query) w.Iterator {
   152  	cacheInfo := &w.MiddlewareInfo{
   153  		Context: ctx,
   154  		Client:  d,
   155  	}
   156  	cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares)
   157  
   158  	return cb.Run(cb.Info, q, q.Dump())
   159  }
   160  
   161  func (d *datastoreImpl) AllocateIDs(ctx context.Context, keys []w.Key) ([]w.Key, error) {
   162  	cacheInfo := &w.MiddlewareInfo{
   163  		Context: ctx,
   164  		Client:  d,
   165  	}
   166  	cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares)
   167  
   168  	return cb.AllocateIDs(cb.Info, keys)
   169  }
   170  
   171  func (d *datastoreImpl) Count(ctx context.Context, q w.Query) (int, error) {
   172  	cacheInfo := &w.MiddlewareInfo{
   173  		Context: ctx,
   174  		Client:  d,
   175  	}
   176  	cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares)
   177  
   178  	return cb.Count(cb.Info, q, q.Dump())
   179  }
   180  
   181  func (d *datastoreImpl) GetAll(ctx context.Context, q w.Query, dst interface{}) ([]w.Key, error) {
   182  	qImpl, ok := q.(*queryImpl)
   183  	if !ok {
   184  		return nil, errors.New("invalid query type")
   185  	}
   186  
   187  	if qImpl.firstError != nil {
   188  		return nil, qImpl.firstError
   189  	}
   190  
   191  	qDump := q.Dump()
   192  	cacheInfo := &w.MiddlewareInfo{
   193  		Context:     ctx,
   194  		Client:      d,
   195  		Transaction: qDump.Transaction,
   196  	}
   197  	cb := shared.NewCacheBridge(cacheInfo, &originalClientBridgeImpl{d}, nil, nil, d.middlewares)
   198  	return shared.GetAllOps(ctx, qDump, dst, func(dst *[]w.PropertyList) ([]w.Key, error) {
   199  		return cb.GetAll(cacheInfo, q, qDump, dst)
   200  	})
   201  }
   202  
   203  func (d *datastoreImpl) IncompleteKey(kind string, parent w.Key) w.Key {
   204  	key := &keyImpl{
   205  		kind: kind,
   206  		id:   0,
   207  		name: "",
   208  	}
   209  	if parent != nil {
   210  		parentImpl := parent.(*keyImpl)
   211  		key.parent = parentImpl
   212  	}
   213  
   214  	return key
   215  }
   216  
   217  func (d *datastoreImpl) NameKey(kind, name string, parent w.Key) w.Key {
   218  	key := &keyImpl{
   219  		kind: kind,
   220  		id:   0,
   221  		name: name,
   222  	}
   223  	if parent != nil {
   224  		parentImpl := parent.(*keyImpl)
   225  		key.parent = parentImpl
   226  	}
   227  
   228  	return key
   229  }
   230  
   231  func (d *datastoreImpl) IDKey(kind string, id int64, parent w.Key) w.Key {
   232  	key := &keyImpl{
   233  		kind: kind,
   234  		id:   id,
   235  		name: "",
   236  	}
   237  	if parent != nil {
   238  		parentImpl := parent.(*keyImpl)
   239  		key.parent = parentImpl
   240  	}
   241  
   242  	return key
   243  }
   244  
   245  func (d *datastoreImpl) NewQuery(kind string) w.Query {
   246  	q := datastore.NewQuery(kind)
   247  	return &queryImpl{ctx: d.ctx, q: q, dump: &w.QueryDump{Kind: kind}}
   248  }
   249  
   250  func (d *datastoreImpl) Close() error {
   251  	return d.client.Close()
   252  }
   253  
   254  func (d *datastoreImpl) DecodeKey(encoded string) (w.Key, error) {
   255  	key, err := datastore.DecodeKey(encoded)
   256  	if err != nil {
   257  		return nil, toWrapperError(err)
   258  	}
   259  
   260  	return toWrapperKey(key), nil
   261  }
   262  
   263  func (d *datastoreImpl) DecodeCursor(s string) (w.Cursor, error) {
   264  	cur, err := datastore.DecodeCursor(s)
   265  	if err != nil {
   266  		return nil, toWrapperError(err)
   267  	}
   268  
   269  	return &cursorImpl{cursor: cur}, nil
   270  }
   271  
   272  func (d *datastoreImpl) Batch() *w.Batch {
   273  	return &w.Batch{Client: d}
   274  }
   275  
   276  func (d *datastoreImpl) AppendMiddleware(mw w.Middleware) {
   277  	d.middlewares = append(d.middlewares, mw)
   278  }
   279  
   280  func (d *datastoreImpl) RemoveMiddleware(mw w.Middleware) bool {
   281  	list := make([]w.Middleware, 0, len(d.middlewares))
   282  	found := false
   283  	for _, old := range d.middlewares {
   284  		if old == mw {
   285  			found = true
   286  			continue
   287  		}
   288  		list = append(list, old)
   289  	}
   290  	d.middlewares = list
   291  
   292  	return found
   293  }
   294  
   295  func (d *datastoreImpl) Context() context.Context {
   296  	return d.ctx
   297  }
   298  
   299  func (d *datastoreImpl) SetContext(ctx context.Context) {
   300  	if ctx == nil {
   301  		panic("ctx can't be nil")
   302  	}
   303  	d.ctx = ctx
   304  }