| 1765 | } |
| 1766 | |
| 1767 | func (db *DatabaseCollectionWithUser) getResyncedDocument(ctx context.Context, doc *Document, regenerateSequences bool, unusedSequences []uint64) (updatedDoc *Document, shouldUpdate bool, updatedExpiry *uint32, highSeq uint64, updatedUnusedSequences []uint64, err error) { |
| 1768 | docid := doc.ID |
| 1769 | forceUpdate := false |
| 1770 | if !doc.HasValidSyncData() { |
| 1771 | // This is a document not known to the sync gateway. Ignore it: |
| 1772 | return nil, false, nil, doc.Sequence, unusedSequences, base.ErrUpdateCancel |
| 1773 | } |
| 1774 | |
| 1775 | base.TracefCtx(ctx, base.KeyCRUD, "\tRe-syncing document %q", base.UD(docid)) |
| 1776 | |
| 1777 | // Run the sync fn over each current/leaf revision, in case there are conflicts: |
| 1778 | changed := 0 |
| 1779 | doc.History.forEachLeaf(func(rev *RevInfo) { |
| 1780 | bodyBytes, _, err := db.get1xRevFromDoc(ctx, doc, rev.ID, false) |
| 1781 | if err != nil { |
| 1782 | base.WarnfCtx(ctx, "Error getting rev from doc %s/%s %s", base.UD(docid), rev.ID, err) |
| 1783 | } |
| 1784 | var body Body |
| 1785 | if err := body.Unmarshal(bodyBytes); err != nil { |
| 1786 | base.WarnfCtx(ctx, "Error unmarshalling body %s/%s for sync function %s", base.UD(docid), rev.ID, err) |
| 1787 | return |
| 1788 | } |
| 1789 | metaMap, err := doc.GetMetaMap(db.UserXattrKey()) |
| 1790 | if err != nil { |
| 1791 | return |
| 1792 | } |
| 1793 | channels, access, roles, syncExpiry, _, err := db.getChannelsAndAccess(ctx, doc, body, metaMap, rev.ID) |
| 1794 | if err != nil { |
| 1795 | // Probably the validator rejected the doc |
| 1796 | base.WarnfCtx(ctx, "Error calling sync() on doc %q: %v", base.UD(docid), err) |
| 1797 | access = nil |
| 1798 | channels = nil |
| 1799 | } |
| 1800 | rev.Channels = channels |
| 1801 | |
| 1802 | if rev.ID == doc.GetRevTreeID() { |
| 1803 | if regenerateSequences { |
| 1804 | updatedUnusedSequences, err = db.assignSequence(ctx, 0, doc, unusedSequences) |
| 1805 | if err != nil { |
| 1806 | base.WarnfCtx(ctx, "Unable to assign a sequence number: %v", err) |
| 1807 | } |
| 1808 | forceUpdate = true |
| 1809 | } |
| 1810 | |
| 1811 | changedChannels, _, err := doc.updateChannels(ctx, channels) |
| 1812 | changed = len(doc.Access.updateAccess(ctx, doc, access)) + |
| 1813 | len(doc.RoleAccess.updateAccess(ctx, doc, roles)) + |
| 1814 | len(changedChannels) |
| 1815 | if err != nil { |
| 1816 | return |
| 1817 | } |
| 1818 | // Only update document expiry based on the current (active) rev |
| 1819 | if syncExpiry != nil { |
| 1820 | doc.UpdateExpiry(*syncExpiry) |
| 1821 | updatedExpiry = syncExpiry |
| 1822 | } |
| 1823 | } |
| 1824 | }) |