// public methods
        public virtual BulkWriteResult Execute(MongoConnection connection)
        {
            var batchResults = new List<BulkWriteBatchResult>();
            var remainingRequests = Enumerable.Empty<WriteRequest>();
            var hasWriteErrors = false;

            var decoratedRequests = DecorateRequests(_args.Requests);
            using (var enumerator = decoratedRequests.GetEnumerator())
            {
                var originalIndex = 0;
                Batch<WriteRequest> batch = new FirstBatch<WriteRequest>(enumerator);
                while (batch != null)
                {
                    if (hasWriteErrors && _args.IsOrdered)
                    {
                        remainingRequests = remainingRequests.Concat(batch.RemainingItems);
                        break;
                    }

                    var batchResult = ExecuteBatch(connection, batch, originalIndex);
                    batchResults.Add(batchResult);

                    hasWriteErrors |= batchResult.HasWriteErrors;
                    originalIndex += batchResult.BatchCount;
                    batch = batchResult.NextBatch;
                }
            }

            var combiner = new BulkWriteBatchResultCombiner(batchResults, _args.WriteConcern.Enabled);
            return combiner.CreateResultOrThrowIfHasErrors(remainingRequests);
        }
        // public methods
        public virtual BulkWriteResult Execute(MongoConnection connection)
        {
            var batchResults      = new List <BulkWriteBatchResult>();
            var remainingRequests = Enumerable.Empty <WriteRequest>();
            var hasWriteErrors    = false;

            var decoratedRequests = DecorateRequests(_args.Requests);

            using (var enumerator = decoratedRequests.GetEnumerator())
            {
                var originalIndex          = 0;
                Batch <WriteRequest> batch = new FirstBatch <WriteRequest>(enumerator);
                while (batch != null)
                {
                    if (hasWriteErrors && _args.IsOrdered)
                    {
                        remainingRequests = remainingRequests.Concat(batch.RemainingItems);
                        break;
                    }

                    var batchResult = ExecuteBatch(connection, batch, originalIndex);
                    batchResults.Add(batchResult);

                    hasWriteErrors |= batchResult.HasWriteErrors;
                    originalIndex  += batchResult.BatchCount;
                    batch           = batchResult.NextBatch;
                }
            }

            var combiner = new BulkWriteBatchResultCombiner(batchResults, _args.WriteConcern.Enabled);

            return(combiner.CreateResultOrThrowIfHasErrors(remainingRequests));
        }
        // public methods
        public IEnumerable<WriteConcernResult> Execute(MongoConnection connection)
        {
            var serverInstance = connection.ServerInstance;
            if (serverInstance.Supports(FeatureId.WriteCommands) && _args.WriteConcern.Enabled)
            {
                var emulator = new InsertOpcodeOperationEmulator(_args);
                return emulator.Execute(connection);
            }

            var results = WriteConcern.Enabled ? new List<WriteConcernResult>() : null;
            var finalException = (Exception)null;

            var requests = _args.Requests.Cast<InsertRequest>();
            if (_args.AssignId != null)
            {
                requests = requests.Select(r => { _args.AssignId(r); return r; });
            }

            using (var enumerator = requests.GetEnumerator())
            {
                var maxBatchCount = _args.MaxBatchCount; // OP_INSERT is not limited by the MaxBatchCount reported by the server
                var maxBatchLength = Math.Min(_args.MaxBatchLength, connection.ServerInstance.MaxMessageLength);
                var maxDocumentSize = connection.ServerInstance.MaxDocumentSize;

                Batch<InsertRequest> nextBatch = new FirstBatch<InsertRequest>(enumerator);
                while (nextBatch != null)
                {
                    // release buffer as soon as possible
                    BatchProgress<InsertRequest> batchProgress;
                    SendMessageWithWriteConcernResult sendBatchResult;
                    using (var buffer = new BsonBuffer(new MultiChunkBuffer(BsonChunkPool.Default), true))
                    {
                        var flags = _continueOnError ? InsertFlags.ContinueOnError : InsertFlags.None;
                        var message = new MongoInsertMessage(
                            _args.WriterSettings,
                            _args.DatabaseName + "." + _args.CollectionName,
                            _args.CheckElementNames,
                            flags,
                            maxBatchCount,
                            maxBatchLength,
                            maxDocumentSize,
                            nextBatch);
                        message.WriteTo(buffer); // consumes as much of nextBatch as fits in one message
                        batchProgress = message.BatchProgress;

                        sendBatchResult = SendBatch(connection, buffer, message.RequestId, batchProgress.IsLast);
                    }

                    // note: getLastError is sent even when WriteConcern is not enabled if ContinueOnError is false
                    if (sendBatchResult.GetLastErrorRequestId.HasValue)
                    {
                        WriteConcernResult writeConcernResult;
                        try
                        {
                            writeConcernResult = ReadWriteConcernResult(connection, sendBatchResult);
                        }
                        catch (WriteConcernException ex)
                        {
                            writeConcernResult = ex.WriteConcernResult;
                            if (_continueOnError)
                            {
                                finalException = ex;
                            }
                            else if (WriteConcern.Enabled)
                            {
                                results.Add(writeConcernResult);
                                ex.Data["results"] = results;
                                throw;
                            }
                            else
                            {
                                return null;
                            }
                        }

                        if (results != null)
                        {
                            results.Add(writeConcernResult);
                        }
                    }

                    nextBatch = batchProgress.NextBatch;
                }
            }

            if (WriteConcern.Enabled && finalException != null)
            {
                finalException.Data["results"] = results;
                throw finalException;
            }

            return results;
        }
