// 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; }
// 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); }