コード例 #1
0
        protected override int ExecuteCmd(DocumentsOperationContext context)
        {
            try
            {
                PutResult = _database.DocumentsStorage.Put(context, _id, _expectedChangeVector, _document);
            }
            catch (Voron.Exceptions.VoronConcurrencyErrorException)
            {
                // RavenDB-10581 - If we have a concurrency error on "doc-id/"
                // this means that we have existing values under the current etag
                // we'll generate a new (random) id for them.

                // The TransactionMerger will re-run us when we ask it to as a
                // separate transaction
                if (_id?.EndsWith('/') == true)
                {
                    _id          = GenerateNonConflictingId(_database, _id);
                    RetryOnError = true;
                }
                throw;
            }
            catch (ConcurrencyException e)
            {
                ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(e);
            }
            return(1);
        }
コード例 #2
0
        protected override long ExecuteCmd(DocumentsOperationContext context)
        {
            if (_shouldValidateAttachments)
            {
                if (_document.TryGet(Constants.Documents.Metadata.Key, out BlittableJsonReaderObject metadata) &&
                    metadata.TryGet(Constants.Documents.Metadata.Attachments, out BlittableJsonReaderArray attachments))
                {
                    ValidateAttachments(attachments, context, _id);
                }
            }
            try
            {
                PutResult = _database.DocumentsStorage.Put(context, _id, _expectedChangeVector, _document);
            }
            catch (Voron.Exceptions.VoronConcurrencyErrorException)
            {
                // RavenDB-10581 - If we have a concurrency error on "doc-id/"
                // this means that we have existing values under the current etag
                // we'll generate a new (random) id for them.

                // The TransactionMerger will re-run us when we ask it to as a
                // separate transaction
                if (_id?.EndsWith('/') == true)
                {
                    _id          = GenerateNonConflictingId(_database, _id);
                    RetryOnError = true;
                }
                throw;
            }
            catch (ConcurrencyException e)
            {
                ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(e);
            }
            return(1);
        }
コード例 #3
0
 public override void Execute(DocumentsOperationContext context, RavenTransaction tx)
 {
     try
     {
         PutResult = Database.DocumentsStorage.Put(context, Key, ExepctedEtag, Document);
     }
     catch (ConcurrencyException e)
     {
         ConcurrencyException = e;
     }
 }
コード例 #4
0
ファイル: DocumentHandler.cs プロジェクト: otgoo0603/ravendb
 public override int Execute(DocumentsOperationContext context)
 {
     try
     {
         PutResult = _database.DocumentsStorage.Put(context, _id, _expectedChangeVector, _document);
     }
     catch (ConcurrencyException e)
     {
         ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(e);
     }
     return(1);
 }
コード例 #5
0
ファイル: BatchHandler.cs プロジェクト: tinybaby/ravendb
            protected void AddPutResult(DocumentsStorage.PutOperationResults putResult)
            {
                LastChangeVector = putResult.ChangeVector;
                ModifiedCollections?.Add(putResult.Collection.Name);

                // Make sure all the metadata fields are always been add
                var putReply = new DynamicJsonValue
                {
                    ["Type"] = nameof(CommandType.PUT),
                    [Constants.Documents.Metadata.Id]           = putResult.Id,
                    [Constants.Documents.Metadata.Collection]   = putResult.Collection.Name,
                    [Constants.Documents.Metadata.ChangeVector] = putResult.ChangeVector,
                    [Constants.Documents.Metadata.LastModified] = putResult.LastModified
                };

                if (putResult.Flags != DocumentFlags.None)
                {
                    putReply[Constants.Documents.Metadata.Flags] = putResult.Flags;
                }

                Reply.Add(putReply);
            }
コード例 #6
0
        public unsafe PatchResultData Apply(DocumentsOperationContext context,
                                            string documentKey,
                                            long?etag,
                                            PatchRequest patch,
                                            PatchRequest patchIfMissing,
                                            bool isTestOnly = false,
                                            bool skipPatchIfEtagMismatch = false)
        {
            var document = _database.DocumentsStorage.Get(context, documentKey);

            if (_logger.IsInfoEnabled)
            {
                _logger.Info(string.Format("Preparing to apply patch on ({0}). Document found?: {1}.", documentKey, document != null));
            }

            if (etag.HasValue && document != null && document.Etag != etag.Value)
            {
                System.Diagnostics.Debug.Assert(document.Etag > 0);

                if (skipPatchIfEtagMismatch)
                {
                    return(new PatchResultData
                    {
                        PatchResult = PatchResult.Skipped
                    });
                }

                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"Got concurrent exception while tried to patch the following document: {documentKey}");
                }
                throw new ConcurrencyException($"Could not patch document '{documentKey}' because non current etag was used")
                      {
                          ActualETag   = document.Etag,
                          ExpectedETag = etag.Value,
                      };
            }

            var patchRequest = patch;

            if (document == null)
            {
                if (patchIfMissing == null)
                {
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info("Tried to patch a not exists document and patchIfMissing is null");
                    }

                    return(new PatchResultData
                    {
                        PatchResult = PatchResult.DocumentDoesNotExists
                    });
                }
                patchRequest = patchIfMissing;
            }
            var scope            = ApplySingleScript(context, document, isTestOnly, patchRequest);
            var modifiedDocument = context.ReadObject(scope.ToBlittable(scope.PatchObject.AsObject()),
                                                      documentKey, BlittableJsonDocumentBuilder.UsageMode.ToDisk);

            var result = new PatchResultData
            {
                PatchResult      = PatchResult.NotModified,
                OriginalDocument = document?.Data,
                DebugInfo        = scope.DebugInfo,
            };

            if (modifiedDocument == null)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"After applying patch, modifiedDocument is null and document is null? {document == null}");
                }

                result.PatchResult = PatchResult.Skipped;
                return(result);
            }

            if (isTestOnly)
            {
                return(new PatchResultData
                {
                    PatchResult = PatchResult.Tested,
                    OriginalDocument = document?.Data,
                    ModifiedDocument = modifiedDocument,
                    DebugActions = scope.DebugActions.GetDebugActions(),
                    DebugInfo = scope.DebugInfo,
                });
            }

            var putResult = new DocumentsStorage.PutOperationResults();

            if (document == null)
            {
                putResult = _database.DocumentsStorage.Put(context, documentKey, null, modifiedDocument);
            }
            else
            {
                var isModified = document.Data.Size != modifiedDocument.Size;
                if (isModified == false) // optimization, if size different, no need to compute hash to check
                {
                    var originHash   = Hashing.XXHash64.Calculate(document.Data.BasePointer, (ulong)document.Data.Size);
                    var modifiedHash = Hashing.XXHash64.Calculate(modifiedDocument.BasePointer, (ulong)modifiedDocument.Size);
                    isModified = originHash != modifiedHash;
                }

                if (isModified)
                {
                    putResult = _database.DocumentsStorage.Put(context, document.Key, document.Etag,
                                                               modifiedDocument);
                    result.PatchResult = PatchResult.Patched;
                }
            }

            if (putResult.Etag != 0)
            {
                result.Etag       = putResult.Etag;
                result.Collection = putResult.Collection;
            }

            return(result);
        }