| 3518 | } |
| 3519 | |
| 3520 | func (db *DatabaseCollectionWithUser) CheckChangeVersion(ctx context.Context, docid, rev string) (missing, possible []string) { |
| 3521 | if strings.HasPrefix(docid, "_design/") && db.user != nil { |
| 3522 | return // Users can't upload design docs, so ignore them |
| 3523 | } |
| 3524 | |
| 3525 | localIsLegacy := false |
| 3526 | changeIsLegacy := false |
| 3527 | |
| 3528 | syncData, hlv, err := db.GetDocSyncDataNoImport(ctx, docid, DocUnmarshalSync) |
| 3529 | if err != nil { |
| 3530 | if !base.IsDocNotFoundError(err) && !base.IsXattrNotFoundError(err) { |
| 3531 | base.WarnfCtx(ctx, "Error fetching doc %s during changes handling: %v", base.UD(docid), err) |
| 3532 | } |
| 3533 | missing = append(missing, rev) |
| 3534 | return |
| 3535 | } |
| 3536 | if hlv == nil { |
| 3537 | hlv, err = legacyRevToHybridLogicalVector(docid, syncData.GetRevTreeID()) |
| 3538 | if err != nil { |
| 3539 | base.WarnfCtx(ctx, "%s", err) |
| 3540 | missing = append(missing, rev) |
| 3541 | return |
| 3542 | } |
| 3543 | } |
| 3544 | if hlv.HasRevEncodedCV() { |
| 3545 | // if local hlv has revID encoded CV given to it mark it as legacy change for the purposes of sending back known revs |
| 3546 | // in legacy format. This will ensure delta sync works correctly replicating legacy revs |
| 3547 | localIsLegacy = true |
| 3548 | } |
| 3549 | // parse in coming version, if it's not known to local doc hlv then it is marked as missing, if it is and is a newer version |
| 3550 | // then it is also marked as missing |
| 3551 | var cvValue Version |
| 3552 | cvValue, changeIsLegacy, err = parseIncomingChange(docid, rev) |
| 3553 | if err != nil { |
| 3554 | base.WarnfCtx(ctx, "%s", err) |
| 3555 | missing = append(missing, rev) |
| 3556 | return |
| 3557 | } |
| 3558 | // CBG-4792: enhance here for conflict check - return conflict rev similar to propose changes here link ticket |
| 3559 | if localVersionDominates(hlv, cvValue) { |
| 3560 | // incoming version is dominated by local doc hlv, so it is not missing |
| 3561 | return |
| 3562 | } |
| 3563 | |
| 3564 | // return the local current rev as known rev, this will mean if you have rev 1,2,3 and remote has rev 1,2,3,4,5 then |
| 3565 | // remote should only send rev 4,5 in rev tree property on the subsequent rev message for this document, we also need to |
| 3566 | // send cv as first element for delta sync purposes. Only send CV if this is not legacy rev change |
| 3567 | if !localIsLegacy && !changeIsLegacy { |
| 3568 | // we should only send CV in response when we are communicating with HLV's both sides of the replication |
| 3569 | possible = append(possible, hlv.GetCurrentVersionString()) |
| 3570 | } |
| 3571 | possible = append(possible, syncData.GetRevTreeID()) |
| 3572 | |
| 3573 | missing = append(missing, rev) |
| 3574 | return |
| 3575 | } |
| 3576 | |
| 3577 | // localVersionDominates will check if local HLV dominates incoming change CV, if it does it will also do some work to |