示例#1
0
        public NpgsqlDate AddYears(int years)
        {
            switch (_type)
            {
            case InternalType.Infinity:
                return(Infinity);

            case InternalType.NegativeInfinity:
                return(NegativeInfinity);

            case InternalType.Finite:
                break;

            default:
                throw PGUtil.ThrowIfReached();
            }

            int newYear = Year + years;

            if (newYear >= 0 && _daysSinceEra < 0) //cross 1CE/1BCE divide going up
            {
                ++newYear;
            }
            else if (newYear <= 0 && _daysSinceEra >= 0) //cross 1CE/1BCE divide going down
            {
                --newYear;
            }
            return(new NpgsqlDate(newYear, Month, Day));
        }
示例#2
0
        public void PrepareWrite(object value, NpgsqlBuffer buf, LengthCache lengthCache, NpgsqlParameter parameter = null)
        {
            _buf     = buf;
            _charPos = -1;
            _byteLen = lengthCache.GetLast();

            _str = value as string;
            if (_str != null)
            {
                _charLen = parameter == null || parameter.Size <= 0 || parameter.Size >= _str.Length ? _str.Length : parameter.Size;
                return;
            }

            _chars = value as char[];
            if (_chars != null)
            {
                _charLen = parameter == null || parameter.Size <= 0 || parameter.Size >= _chars.Length ? _chars.Length : parameter.Size;
                return;
            }

            if (value is char)
            {
                _singleCharArray[0] = (char)value;
                _chars   = _singleCharArray;
                _charLen = 1;
                return;
            }

            throw PGUtil.ThrowIfReached();
        }
示例#3
0
        public NpgsqlDate AddMonths(int months)
        {
            switch (_type)
            {
            case InternalType.Infinity:
                return(Infinity);

            case InternalType.NegativeInfinity:
                return(NegativeInfinity);

            case InternalType.Finite:
                break;

            default:
                throw PGUtil.ThrowIfReached();
            }

            int newYear  = Year;
            int newMonth = Month + months;

            while (newMonth > 12)
            {
                newMonth -= 12;
                newYear  += 1;
            }
            while (newMonth < 1)
            {
                newMonth += 12;
                newYear  -= 1;
            }
            var maxDay = (IsLeap(newYear) ? LeapYearMaxes : CommonYearMaxes)[newMonth - 1];
            var newDay = Day > maxDay ? maxDay : Day;

            return(new NpgsqlDate(newYear, newMonth, newDay));
        }
示例#4
0
        bool ReadSingleElement <TElement>(out TElement element)
        {
            try
            {
                if (_elementLen == -1)
                {
                    if (_buf.ReadBytesLeft < 4)
                    {
                        element = default(TElement);
                        return(false);
                    }
                    _elementLen = _buf.ReadInt32();
                    if (_elementLen == -1)
                    {
                        // TODO: Nullables
                        element = default(TElement);
                        return(true);
                    }
                }

                var asSimpleReader = ElementHandler as ISimpleTypeReader <TElement>;
                if (asSimpleReader != null)
                {
                    if (_buf.ReadBytesLeft < _elementLen)
                    {
                        element = default(TElement);
                        return(false);
                    }
                    element     = asSimpleReader.Read(_buf, _elementLen, _fieldDescription);
                    _elementLen = -1;
                    return(true);
                }

                var asChunkingReader = ElementHandler as IChunkingTypeReader <TElement>;
                if (asChunkingReader != null)
                {
                    if (!_preparedRead)
                    {
                        asChunkingReader.PrepareRead(_buf, _elementLen, _fieldDescription);
                        _preparedRead = true;
                    }
                    if (!asChunkingReader.Read(out element))
                    {
                        return(false);
                    }
                    _elementLen   = -1;
                    _preparedRead = false;
                    return(true);
                }

                throw PGUtil.ThrowIfReached();
            }
            catch (SafeReadException e)
            {
                // TODO: Implement safe reading for array: read all values to the end, only then raise the
                // SafeReadException. For now, translate the safe exception to an unsafe one to break the connector.
                throw e.InnerException;
            }
        }
