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