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

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