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); }
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); }
public override void Execute(DocumentsOperationContext context, RavenTransaction tx) { try { PutResult = Database.DocumentsStorage.Put(context, Key, ExepctedEtag, Document); } catch (ConcurrencyException e) { ConcurrencyException = e; } }
public override int Execute(DocumentsOperationContext context) { try { PutResult = _database.DocumentsStorage.Put(context, _id, _expectedChangeVector, _document); } catch (ConcurrencyException e) { ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(e); } return(1); }
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); }
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); }