internal override void WriteFully(NpgsqlWriteBuffer buf)
        {
            Debug.Assert(Name != null && Name.All(c => c < 128));

            buf.WriteByte(Code);
            buf.WriteInt32(Length - 1);
            buf.WriteByte((byte)StatementOrPortal);
            buf.WriteNullTerminatedString(Name);
        }
示例#2
0
        internal PgServerMock WriteRowDescription(params FieldDescription[] fields)
        {
            CheckDisposed();

            _writeBuffer.WriteByte((byte)BackendMessageCode.RowDescription);
            _writeBuffer.WriteInt32(4 + 2 + fields.Sum(f => Encoding.GetByteCount(f.Name) + 1 + 18));
            _writeBuffer.WriteInt16(fields.Length);

            foreach (var field in fields)
            {
                _writeBuffer.WriteNullTerminatedString(field.Name);
                _writeBuffer.WriteUInt32(field.TableOID);
                _writeBuffer.WriteInt16(field.ColumnAttributeNumber);
                _writeBuffer.WriteUInt32(field.TypeOID);
                _writeBuffer.WriteInt16(field.TypeSize);
                _writeBuffer.WriteInt32(field.TypeModifier);
                _writeBuffer.WriteInt16((short)field.FormatCode);
            }

            return(this);
        }
示例#3
0
        internal override async Task Write(NpgsqlWriteBuffer buf, bool async)
        {
            Debug.Assert(Statement != null && Statement.All(c => c < 128));

            var queryByteLen = _encoding.GetByteCount(Query);

            if (buf.WriteSpaceLeft < 1 + 4 + Statement.Length + 1)
            {
                await buf.Flush(async);
            }

            var messageLength =
                1 +                         // Message code
                4 +                         // Length
                Statement.Length +
                1 +                         // Null terminator
                queryByteLen +
                1 +                         // Null terminator
                2 +                         // Number of parameters
                ParameterTypeOIDs.Count * 4;

            buf.WriteByte(Code);
            buf.WriteInt32(messageLength - 1);
            buf.WriteNullTerminatedString(Statement);

            await buf.WriteString(Query, queryByteLen, async);

            if (buf.WriteSpaceLeft < 1 + 2)
            {
                await buf.Flush(async);
            }
            buf.WriteByte(0); // Null terminator for the query
            buf.WriteInt16((short)ParameterTypeOIDs.Count);

            foreach (var t in ParameterTypeOIDs)
            {
                if (buf.WriteSpaceLeft < 4)
                {
                    await buf.Flush(async);
                }
                buf.WriteInt32((int)t);
            }
        }
示例#4
0
        internal override async Task Write(NpgsqlWriteBuffer buf, bool async)
        {
            Debug.Assert(Statement != null && Statement.All(c => c < 128));
            Debug.Assert(Portal != null && Portal.All(c => c < 128));

            var headerLength =
                1 +                        // Message code
                4 +                        // Message length
                1 +                        // Portal is always empty (only a null terminator)
                Statement.Length + 1 +
                2;                         // Number of parameter format codes that follow

            if (buf.WriteSpaceLeft < headerLength)
            {
                Debug.Assert(buf.Size >= headerLength, "Buffer too small for Bind header");
                await buf.Flush(async);
            }

            var formatCodesSum = 0;
            var paramsLength   = 0;

            foreach (var p in InputParameters)
            {
                formatCodesSum += (int)p.FormatCode;
                p.LengthCache?.Rewind();
                paramsLength += p.ValidateAndGetLength();
            }

            var formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count;

            var messageLength = headerLength +
                                2 * formatCodeListLength +                // List of format codes
                                2 +                                       // Number of parameters
                                4 * InputParameters.Count +               // Parameter lengths
                                paramsLength +                            // Parameter values
                                2 +                                       // Number of result format codes
                                2 * (UnknownResultTypeList?.Length ?? 1); // Result format codes

            buf.WriteByte(Code);
            buf.WriteInt32(messageLength - 1);
            Debug.Assert(Portal == string.Empty);
            buf.WriteByte(0);  // Portal is always empty

            buf.WriteNullTerminatedString(Statement);
            buf.WriteInt16(formatCodeListLength);

            // 0 length implicitly means all-text, 1 means all-binary, >1 means mix-and-match
            if (formatCodeListLength == 1)
            {
                if (buf.WriteSpaceLeft < 2)
                {
                    await buf.Flush(async);
                }
                buf.WriteInt16((short)FormatCode.Binary);
            }
            else if (formatCodeListLength > 1)
            {
                foreach (var p in InputParameters)
                {
                    if (buf.WriteSpaceLeft < 2)
                    {
                        await buf.Flush(async);
                    }
                    buf.WriteInt16((short)p.FormatCode);
                }
            }

            if (buf.WriteSpaceLeft < 2)
            {
                await buf.Flush(async);
            }

            buf.WriteInt16(InputParameters.Count);

            foreach (var param in InputParameters)
            {
                param.LengthCache?.Rewind();
                await param.WriteWithLength(buf, async);
            }

            if (UnknownResultTypeList != null)
            {
                if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2)
                {
                    await buf.Flush(async);
                }
                buf.WriteInt16(UnknownResultTypeList.Length);
                foreach (var t in UnknownResultTypeList)
                {
                    buf.WriteInt16(t ? 0 : 1);
                }
            }
            else
            {
                if (buf.WriteSpaceLeft < 4)
                {
                    await buf.Flush(async);
                }
                buf.WriteInt16(1);
                buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1);
            }
        }