Exemple #1
0
        public async Task Put()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var id = GetQueryStringValueAndAssertIfSingleAndNotEmpty("id");
                // We HAVE to read the document in full, trying to parallelize the doc read
                // and the identity generation needs to take into account that the identity
                // generation can fail and will leave the reading task hanging if we abort
                // easier to just do in synchronously
                var doc = await context.ReadForDiskAsync(RequestBodyStream(), id).ConfigureAwait(false);

                if (id[id.Length - 1] == '|')
                {
                    var(_, clusterId, _) = await ServerStore.GenerateClusterIdentityAsync(id, Database.Name);

                    id = clusterId;
                }

                var changeVector = context.GetLazyString(GetStringFromHeaders("If-Match"));

                using (var cmd = new MergedPutCommand(doc, id, changeVector, Database))
                {
                    await Database.TxMerger.Enqueue(cmd);

                    cmd.ExceptionDispatchInfo?.Throw();

                    HttpContext.Response.StatusCode = (int)HttpStatusCode.Created;

                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        writer.WriteStartObject();

                        writer.WritePropertyName(nameof(PutResult.Id));
                        writer.WriteString(cmd.PutResult.Id);
                        writer.WriteComma();

                        writer.WritePropertyName(nameof(PutResult.ChangeVector));
                        writer.WriteString(cmd.PutResult.ChangeVector);

                        writer.WriteEndObject();
                    }
                }
            }
        }
Exemple #2
0
        public async Task Put()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var id = GetQueryStringValueAndAssertIfSingleAndNotEmpty("id");

                var doc = context.ReadForDiskAsync(RequestBodyStream(), id).ConfigureAwait(false);

                if (id[id.Length - 1] == '|')
                {
                    var(_, clusterId) = await ServerStore.GenerateClusterIdentityAsync(id, Database.Name);

                    id = clusterId;
                }

                var changeVector = context.GetLazyString(GetStringQueryString("If-Match", false));

                var cmd = new MergedPutCommand(await doc, id, changeVector, Database);

                await Database.TxMerger.Enqueue(cmd);

                cmd.ExceptionDispatchInfo?.Throw();

                HttpContext.Response.StatusCode = (int)HttpStatusCode.Created;

                using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                {
                    writer.WriteStartObject();

                    writer.WritePropertyName(nameof(PutResult.Id));
                    writer.WriteString(cmd.PutResult.Id);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(PutResult.ChangeVector));
                    writer.WriteString(cmd.PutResult.ChangeVector);

                    writer.WriteEndObject();
                }
            }
        }
        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));
        }