상속: MongoRequestMessage
예제 #1
0
        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;
        }
예제 #2
0
        // 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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        // 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);
        }
예제 #5
0
        // 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;
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
        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);
            }
        }