Пример #4
0
        // public methods
        public IEnumerable <WriteConcernResult> Execute(MongoConnection connection)
        {
            var serverInstance = connection.ServerInstance;

            if (serverInstance.Supports(FeatureId.WriteCommands) && _args.WriteConcern.Enabled)
            {
                var emulator = new InsertOpcodeOperationEmulator(_args);
                return(emulator.Execute(connection));
            }

            var results        = WriteConcern.Enabled ? new List <WriteConcernResult>() : null;
            var finalException = (Exception)null;

            var requests = _args.Requests.Cast <InsertRequest>();

            if (_args.AssignId != null)
            {
                requests = requests.Select(r => { _args.AssignId(r); return(r); });
            }

            using (var enumerator = requests.GetEnumerator())
            {
                var maxBatchCount   = _args.MaxBatchCount; // OP_INSERT is not limited by the MaxBatchCount reported by the server
                var maxBatchLength  = Math.Min(_args.MaxBatchLength, connection.ServerInstance.MaxMessageLength);
                var maxDocumentSize = connection.ServerInstance.MaxDocumentSize;

                Batch <InsertRequest> nextBatch = new FirstBatch <InsertRequest>(enumerator);
                while (nextBatch != null)
                {
                    // release buffer as soon as possible
                    BatchProgress <InsertRequest>     batchProgress;
                    SendMessageWithWriteConcernResult sendBatchResult;
                    using (var stream = new MemoryStream())
                    {
                        var flags   = _continueOnError ? InsertFlags.ContinueOnError : InsertFlags.None;
                        var message = new MongoInsertMessage(
                            _args.WriterSettings,
                            _args.DatabaseName + "." + _args.CollectionName,
                            _args.CheckElementNames,
                            flags,
                            maxBatchCount,
                            maxBatchLength,
                            maxDocumentSize,
                            nextBatch);
                        message.WriteTo(stream); // consumes as much of nextBatch as fits in one message
                        batchProgress = message.BatchProgress;

                        sendBatchResult = SendBatch(connection, stream, message.RequestId, batchProgress.IsLast);
                    }

                    // note: getLastError is sent even when WriteConcern is not enabled if ContinueOnError is false
                    if (sendBatchResult.GetLastErrorRequestId.HasValue)
                    {
                        WriteConcernResult writeConcernResult;
                        try
                        {
                            writeConcernResult = ReadWriteConcernResult(connection, sendBatchResult);
                        }
                        catch (WriteConcernException ex)
                        {
                            writeConcernResult = ex.WriteConcernResult;
                            if (_continueOnError)
                            {
                                finalException = ex;
                            }
                            else if (WriteConcern.Enabled)
                            {
                                results.Add(writeConcernResult);
                                ex.Data["results"] = results;
                                throw;
                            }
                            else
                            {
                                return(null);
                            }
                        }

                        if (results != null)
                        {
                            results.Add(writeConcernResult);
                        }
                    }

                    nextBatch = batchProgress.NextBatch;
                }
            }

            if (WriteConcern.Enabled && finalException != null)
            {
                finalException.Data["results"] = results;
                throw finalException;
            }

            return(results);
        }