// UpdateEntryWithEtag updates an entry in persistent storage in a way that // detects concurrent modification. It also prevents users from modifying // entries they do not own by returning ErrNoSuchId. t, the transaction, // must be non nil. func UpdateEntryWithEtag( store SafeUpdateEntryRunner, t db.Transaction, id int64, tag uint64, key *vsafe.Key, update functional.Filterer) error { if t == nil { panic("Transaction must be non-nil") } var origEntry vsafe.EntryWithEtag err := EntryByIdWithEtag(store, t, id, key, &origEntry) if err != nil { return err } err = update.Filter(&origEntry.Entry) if err == functional.Skipped { return nil } if err != nil { return err } if tag != origEntry.Etag { return ErrConcurrentModification } origEntry.Id = id return UpdateEntry(store, t, key, &origEntry.Entry) }
func (f FakeStore) EntryByIdWithEtag( t db.Transaction, id int64, e *vsafe.EntryWithEtag) error { // Only computes etag on the string fields if int(id) > len(f) { return vsafedb.ErrNoSuchId } e.Entry = *f[id-1] e.Etag = 57 return nil }