Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IvanProdaiko94/561be1a310b9cc7e83e5a5272ca5479f to your computer and use it in GitHub Desktop.
Save IvanProdaiko94/561be1a310b9cc7e83e5a5272ca5479f to your computer and use it in GitHub Desktop.
Convenient way to avoid `read-after-write` errors in datastore transactions. Having delta one can store every change inside it and in the end of transaction call `td.Apply()`.
package firestore
import (
"cloud.google.com/go/firestore"
)
type TransactionDelta struct {
tx *firestore.Transaction
delta []func() error
}
func (writes *TransactionDelta) Create(doc *firestore.DocumentRef, d interface{}) {
writes.delta = append(writes.delta, func() error {
return writes.tx.Create(doc, d)
})
}
func (writes *TransactionDelta) Set(doc *firestore.DocumentRef, d interface{}, opts... firestore.SetOption) {
writes.delta = append(writes.delta, func() error {
return writes.tx.Set(doc, d, opts...)
})
}
func (writes *TransactionDelta) Update(doc *firestore.DocumentRef, u []firestore.Update, precondition... firestore.Precondition) {
writes.delta = append(writes.delta, func() error {
return writes.tx.Update(doc, u, precondition...)
})
}
func (writes *TransactionDelta) Delete(doc *firestore.DocumentRef, precondition... firestore.Precondition) {
writes.delta = append(writes.delta, func() error {
return writes.tx.Delete(doc, precondition...)
})
}
func (writes *TransactionDelta) Apply() error {
for _, fn := range writes.delta {
err := fn()
if err != nil {
return err
}
}
return nil
}
func NewTransactionDelta(tx *firestore.Transaction) *TransactionDelta {
return &TransactionDelta{
tx: tx,
delta: []func() error{},
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment