@@ -1824,96 +1824,67 @@ func (db *DatabaseCollectionWithUser) getResyncedDocument(ctx context.Context, d
18241824
18251825// ResyncDocument will re-run the sync function on the document and write an updated version to the bucket. If
18261826// the sync function doesn't change any channels or access grants, no write will be performed.
1827- func (db * DatabaseCollectionWithUser ) ResyncDocument (ctx context.Context , docid , key string , regenerateSequences bool , unusedSequences [] uint64 ) (updatedHighSeq uint64 , updatedUnusedSequences []uint64 , err error ) {
1827+ func (db * DatabaseCollectionWithUser ) ResyncDocument (ctx context.Context , docid string , previousDoc * sgbucket. BucketDocument , regenerateSequences bool ) (updatedUnusedSequences []uint64 , err error ) {
18281828 var updatedDoc * Document
18291829 var shouldUpdate bool
18301830 var updatedExpiry * uint32
1831- if db .UseXattrs () {
1832- writeUpdateFunc := func (currentValue []byte , currentXattrs map [string ][]byte , cas uint64 ) (sgbucket.UpdatedDoc , error ) {
1833- // There's no scenario where a doc should from non-deleted to deleted during UpdateAllDocChannels processing,
1834- // so deleteDoc is always returned as false.
1835- if currentValue == nil || len (currentValue ) == 0 {
1836- return sgbucket.UpdatedDoc {}, base .ErrUpdateCancel
1837- }
1838- doc , err := db .unmarshalDocumentWithXattrs (ctx , docid , currentValue , currentXattrs , cas , DocUnmarshalAll )
1839- if err != nil {
1840- return sgbucket.UpdatedDoc {}, err
1841- }
1842- updatedDoc , shouldUpdate , updatedExpiry , updatedHighSeq , unusedSequences , err = db .getResyncedDocument (ctx , doc , regenerateSequences , unusedSequences )
1843- if err != nil {
1844- return sgbucket.UpdatedDoc {}, err
1845- }
1846- if ! shouldUpdate {
1847- return sgbucket.UpdatedDoc {}, base .ErrUpdateCancel
1848- }
1849- base .TracefCtx (ctx , base .KeyAccess , "Saving updated channels and access grants of %q" , base .UD (docid ))
1850- if updatedExpiry != nil {
1851- updatedDoc .UpdateExpiry (* updatedExpiry )
1852- }
1853- doc .SetCrc32cUserXattrHash ()
1854-
1855- // Update MetadataOnlyUpdate based on previous Cas, MetadataOnlyUpdate
1856- if db .useMou () {
1857- doc .MetadataOnlyUpdate = computeMetadataOnlyUpdate (doc .Cas , doc .RevSeqNo , doc .MetadataOnlyUpdate )
1858- }
1859-
1860- _ , rawSyncXattr , _ , rawMouXattr , rawGlobalXattr , err := updatedDoc .MarshalWithXattrs ()
1861- updatedDoc := sgbucket.UpdatedDoc {
1862- Doc : nil , // Resync does not require document body update
1863- Xattrs : map [string ][]byte {
1864- base .SyncXattrName : rawSyncXattr ,
1865- },
1866- Expiry : updatedExpiry ,
1867- }
1868- if db .useMou () {
1869- updatedDoc .Xattrs [base .MouXattrName ] = rawMouXattr
1870- if doc .MetadataOnlyUpdate .HexCAS == expandMacroCASValueString {
1871- updatedDoc .Spec = append (updatedDoc .Spec , sgbucket .NewMacroExpansionSpec (XattrMouCasPath (), sgbucket .MacroCas ))
1872- }
1873- }
1874- if rawGlobalXattr != nil {
1875- updatedDoc .Xattrs [base .GlobalXattrName ] = rawGlobalXattr
1876- }
1877- return updatedDoc , err
1831+ writeUpdateFunc := func (currentValue []byte , currentXattrs map [string ][]byte , cas uint64 ) (sgbucket.UpdatedDoc , error ) {
1832+ // resyncDocument is not called on tombstoned documents, so this value will only be empty if the document was
1833+ // deleted between DCP event and calling this function. In any case, we do not need to update it.
1834+ if len (currentValue ) == 0 {
1835+ return sgbucket.UpdatedDoc {}, base .ErrUpdateCancel
18781836 }
1879- opts := & sgbucket.MutateInOptions {
1880- MacroExpansion : macroExpandSpec (base .SyncXattrName ),
1837+ doc , err := db .unmarshalDocumentWithXattrs (ctx , docid , currentValue , currentXattrs , cas , DocUnmarshalAll )
1838+ if err != nil {
1839+ return sgbucket.UpdatedDoc {}, err
18811840 }
1882- _ , err = db .dataStore .WriteUpdateWithXattrs (ctx , key , db .syncGlobalSyncMouRevSeqNoAndUserXattrKeys (), 0 , nil , opts , writeUpdateFunc )
1883- } else {
1884- _ , err = db .dataStore .Update (key , 0 , func (currentValue []byte ) ([]byte , * uint32 , bool , error ) {
1885- // Be careful: this block can be invoked multiple times if there are races!
1886- if currentValue == nil {
1887- return nil , nil , false , base .ErrUpdateCancel // someone deleted it?!
1888- }
1889- doc , err := unmarshalDocument (docid , currentValue )
1890- if err != nil {
1891- return nil , nil , false , err
1892- }
1893- updatedDoc , shouldUpdate , updatedExpiry , updatedHighSeq , unusedSequences , err = db .getResyncedDocument (ctx , doc , regenerateSequences , unusedSequences )
1894- if err != nil {
1895- return nil , nil , false , err
1896- }
1897- if shouldUpdate {
1898- base .TracefCtx (ctx , base .KeyAccess , "Saving updated channels and access grants of %q" , base .UD (docid ))
1899- if updatedExpiry != nil {
1900- updatedDoc .UpdateExpiry (* updatedExpiry )
1901- }
1841+ fmt .Printf ("%+v\n " , doc )
1842+ updatedDoc , shouldUpdate , updatedExpiry , _ , updatedUnusedSequences , err = db .getResyncedDocument (ctx , doc , regenerateSequences , nil )
1843+ if err != nil {
1844+ return sgbucket.UpdatedDoc {}, err
1845+ }
1846+ if ! shouldUpdate {
1847+ return sgbucket.UpdatedDoc {}, base .ErrUpdateCancel
1848+ }
1849+ base .TracefCtx (ctx , base .KeyAccess , "Saving updated channels and access grants of %q" , base .UD (docid ))
1850+ if updatedExpiry != nil {
1851+ updatedDoc .UpdateExpiry (* updatedExpiry )
1852+ }
1853+ doc .SetCrc32cUserXattrHash ()
19021854
1903- updatedBytes , marshalErr := base .JSONMarshal (updatedDoc )
1904- return updatedBytes , updatedExpiry , false , marshalErr
1905- } else {
1906- return nil , nil , false , base .ErrUpdateCancel
1855+ // Update MetadataOnlyUpdate based on previous Cas, MetadataOnlyUpdate
1856+ doc .MetadataOnlyUpdate = computeMetadataOnlyUpdate (doc .Cas , doc .RevSeqNo , doc .MetadataOnlyUpdate )
1857+ fmt .Printf ("updatedDoc= %+v\n " , updatedDoc )
1858+ _ , rawSyncXattr , _ , rawMouXattr , rawGlobalXattr , err := updatedDoc .MarshalWithXattrs ()
1859+ updatedDoc := sgbucket.UpdatedDoc {
1860+ Doc : nil , // Resync does not require document body update
1861+ Xattrs : map [string ][]byte {
1862+ base .SyncXattrName : rawSyncXattr ,
1863+ base .MouXattrName : rawMouXattr ,
1864+ },
1865+ Expiry : updatedExpiry ,
1866+ }
1867+ if doc .MetadataOnlyUpdate != nil {
1868+ if doc .MetadataOnlyUpdate .HexCAS == expandMacroCASValueString {
1869+ updatedDoc .Spec = append (updatedDoc .Spec , sgbucket .NewMacroExpansionSpec (XattrMouCasPath (), sgbucket .MacroCas ))
19071870 }
1908- })
1871+ }
1872+ if rawGlobalXattr != nil {
1873+ updatedDoc .Xattrs [base .GlobalXattrName ] = rawGlobalXattr
1874+ }
1875+ return updatedDoc , err
1876+ }
1877+ opts := & sgbucket.MutateInOptions {
1878+ MacroExpansion : macroExpandSpec (base .SyncXattrName ),
19091879 }
1880+ _ , err = db .dataStore .WriteUpdateWithXattrs (ctx , docid , db .syncGlobalSyncMouRevSeqNoAndUserXattrKeys (), 0 , previousDoc , opts , writeUpdateFunc )
19101881 if err == nil {
19111882 base .Audit (ctx , base .AuditIDDocumentResync , base.AuditFields {
19121883 base .AuditFieldDocID : docid ,
19131884 base .AuditFieldDocVersion : updatedDoc .CVOrRevTreeID (),
19141885 })
19151886 }
1916- return updatedHighSeq , unusedSequences , err
1887+ return updatedUnusedSequences , err
19171888}
19181889
19191890// invalidateAllPrincipals invalidates computed channels and roles for all users/roles, for the specified collections:
0 commit comments