예제 #1
0
        public void AssertNoErrors_EmitsAseException_WithErrorsInOrderOfSeverity()
        {
            var handler = new MessageTokenHandler();

            handler.Handle(new EedToken
            {
                Severity          = 11,
                ServerName        = "",
                LineNumber        = 1,
                Message           = "Least Severe",
                MessageNumber     = 20000,
                ProcedureName     = "",
                SqlState          = new byte[0],
                State             = 1,
                Status            = EedToken.EedStatus.TDS_EED_INFO,
                TransactionStatus = TranState.TDS_NOT_IN_TRAN
            });
            handler.Handle(new EedToken
            {
                Severity          = 21,
                ServerName        = "",
                LineNumber        = 1,
                Message           = "Most Severe",
                MessageNumber     = 20000,
                ProcedureName     = "",
                SqlState          = new byte[0],
                State             = 1,
                Status            = EedToken.EedStatus.TDS_EED_INFO,
                TransactionStatus = TranState.TDS_NOT_IN_TRAN
            });
            var ex = Assert.Throws <AseException>(() => handler.AssertNoErrors());

            Assert.AreEqual("Most Severe", ex.Message);
        }
예제 #2
0
        public void SetTextSize(int textSize)
        {
            //todo: may need to remove this, user scripts could change the textsize value
            if (_environment.TextSize == textSize)
            {
                return;
            }

            SendPacket(new NormalPacket(OptionCommandToken.CreateSetTextSize(textSize)));

            var envChangeTokenHandler = new EnvChangeTokenHandler(_environment, _parameters.Charset);
            var messageHandler        = new MessageTokenHandler(EventNotifier);
            var dataReaderHandler     = new DataReaderTokenHandler();
            var doneHandler           = new DoneTokenHandler();

            ReceiveTokens(
                envChangeTokenHandler,
                messageHandler,
                dataReaderHandler,
                doneHandler);

            messageHandler.AssertNoErrors();

            _environment.TextSize = textSize;
        }
