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); } }
/// <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); } }
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); } }
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."); } }
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); } }
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); }
/// <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); }
internal override void WriteFully(NpgsqlWriteBuffer buf) { Debug.Assert(BackendProcessId != 0); buf.WriteInt32(Length); buf.WriteInt32(CancelRequestCode); buf.WriteInt32(BackendProcessId); buf.WriteInt32(BackendSecretKey); }
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 }
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); }
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 }
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); }
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); } }
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); } }
/// <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); } }
/// <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); } }
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); }
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;
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); } }
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); }
/// <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)); }
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); }
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)); }
/// <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); }
/// <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); }
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(); }
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); } }
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); }