public unsafe void HandleConflictForDocument( DocumentsOperationContext documentsContext, string id, string collection, long lastModifiedTicks, BlittableJsonReaderObject doc, string changeVector, DocumentFlags flags) { if (id.StartsWith(HiLoHandler.RavenHiloIdPrefix, StringComparison.OrdinalIgnoreCase)) { HandleHiloConflict(documentsContext, id, doc, changeVector); return; } if (TryResolveIdenticalDocument( documentsContext, id, doc, lastModifiedTicks, changeVector)) { return; } var lazyId = documentsContext.GetLazyString(id); using (DocumentIdWorker.GetLower(documentsContext.Allocator, lazyId, out var loweredKey)) { var conflictedDoc = new DocumentConflict { Doc = doc, Collection = documentsContext.GetLazyStringForFieldWithCaching( collection ?? CollectionName.GetCollectionName(doc) ), LastModified = new DateTime(lastModifiedTicks), LowerId = documentsContext.AllocateStringValue(null, loweredKey.Content.Ptr, loweredKey.Content.Length), Id = lazyId, ChangeVector = changeVector, Flags = flags }; if (TryResolveConflictByScript( documentsContext, conflictedDoc)) { return; } if (_database.ReplicationLoader.ConflictSolverConfig?.ResolveToLatest ?? true) { var conflicts = new List <DocumentConflict> { conflictedDoc.Clone() }; conflicts.AddRange(_database.DocumentsStorage.ConflictsStorage.GetConflictsFor(documentsContext, id)); var localDocumentTuple = _database.DocumentsStorage.GetDocumentOrTombstone(documentsContext, id, false); var local = DocumentConflict.From(documentsContext, localDocumentTuple.Document) ?? DocumentConflict.From(localDocumentTuple.Tombstone); if (local != null) { conflicts.Add(local); } var resolved = _conflictResolver.ResolveToLatest(conflicts); _conflictResolver.PutResolvedDocument(documentsContext, resolved, resolvedToLatest: true, conflictedDoc); return; } _database.DocumentsStorage.ConflictsStorage.AddConflict(documentsContext, id, lastModifiedTicks, doc, changeVector, collection, flags); } }
private IEnumerable <DocumentConflict> ReadConflicts(INewDocumentActions actions = null) { if (UnmanagedJsonParserHelper.Read(_peepingTomStream, _parser, _state, _buffer) == false) { UnmanagedJsonParserHelper.ThrowInvalidJson("Unexpected end of json", _peepingTomStream, _parser); } if (_state.CurrentTokenType != JsonParserToken.StartArray) { UnmanagedJsonParserHelper.ThrowInvalidJson("Expected start array, but got " + _state.CurrentTokenType, _peepingTomStream, _parser); } var context = _context; var builder = CreateBuilder(context, null); try { while (true) { if (UnmanagedJsonParserHelper.Read(_peepingTomStream, _parser, _state, _buffer) == false) { UnmanagedJsonParserHelper.ThrowInvalidJson("Unexpected end of json while reading docs", _peepingTomStream, _parser); } if (_state.CurrentTokenType == JsonParserToken.EndArray) { break; } if (actions != null) { var oldContext = context; context = actions.GetContextForNewDocument(); if (oldContext != context) { builder.Dispose(); builder = CreateBuilder(context, null); } } builder.Renew("import/object", BlittableJsonDocumentBuilder.UsageMode.ToDisk); _context.CachedProperties.NewDocument(); ReadObject(builder); var data = builder.CreateReader(); builder.Reset(); var conflict = new DocumentConflict(); if (data.TryGet(nameof(DocumentConflict.Id), out conflict.Id) && data.TryGet(nameof(DocumentConflict.Collection), out conflict.Collection) && data.TryGet(nameof(DocumentConflict.Flags), out string flags) && data.TryGet(nameof(DocumentConflict.ChangeVector), out conflict.ChangeVector) && data.TryGet(nameof(DocumentConflict.Etag), out conflict.Etag) && data.TryGet(nameof(DocumentConflict.LastModified), out conflict.LastModified) && data.TryGet(nameof(DocumentConflict.Doc), out conflict.Doc)) { conflict.Flags = Enum.Parse <DocumentFlags>(flags); if (conflict.Doc != null) // This is null for conflict that was generated from tombstone { conflict.Doc = context.ReadObject(conflict.Doc, conflict.Id, BlittableJsonDocumentBuilder.UsageMode.ToDisk); } yield return(conflict); } else { var msg = "Ignoring an invalied conflict which you try to import. " + data; if (_log.IsOperationsEnabled) { _log.Operations(msg); } _result.Conflicts.ErroredCount++; _result.AddWarning(msg); } } } finally { builder.Dispose(); } }