示例#1
0
        private async Task WriteExecFinishAndProcess <TState, TResult>(
            TState initialState,
            Func <TState, TResult> resultFactory,
            Action <TResult, ReadBuffer, int, int> columnBinder)
        {
            await WriteExecFinish();

            await _readBuffer.ReceiveAsync();

read:

            var message = _readBuffer.ReadMessage();

            switch (message.Type)
            {
            case MessageType.BindComplete:
                goto read;

            case MessageType.DataRow:
            {
                var result
                    = resultFactory != null
                            ? resultFactory(initialState)
                            : default;

                var columns = _readBuffer.ReadShort();

                for (var i = 0; i < columns; i++)
                {
                    var length = _readBuffer.ReadInt();

                    columnBinder(result, _readBuffer, i, length);
                }

                goto read;
            }

            case MessageType.CommandComplete:
                return;

            case MessageType.ErrorResponse:
                throw new InvalidOperationException(_readBuffer.ReadErrorMessage());

            default:
                throw new NotImplementedException(message.Type.ToString());
            }
        }
示例#2
0
        private async Task StartSessionAsync(int millisecondsTimeout)
        {
            await OpenSocketAsync(millisecondsTimeout);

            _writeBuffer = new WriteBuffer(_awaitableSocket);
            _readBuffer  = new ReadBuffer(_awaitableSocket);

            await WriteStartupAsync();

            await _readBuffer.ReceiveAsync();

read:

            var message = _readBuffer.ReadMessage();

            switch (message.Type)
            {
            case MessageType.AuthenticationRequest:
            {
                var authenticationRequestType
                    = (AuthenticationRequestType)_readBuffer.ReadInt();

                switch (authenticationRequestType)
                {
                case AuthenticationRequestType.AuthenticationOk:
                {
                    return;
                }

                case AuthenticationRequestType.AuthenticationMD5Password:
                {
                    var salt = _readBuffer.ReadBytes(4);
                    var hash = Hashing.CreateMD5(_password, _user, salt);

                    await _writeBuffer
                    .StartMessage('p')
                    .WriteBytes(hash)
                    .EndMessage()
                    .FlushAsync();

                    await _readBuffer.ReceiveAsync();

                    goto read;
                }

                default:
                    throw new NotImplementedException(authenticationRequestType.ToString());
                }
            }

            case MessageType.ErrorResponse:
                throw new InvalidOperationException(_readBuffer.ReadErrorMessage());

            case MessageType.BackendKeyData:
            case MessageType.EmptyQueryResponse:
            case MessageType.ParameterStatus:
            case MessageType.ReadyForQuery:
                throw new NotImplementedException($"Unhandled MessageType '{message.Type}'");

            default:
                throw new InvalidOperationException($"Unexpected MessageType '{message.Type}'");
            }
        }
示例#3
0
        public async Task ExecuteAsync <TResult>(
            string statementName,
            Func <TResult> resultFactory,
            Action <TResult, ReadBuffer, int, int> columnBinder)
        {
            ThrowIfDisposed();
            ThrowIfNotConnected();

            await _writeBuffer
            .StartMessage('B')
            .WriteNull()
            .WriteString(statementName)
            .WriteShort(0)
            .WriteShort(0)
            .WriteShort(1)
            .WriteShort(1)
            .EndMessage()
            .StartMessage('E')
            .WriteNull()
            .WriteInt(0)
            .EndMessage()
            .StartMessage('S')
            .EndMessage()
            .FlushAsync();

            await _readBuffer.ReceiveAsync();

read:

            var message = ReadMessage();

            switch (message.Type)
            {
            case MessageType.BindComplete:
                goto read;

            case MessageType.DataRow:
            {
                var result
                    = resultFactory != null
                            ? resultFactory()
                            : default;

                var columns = _readBuffer.ReadShort();

                for (var i = 0; i < columns; i++)
                {
                    var length = _readBuffer.ReadInt();

                    columnBinder(result, _readBuffer, i, length);
                }

                goto read;
            }

            case MessageType.CommandComplete:
                return;

            case MessageType.ErrorResponse:
                throw new InvalidOperationException(ReadErrorMessage());

            default:
                throw new NotImplementedException(message.Type.ToString());
            }
        }