MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / MigrateAttachmentMetadata

Method MigrateAttachmentMetadata

db/crud.go:1085–1136  ·  view source on GitHub ↗

MigrateAttachmentMetadata will move any attachment metadata defined in sync data to global sync xattr

(ctx context.Context, docID string, cas uint64, syncData *SyncData)

Source from the content-addressed store, hash-verified

1083
1084// MigrateAttachmentMetadata will move any attachment metadata defined in sync data to global sync xattr
1085func (c *DatabaseCollectionWithUser) MigrateAttachmentMetadata(ctx context.Context, docID string, cas uint64, syncData *SyncData) error {
1086 xattrs, _, err := c.dataStore.GetXattrs(ctx, docID, []string{base.GlobalXattrName, base.VirtualXattrRevSeqNo})
1087 if err != nil && !base.IsXattrNotFoundError(err) {
1088 return err
1089 }
1090 var globalData GlobalSyncData
1091 if xattrs[base.GlobalXattrName] != nil {
1092 // we have a global xattr to preserve
1093 err := base.JSONUnmarshal(xattrs[base.GlobalXattrName], &globalData)
1094 if err != nil {
1095 return base.RedactErrorf("Failed to Unmarshal global sync data when attempting to migrate sync data attachments to global xattr with id: %s. Error: %v", base.UD(docID), err)
1096 }
1097 }
1098 globalData.Attachments = mergeAttachments(syncData.AttachmentsPre4dot0, globalData.Attachments)
1099 syncData.AttachmentsPre4dot0 = nil // clear out the pre-4.0 attachments so we don't try to write them to the doc
1100 globalXattr, err := base.JSONMarshal(globalData)
1101 if err != nil {
1102 return base.RedactErrorf("Failed to Marshal global sync data when attempting to migrate sync data attachments to global xattr with id: %s. Error: %v", base.UD(docID), err)
1103 }
1104 rawSyncXattr, err := base.JSONMarshal(*syncData)
1105 if err != nil {
1106 return base.RedactErrorf("Failed to Marshal sync data when attempting to migrate sync data attachments to global xattr with id: %s. Error: %v", base.UD(docID), err)
1107 }
1108 revSeqNo, err := unmarshalRevSeqNo(xattrs[base.VirtualXattrRevSeqNo])
1109 if err != nil {
1110 base.InfofCtx(ctx, base.KeyCRUD, "Could not determine revSeqNo found when attempting to migrate sync data attachments to global xattr for doc %q. Assuming 0. Error: %v", base.UD(docID), err)
1111 }
1112
1113 metadataOnlyUpdate := &MetadataOnlyUpdate{
1114 HexCAS: expandMacroCASValueString, // when non-empty, this is replaced with cas macro expansion
1115 PreviousHexCAS: syncData.Cas,
1116 PreviousRevSeqNo: revSeqNo,
1117 }
1118 rawMouXattr, err := base.JSONMarshal(metadataOnlyUpdate)
1119 if err != nil {
1120 return base.RedactErrorf("Failed to marshal _mou when attempting to migrate sync data attachments to global xattr with id: %s. Error: %v", base.UD(docID), err)
1121 }
1122
1123 // build macro expansion for sync data. This will avoid the update to xattrs causing an extra import event (i.e. sync cas will be == to doc cas)
1124 opts := &sgbucket.MutateInOptions{}
1125 spec := append(macroExpandSpec(base.SyncXattrName), sgbucket.NewMacroExpansionSpec(XattrMouCasPath(), sgbucket.MacroCas))
1126 opts.MacroExpansion = spec
1127 opts.PreserveExpiry = true // if doc has expiry, we should preserve this
1128
1129 updatedXattr := map[string][]byte{
1130 base.SyncXattrName: rawSyncXattr,
1131 base.GlobalXattrName: globalXattr,
1132 base.MouXattrName: rawMouXattr,
1133 }
1134 _, err = c.dataStore.UpdateXattrs(ctx, docID, 0, cas, updatedXattr, opts)
1135 return err
1136}
1137
1138// Updates or creates a document.
1139// The new body's BodyRev property must match the current revision's, if any.

Callers 3

RunMethod · 0.95
ImportFeedEventMethod · 0.80

Calls 12

IsXattrNotFoundErrorFunction · 0.92
JSONUnmarshalFunction · 0.92
RedactErrorfFunction · 0.92
UDFunction · 0.92
JSONMarshalFunction · 0.92
InfofCtxFunction · 0.92
mergeAttachmentsFunction · 0.85
unmarshalRevSeqNoFunction · 0.85
macroExpandSpecFunction · 0.85
XattrMouCasPathFunction · 0.85
GetXattrsMethod · 0.45
UpdateXattrsMethod · 0.45

Tested by 1