Example #1
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;
                    }
                }
        }
        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;
                        }
                    }
        }