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

Method CheckProposedVersion

db/crud.go:3698–3778  ·  view source on GitHub ↗

CheckProposedVersion - given DocID and a version in string form, check whether it can be added without conflict. proposedVersionStr is the string representation of the proposed version's CV. previousRev is the string representation of the CV of the last known parent of the proposed version. proposed

(ctx context.Context, docid, proposedVersionStr string, previousRev string, proposedHLVString string)

Source from the content-addressed store, hash-verified

3696// previousRev is the string representation of the CV of the last known parent of the proposed version.
3697// proposedHLVString is the string representation of the proposed version's full HLV.
3698func (db *DatabaseCollectionWithUser) CheckProposedVersion(ctx context.Context, docid, proposedVersionStr string, previousRev string, proposedHLVString string) (status ProposedRevStatus, currentVersion string) {
3699
3700 proposedVersion, err := ParseVersion(proposedVersionStr)
3701 if err != nil {
3702 base.WarnfCtx(ctx, "Couldn't parse proposed version for doc %q / %q: %v", base.UD(docid), proposedVersionStr, err)
3703 return ProposedRev_Error, ""
3704 }
3705
3706 // previousRev may be revTreeID or version
3707 var previousVersion Version
3708 previousRevFormat := "version"
3709 // TODO: CBG-4812 Use base.IsRevTreeID
3710 if !strings.Contains(previousRev, "@") {
3711 previousRevFormat = "revTreeID"
3712 }
3713 if previousRev != "" && previousRevFormat == "version" {
3714 var err error
3715 previousVersion, err = ParseVersion(previousRev)
3716 if err != nil {
3717 base.WarnfCtx(ctx, "Couldn't parse previous version for doc %q / %q: %v", base.UD(docid), previousRev, err)
3718 return ProposedRev_Error, ""
3719 }
3720 }
3721
3722 localDocCV := Version{}
3723 syncData, hlv, err := db.GetDocSyncDataNoImport(ctx, docid, DocUnmarshalNoHistory)
3724 if hlv != nil {
3725 localDocCV.SourceID, localDocCV.Value = hlv.GetCurrentVersion()
3726 }
3727 if err != nil {
3728 if !base.IsDocNotFoundError(err) && !errors.Is(err, base.ErrXattrNotFound) {
3729 base.WarnfCtx(ctx, "CheckProposedRev(%q) --> %T %v", base.UD(docid), err, err)
3730 return ProposedRev_Error, ""
3731 }
3732 // New document not found on server
3733 return ProposedRev_OK_IsNew, ""
3734 } else if previousRevFormat == "revTreeID" && syncData.GetRevTreeID() == previousRev {
3735 if proposedVersion.SourceID == encodedRevTreeSourceID {
3736 // If we have encoded CV proposed to us and local CV is not encoded, check if proposed encoded CV
3737 // is derived from the local current revID. If so we already have this rev.
3738 localEncodedCV, err := LegacyRevToRevTreeEncodedVersion(syncData.GetRevTreeID())
3739 if err != nil {
3740 base.DebugfCtx(ctx, base.KeyCRUD, "Failed to parse local revID to encoded CV for doc %q / %q: %v", base.UD(docid), previousRev, err)
3741 return ProposedRev_Error, ""
3742 }
3743 if localEncodedCV.Equal(proposedVersion) {
3744 return ProposedRev_Exists, ""
3745 }
3746 }
3747 // Non-conflicting update, client's previous legacy revTreeID is server's currentRev
3748 return ProposedRev_OK, ""
3749 } else if hlv == nil {
3750 // no HLV on this doc in SGW so if previousRev didn't match current rev then it is a conflict
3751 return ProposedRev_Conflict, syncData.GetRevTreeID()
3752 } else if previousRevFormat == "version" && localDocCV == previousVersion {
3753 // Non-conflicting update, client's previous version is server's CV
3754 return ProposedRev_OK, ""
3755 } else if hlv.DominatesSource(proposedVersion) {

Callers 3

handleProposeChangesMethod · 0.80
TestCheckProposedVersionFunction · 0.80

Calls 14

StringMethod · 0.95
WarnfCtxFunction · 0.92
UDFunction · 0.92
IsDocNotFoundErrorFunction · 0.92
DebugfCtxFunction · 0.92
ParseVersionFunction · 0.85
extractHLVFromBlipStringFunction · 0.85
GetCurrentVersionMethod · 0.80
DominatesSourceMethod · 0.80
ContainsMethod · 0.65

Tested by 2

TestCheckProposedVersionFunction · 0.64