예제 #3
0
        public void ChangeDatabase(string databaseName)
        {
            if (string.IsNullOrWhiteSpace(databaseName) || string.Equals(databaseName, Database, StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            AssertExecutionStart();

            //turns out, you can't issue an env change token to change the database, it responds saying it doesn't know how to process such a token
            SendPacket(new NormalPacket(new LanguageToken
            {
                HasParameters = false,
                CommandText   = $"USE {databaseName}"
            }));

            var messageHandler        = new MessageTokenHandler(EventNotifier);
            var envChangeTokenHandler = new EnvChangeTokenHandler(_environment, _parameters.Charset);

            ReceiveTokens(envChangeTokenHandler, messageHandler);

            AssertExecutionCompletion();

            messageHandler.AssertNoErrors();
        }
예제 #4
0
        public void AssertCanDetermineBackupErrors()
        {
            var handler = new MessageTokenHandler();

            handler.Handle(new EedToken
            {
                Severity          = 1,
                ServerName        = "AZ3_BS",
                LineNumber        = 0,
                Message           = "Backup Server: 4.172.1.4: The value of 'allocated pages threshold' has been set to 40%.\n", // This is severity 1, i.e. informational
                MessageNumber     = 417201,
                ProcedureName     = "bs_optimize",
                SqlState          = new byte[0],
                State             = 40,
                Status            = EedToken.EedStatus.TDS_NO_EED,
                TransactionStatus = TranState.TDS_NOT_IN_TRAN
            });
            handler.Handle(new EedToken
            {
                Severity          = 2, // This is not >10, but severity "2" in the backup server's message, so must be treated as error.
                ServerName        = "AZ3_BS",
                LineNumber        = 0,
                Message           = "Backup Server: 4.141.2.40: [11] The 'open' call failed for database/archive device while working on stripe device '/doesnotexist/foo' with error number 2 (No such file or directory). Refer to your operating system documentation for further details.\0",
                MessageNumber     = 414102,
                ProcedureName     = "bs_write_header",
                SqlState          = new byte[0],
                State             = 40,
                Status            = EedToken.EedStatus.TDS_NO_EED,
                TransactionStatus = TranState.TDS_NOT_IN_TRAN
            });
            handler.Handle(new EedToken
            {
                Severity          = 16,
                ServerName        = "AZ3",
                LineNumber        = 1,
                Message           = "Error encountered by Backup Server.  Please refer to Backup Server messages for details.\n",
                MessageNumber     = 8009,
                ProcedureName     = "",
                SqlState          = new byte[0],
                State             = 1,
                Status            = EedToken.EedStatus.TDS_EED_INFO,
                TransactionStatus = TranState.TDS_NOT_IN_TRAN
            });
            var ex = Assert.Throws <AseException>(() => handler.AssertNoErrors());

            Assert.AreEqual(3, ex.Errors.Count);
            Assert.AreEqual(16, ex.Errors[0].Severity);

            Assert.AreEqual(1, ex.Errors[1].Severity);
            Assert.IsFalse(ex.Errors[1].IsError);
            Assert.IsTrue(ex.Errors[1].IsInformation);

            Assert.AreEqual(2, ex.Errors[2].Severity);
            Assert.IsFalse(ex.Errors[2].IsError);
            Assert.IsTrue(ex.Errors[2].IsInformation);
        }
예제 #5
0
        public void Login()
        {
            //socket is established already
            //login
            SendPacket(
                new LoginPacket(
                    _parameters.ClientHostName,
                    _parameters.Username,
                    _parameters.Password,
                    _parameters.ProcessId,
                    _parameters.ApplicationName,
                    _parameters.Server,
                    "us_english",
                    _parameters.Charset,
                    "ADO.NET",
                    _environment.PacketSize,
                    new ClientCapabilityToken(_parameters.EnableServerPacketSize),
                    _parameters.EncryptPassword));

            var ackHandler            = new LoginTokenHandler();
            var envChangeTokenHandler = new EnvChangeTokenHandler(_environment, _parameters.Charset);
            var messageHandler        = new MessageTokenHandler(EventNotifier);

            ReceiveTokens(
                ackHandler,
                envChangeTokenHandler,
                messageHandler);

            messageHandler.AssertNoErrors();

            if (!ackHandler.ReceivedAck)
            {
                IsDoomed = true;
                throw new InvalidOperationException("No login ack found");
            }

            if (ackHandler.LoginStatus == LoginAckToken.LoginStatus.TDS_LOG_NEGOTIATE)
            {
                NegotiatePassword(ackHandler.Message.MessageId, ackHandler.Parameters.Parameters, _parameters.Password);
            }
            else if (ackHandler.LoginStatus != LoginAckToken.LoginStatus.TDS_LOG_SUCCEED)
            {
                throw new AseException("Login failed.\n", 4002); //just in case the server doesn't respond with an appropriate EED token
            }

            ServerVersion = ackHandler.Token.ProgramVersion;

            Created = DateTime.UtcNow;
            SetState(InternalConnectionState.Ready);
        }
예제 #6
0
        public void SetAnsiNull(bool enabled)
        {
            SendPacket(new NormalPacket(OptionCommandToken.CreateSetAnsiNull(enabled)));

            var envChangeTokenHandler = new EnvChangeTokenHandler(_environment, _parameters.Charset);
            var messageHandler        = new MessageTokenHandler(EventNotifier);
            var doneHandler           = new DoneTokenHandler();

            ReceiveTokens(
                envChangeTokenHandler,
                messageHandler,
                doneHandler);

            messageHandler.AssertNoErrors();
        }
        private void InternalExecuteQueryAsync(AseCommand command, AseTransaction transaction, TaskCompletionSource <DbDataReader> readerSource, CommandBehavior behavior)
        {
            AssertExecutionStart();

            try
            {
                SendPacket(new NormalPacket(BuildCommandTokens(command, behavior)));

                var envChangeTokenHandler         = new EnvChangeTokenHandler(_environment, _parameters.Charset);
                var doneHandler                   = new DoneTokenHandler();
                var messageHandler                = new MessageTokenHandler(EventNotifier);
                var dataReaderHandler             = new DataReaderTokenHandler();
                var responseParameterTokenHandler = new ResponseParameterTokenHandler(command.AseParameters);

                ReceiveTokens(
                    envChangeTokenHandler,
                    doneHandler,
                    messageHandler,
                    dataReaderHandler,
                    responseParameterTokenHandler);

                AssertExecutionCompletion(doneHandler);

                if (transaction != null && doneHandler.TransactionState == TranState.TDS_TRAN_ABORT)
                {
                    transaction.MarkAborted();
                }

                messageHandler.AssertNoErrors();

                if (doneHandler.Canceled)
                {
                    readerSource.TrySetCanceled(); // If we have already begun returning data, then this will get lost.
                }
                else
                {
#if ENABLE_SYSTEM_DATA_COMMON_EXTENSIONS
                    readerSource.TrySetResult(new AseDataReader(dataReaderHandler.Results(), command, behavior));
#else
                    readerSource.TrySetResult(new AseDataReader(dataReaderHandler.Results(), behavior));
#endif
                }
            }
            catch (Exception ex)
            {
                readerSource.TrySetException(ex); // If we have already begun returning data, then this will get lost.
            }
        }
예제 #8
0
        public void GetTextSize()
        {
            SendPacket(new NormalPacket(OptionCommandToken.CreateGet(OptionCommandToken.OptionType.TDS_OPT_TEXTSIZE)));

            var doneHandler       = new DoneTokenHandler();
            var messageHandler    = new MessageTokenHandler();
            var dataReaderHandler = new DataReaderTokenHandler();

            ReceiveTokens(
                new EnvChangeTokenHandler(_environment),
                messageHandler,
                dataReaderHandler,
                doneHandler);

            messageHandler.AssertNoErrors();
        }
예제 #9
0
        private void InternalExecuteNonQueryAsync(AseCommand command, AseTransaction transaction, TaskCompletionSource <int> rowsAffectedSource)
        {
            AssertExecutionStart();

            try
            {
                SendPacket(new NormalPacket(BuildCommandTokens(command, CommandBehavior.Default)));

                var envChangeTokenHandler         = new EnvChangeTokenHandler(_environment, _parameters.Charset);
                var messageHandler                = new MessageTokenHandler(EventNotifier);
                var responseParameterTokenHandler = new ResponseParameterTokenHandler(command.AseParameters);
                var doneHandler = new DoneTokenHandler();

                ReceiveTokens(
                    envChangeTokenHandler,
                    messageHandler,
                    responseParameterTokenHandler,
                    doneHandler);

                AssertExecutionCompletion(doneHandler);

                if (transaction != null && doneHandler.TransactionState == TranState.TDS_TRAN_ABORT)
                {
                    transaction.MarkAborted();
                }

                messageHandler.AssertNoErrors();

                if (doneHandler.Canceled)
                {
                    rowsAffectedSource.TrySetCanceled();
                }
                else
                {
                    rowsAffectedSource.TrySetResult(doneHandler.RowsAffected);
                }
            }
            catch (Exception ex)
            {
                if (!rowsAffectedSource.TrySetException(ex))
                {
                    throw;
                }
            }
        }
예제 #10
0
        private void InternalExecuteAsync(AseCommand command, AseTransaction transaction, TaskCompletionSource <int> rowsAffectedSource = null, TaskCompletionSource <DbDataReader> readerSource = null, CommandBehavior behavior = CommandBehavior.Default)
        {
            AssertExecutionStart();

            try
            {
                SendPacket(new NormalPacket(BuildCommandTokens(command, behavior)));

                var doneHandler       = new DoneTokenHandler();
                var messageHandler    = new MessageTokenHandler(EventNotifier);
                var dataReaderHandler = readerSource != null ? new DataReaderTokenHandler() : null;

                ReceiveTokens(
                    new EnvChangeTokenHandler(_environment),
                    messageHandler,
                    dataReaderHandler,
                    new ResponseParameterTokenHandler(command.AseParameters),
                    doneHandler);

                AssertExecutionCompletion(doneHandler);

                if (transaction != null && doneHandler.TransactionState == TranState.TDS_TRAN_ABORT)
                {
                    transaction.MarkAborted();
                }

                messageHandler.AssertNoErrors();

                if (doneHandler.Canceled)
                {
                    rowsAffectedSource?.SetCanceled();
                    readerSource?.SetCanceled();
                }
                else
                {
                    rowsAffectedSource?.SetResult(doneHandler.RowsAffected);
                    readerSource?.SetResult(new AseDataReader(dataReaderHandler.Results(), command, behavior));
                }
            }
            catch (Exception ex)
            {
                rowsAffectedSource?.SetException(ex);
                readerSource?.SetException(ex);
            }
        }
예제 #11
0
        public void Login()
        {
            //socket is established already
            //login
            SendPacket(new LoginPacket(
                           _parameters.ClientHostName,
                           _parameters.Username,
                           _parameters.Password,
                           _parameters.ProcessId,
                           _parameters.ApplicationName,
                           _parameters.Server,
                           "us_english",
                           _parameters.Charset,
                           "ADO.NET",
                           _environment.PacketSize,
                           new CapabilityToken()));

            var ackHandler     = new LoginTokenHandler();
            var messageHandler = new MessageTokenHandler();

            ReceiveTokens(
                ackHandler,
                new EnvChangeTokenHandler(_environment),
                messageHandler);

            messageHandler.AssertNoErrors();

            if (!ackHandler.ReceivedAck)
            {
                IsDoomed = true;
                throw new InvalidOperationException("No login ack found");
            }

            ServerVersion = ackHandler.Token.ProgramVersion;

            Created = DateTime.UtcNow;
            SetState(InternalConnectionState.Ready);
        }
예제 #12
0
        public bool Ping()
        {
            try
            {
                AssertExecutionStart();
                SendPacket(new NormalPacket(OptionCommandToken.CreateGet(OptionCommandToken.OptionType.TDS_OPT_STAT_TIME)));

                var messageHandler = new MessageTokenHandler();

                ReceiveTokens(messageHandler);

                AssertExecutionCompletion();
                messageHandler.AssertNoErrors();

                return(true);
            }
            catch (Exception ex)
            {
                Logger.Instance?.WriteLine($"Internal ping resulted in exception: {ex}");
                IsDoomed = true;
                return(false);
            }
        }
예제 #13
0
        private void DoEncrypt3Scheme(ParametersToken.Parameter[] parameters, string password)
        {
            var encryptedPassword = Encryption.EncryptPassword3((int)parameters[0].Value, (byte[])parameters[1].Value, (byte[])parameters[2].Value, Encoding.ASCII.GetBytes(password));

            SendPacket(new NormalPacket(Encryption.BuildEncrypt3Tokens(encryptedPassword)));

            // 5. Expect an ack
            var ackHandler            = new LoginTokenHandler();
            var envChangeTokenHandler = new EnvChangeTokenHandler(_environment, _parameters.Charset);
            var messageHandler        = new MessageTokenHandler(EventNotifier);

            ReceiveTokens(
                ackHandler,
                envChangeTokenHandler,
                messageHandler);

            messageHandler.AssertNoErrors();

            if (ackHandler.LoginStatus != LoginAckToken.LoginStatus.TDS_LOG_SUCCEED)
            {
                throw new AseException("Login failed.\n", 4002); //just in case the server doesn't respond with an appropriate EED token
            }
        }
예제 #14
0
        private void InternalExecuteQueryAsync(AseCommand command, AseTransaction transaction, TaskCompletionSource <DbDataReader> readerSource, CommandBehavior behavior,
                                               ReaderSourceType readerSourceType = ReaderSourceType.Standard)
        {
            AssertExecutionStart();

            try
            {
                SendPacket(new NormalPacket(BuildCommandTokens(command, behavior)));

                var envChangeTokenHandler = new EnvChangeTokenHandler(_environment, _parameters.Charset);
                var doneHandler           = new DoneTokenHandler();
                var messageHandler        = new MessageTokenHandler(EventNotifier);
                // Only one of these two data readers will not be null
                var dataReaderHandler             = readerSourceType == ReaderSourceType.Standard ? new DataReaderTokenHandler() : null;
                var dataReaderEventHandler        = readerSourceType == ReaderSourceType.ForCallback ? new DataReaderCallbackTokenHandler(behavior, EventNotifier) : null;
                var responseParameterTokenHandler = new ResponseParameterTokenHandler(command.AseParameters);

                if (readerSourceType == ReaderSourceType.ForCallback)
                {
                    ReceivePartialTokens(
                        envChangeTokenHandler,
                        doneHandler,
                        messageHandler,
                        dataReaderEventHandler,
                        responseParameterTokenHandler);
                }
                else
                {
                    ReceiveTokens(
                        envChangeTokenHandler,
                        doneHandler,
                        messageHandler,
                        dataReaderHandler,
                        responseParameterTokenHandler);
                }

                AssertExecutionCompletion(doneHandler);

                if (transaction != null && doneHandler.TransactionState == TranState.TDS_TRAN_ABORT)
                {
                    transaction.MarkAborted();
                }

                messageHandler.AssertNoErrors();

                if (doneHandler.Canceled)
                {
                    readerSource.TrySetCanceled(); // If we have already begun returning data, then this will get lost.
                }
                else
                {
                    if (dataReaderHandler != null)
#if ENABLE_SYSTEM_DATA_COMMON_EXTENSIONS
                    { readerSource.TrySetResult(new AseDataReader(dataReaderHandler.Results(), command, behavior)); }
#else
                    { readerSource.TrySetResult(new AseDataReader(dataReaderHandler.Results(), behavior)); }
#endif
                    else if (dataReaderEventHandler != null)
                    {
                        // Set this so that Task.Wait will stop waiting
                        readerSource.SetResult(null);
                    }
                }