diff --git a/couchbase/client.go b/couchbase/client.go index 5dde605..5c57a09 100644 --- a/couchbase/client.go +++ b/couchbase/client.go @@ -82,6 +82,49 @@ func (s *client) GetAgent() *gocbcore.Agent { return s.agent } +func (s *client) CreateMultiPath(ctx context.Context, + scopeName string, + collectionName string, + id []byte, + pathValues []PathValue, + flags memd.SubdocDocFlag, + cas *gocbcore.Cas, + expiry uint32, + preserveExpiry bool, + cb gocbcore.MutateInCallback, +) error { + deadline, _ := ctx.Deadline() + + ops := make([]gocbcore.SubDocOp, len(pathValues)) + + for i, pv := range pathValues { + ops[i] = gocbcore.SubDocOp{ + Op: memd.SubDocOpDictSet, + Path: string(pv.Path), + Value: pv.Value, + } + } + + options := gocbcore.MutateInOptions{ + Key: id, + Flags: flags, + Ops: ops, + Expiry: expiry, + PreserveExpiry: preserveExpiry, + Deadline: deadline, + ScopeName: scopeName, + CollectionName: collectionName, + } + + if cas != nil { + options.Cas = *cas + } + + _, err := s.agent.MutateIn(options, cb) + + return err +} + func (s *client) CreatePath(ctx context.Context, scopeName string, collectionName string, @@ -229,6 +272,17 @@ func (s *client) Execute(ctx context.Context, action *CBActionDocument, callback func(result *gocbcore.MutateInResult, err error) { callback(err) }) + case action.Type == MultiMutateIn: + flags := memd.SubdocDocFlagMkDoc + if action.DisableAutoCreate { + flags = memd.SubdocDocFlagNone + } + + err = s.CreateMultiPath(ctx, s.config.ScopeName, s.config.CollectionName, + action.ID, action.PathValues, flags, casPtr, action.Expiry, action.PreserveExpiry, + func(result *gocbcore.MutateInResult, err error) { + callback(err) + }) case action.Type == DeletePath: err = s.DeletePath(ctx, s.config.ScopeName, s.config.CollectionName, action.ID, action.Path, casPtr, action.Expiry, action.PreserveExpiry, diff --git a/couchbase/document.go b/couchbase/document.go index 26e6d2f..f4a32da 100644 --- a/couchbase/document.go +++ b/couchbase/document.go @@ -2,16 +2,23 @@ package couchbase type CbAction string +type PathValue struct { + Path []byte + Value []byte +} + const ( - Set CbAction = "Set" - Delete CbAction = "Delete" - MutateIn CbAction = "MutateIn" - DeletePath CbAction = "DeletePath" + Set CbAction = "Set" + Delete CbAction = "Delete" + MutateIn CbAction = "MutateIn" + MultiMutateIn CbAction = "MultiMutateIn" + DeletePath CbAction = "DeletePath" ) type CBActionDocument struct { Cas *uint64 Type CbAction + PathValues []PathValue Source []byte ID []byte Path []byte @@ -54,6 +61,20 @@ func NewSetAction(key []byte, source []byte) CBActionDocument { } } +func NewMultiMutateInAction(key []byte, pathValues []PathValue) CBActionDocument { + size := len(key) + for _, pv := range pathValues { + size += len(pv.Path) + len(pv.Value) + } + + return CBActionDocument{ + ID: key, + PathValues: pathValues, + Type: MultiMutateIn, + Size: size, + } +} + func NewMutateInAction(key []byte, path []byte, source []byte) CBActionDocument { return CBActionDocument{ ID: key,