示例#5
0
        public override bool Write(ref DirectBuffer directBuf)
        {
            if (_fieldIndex == -1)
            {
                if (_writeBuf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                _writeBuf.WriteInt32(_members.Count);
                _fieldIndex = 0;
            }

            for (; _fieldIndex < _members.Count; _fieldIndex++)
            {
                var fieldDescriptor = _members[_fieldIndex];
                var fieldHandler    = fieldDescriptor.Handler;
                var fieldValue      = fieldDescriptor.GetValue(_value);

                var asSimpleWriter = fieldHandler as ISimpleTypeHandler;
                if (asSimpleWriter != null)
                {
                    var elementLen = asSimpleWriter.ValidateAndGetLength(fieldValue, null);
                    if (_writeBuf.WriteSpaceLeft < 8 + elementLen)
                    {
                        return(false);
                    }
                    _writeBuf.WriteUInt32(fieldHandler.BackendType.OID);
                    _writeBuf.WriteInt32(elementLen);
                    asSimpleWriter.Write(fieldValue, _writeBuf, null);
                    continue;
                }

                var asChunkedWriter = fieldHandler as IChunkingTypeHandler;
                if (asChunkedWriter != null)
                {
                    if (!_wroteFieldHeader)
                    {
                        if (_writeBuf.WriteSpaceLeft < 8)
                        {
                            return(false);
                        }
                        _writeBuf.WriteUInt32(fieldHandler.BackendType.OID);
                        _writeBuf.WriteInt32(asChunkedWriter.ValidateAndGetLength(fieldValue, ref _lengthCache, null));
                        asChunkedWriter.PrepareWrite(fieldValue, _writeBuf, _lengthCache, null);
                        _wroteFieldHeader = true;
                    }
                    if (!asChunkedWriter.Write(ref directBuf))
                    {
                        return(false);
                    }
                    _wroteFieldHeader = false;
                    continue;
                }

                throw PGUtil.ThrowIfReached();
            }

            return(true);
        }
示例#6
0
        public override void Write(object value, NpgsqlBuffer buf, NpgsqlParameter parameter)
        {
            if (parameter != null && parameter.ConvertedValue != null)
            {
                value = parameter.ConvertedValue;
            }

            if (value is NpgsqlDateTime)
            {
                var ts = (NpgsqlDateTime)value;
                switch (ts.Kind)
                {
                case DateTimeKind.Unspecified:
                case DateTimeKind.Utc:
                    break;

                case DateTimeKind.Local:
                    ts = ts.ToUniversalTime();
                    break;

                default:
                    throw PGUtil.ThrowIfReached();
                }
                base.Write(ts, buf, parameter);
                return;
            }

            if (value is DateTime)
            {
                var dt = (DateTime)value;
                switch (dt.Kind)
                {
                case DateTimeKind.Unspecified:
                case DateTimeKind.Utc:
                    break;

                case DateTimeKind.Local:
                    dt = dt.ToUniversalTime();
                    break;

                default:
                    throw PGUtil.ThrowIfReached();
                }
                base.Write(dt, buf, parameter);
                return;
            }

            if (value is DateTimeOffset)
            {
                base.Write(((DateTimeOffset)value).ToUniversalTime(), buf, parameter);
                return;
            }

            throw PGUtil.ThrowIfReached();
        }
示例#7
0
        public virtual void Write(object value, NpgsqlBuffer buf)
        {
            NpgsqlDateTime ts;

            if (value is NpgsqlDateTime)
            {
                ts = (NpgsqlDateTime)value;
                if (!ts.IsFinite)
                {
                    if (ts.IsInfinity)
                    {
                        buf.WriteInt64(Int64.MaxValue);
                        return;
                    }

                    if (ts.IsMinusInfinity)
                    {
                        buf.WriteInt64(Int64.MinValue);
                        return;
                    }

                    throw PGUtil.ThrowIfReached();
                }
            }
            else if (value is DateTime)
            {
                ts = new NpgsqlDateTime((DateTime)value);
            }
            else if (value is DateTimeOffset)
            {
                ts = new NpgsqlDateTime(((DateTimeOffset)value).DateTime);
            }
            else if (value is string)
            {
                // TODO: Decide what to do with this
                throw new InvalidOperationException("String DateTimes are not allowed, use DateTime instead.");
            }
            else
            {
                throw new InvalidCastException();
            }

            var uSecsTime = ts.Time.Ticks / 10;

            if (ts >= new NpgsqlDateTime(2000, 1, 1, 0, 0, 0))
            {
                var uSecsDate = (ts.Date.DaysSinceEra - 730119) * 86400000000L;
                buf.WriteInt64(uSecsDate + uSecsTime);
            }
            else
            {
                var uSecsDate = (730119 - ts.Date.DaysSinceEra) * 86400000000L;
                buf.WriteInt64(-(uSecsDate - uSecsTime));
            }
        }
示例#8
0
        public void Write(object value, NpgsqlBuffer buf, NpgsqlParameter parameter)
        {
            if (parameter != null && parameter.ConvertedValue != null)
            {
                value = parameter.ConvertedValue;
            }

            NpgsqlDate date;

            if (value is NpgsqlDate)
            {
                date = (NpgsqlDate)value;
            }
            else if (value is DateTime)
            {
                var dt = (DateTime)value;
                if (_convertInfinityDateTime)
                {
                    if (dt == DateTime.MaxValue)
                    {
                        date = NpgsqlDate.Infinity;
                    }
                    else if (dt == DateTime.MinValue)
                    {
                        date = NpgsqlDate.NegativeInfinity;
                    }
                    else
                    {
                        date = new NpgsqlDate(dt);
                    }
                }
                else
                {
                    date = new NpgsqlDate(dt);
                }
            }
            else
            {
                throw PGUtil.ThrowIfReached();
            }

            if (date == NpgsqlDate.NegativeInfinity)
            {
                buf.WriteInt32(int.MinValue);
            }
            else if (date == NpgsqlDate.Infinity)
            {
                buf.WriteInt32(int.MaxValue);
            }
            else
            {
                buf.WriteInt32(date.DaysSinceEra - 730119);
            }
        }
示例#9
0
        bool WriteSingleElement(object element, out byte[] directBuf)
        {
            // TODO: Need generic version of this...
            directBuf = null;

            if (element == null || element is DBNull)
            {
                if (_buf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                _buf.WriteInt32(-1);
                return(true);
            }

            var asSimpleWriter = ElementHandler as ISimpleTypeWriter;

            if (asSimpleWriter != null)
            {
                var elementLen = asSimpleWriter.ValidateAndGetLength(element);
                if (_buf.WriteSpaceLeft < 4 + elementLen)
                {
                    return(false);
                }
                _buf.WriteInt32(elementLen);
                asSimpleWriter.Write(element, _buf);
                return(true);
            }

            var asChunkedWriter = ElementHandler as IChunkingTypeWriter;

            if (asChunkedWriter != null)
            {
                if (!_wroteElementLen)
                {
                    if (_buf.WriteSpaceLeft < 4)
                    {
                        return(false);
                    }
                    _buf.WriteInt32(asChunkedWriter.ValidateAndGetLength(element));
                    asChunkedWriter.PrepareWrite(_buf, element);
                    _wroteElementLen = true;
                }
                if (!asChunkedWriter.Write(ref directBuf))
                {
                    return(false);
                }
                _wroteElementLen = false;
                return(true);
            }

            throw PGUtil.ThrowIfReached();
        }
示例#10
0
 internal object GetValue(object container)
 {
     if (_property != null)
     {
         return(_property.GetValue(container));
     }
     if (_field != null)
     {
         return(_field.GetValue(container));
     }
     throw PGUtil.ThrowIfReached();
 }
示例#11
0
        public override void Write(object value, NpgsqlBuffer buf)
        {
            if (value is NpgsqlDateTime)
            {
                var ts = (NpgsqlDateTime)value;
                switch (ts.Kind)
                {
                case DateTimeKind.Unspecified:
                // Treat as Local
                case DateTimeKind.Utc:
                    break;

                case DateTimeKind.Local:
                    ts = ts.ToUniversalTime();
                    break;

                default:
                    throw PGUtil.ThrowIfReached();
                }
                base.Write(ts, buf);
                return;
            }

            if (value is DateTime)
            {
                var dt = (DateTime)value;
                switch (dt.Kind)
                {
                case DateTimeKind.Unspecified:
                // Treat as Local
                case DateTimeKind.Utc:
                    break;

                case DateTimeKind.Local:
                    dt = dt.ToUniversalTime();
                    break;

                default:
                    throw PGUtil.ThrowIfReached();
                }
                base.Write(dt, buf);
                return;
            }

            if (value is DateTimeOffset)
            {
                base.Write(((DateTimeOffset)value).ToUniversalTime(), buf);
                return;
            }

            throw new InvalidCastException();
        }
示例#12
0
        bool ReadSingleElement(out TElement element)
        {
            try {
                if (_elementLen == -1)
                {
                    if (_readBuf.ReadBytesLeft < 4)
                    {
                        element = default(TElement);
                        return(false);
                    }
                    _elementLen = _readBuf.ReadInt32();
                    Contract.Assume(_elementLen != -1);
                }

                var asSimpleReader = ElementHandler as ISimpleTypeHandler <TElement>;
                if (asSimpleReader != null)
                {
                    if (_readBuf.ReadBytesLeft < _elementLen)
                    {
                        element = default(TElement);
                        return(false);
                    }
                    element     = asSimpleReader.Read(_readBuf, _elementLen, _fieldDescription);
                    _elementLen = -1;
                    return(true);
                }

                var asChunkingReader = ElementHandler as IChunkingTypeHandler <TElement>;
                if (asChunkingReader != null)
                {
                    if (!_preparedRead)
                    {
                        asChunkingReader.PrepareRead(_readBuf, _elementLen, _fieldDescription);
                        _preparedRead = true;
                    }
                    if (!asChunkingReader.Read(out element))
                    {
                        return(false);
                    }
                    _elementLen   = -1;
                    _preparedRead = false;
                    return(true);
                }

                throw PGUtil.ThrowIfReached();
            } catch (SafeReadException e) {
                // TODO: Implement safe reading. For now, translate the safe exception to an unsafe one
                // to break the connector.
                throw e.InnerException;
            }
        }
示例#13
0
        public bool Write(ref DirectBuffer directBuf)
        {
            var asChunkingWriter = ElementHandler as IChunkingTypeWriter;

            switch (_state)
            {
            case State.Flags:
                if (_buf.WriteSpaceLeft < 1)
                {
                    return(false);
                }
                _buf.WriteByte((byte)_value.Flags);
                if (_value.IsEmpty)
                {
                    CleanupState();
                    return(true);
                }
                goto case State.LowerBound;

            case State.LowerBound:
                _state = State.LowerBound;
                if (_value.LowerBoundInfinite)
                {
                    goto case State.UpperBound;
                }

                if (!WriteSingleElement(_value.LowerBound, ref directBuf))
                {
                    return(false);
                }
                goto case State.UpperBound;

            case State.UpperBound:
                _state = State.UpperBound;
                if (_value.UpperBoundInfinite)
                {
                    CleanupState();
                    return(true);
                }
                if (!WriteSingleElement(_value.UpperBound, ref directBuf))
                {
                    return(false);
                }
                CleanupState();
                return(true);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
示例#14
0
        // TODO: Duplicated from ArrayHandler... Refactor...
        bool WriteSingleElement([CanBeNull] object element, ref DirectBuffer directBuf)
        {
            if (element == null || element is DBNull)
            {
                if (_writeBuf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                _writeBuf.WriteInt32(-1);
                return(true);
            }

            var asSimpleWriter = ElementHandler as ISimpleTypeHandler;

            if (asSimpleWriter != null)
            {
                var elementLen = asSimpleWriter.ValidateAndGetLength(element, null);
                if (_writeBuf.WriteSpaceLeft < 4 + elementLen)
                {
                    return(false);
                }
                _writeBuf.WriteInt32(elementLen);
                asSimpleWriter.Write(element, _writeBuf, null);
                return(true);
            }

            var asChunkedWriter = ElementHandler as IChunkingTypeHandler;

            if (asChunkedWriter != null)
            {
                if (!_wroteElementLen)
                {
                    if (_writeBuf.WriteSpaceLeft < 4)
                    {
                        return(false);
                    }
                    _writeBuf.WriteInt32(asChunkedWriter.ValidateAndGetLength(element, ref _lengthCache, null));
                    asChunkedWriter.PrepareWrite(element, _writeBuf, _lengthCache, null);
                    _wroteElementLen = true;
                }
                if (!asChunkedWriter.Write(ref directBuf))
                {
                    return(false);
                }
                _wroteElementLen = false;
                return(true);
            }

            throw PGUtil.ThrowIfReached();
        }
示例#15
0
 internal void SetValue(object container, object fieldValue)
 {
     if (_property != null)
     {
         _property.SetValue(container, fieldValue);
     }
     else if (_field != null)
     {
         _field.SetValue(container, fieldValue);
     }
     else
     {
         throw PGUtil.ThrowIfReached();
     }
 }
示例#16
0
 public bool Write(ref DirectBuffer directBuf)
 {
     if (_value is BitArray[])
     {
         return(base.Write <BitArray>(ref directBuf));
     }
     if (_value is bool[])
     {
         return(base.Write <bool>(ref directBuf));
     }
     if (_value is string[])
     {
         return(base.Write <string>(ref directBuf));
     }
     throw PGUtil.ThrowIfReached(String.Format("Can't write type {0} as an bitstring array", _value.GetType()));
 }
示例#17
0
 public override bool Write(ref DirectBuffer directBuf)
 {
     if (_value is BitArray[])
     {
         return(base.Write <BitArray>(ref directBuf));
     }
     if (_value is bool[])
     {
         return(base.Write <bool>(ref directBuf));
     }
     if (_value is string[])
     {
         return(base.Write <string>(ref directBuf));
     }
     throw PGUtil.ThrowIfReached($"Can't write type {_value.GetType()} as an bitstring array");
 }
示例#18
0
        public bool Equals(NpgsqlDate other)
        {
            switch (_type)
            {
            case InternalType.Infinity:
                return(other._type == InternalType.Infinity);

            case InternalType.NegativeInfinity:
                return(other._type == InternalType.NegativeInfinity);

            case InternalType.Finite:
                return(other._type == InternalType.Finite && _daysSinceEra == other._daysSinceEra);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
示例#19
0
        static InternalType KindToInternalType(DateTimeKind kind)
        {
            switch (kind)
            {
            case DateTimeKind.Unspecified:
                return(InternalType.FiniteUnspecified);

            case DateTimeKind.Utc:
                return(InternalType.FiniteUtc);

            case DateTimeKind.Local:
                return(InternalType.FiniteLocal);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
示例#20
0
        public NpgsqlDate AddDays(int days)
        {
            switch (_type)
            {
            case InternalType.Infinity:
                return(Infinity);

            case InternalType.NegativeInfinity:
                return(NegativeInfinity);

            case InternalType.Finite:
                return(new NpgsqlDate(_daysSinceEra + days));

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
示例#21
0
        public void PrepareWrite(object value, NpgsqlBuffer buf, LengthCache lengthCache, NpgsqlParameter parameter)
        {
            _buf         = buf;
            _lengthCache = lengthCache;
            _parameter   = parameter;
            _state       = State.Count;

            var asDict = value as IDictionary <string, string>;

            if (asDict != null)
            {
                _value = asDict;
                return;
            }

            throw PGUtil.ThrowIfReached();
        }
示例#22
0
        public void Write(object value, NpgsqlBuffer buf, NpgsqlParameter parameter)
        {
            if (value is DateTimeOffset)
            {
                var dto = (DateTimeOffset)value;
                buf.WriteInt64(dto.TimeOfDay.Ticks / 10);
                buf.WriteInt32(-(int)(dto.Offset.Ticks / TimeSpan.TicksPerSecond));
                return;
            }

            if (value is DateTime)
            {
                var dt = (DateTime)value;

                buf.WriteInt64(dt.TimeOfDay.Ticks / 10);

                switch (dt.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 PGUtil.ThrowIfReached();
                }

                return;
            }

            if (value is TimeSpan)
            {
                var ts = (TimeSpan)value;
                buf.WriteInt64(ts.Ticks / 10);
                buf.WriteInt32(-(int)(TimeZoneInfo.Local.BaseUtcOffset.Ticks / TimeSpan.TicksPerSecond));
                return;
            }

            throw PGUtil.ThrowIfReached();
        }
示例#23
0
        /// <summary>
        /// Converts the value of the current <see cref="NpgsqlDateTime"/> object to local time.
        /// </summary>
        /// <remarks>
        /// See the MSDN documentation for DateTime.ToLocalTime().
        /// <b>Note:</b> this method <b>only</b> takes into account the time zone's base offset, and does
        /// <b>not</b> respect daylight savings. See https://github.com/npgsql/npgsql/pull/684 for more
        /// details.
        /// </remarks>
        public NpgsqlDateTime ToLocalTime()
        {
            switch (_type)
            {
            case InternalType.FiniteUnspecified:
            // Treat as UTC
            case InternalType.FiniteUtc:
                return(new NpgsqlDateTime(Add(TimeZoneInfo.Local.BaseUtcOffset).Ticks, DateTimeKind.Local));

            case InternalType.FiniteLocal:
            case InternalType.Infinity:
            case InternalType.NegativeInfinity:
                return(this);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
示例#24
0
        internal NpgsqlDate Add(NpgsqlTimeSpan interval, int carriedOverflow)
        {
            switch (_type)
            {
            case InternalType.Infinity:
                return(Infinity);

            case InternalType.NegativeInfinity:
                return(NegativeInfinity);

            case InternalType.Finite:
                break;

            default:
                throw PGUtil.ThrowIfReached();
            }

            return(AddMonths(interval.Months).AddDays(interval.Days + carriedOverflow));
        }
示例#25
0
        public override bool Write(ref DirectBuffer directBuf)
        {
            var bitArray = _value as BitArray;

            if (bitArray != null)
            {
                return(WriteBitArray(bitArray));
            }

            if (_value is bool)
            {
                return(WriteBool((bool)_value));
            }

            var str = _value as string;

            if (str != null)
            {
                return(WriteString(str));
            }

            throw PGUtil.ThrowIfReached($"Bad type {_value.GetType()} some made its way into BitStringHandler.Write()");
        }
示例#26
0
        public bool Write(ref byte[] directBuf)
        {
            var bitArray = _value as BitArray;

            if (bitArray != null)
            {
                return(WriteBitArray(bitArray));
            }

            if (_value is bool)
            {
                return(WriteBool((bool)_value));
            }

            var str = _value as string;

            if (str != null)
            {
                return(WriteString(str));
            }

            throw PGUtil.ThrowIfReached(String.Format("Bad type {0} some made its way into BitStringHandler.Write()", _value.GetType()));
        }
示例#27
0
        /// <summary>
        /// Converts the value of the current <see cref="NpgsqlDateTime"/> object to local time.
        /// </summary>
        /// <remarks>
        /// See the MSDN documentation for DateTime.ToLocalTime().
        /// <b>Note:</b> this method <b>only</b> takes into account the time zone's base offset, and does
        /// <b>not</b> respect daylight savings. See https://github.com/npgsql/npgsql/pull/684 for more
        /// details.
        /// </remarks>
        public NpgsqlDateTime ToLocalTime()
        {
            switch (_type)
            {
            case InternalType.FiniteUnspecified:
            // Treat as UTC
            case InternalType.FiniteUtc:
                if (_date.DaysSinceEra >= 1 && _date.DaysSinceEra <= MaxDateTimeDay - 1)
                {
                    // Day between 0001-01-02 and 9999-12-30, so we can use DateTime and it will always succeed
                    return(new NpgsqlDateTime(TimeZoneInfo.ConvertTimeFromUtc(new DateTime(this.DateTime.Ticks, DateTimeKind.Utc), TimeZoneInfo.Local)));
                }
                // Else there are no DST rules available in the system for outside the DateTime range, so just use the base offset
                return(new NpgsqlDateTime(Add(TimeZoneInfo.Local.BaseUtcOffset).Ticks, DateTimeKind.Local));

            case InternalType.FiniteLocal:
            case InternalType.Infinity:
            case InternalType.NegativeInfinity:
                return(this);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
示例#28
0
        internal override bool Write(NpgsqlBuffer buf, ref byte[] directBuf)
        {
            Contract.Requires(Statement != null && Statement.All(c => c < 128));
            Contract.Requires(Portal != null && Portal.All(c => c < 128));

            switch (_state)
            {
            case State.WroteNothing:
                var formatCodesSum       = InputParameters.Select(p => p.FormatCode).Sum(c => (int)c);
                var formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count;

                var headerLength =
                    4 +                            // Message length
                    Portal.Length + 1 +
                    Statement.Length + 1 +
                    2 +                            // Number of parameter format codes that follow
                    2 * formatCodeListLength +     // List of format codes
                    2;                             // Number of parameters

                if (buf.WriteSpaceLeft < headerLength)
                {
                    if (buf.Size < headerLength)
                    {
                        throw new Exception("Buffer too small for Bind header");
                    }
                    return(false);
                }

                var messageLength = headerLength +
                                    4 * InputParameters.Count +                                             // Parameter lengths
                                    InputParameters.Select(p => p.BoundSize).Sum() +                        // Parameter values
                                    2 +                                                                     // Number of result format codes
                                    2 * (UnknownResultTypeList == null ? 1 : UnknownResultTypeList.Length); // Result format codes

                buf.WriteByte(Code);
                buf.WriteInt32(messageLength);
                buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Portal));
                buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Statement));

                // 0 implicitly means all-text, 1 means all binary, >1 means mix-and-match
                buf.WriteInt16(formatCodeListLength);
                if (formatCodeListLength == 1)
                {
                    buf.WriteInt16((short)FormatCode.Binary);
                }
                else if (formatCodeListLength > 1)
                {
                    foreach (var code in InputParameters.Select(p => p.FormatCode))
                    {
                        buf.WriteInt16((short)code);
                    }
                }

                buf.WriteInt16(InputParameters.Count);
                _state = State.WroteHeader;
                goto case State.WroteHeader;

            case State.WroteHeader:
                if (!WriteParameters(buf, ref directBuf))
                {
                    return(false);
                }
                _state = State.WroteParameters;
                goto case State.WroteParameters;

            case State.WroteParameters:
                if (UnknownResultTypeList != null)
                {
                    if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2)
                    {
                        return(false);
                    }
                    buf.WriteInt16(UnknownResultTypeList.Length);
                    foreach (var t in UnknownResultTypeList)
                    {
                        buf.WriteInt16(t ? 0 : 1);
                    }
                }
                else
                {
                    if (buf.WriteSpaceLeft < 4)
                    {
                        return(false);
                    }
                    buf.WriteInt16(1);
                    buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1);
                }

                _state = State.Done;
                return(true);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
示例#29
0
        internal override bool Write(NpgsqlBuffer buf, ref DirectBuffer directBuf)
        {
            Contract.Requires(Statement != null && Statement.All(c => c < 128));

            switch (_state)
            {
            case State.WroteNothing:
                _statementNameBytes = PGUtil.UTF8Encoding.GetBytes(Statement);
                _queryLen           = PGUtil.UTF8Encoding.GetByteCount(Query);
                if (buf.WriteSpaceLeft < 1 + 4 + _statementNameBytes.Length + 1)
                {
                    return(false);
                }

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

                buf.WriteByte(Code);
                buf.WriteInt32(messageLength - 1);
                buf.WriteBytesNullTerminated(_statementNameBytes);
                goto case State.WroteHeader;

            case State.WroteHeader:
                _state = State.WroteHeader;

                if (_queryLen <= buf.WriteSpaceLeft)
                {
                    buf.WriteString(Query);
                    goto case State.WroteQuery;
                }

                if (_queryLen <= buf.Size)
                {
                    // String can fit entirely in an empty buffer. Flush and retry rather than
                    // going into the partial writing flow below (which requires ToCharArray())
                    return(false);
                }

                _queryChars = Query.ToCharArray();
                _charPos    = 0;
                goto case State.WritingQuery;

            case State.WritingQuery:
                _state = State.WritingQuery;
                int  charsUsed;
                bool completed;
                buf.WriteStringChunked(_queryChars, _charPos, _queryChars.Length - _charPos, true,
                                       out charsUsed, out completed);
                if (!completed)
                {
                    _charPos += charsUsed;
                    return(false);
                }
                goto case State.WroteQuery;

            case State.WroteQuery:
                _state = State.WroteQuery;
                if (buf.WriteSpaceLeft < 1 + 2)
                {
                    return(false);
                }
                buf.WriteByte(0);     // Null terminator for the query
                buf.WriteInt16((short)ParameterTypeOIDs.Count);
                goto case State.WritingParameterTypes;

            case State.WritingParameterTypes:
                _state = State.WritingParameterTypes;
                for (; _parameterTypePos < ParameterTypeOIDs.Count; _parameterTypePos++)
                {
                    if (buf.WriteSpaceLeft < 4)
                    {
                        return(false);
                    }
                    buf.WriteInt32((int)ParameterTypeOIDs[_parameterTypePos]);
                }

                _state = State.WroteAll;
                return(true);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
示例#30
0
        public bool Write <TElement>(ref DirectBuffer directBuf)
        {
            switch (_writeState)
            {
            case WriteState.WroteNothing:
                var len =
                    4 +                   // ndim
                    4 +                   // has_nulls
                    4 +                   // element_oid
                    _dimensions * 8;      // dim (4) + lBound (4)

                if (_buf.WriteSpaceLeft < len)
                {
                    Contract.Assume(_buf.Size >= len, "Buffer too small for header");
                    return(false);
                }
                _buf.WriteInt32(_dimensions);
                _buf.WriteInt32(_hasNulls ? 1 : 0);     // Actually not used by backend
                _buf.WriteInt32((int)ElementHandler.OID);
                var asArray = _writeValue as Array;
                if (asArray != null)
                {
                    for (var i = 0; i < _dimensions; i++)
                    {
                        _buf.WriteInt32(asArray.GetLength(i));
                        _buf.WriteInt32(LowerBound);      // We don't map .NET lower bounds to PG
                    }
                }
                else
                {
                    _buf.WriteInt32(_writeValue.Count);
                    _buf.WriteInt32(LowerBound);      // We don't map .NET lower bounds to PG
                    _enumerator = _writeValue.GetEnumerator();
                }

                var asGeneric = _writeValue as IList <TElement>;
                _enumerator = asGeneric != null?asGeneric.GetEnumerator() : _writeValue.GetEnumerator();

                if (!_enumerator.MoveNext())
                {
                    goto case WriteState.Cleanup;
                }

                _writeState = WriteState.WritingElements;
                goto case WriteState.WritingElements;

            case WriteState.WritingElements:
                var genericEnumerator = _enumerator as IEnumerator <TElement>;
                if (genericEnumerator != null)
                {
                    // TODO: Actually call the element writer generically...!
                    do
                    {
                        if (!WriteSingleElement(genericEnumerator.Current, ref directBuf))
                        {
                            return(false);
                        }
                    } while (genericEnumerator.MoveNext());
                }
                else
                {
                    do
                    {
                        if (!WriteSingleElement(_enumerator.Current, ref directBuf))
                        {
                            return(false);
                        }
                    } while (_enumerator.MoveNext());
                }
                goto case WriteState.Cleanup;

            case WriteState.Cleanup:
                _writeValue = null;
                _buf        = null;
                _parameter  = null;
                _writeState = WriteState.NeedPrepare;
                return(true);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }