storage/inmemory: implement patch operation (#4654)

Add a new Patch() method that updates specific fields of an existing
record's data, based on a field mask.

Extract some logic from the existing Get() and Put() methods so it can
be shared with the new Patch() method.
This commit is contained in:
Kenneth Jenkins 2023-11-02 11:03:00 -07:00 committed by GitHub
parent 5f4e13e130
commit 47890e9ee1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 270 additions and 16 deletions

36
pkg/storage/patch.go Normal file
View file

@ -0,0 +1,36 @@
package storage
import (
"fmt"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/fieldmaskpb"
"github.com/pomerium/pomerium/pkg/grpc/databroker"
"github.com/pomerium/pomerium/pkg/protoutil"
)
// PatchRecord extracts the data from existing and record, updates the existing
// data subject to the provided field mask, and stores the result back into
// record. The existing record is not modified.
func PatchRecord(existing, record *databroker.Record, fields *fieldmaskpb.FieldMask) error {
dst, err := existing.GetData().UnmarshalNew()
if err != nil {
return fmt.Errorf("could not unmarshal existing record data: %w", err)
}
src, err := record.GetData().UnmarshalNew()
if err != nil {
return fmt.Errorf("could not unmarshal new record data: %w", err)
}
if err := protoutil.OverwriteMasked(dst, src, fields); err != nil {
return fmt.Errorf("cannot patch record: %w", err)
}
record.Data, err = anypb.New(dst)
if err != nil {
return fmt.Errorf("could not marshal new record data: %w", err)
}
return nil
}