Ejemplo n.º 1
0
        public static void ResolveConflict(this DocumentDatabase database, JsonDocument document, Storage.IStorageActionsAccessor actions, out JsonDocument newDocument)
        {
            newDocument = null;
            if (document == null)
            {
                return;
            }

            var conflicts = actions
                            .Documents
                            .GetDocumentsWithIdStartingWith(document.Key, 0, int.MaxValue, null)
                            .Where(x => x.Key.Contains("/conflicts/"))
                            .ToList();

            KeyValuePair <JsonDocument, DateTime> local;
            KeyValuePair <JsonDocument, DateTime> remote;

            database.GetConflictDocuments(conflicts, out local, out remote);

            var docsReplicationConflictResolvers = database.DocsConflictResolvers();

            foreach (var replicationConflictResolver in docsReplicationConflictResolvers)
            {
                if (remote.Key != null && local.Key != null)
                {
                    RavenJObject metadataToSave;
                    RavenJObject documentToSave;
                    Func <object, JsonDocument> getDocument = key => actions.Documents.DocumentByKey(document.Key);
                    var conflictResolved = replicationConflictResolver.TryResolveConflict(document.Key,
                                                                                          remote.Key.Metadata,
                                                                                          remote.Key.DataAsJson,
                                                                                          local.Key,
                                                                                          getDocument,
                                                                                          out metadataToSave,
                                                                                          out documentToSave);

                    if (conflictResolved)
                    {
                        foreach (var conflict in conflicts)
                        {
                            Etag         etag;
                            RavenJObject metadata;
                            actions.Documents.DeleteDocument(conflict.Key, null, out metadata, out etag);
                        }

                        if (metadataToSave != null && metadataToSave.Value <bool>(Constants.RavenDeleteMarker))
                        {
                            database.Documents.Delete(document.Key, null, null);
                        }
                        else
                        {
                            using (database.DocumentLock.Lock())
                            {
                                if (metadataToSave != null)
                                {
                                    metadataToSave.Remove(Constants.RavenReplicationConflictDocument);
                                    metadataToSave.Remove(Constants.RavenReplicationConflict);
                                    metadataToSave.Add("@id", document.Key);
                                }

                                var addDocumentResult = actions.Documents.AddDocument(document.Key, document.Etag, documentToSave, metadataToSave);

                                newDocument = new JsonDocument
                                {
                                    Metadata            = metadataToSave,
                                    Key                 = document.Key,
                                    DataAsJson          = documentToSave,
                                    Etag                = addDocumentResult.Etag,
                                    LastModified        = addDocumentResult.SavedAt,
                                    SkipDeleteFromIndex = addDocumentResult.Updated == false
                                };
                            }
                        }
                    }
                }
            }
        }