gitlab.com/picnic-app/backend/role-api@v0.0.0-20230614140944-06a76ff3696d/internal/repo/spanner/tx.go (about)

     1  package spanner
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"cloud.google.com/go/spanner"
     8  
     9  	"gitlab.com/picnic-app/backend/role-api/internal/repo"
    10  )
    11  
    12  type (
    13  	readOnly  struct{ tx *spanner.ReadOnlyTransaction }
    14  	writeOnly struct{ cli *spanner.Client }
    15  	readWrite struct{ tx *spanner.ReadWriteTransaction }
    16  )
    17  
    18  var (
    19  	_ repo.ReadActions      = readOnly{}
    20  	_ repo.WriteActions     = writeOnly{}
    21  	_ repo.ReadWriteActions = readWrite{}
    22  )
    23  
    24  func (r Repo) SingleRead() repo.ReadActions { return readOnly{tx: r.cli.Single()} }
    25  
    26  func (r Repo) SingleWrite() repo.WriteActions { return writeOnly(r) }
    27  
    28  func (r Repo) ReadOnlyTx(ctx context.Context, f func(context.Context, repo.ReadActions) error) error {
    29  	tx := r.cli.ReadOnlyTransaction()
    30  	defer tx.Close()
    31  
    32  	err := f(ctx, readOnly{tx: tx})
    33  	if err != nil {
    34  		return fromError(err)
    35  	}
    36  
    37  	return nil
    38  }
    39  
    40  func (r Repo) ReadWriteTx(
    41  	ctx context.Context,
    42  	f func(context.Context, repo.ReadWriteActions) error,
    43  ) (time.Time, error) {
    44  	ts, err := r.cli.ReadWriteTransaction(ctx, func(ctx context.Context, tx *spanner.ReadWriteTransaction) error {
    45  		return f(ctx, readWrite{tx: tx})
    46  	})
    47  	if err != nil {
    48  		return ts, fromError(err)
    49  	}
    50  
    51  	return ts, nil
    52  }
    53  
    54  func (w writeOnly) tx(ctx context.Context, f func(ctx context.Context, tx repo.WriteActions) error) error {
    55  	_, err := w.cli.ReadWriteTransaction(ctx, func(ctx context.Context, tx *spanner.ReadWriteTransaction) error {
    56  		return f(ctx, readWrite{tx: tx})
    57  	})
    58  	return fromError(err)
    59  }
    60  
    61  func (w writeOnly) bufferWriter(ctx context.Context, opts ...spanner.ApplyOption) bufferWriter {
    62  	return bufferWriter{ctx: ctx, cli: w.cli, opts: opts}
    63  }
    64  
    65  type bufferWriter struct {
    66  	ctx  context.Context
    67  	cli  *spanner.Client
    68  	opts []spanner.ApplyOption
    69  }
    70  
    71  func (u bufferWriter) BufferWrite(m []*spanner.Mutation) error {
    72  	_, err := u.cli.Apply(u.ctx, m, u.opts...)
    73  	return fromError(err)
    74  }