protected WriteConcernResult SendMessageWithWriteConcern( MongoConnection connection, BsonBuffer buffer, int requestId, BsonBinaryReaderSettings readerSettings, BsonBinaryWriterSettings writerSettings, WriteConcern writeConcern) { CommandDocument getLastErrorCommand = null; if (writeConcern.Enabled) { var fsync = (writeConcern.FSync == null) ? null : (BsonValue)writeConcern.FSync; var journal = (writeConcern.Journal == null) ? null : (BsonValue)writeConcern.Journal; var w = (writeConcern.W == null) ? null : writeConcern.W.ToGetLastErrorWValue(); var wTimeout = (writeConcern.WTimeout == null) ? null : (BsonValue)(int)writeConcern.WTimeout.Value.TotalMilliseconds; getLastErrorCommand = new CommandDocument { { "getlasterror", 1 }, // use all lowercase for backward compatibility { "fsync", fsync, fsync != null }, { "j", journal, journal != null }, { "w", w, w != null }, { "wtimeout", wTimeout, wTimeout != null } }; // piggy back on network transmission for message var getLastErrorMessage = new MongoQueryMessage(writerSettings, DatabaseName + ".$cmd", QueryFlags.None, 0, 1, getLastErrorCommand, null); getLastErrorMessage.WriteToBuffer(buffer); } connection.SendMessage(buffer, requestId); WriteConcernResult writeConcernResult = null; if (writeConcern.Enabled) { var writeConcernResultSerializer = BsonSerializer.LookupSerializer(typeof(WriteConcernResult)); var replyMessage = connection.ReceiveMessage<WriteConcernResult>(readerSettings, writeConcernResultSerializer, null); if (replyMessage.NumberReturned == 0) { throw new MongoCommandException("Command 'getLastError' failed. No response returned"); } writeConcernResult = replyMessage.Documents[0]; writeConcernResult.Command = getLastErrorCommand; var mappedException = ExceptionMapper.Map(writeConcernResult); if (mappedException != null) { throw mappedException; } } return writeConcernResult; }
// this is a low level method that doesn't require a MongoServer // so it can be used while connecting to a MongoServer internal CommandResult RunCommand( string collectionName, QueryFlags queryFlags, CommandDocument command ) { var commandName = command.GetElement(0).Name; var writerSettings = new BsonBinaryWriterSettings { GuidRepresentation = GuidRepresentation.Unspecified, MaxDocumentSize = serverInstance.MaxDocumentSize }; using ( var message = new MongoQueryMessage( writerSettings, collectionName, queryFlags, 0, // numberToSkip 1, // numberToReturn (must be 1 or -1 for commands) command, null // fields ) ) { SendMessage(message, SafeMode.False); } var readerSettings = new BsonBinaryReaderSettings { GuidRepresentation = GuidRepresentation.Unspecified, MaxDocumentSize = serverInstance.MaxDocumentSize }; var reply = ReceiveMessage <BsonDocument>(readerSettings, null); if (reply.NumberReturned == 0) { var message = string.Format("Command '{0}' failed. No response returned.", commandName); throw new MongoCommandException(message); } var commandResult = new CommandResult(command, reply.Documents[0]); if (!commandResult.Ok) { throw new MongoCommandException(commandResult); } return(commandResult); }
private MongoReplyMessage <TDocument> GetFirst() { var connection = AcquireConnection(); try { // some of these weird conditions are necessary to get commands to run correctly // specifically numberToReturn has to be 1 or -1 for commands int numberToReturn; if (cursor.Limit < 0) { numberToReturn = cursor.Limit; } else if (cursor.Limit == 0) { numberToReturn = cursor.BatchSize; } else if (cursor.BatchSize == 0) { numberToReturn = cursor.Limit; } else if (cursor.Limit < cursor.BatchSize) { numberToReturn = cursor.Limit; } else { numberToReturn = cursor.BatchSize; } using ( var message = new MongoQueryMessage( connection, cursor.Collection.FullName, cursor.Flags, cursor.Skip, numberToReturn, WrapQuery(), cursor.Fields ) ) { return(GetReply(connection, message)); } } finally { cursor.Server.ReleaseConnection(connection); } }
// this is a low level method that doesn't require a MongoServer // so it can be used while connecting to a MongoServer internal CommandResult RunCommand( string databaseName, QueryFlags queryFlags, CommandDocument command, bool throwOnError) { var commandName = command.GetElement(0).Name; var writerSettings = new BsonBinaryWriterSettings { GuidRepresentation = GuidRepresentation.Unspecified, MaxDocumentSize = _serverInstance.MaxDocumentSize }; using (var message = new MongoQueryMessage(writerSettings, databaseName + ".$cmd", queryFlags, 0, 1, command, null)) { SendMessage(message, null, databaseName); // write concern doesn't apply to queries } var readerSettings = new BsonBinaryReaderSettings { GuidRepresentation = GuidRepresentation.Unspecified, MaxDocumentSize = _serverInstance.MaxDocumentSize }; var reply = ReceiveMessage <BsonDocument>(readerSettings, null); if (reply.NumberReturned == 0) { var message = string.Format("Command '{0}' failed. No response returned.", commandName); throw new MongoCommandException(message); } var commandResult = new CommandResult(command, reply.Documents[0]); if (throwOnError && !commandResult.Ok) { throw new MongoCommandException(commandResult); } return(commandResult); }
// this is a low level method that doesn't require a MongoServer // so it can be used while connecting to a MongoServer internal CommandResult RunCommand( MongoServer server, string collectionName, QueryFlags queryFlags, CommandDocument command ) { var commandName = command.GetElement(0).Name; using ( var message = new MongoQueryMessage( server, collectionName, queryFlags, 0, // numberToSkip 1, // numberToReturn (must be 1 or -1 for commands) command, null // fields ) ) { SendMessage(message, SafeMode.False); } var reply = ReceiveMessage <BsonDocument>(server); if (reply.NumberReturned == 0) { var message = string.Format("Command '{0}' failed: no response returned", commandName); throw new MongoCommandException(message); } var commandResult = new CommandResult(command, reply.Documents[0]); if (!commandResult.Ok) { throw new MongoCommandException(commandResult); } return(commandResult); }
protected SendMessageWithWriteConcernResult SendMessageWithWriteConcern( MongoConnection connection, Stream stream, int requestId, BsonBinaryReaderSettings readerSettings, BsonBinaryWriterSettings writerSettings, WriteConcern writeConcern) { var result = new SendMessageWithWriteConcernResult(); if (writeConcern.Enabled) { var maxDocumentSize = connection.ServerInstance.MaxDocumentSize; var fsync = (writeConcern.FSync == null) ? null : (BsonValue)writeConcern.FSync; var journal = (writeConcern.Journal == null) ? null : (BsonValue)writeConcern.Journal; var w = (writeConcern.W == null) ? null : writeConcern.W.ToGetLastErrorWValue(); var wTimeout = (writeConcern.WTimeout == null) ? null : (BsonValue)(int)writeConcern.WTimeout.Value.TotalMilliseconds; var getLastErrorCommand = new CommandDocument { { "getlasterror", 1 }, // use all lowercase for backward compatibility { "fsync", fsync, fsync != null }, { "j", journal, journal != null }, { "w", w, w != null }, { "wtimeout", wTimeout, wTimeout != null } }; // piggy back on network transmission for message var getLastErrorMessage = new MongoQueryMessage(writerSettings, DatabaseName + ".$cmd", QueryFlags.None, maxDocumentSize, 0, 1, getLastErrorCommand, null); getLastErrorMessage.WriteTo(stream); result.GetLastErrorCommand = getLastErrorCommand; result.GetLastErrorRequestId = getLastErrorMessage.RequestId; } connection.SendMessage(stream, requestId); return result; }
internal WriteConcernResult SendMessage(MongoRequestMessage message, WriteConcern writeConcern, string databaseName) { if (_state == MongoConnectionState.Closed) { throw new InvalidOperationException("Connection is closed."); } lock (_connectionLock) { _requestId = message.RequestId; message.WriteToBuffer(); CommandDocument getLastErrorCommand = null; if (writeConcern != null && writeConcern.Enabled) { var fsync = (writeConcern.FSync == null) ? null : (BsonValue)writeConcern.FSync; var journal = (writeConcern.Journal == null) ? null : (BsonValue)writeConcern.Journal; var w = (writeConcern.W == null) ? null : writeConcern.W.ToGetLastErrorWValue(); var wTimeout = (writeConcern.WTimeout == null) ? null : (BsonValue)(int)writeConcern.WTimeout.Value.TotalMilliseconds; getLastErrorCommand = new CommandDocument { { "getlasterror", 1 }, // use all lowercase for backward compatibility { "fsync", fsync, fsync != null }, { "j", journal, journal != null }, { "w", w, w != null }, { "wtimeout", wTimeout, wTimeout != null } }; // piggy back on network transmission for message using (var getLastErrorMessage = new MongoQueryMessage(message.Buffer, message.WriterSettings, databaseName + ".$cmd", QueryFlags.None, 0, 1, getLastErrorCommand, null)) { getLastErrorMessage.WriteToBuffer(); } } try { var networkStream = GetNetworkStream(); var writeTimeout = (int)_serverInstance.Settings.SocketTimeout.TotalMilliseconds; if (writeTimeout != 0) { networkStream.WriteTimeout = writeTimeout; } message.Buffer.WriteTo(networkStream); _messageCounter++; } catch (Exception ex) { HandleException(ex); throw; } WriteConcernResult writeConcernResult = null; if (writeConcern != null && writeConcern.Enabled) { var readerSettings = new BsonBinaryReaderSettings { GuidRepresentation = message.WriterSettings.GuidRepresentation, MaxDocumentSize = _serverInstance.MaxDocumentSize }; var replyMessage = ReceiveMessage <BsonDocument>(readerSettings, null); var getLastErrorResponse = replyMessage.Documents[0]; writeConcernResult = new WriteConcernResult(); writeConcernResult.Initialize(getLastErrorCommand, getLastErrorResponse); if (!writeConcernResult.Ok) { var errorMessage = string.Format( "WriteConcern detected an error '{0}'. (response was {1}).", writeConcernResult.ErrorMessage, getLastErrorResponse.ToJson()); throw new WriteConcernException(errorMessage, writeConcernResult); } if (writeConcernResult.HasLastErrorMessage) { var errorMessage = string.Format( "WriteConcern detected an error '{0}'. (Response was {1}).", writeConcernResult.LastErrorMessage, getLastErrorResponse.ToJson()); throw new WriteConcernException(errorMessage, writeConcernResult); } } return(writeConcernResult); } }
internal SafeModeResult SendMessage( MongoRequestMessage message, SafeMode safeMode ) { if (state == MongoConnectionState.Closed) { throw new InvalidOperationException("Connection is closed"); } lock (connectionLock) { message.WriteToBuffer(); CommandDocument safeModeCommand = null; if (safeMode.Enabled) { safeModeCommand = new CommandDocument { { "getlasterror", 1 }, // use all lowercase for backward compatibility { "fsync", true, safeMode.FSync }, { "w", safeMode.W, safeMode.W > 1 }, { "wtimeout", (int)safeMode.WTimeout.TotalMilliseconds, safeMode.W > 1 && safeMode.WTimeout != TimeSpan.Zero } }; using ( var getLastErrorMessage = new MongoQueryMessage( message.Server, "admin.$cmd", // collectionFullName QueryFlags.None, 0, // numberToSkip 1, // numberToReturn safeModeCommand, null, // fields message.Buffer // piggy back on network transmission for message ) ) { getLastErrorMessage.WriteToBuffer(); } } try { var networkStream = GetNetworkStream(); networkStream.WriteTimeout = (int)message.Server.Settings.SocketTimeout.TotalMilliseconds; message.Buffer.WriteTo(networkStream); messageCounter++; } catch (Exception ex) { HandleException(ex); throw; } SafeModeResult safeModeResult = null; if (safeMode.Enabled) { var replyMessage = ReceiveMessage <BsonDocument>(message.Server); var safeModeResponse = replyMessage.Documents[0]; safeModeResult = new SafeModeResult(); safeModeResult.Initialize(safeModeCommand, safeModeResponse); if (!safeModeResult.Ok) { var errorMessage = string.Format("Safemode detected an error: {0} (response: {1})", safeModeResult.ErrorMessage, safeModeResponse.ToJson()); throw new MongoSafeModeException(errorMessage, safeModeResult); } if (safeModeResult.HasLastErrorMessage) { var errorMessage = string.Format("Safemode detected an error: {0} (response: {1})", safeModeResult.LastErrorMessage, safeModeResponse.ToJson()); throw new MongoSafeModeException(errorMessage, safeModeResult); } } return(safeModeResult); } }
internal SafeModeResult SendMessage(MongoRequestMessage message, SafeMode safeMode) { if (_state == MongoConnectionState.Closed) { throw new InvalidOperationException("Connection is closed."); } lock (_connectionLock) { _requestId = message.RequestId; message.WriteToBuffer(); CommandDocument safeModeCommand = null; if (safeMode.Enabled) { safeModeCommand = new CommandDocument { { "getlasterror", 1 }, // use all lowercase for backward compatibility { "fsync", true, safeMode.FSync }, { "j", true, safeMode.Journal }, { "w", safeMode.W, safeMode.W > 1 }, { "w", safeMode.WMode, safeMode.WMode != null }, { "wtimeout", (int)safeMode.WTimeout.TotalMilliseconds, safeMode.W > 1 && safeMode.WTimeout != TimeSpan.Zero } }; // piggy back on network transmission for message using (var getLastErrorMessage = new MongoQueryMessage(message.Buffer, message.WriterSettings, "admin.$cmd", QueryFlags.None, 0, 1, safeModeCommand, null)) { getLastErrorMessage.WriteToBuffer(); } } try { var networkStream = GetNetworkStream(); var writeTimeout = (int)_serverInstance.Server.Settings.SocketTimeout.TotalMilliseconds; if (writeTimeout != 0) { networkStream.WriteTimeout = writeTimeout; } message.Buffer.WriteTo(networkStream); _messageCounter++; } catch (Exception ex) { HandleException(ex); throw; } SafeModeResult safeModeResult = null; if (safeMode.Enabled) { var readerSettings = new BsonBinaryReaderSettings { GuidRepresentation = message.WriterSettings.GuidRepresentation, MaxDocumentSize = _serverInstance.MaxDocumentSize }; var replyMessage = ReceiveMessage <BsonDocument>(readerSettings, null); var safeModeResponse = replyMessage.Documents[0]; safeModeResult = new SafeModeResult(); safeModeResult.Initialize(safeModeCommand, safeModeResponse); if (!safeModeResult.Ok) { var errorMessage = string.Format( "Safemode detected an error '{0}'. (response was {1}).", safeModeResult.ErrorMessage, safeModeResponse.ToJson()); throw new MongoSafeModeException(errorMessage, safeModeResult); } if (safeModeResult.HasLastErrorMessage) { var errorMessage = string.Format( "Safemode detected an error '{0}'. (Response was {1}).", safeModeResult.LastErrorMessage, safeModeResponse.ToJson()); throw new MongoSafeModeException(errorMessage, safeModeResult); } } return(safeModeResult); } }