예제 #1
0
 public Task <IOperationResult> ExecutePatch(string collectionName, CollectionOperationOptions options, PatchRequest patch,
                                             BlittableJsonReaderObject patchArgs, Action <IOperationProgress> onProgress, OperationCancelToken token)
 {
     return(ExecuteOperation(collectionName, options, Context, onProgress,
                             key => new PatchDocumentCommand(Context, key, null, false, (patch, patchArgs), (null, null),
                                                             Database, false, false), token));
 }
예제 #2
0
        protected Task <IOperationResult> ExecutePatch(IndexQueryServerSide query, Index index, QueryOperationOptions options, PatchRequest patch,
                                                       BlittableJsonReaderObject patchArgs, QueryOperationContext queryContext, Action <DeterminateProgress> onProgress, OperationCancelToken token)
        {
            return(ExecuteOperation(query, index, options, queryContext, onProgress,
                                    (key, retrieveDetails) =>
            {
                var command = new PatchDocumentCommand(queryContext.Documents, key,
                                                       expectedChangeVector: null,
                                                       skipPatchIfChangeVectorMismatch: false,
                                                       patch: (patch, patchArgs),
                                                       patchIfMissing: (null, null),
                                                       createIfMissing: null,
                                                       database: Database,
                                                       debugMode: false,
                                                       isTest: false,
                                                       collectResultsNeeded: true,
                                                       returnDocument: false);

                return new BulkOperationCommand <PatchDocumentCommand>(command, retrieveDetails,
                                                                       x => new BulkOperationResult.PatchDetails
                {
                    Id = key,
                    ChangeVector = x.PatchResult.ChangeVector,
                    Status = x.PatchResult.Status
                },
                                                                       c => c.PatchResult?.Dispose());
            }, token));
예제 #3
0
        private void WritePatchResultToResponse(DocumentsOperationContext context, PatchDocumentCommand command)
        {
            using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
            {
                writer.WriteStartObject();

                writer.WritePropertyName(nameof(command.PatchResult.Status));
                writer.WriteString(command.PatchResult.Status.ToString());
                writer.WriteComma();

                writer.WritePropertyName(nameof(command.PatchResult.ModifiedDocument));
                writer.WriteObject(command.PatchResult.ModifiedDocument);

                writer.WriteComma();
                writer.WritePropertyName(nameof(command.PatchResult.OriginalDocument));
                writer.WriteObject(command.PatchResult.OriginalDocument);

                writer.WriteComma();

                writer.WritePropertyName(nameof(command.PatchResult.Debug));

                context.Write(writer, new DynamicJsonValue
                {
                    ["Info"]    = new DynamicJsonArray(command.DebugOutput),
                    ["Actions"] = command.DebugActions
                });

                writer.WriteEndObject();
            }
        }
예제 #4
0
        public async Task SerializeAndDeserialize_PatchDocumentCommandTest()
        {
            using (var database = CreateDocumentDatabase())
                using (database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                {
                    //Arrange
                    var data         = new { ParentProperty = new { NestedProperty = "Some Value" } };
                    var arg          = DocumentConventions.Default.Serialization.DefaultConverter.ToBlittable(data, context);
                    var patchRequest = new PatchRequest("", PatchRequestType.None);

                    var expected = new PatchDocumentCommand(
                        context,
                        "Some Id",
                        context.GetLazyString("Some Lazy String"),
                        false,
                        (patchRequest, arg),
                        (null, null),
                        null,
                        database,
                        false, false, false, false);

                    //Action
                    var jsonSerializer = GetJsonSerializer();
                    BlittableJsonReaderObject blitCommand;
                    using (var writer = new BlittableJsonWriter(context))
                    {
                        var dto = expected.ToDto(context);
                        jsonSerializer.Serialize(writer, dto);
                        writer.FinalizeDocument();

                        blitCommand = writer.CreateReader();
                    }
                    var fromStream = await SerializeTestHelper.SimulateSavingToFileAndLoadingAsync(context, blitCommand);

                    PatchDocumentCommand actual;
                    using (var reader = new BlittableJsonReader(context))
                    {
                        reader.Initialize(fromStream);

                        var dto = jsonSerializer.Deserialize <PatchDocumentCommandDto>(reader);
                        actual = dto.ToCommand(context, database);
                    }

                    //Assert
                    Assert.Equal(expected, actual, new CustomComparer <PatchDocumentCommand>(context));
                }
        }
예제 #5
0
        public Task <IOperationResult> ExecutePatchQuery(IndexQueryServerSide query, QueryOperationOptions options, PatchRequest patch, BlittableJsonReaderObject patchArgs, DocumentsOperationContext context, Action <DeterminateProgress> onProgress, OperationCancelToken token)
        {
            return(ExecuteOperation(query, options, context, onProgress, (key, retrieveDetails) =>
            {
                var command = new PatchDocumentCommand(context, key,
                                                       expectedChangeVector: null,
                                                       skipPatchIfChangeVectorMismatch: false,
                                                       patch: (patch, patchArgs),
                                                       patchIfMissing: (null, null),
                                                       database: _database,
                                                       debugMode: false,
                                                       isTest: false);

                return new BulkOperationCommand <PatchDocumentCommand>(command, retrieveDetails, x => new BulkOperationResult.PatchDetails
                {
                    Id = key,
                    ChangeVector = x.PatchResult.ChangeVector,
                    Status = x.PatchResult.Status
                });
            }, token));
예제 #6
0
        public static async Task BuildCommandsAsync(JsonOperationContext ctx, BatchHandler.MergedBatchCommand command, Stream stream,
                                                    DocumentDatabase database, ServerStore serverStore)
        {
            CommandData[] cmds       = Empty;
            List <string> identities = null;
            List <int>    positionInListToCommandIndex = null;

            int index = -1;
            var state = new JsonParserState();

            using (ctx.GetManagedBuffer(out JsonOperationContext.ManagedPinnedBuffer buffer))
                using (var parser = new UnmanagedJsonParser(ctx, state, "bulk_docs"))
                {
                    while (parser.Read() == false)
                    {
                        await RefillParserBuffer(stream, buffer, parser);
                    }

                    if (state.CurrentTokenType != JsonParserToken.StartObject)
                    {
                        ThrowUnexpectedToken(JsonParserToken.StartObject, state);
                    }

                    while (parser.Read() == false)
                    {
                        await RefillParserBuffer(stream, buffer, parser);
                    }

                    if (state.CurrentTokenType != JsonParserToken.String)
                    {
                        ThrowUnexpectedToken(JsonParserToken.String, state);
                    }

                    if (GetLongFromStringBuffer(state) != 8314892176759549763) // Commands
                    {
                        ThrowUnexpectedToken(JsonParserToken.String, state);
                    }

                    while (parser.Read() == false)
                    {
                        await RefillParserBuffer(stream, buffer, parser);
                    }

                    if (state.CurrentTokenType != JsonParserToken.StartArray)
                    {
                        ThrowUnexpectedToken(JsonParserToken.StartArray, state);
                    }

                    while (true)
                    {
                        while (parser.Read() == false)
                        {
                            await RefillParserBuffer(stream, buffer, parser);
                        }

                        if (state.CurrentTokenType == JsonParserToken.EndArray)
                        {
                            break;
                        }

                        index++;
                        if (index >= cmds.Length)
                        {
                            cmds = IncreaseSizeOfCommandsBuffer(index, cmds);
                        }

                        var commandData = await ReadSingleCommand(ctx, stream, state, parser, buffer, default);

                        if (commandData.Type == CommandType.PATCH)
                        {
                            commandData.PatchCommand =
                                new PatchDocumentCommand(ctx, commandData.Id, commandData.ChangeVector,
                                                         false,
                                                         (commandData.Patch, commandData.PatchArgs),
                                                         (commandData.PatchIfMissing, commandData.PatchIfMissingArgs),
                                                         database,
                                                         false,
                                                         false,
                                                         true
                                                         );
                        }

                        if (commandData.Type == CommandType.PUT && string.IsNullOrEmpty(commandData.Id) == false && commandData.Id[commandData.Id.Length - 1] == '|')
                        {
                            if (identities == null)
                            {
                                identities = new List <string>();
                                positionInListToCommandIndex = new List <int>();
                            }
                            // queue identities requests in order to send them at once to the leader (using List for simplicity)
                            identities.Add(commandData.Id);
                            positionInListToCommandIndex.Add(index);
                        }

                        cmds[index] = commandData;
                    }

                    if (identities != null)
                    {
                        await GetIdentitiesValues(ctx,
                                                  database,
                                                  serverStore,
                                                  identities,
                                                  positionInListToCommandIndex,
                                                  cmds);
                    }

                    command.ParsedCommands = new ArraySegment <CommandData>(cmds, 0, index + 1);
                    if (await IsClusterTransaction(stream, parser, buffer, state))
                    {
                        command.IsClusterTransaction = true;
                    }
                }
        }
예제 #7
0
 public Task <IOperationResult> ExecutePatch(string collectionName, long start, long take, CollectionOperationOptions options, PatchRequest patch,
                                             BlittableJsonReaderObject patchArgs, Action <IOperationProgress> onProgress, OperationCancelToken token)
 {
     return(ExecuteOperation(collectionName, start, take, options, Context, onProgress,
                             key => new PatchDocumentCommand(Context, key, expectedChangeVector: null, skipPatchIfChangeVectorMismatch: false, patch: (patch, patchArgs), patchIfMissing: (null, null), createIfMissing: null, Database, isTest: false, debugMode: false, collectResultsNeeded: false, returnDocument: false), token));
 }
예제 #8
0
        public static async Task <ArraySegment <CommandData> > BuildCommandsAsync(JsonOperationContext ctx, Stream stream, DocumentDatabase database, ServerStore serverStore)
        {
            CommandData[] cmds = Empty;

            int index = -1;
            var state = new JsonParserState();

            using (ctx.GetManagedBuffer(out JsonOperationContext.ManagedPinnedBuffer buffer))
                using (var parser = new UnmanagedJsonParser(ctx, state, "bulk_docs"))
                {
                    while (parser.Read() == false)
                    {
                        await RefillParserBuffer(stream, buffer, parser);
                    }

                    if (state.CurrentTokenType != JsonParserToken.StartObject)
                    {
                        ThrowUnexpectedToken(JsonParserToken.StartObject, state);
                    }

                    while (parser.Read() == false)
                    {
                        await RefillParserBuffer(stream, buffer, parser);
                    }

                    if (state.CurrentTokenType != JsonParserToken.String)
                    {
                        ThrowUnexpectedToken(JsonParserToken.String, state);
                    }

                    if (GetLongFromStringBuffer(state) != 8314892176759549763) // Commands
                    {
                        ThrowUnexpectedToken(JsonParserToken.String, state);
                    }

                    while (parser.Read() == false)
                    {
                        await RefillParserBuffer(stream, buffer, parser);
                    }

                    if (state.CurrentTokenType != JsonParserToken.StartArray)
                    {
                        ThrowUnexpectedToken(JsonParserToken.StartArray, state);
                    }

                    while (true)
                    {
                        while (parser.Read() == false)
                        {
                            await RefillParserBuffer(stream, buffer, parser);
                        }

                        if (state.CurrentTokenType == JsonParserToken.EndArray)
                        {
                            break;
                        }

                        index++;
                        if (index >= cmds.Length)
                        {
                            cmds = IncreaseSizeOfCommandsBuffer(index, cmds);
                        }

                        var commandData = await ReadSingleCommand(ctx, stream, state, parser, buffer, default(CancellationToken));

                        if (commandData.Type == CommandType.PATCH)
                        {
                            commandData.PatchCommand =
                                new PatchDocumentCommand(ctx, commandData.Id, commandData.ChangeVector,
                                                         false,
                                                         (commandData.Patch, commandData.PatchArgs),
                                                         (commandData.PatchIfMissing, commandData.PatchIfMissingArgs),
                                                         database,
                                                         false,
                                                         false
                                                         );
                        }

                        if (commandData.Type == CommandType.PUT && string.IsNullOrEmpty(commandData.Id) == false && commandData.Id[commandData.Id.Length - 1] == '|')
                        {
                            var(_, id) = await serverStore.GenerateClusterIdentityAsync(commandData.Id, database.Name);

                            commandData.Id = id;
                        }

                        cmds[index] = commandData;
                    }
                }
            return(new ArraySegment <CommandData>(cmds, 0, index + 1));
        }
예제 #9
0
        public static async Task BuildCommandsAsync(JsonOperationContext ctx, BatchHandler.MergedBatchCommand command, Stream stream,
                                                    DocumentDatabase database, ServerStore serverStore)
        {
            CommandData[] cmds       = Empty;
            List <string> identities = null;
            List <int>    positionInListToCommandIndex = null;

            int index = -1;
            var state = new JsonParserState();

            using (ctx.GetManagedBuffer(out JsonOperationContext.ManagedPinnedBuffer buffer))
                using (var parser = new UnmanagedJsonParser(ctx, state, "bulk_docs"))
                    /* In case we have a conflict between attachment with the same name we need attachment information from metadata */
                    /* we can't know from advanced if we will need this information so we save this for all batch commands */
                    using (var modifier = new BlittableMetadataModifier(ctx, false, false, DatabaseItemType.Attachments))
                    {
                        while (parser.Read() == false)
                        {
                            await RefillParserBuffer(stream, buffer, parser);
                        }

                        if (state.CurrentTokenType != JsonParserToken.StartObject)
                        {
                            ThrowUnexpectedToken(JsonParserToken.StartObject, state);
                        }

                        while (parser.Read() == false)
                        {
                            await RefillParserBuffer(stream, buffer, parser);
                        }

                        if (state.CurrentTokenType != JsonParserToken.String)
                        {
                            ThrowUnexpectedToken(JsonParserToken.String, state);
                        }

                        if (GetLongFromStringBuffer(state) != 8314892176759549763) // Commands
                        {
                            ThrowUnexpectedToken(JsonParserToken.String, state);
                        }

                        while (parser.Read() == false)
                        {
                            await RefillParserBuffer(stream, buffer, parser);
                        }

                        if (state.CurrentTokenType != JsonParserToken.StartArray)
                        {
                            ThrowUnexpectedToken(JsonParserToken.StartArray, state);
                        }

                        while (true)
                        {
                            while (parser.Read() == false)
                            {
                                await RefillParserBuffer(stream, buffer, parser);
                            }

                            if (state.CurrentTokenType == JsonParserToken.EndArray)
                            {
                                break;
                            }

                            index++;
                            if (index >= cmds.Length)
                            {
                                cmds = IncreaseSizeOfCommandsBuffer(index, cmds);
                            }

                            var commandData = await ReadSingleCommand(ctx, stream, state, parser, buffer, modifier, default);

                            if (commandData.Type == CommandType.PATCH)
                            {
                                commandData.PatchCommand =
                                    new PatchDocumentCommand(
                                        ctx,
                                        commandData.Id,
                                        commandData.ChangeVector,
                                        skipPatchIfChangeVectorMismatch: false,
                                        (commandData.Patch, commandData.PatchArgs),
                                        (commandData.PatchIfMissing, commandData.PatchIfMissingArgs),
                                        database,
                                        isTest: false,
                                        debugMode: false,
                                        collectResultsNeeded: true,
                                        returnDocument: commandData.ReturnDocument
                                        );
                            }

                            if (commandData.Type == CommandType.BatchPATCH)
                            {
                                commandData.PatchCommand =
                                    new BatchPatchDocumentCommand(
                                        ctx,
                                        commandData.Ids,
                                        skipPatchIfChangeVectorMismatch: false,
                                        (commandData.Patch, commandData.PatchArgs),
                                        (commandData.PatchIfMissing, commandData.PatchIfMissingArgs),
                                        database,
                                        isTest: false,
                                        debugMode: false,
                                        collectResultsNeeded: true
                                        );
                            }

                            if (commandData.Type == CommandType.PUT && string.IsNullOrEmpty(commandData.Id) == false && commandData.Id[commandData.Id.Length - 1] == '|')
                            {
                                if (identities == null)
                                {
                                    identities = new List <string>();
                                    positionInListToCommandIndex = new List <int>();
                                }
                                // queue identities requests in order to send them at once to the leader (using List for simplicity)
                                identities.Add(commandData.Id);
                                positionInListToCommandIndex.Add(index);
                            }

                            cmds[index] = commandData;
                        }

                        if (identities != null)
                        {
                            await GetIdentitiesValues(ctx,
                                                      database,
                                                      serverStore,
                                                      identities,
                                                      positionInListToCommandIndex,
                                                      cmds);
                        }

                        command.ParsedCommands = new ArraySegment <CommandData>(cmds, 0, index + 1);
                        if (await IsClusterTransaction(stream, parser, buffer, state))
                        {
                            command.IsClusterTransaction = true;
                        }
                    }
        }