Пример #1
0
        protected internal override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
        {
            if (value == null || value is DBNull)
            {
                return(base.WriteObjectWithLength(value, buf, lengthCache, parameter, async));
            }

            var convertedValue = value is string asString
                ? asString
                : (string)parameter.ConvertedValue;

            if (buf.WriteSpaceLeft < 4)
            {
                return(WriteWithLengthLong());
            }

            buf.WriteInt32(ValidateObjectAndGetLength(value, ref lengthCache, parameter));
            return(base.Write(convertedValue, buf, lengthCache, parameter, async));

            async Task WriteWithLengthLong()
            {
                await buf.Flush(async);

                buf.WriteInt32(ValidateObjectAndGetLength(value, ref lengthCache, parameter));
                await base.Write(convertedValue, buf, lengthCache, parameter, async);
            }
        }
Пример #2
0
        /// <summary>
        /// In the vast majority of cases writing a parameter to the buffer won't need to perform I/O.
        /// </summary>
        public override Task WriteWithLengthInternal <TAny>([AllowNull] TAny value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
        {
            if (buf.WriteSpaceLeft < 4)
            {
                return(WriteWithLengthLong());
            }

            if (value == null || typeof(TAny) == typeof(DBNull))
            {
                buf.WriteInt32(-1);
                return(Task.CompletedTask);
            }

            return(WriteWithLength(value, buf, lengthCache, parameter, async, cancellationToken));

            async Task WriteWithLengthLong()
            {
                if (buf.WriteSpaceLeft < 4)
                {
                    await buf.Flush(async, cancellationToken);
                }

                if (value == null || typeof(TAny) == typeof(DBNull))
                {
                    buf.WriteInt32(-1);
                    return;
                }

                await WriteWithLength(value, buf, lengthCache, parameter, async, cancellationToken);
            }
        }
Пример #3
0
        public async Task Write(MultiLineString value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
        {
            var type = EwkbGeometryType.MultiLineString;
            var size = SizeOfHeader;
            var srid = GetSrid(value.CRS);

            if (srid != 0)
            {
                size += sizeof(int);
                type |= EwkbGeometryType.HasSrid;
            }

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

            var coordinates = value.Coordinates;

            buf.WriteByte(0); // Most significant byte first
            buf.WriteInt32((int)type);
            buf.WriteInt32(coordinates.Count);

            if (srid != 0)
            {
                buf.WriteInt32(srid);
            }

            for (var i = 0; i < coordinates.Count; ++i)
            {
                await Write(coordinates[i], buf, lengthCache, parameter, async);
            }
        }
Пример #4
0
        public void Write(DateTime value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
        {
            if (_integerFormat)
            {
                buf.WriteInt64(value.TimeOfDay.Ticks / 10);
            }
            else
            {
                buf.WriteDouble((double)value.TimeOfDay.Ticks / TimeSpan.TicksPerSecond);
            }

            switch (value.Kind)
            {
            case DateTimeKind.Utc:
                buf.WriteInt32(0);
                break;

            case DateTimeKind.Unspecified:
            // Treat as local...
            case DateTimeKind.Local:
                buf.WriteInt32(-(int)(TimeZoneInfo.Local.BaseUtcOffset.Ticks / TimeSpan.TicksPerSecond));
                break;

            default:
                throw new InvalidOperationException($"Internal Npgsql bug: unexpected value {value.Kind} of enum {nameof(DateTimeKind)}. Please file a bug.");
            }
        }
Пример #5
0
        public async Task Write(GeometryCollection value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
        {
            var type = EwkbGeometryType.GeometryCollection;
            var size = SizeOfHeader;
            var srid = GetSrid(value.CRS);

            if (srid != 0)
            {
                size += sizeof(int);
                type |= EwkbGeometryType.HasSrid;
            }

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

            var geometries = value.Geometries;

            buf.WriteByte(0); // Most significant byte first
            buf.WriteInt32((int)type);
            buf.WriteInt32(geometries.Count);

            if (srid != 0)
            {
                buf.WriteInt32(srid);
            }

            for (var i = 0; i < geometries.Count; ++i)
            {
                await Write((GeoJSONObject)geometries[i], buf, lengthCache, parameter, async);
            }
        }
Пример #6
0
        public async Task Write(Point value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
        {
            var type = EwkbGeometryType.Point;
            var size = SizeOfHeader;
            var srid = GetSrid(value.CRS);

            if (srid != 0)
            {
                size += sizeof(int);
                type |= EwkbGeometryType.HasSrid;
            }

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

            buf.WriteByte(0); // Most significant byte first
            buf.WriteInt32((int)type);

            if (srid != 0)
            {
                buf.WriteInt32(srid);
            }

            await WritePosition(value.Coordinates, buf, async);
        }
Пример #7
0
    /// <inheritdoc />
    public override void Write(TimeSpan value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter)
    {
        var ticksInDay = value.Ticks - TimeSpan.TicksPerDay * value.Days;

        buf.WriteInt64(ticksInDay / 10);
        buf.WriteInt32(value.Days);
        buf.WriteInt32(0);
    }
Пример #8
0
        internal override void WriteFully(NpgsqlWriteBuffer buf)
        {
            Debug.Assert(BackendProcessId != 0);

            buf.WriteInt32(Length);
            buf.WriteInt32(CancelRequestCode);
            buf.WriteInt32(BackendProcessId);
            buf.WriteInt32(BackendSecretKey);
        }
Пример #9
0
        public override void Write(Period value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter)
        {
            var microsecondsInDay =
                (((value.Hours * NodaConstants.MinutesPerHour + value.Minutes) * NodaConstants.SecondsPerMinute + value.Seconds) * NodaConstants.MillisecondsPerSecond + value.Milliseconds) * 1000 +
                value.Nanoseconds / 1000; // Take the microseconds, discard the nanosecond remainder

            buf.WriteInt64(microsecondsInDay);
            buf.WriteInt32(value.Weeks * 7 + value.Days);    // days
            buf.WriteInt32(value.Years * 12 + value.Months); // months
        }
Пример #10
0
        internal override void WriteFully(NpgsqlWriteBuffer buf)
        {
            Debug.Assert(Portal != null && Portal.All(c => c < 128));

            buf.WriteByte(Code);
            buf.WriteInt32(Length - 1);
            Debug.Assert(Portal == string.Empty);
            buf.WriteByte(0);   // Portal is always an empty string
            buf.WriteInt32(MaxRows);
        }
Пример #11
0
        public void Write(Duration value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter)
        {
            const int microsecondsPerSecond = 1_000_000;

            var microsecondsInDay =
                (((value.Hours * NodaConstants.MinutesPerHour + value.Minutes) * NodaConstants.SecondsPerMinute + value.Seconds) *
                 microsecondsPerSecond + value.SubsecondNanoseconds / 1000);    // Take the microseconds, discard the nanosecond remainder

            buf.WriteInt64(microsecondsInDay);
            buf.WriteInt32(value.Days); // days
            buf.WriteInt32(0);          // months
        }
Пример #12
0
        public override void Write(NpgsqlTimeSpan value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
        {
            if (_integerFormat)
            {
                buf.WriteInt64(value.Ticks / 10); // TODO: round?
            }
            else
            {
                buf.WriteDouble(value.TotalSeconds - (value.Days * 86400) - (value.Months * NpgsqlTimeSpan.DaysPerMonth * 86400));
            }

            buf.WriteInt32(value.Days);
            buf.WriteInt32(value.Months);
        }
Пример #13
0
 public override void Write(NpgsqlDate value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
 {
     if (value == NpgsqlDate.NegativeInfinity)
     {
         buf.WriteInt32(int.MinValue);
     }
     else if (value == NpgsqlDate.Infinity)
     {
         buf.WriteInt32(int.MaxValue);
     }
     else
     {
         buf.WriteInt32(value.DaysSinceEra - 730119);
     }
 }
Пример #14
0
        public override async Task Write(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
        {
            Debug.Assert(_resolvedType != null);
            Debug.Assert(_members != null);

            if (buf.WriteSpaceLeft < 4)
            {
                await buf.Flush(async);
            }
            buf.WriteInt32(_members.Count);

            foreach (var fieldDescriptor in _members)
            {
                var fieldHandler = fieldDescriptor.Handler;
                var fieldValue   = fieldDescriptor.Getter(value);

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

                buf.WriteUInt32(fieldDescriptor.OID);
                await fieldHandler.WriteObjectWithLength(fieldValue, buf, lengthCache, null, async);
            }
        }
Пример #15
0
        /// <inheritdoc />
        public override async Task Write(BitArray value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
        {
            // Initial bitlength byte
            if (buf.WriteSpaceLeft < 4)
            {
                await buf.Flush(async, cancellationToken);
            }
            buf.WriteInt32(value.Length);

            var byteLen = (value.Length + 7) / 8;
            var pos     = 0;

            while (true)
            {
                var endPos = pos + Math.Min(byteLen - pos, buf.WriteSpaceLeft);
                for (; pos < endPos; pos++)
                {
                    var bitPos = pos * 8;
                    var b      = 0;
                    for (var i = 0; i < Math.Min(8, value.Length - bitPos); i++)
                    {
                        b += (value[bitPos + i] ? 1 : 0) << (8 - i - 1);
                    }
                    buf.WriteByte((byte)b);
                }

                if (pos == byteLen)
                {
                    return;
                }
                await buf.Flush(async, cancellationToken);
            }
        }
Пример #16
0
        /// <inheritdoc />
        public async Task Write(BitVector32 value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
        {
            if (buf.WriteSpaceLeft < 8)
            {
                await buf.Flush(async, cancellationToken);
            }

            if (value.Data == 0)
            {
                buf.WriteInt32(0);
            }
            else
            {
                buf.WriteInt32(32);
                buf.WriteInt32(value.Data);
            }
        }
Пример #17
0
 internal override void WriteFully(NpgsqlWriteBuffer buf)
 {
     buf.WriteByte(Code);
     buf.WriteInt32(Length - 1);
     // Error message not supported for now
     Debug.Assert(_errorMessage == null);
     buf.WriteByte(0);
 }
Пример #18
0
    public override void Write(LocalDate value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter)
    {
        if (!DisableDateTimeInfinityConversions)
        {
            if (value == LocalDate.MaxIsoValue)
            {
                buf.WriteInt32(int.MaxValue);
                return;
            }
            if (value == LocalDate.MinIsoValue)
            {
                buf.WriteInt32(int.MinValue);
                return;
            }
        }

        var totalDaysSinceEra = Period.Between(default, value, PeriodUnits.Days).Days;
Пример #19
0
        public async Task Write(BitVector32 value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
        {
            if (buf.WriteSpaceLeft < 8)
            {
                await buf.Flush(async);
            }

            if (value.Data == 0)
            {
                buf.WriteInt32(0);
            }
            else
            {
                buf.WriteInt32(32);
                buf.WriteInt32(value.Data);
            }
        }
Пример #20
0
        internal override void WriteFully(NpgsqlWriteBuffer buf)
        {
            buf.WriteByte(Code);
            buf.WriteInt32(Length - 1);

            buf.WriteString(_mechanism);
            buf.WriteByte(0);   // null terminator
            if (_initialResponse == null)
            {
                buf.WriteInt32(-1);
            }
            else
            {
                buf.WriteInt32(_initialResponse.Length);
                buf.WriteBytes(_initialResponse);
            }
        }
        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);
        }
Пример #22
0
        /// <summary>
        /// Typically does not need to be overridden by type handlers, but may be needed in some
        /// cases (e.g. <see cref="ArrayHandler"/>.
        /// Note that this method assumes it can write 4 bytes of length (already verified by
        /// <see cref="WriteWithLengthInternal{TAny}"/>).
        /// </summary>
        protected virtual Task WriteWithLength <TAny>(TAny value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
        {
            Debug.Assert(this is INpgsqlTypeHandler <TAny>);

            var typedHandler = (INpgsqlTypeHandler <TAny>) this;

            buf.WriteInt32(typedHandler.ValidateAndGetLength(value, ref lengthCache, parameter));
            return(typedHandler.Write(value, buf, lengthCache, parameter, async, cancellationToken));
        }
Пример #23
0
 public async Task Write(bool value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
 {
     if (buf.WriteSpaceLeft < 5)
     {
         await buf.Flush(async);
     }
     buf.WriteInt32(1);
     buf.WriteByte(value ? (byte)0x80 : (byte)0);
 }
Пример #24
0
 protected internal override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
 {
     if (value == null || value is DBNull)
     {
         return(WriteWithLengthInternal <DBNull>(null, buf, lengthCache, parameter, async));
     }
     buf.WriteInt32(ValidateAndGetLength(value, ref lengthCache, parameter));
     return(Write(value, buf, lengthCache, parameter, async));
 }
Пример #25
0
        /// <inheritdoc />
        public override void Write(Guid value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter)
        {
            var raw = new GuidRaw(value);

            buf.WriteInt32(raw.Data1);
            buf.WriteInt16(raw.Data2);
            buf.WriteInt16(raw.Data3);
            buf.WriteInt64(raw.Data4, BitConverter.IsLittleEndian);
        }
Пример #26
0
 /// <inheritdoc />
 public async Task Write(bool value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
 {
     if (buf.WriteSpaceLeft < 5)
     {
         await buf.Flush(async, cancellationToken);
     }
     buf.WriteInt32(1);
     buf.WriteByte(value ? (byte)0x80 : (byte)0);
 }
Пример #27
0
        public override Task WriteWithLengthInternal <TAny>([AllowNull] TAny value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
        {
            if (buf.WriteSpaceLeft < 4)
            {
                return(WriteWithLengthLong());
            }

            if (value == null || typeof(TAny) == typeof(DBNull))
            {
                buf.WriteInt32(-1);
                return(Task.CompletedTask);
            }

            return(WriteWithLengthCore());

            async Task WriteWithLengthLong()
            {
                if (buf.WriteSpaceLeft < 4)
                {
                    await buf.Flush(async, cancellationToken);
                }

                if (value == null || typeof(TAny) == typeof(DBNull))
                {
                    buf.WriteInt32(-1);
                    return;
                }

                await WriteWithLengthCore();
            }

            Task WriteWithLengthCore()
            {
                if (this is INpgsqlTypeHandler <TAny> typedHandler)
                {
                    buf.WriteInt32(typedHandler.ValidateAndGetLength(value, ref lengthCache, parameter));
                    return(typedHandler.Write(value, buf, lengthCache, parameter, async, cancellationToken));
                }
                else
                {
                    throw new InvalidCastException($"Can't write CLR type {typeof(TAny)} to database type {PgDisplayName}");
                }
            }
        }
        public override async Task Write(NpgsqlTsQuery query, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
        {
            var numTokens = GetTokenCount(query);

            if (buf.WriteSpaceLeft < 4)
            {
                await buf.Flush(async);
            }
            buf.WriteInt32(numTokens);

            if (numTokens == 0)
            {
                return;
            }

            _stack.Push(query);

            while (_stack.Count > 0)
            {
                if (buf.WriteSpaceLeft < 2)
                {
                    await buf.Flush(async);
                }

                if (_stack.Peek().Kind == NpgsqlTsQuery.NodeKind.Lexeme && buf.WriteSpaceLeft < MaxSingleTokenBytes)
                {
                    await buf.Flush(async);
                }

                var node = _stack.Pop();
                buf.WriteByte(node.Kind == NpgsqlTsQuery.NodeKind.Lexeme ? (byte)1 : (byte)2);
                if (node.Kind != NpgsqlTsQuery.NodeKind.Lexeme)
                {
                    buf.WriteByte((byte)node.Kind);
                    if (node.Kind == NpgsqlTsQuery.NodeKind.Not)
                    {
                        _stack.Push(((NpgsqlTsQueryNot)node).Child);
                    }
                    else
                    {
                        _stack.Push(((NpgsqlTsQueryBinOp)node).Right);
                        _stack.Push(((NpgsqlTsQueryBinOp)node).Left);
                    }
                }
                else
                {
                    var lexemeNode = (NpgsqlTsQueryLexeme)node;
                    buf.WriteByte((byte)lexemeNode.Weights);
                    buf.WriteByte(lexemeNode.IsPrefixSearch ? (byte)1 : (byte)0);
                    buf.WriteString(lexemeNode.Text);
                    buf.WriteByte(0);
                }
            }

            _stack.Clear();
        }
Пример #29
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);
            }
        }
Пример #30
0
        public override void Write(Guid value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter)
        {
            // TODO: Allocation... investigate alternatives?
            var bytes = value.ToByteArray();

            buf.WriteInt32(BitConverter.ToInt32(bytes, 0));
            buf.WriteInt16(BitConverter.ToInt16(bytes, 4));
            buf.WriteInt16(BitConverter.ToInt16(bytes, 6));
            buf.WriteBytes(bytes, 8, 8);
        }