/// <inheritdoc /> public override async ValueTask <Dictionary <string, string?> > Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4, async); var numElements = buf.ReadInt32(); var hstore = new Dictionary <string, string?>(numElements); for (var i = 0; i < numElements; i++) { await buf.Ensure(4, async); var keyLen = buf.ReadInt32(); Debug.Assert(keyLen != -1); var key = await _textHandler.Read(buf, keyLen, async); await buf.Ensure(4, async); var valueLen = buf.ReadInt32(); hstore[key] = valueLen == -1 ? null : await _textHandler.Read(buf, valueLen, async); } return(hstore); }
public override async ValueTask <object> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { if (_members == null) { ResolveFields(); } Debug.Assert(_members != null); await buf.Ensure(4, async); var fieldCount = buf.ReadInt32(); if (fieldCount != _members.Count) // PostgreSQL sanity check { throw new Exception($"pg_attributes contains {_members.Count} rows for type {PgDisplayName}, but {fieldCount} fields were received!"); } var result = (IDictionary <string, object>) new ExpandoObject(); foreach (var member in _members) { await buf.Ensure(8, async); buf.ReadInt32(); // read typeOID, not used var fieldLen = buf.ReadInt32(); if (fieldLen == -1) { // Null field, simply skip it and leave at default continue; } // TODO: We need name translation result[member.PgName] = await member.Handler.ReadAsObject(buf, fieldLen, async); } return(result); }
protected internal override async ValueTask <TAny> Read <TAny>(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { if (_resolvedType != typeof(TAny)) { Map(typeof(TAny)); } await buf.Ensure(4, async); var fieldCount = buf.ReadInt32(); if (fieldCount != _members.Count) // PostgreSQL sanity check { throw new Exception($"pg_attributes contains {_members.Count} rows for type {PgDisplayName}, but {fieldCount} fields were received!"); } // If TAny is a struct, we have to box it here to properly set its fields below object result = Activator.CreateInstance <TAny>(); foreach (var member in _members) { await buf.Ensure(8, async); buf.ReadInt32(); // read typeOID, not used var fieldLen = buf.ReadInt32(); if (fieldLen == -1) { continue; // Null field, simply skip it and leave at default } member.Setter(result, await member.Handler.ReadAsObject(buf, fieldLen, async)); } return((TAny)result); }
internal async Task Startup() { // Read and skip the startup message await _readBuffer.EnsureAsync(4); var startupMessageLen = _readBuffer.ReadInt32(); await _readBuffer.EnsureAsync(startupMessageLen - 4); _readBuffer.Skip(startupMessageLen - 4); WriteAuthenticateOk(); WriteParameterStatuses(new Dictionary <string, string> { { "server_version", "13" }, { "server_encoding", "UTF8" }, { "client_encoding", "UTF8" }, { "application_name", "Mock" }, { "is_superuser", "on" }, { "session_authorization", "foo" }, { "DateStyle", "ISO, MDY" }, { "IntervalStyle", "postgres" }, { "TimeZone", "UTC" }, { "integer_datetimes", "on" }, { "standard_conforming_strings", "on" } }); WriteBackendKeyData(ProcessId, BackendSecret); WriteReadyForQuery(); await FlushAsync(); }
NpgsqlInterval INpgsqlSimpleTypeHandler <NpgsqlInterval> .Read(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription) { var ticks = buf.ReadInt64(); var day = buf.ReadInt32(); var month = buf.ReadInt32(); return(new NpgsqlInterval(month, day, ticks)); }
/// <inheritdoc /> protected override NpgsqlTimeSpan ReadPsv(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription = null) { var ticks = buf.ReadInt64(); var day = buf.ReadInt32(); var month = buf.ReadInt32(); return(new NpgsqlTimeSpan(month, day, ticks * 10)); }
internal async Task SkipMessage() { await _readBuffer.EnsureAsync(4); var len = _readBuffer.ReadInt32(); await _readBuffer.EnsureAsync(len - 4); _readBuffer.Skip(len - 4); }
/// <inheritdoc /> public override TimeSpan Read(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription = null) { var microseconds = buf.ReadInt64(); var days = buf.ReadInt32(); var months = buf.ReadInt32(); if (months > 0) { throw new InvalidCastException("Cannot convert interval value with non-zero months to TimeSpan"); } return(new(microseconds * 10 + days * TimeSpan.TicksPerDay)); }
Duration INpgsqlSimpleTypeHandler <Duration> .Read(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription) { var microsecondsInDay = buf.ReadInt64(); var days = buf.ReadInt32(); var totalMonths = buf.ReadInt32(); if (totalMonths != 0) { throw new NpgsqlException("Cannot read PostgreSQL interval with non-zero months to NodaTime Duration. Try reading as a NodaTime Period instead."); } return(Duration.FromDays(days) + Duration.FromNanoseconds(microsecondsInDay * 1000)); }
async ValueTask <BitVector32> INpgsqlTypeHandler <BitVector32> .Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription) { if (len > 4 + 4) { throw new InvalidCastException("Can't read PostgreSQL bitstring with more than 32 bits into BitVector32"); } await buf.Ensure(4 + 4, async); var numBits = buf.ReadInt32(); return(numBits == 0 ? new BitVector32(0) : new BitVector32(buf.ReadInt32())); }
internal RowDescriptionMessage Load(NpgsqlReadBuffer buf, ConnectorTypeMapper typeMapper) { Fields.Clear(); _nameIndex.Clear(); _caseInsensitiveNameIndex.Clear(); var numFields = buf.ReadInt16(); for (var i = 0; i != numFields; ++i) { // TODO: Recycle var field = new FieldDescription(); field.Populate( typeMapper, buf.ReadNullTerminatedString(), // Name buf.ReadUInt32(), // TableOID buf.ReadInt16(), // ColumnAttributeNumber buf.ReadUInt32(), // TypeOID buf.ReadInt16(), // TypeSize buf.ReadInt32(), // TypeModifier (FormatCode)buf.ReadInt16() // FormatCode ); Fields.Add(field); if (!_nameIndex.ContainsKey(field.Name)) { _nameIndex.Add(field.Name, i); if (!_caseInsensitiveNameIndex.ContainsKey(field.Name)) { _caseInsensitiveNameIndex.Add(field.Name, i); } } } return(this); }
public override async ValueTask <NpgsqlPath> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription fieldDescription = null) { await buf.Ensure(5, async); bool open; var openByte = buf.ReadByte(); switch (openByte) { case 1: open = false; break; case 0: open = true; break; default: throw new Exception("Error decoding binary geometric path: bad open byte"); } var numPoints = buf.ReadInt32(); var result = new NpgsqlPath(numPoints, open); for (var i = 0; i < numPoints; i++) { await buf.Ensure(16, async); result.Add(new NpgsqlPoint(buf.ReadDouble(), buf.ReadDouble())); } return(result); }
public override async ValueTask Read(TComposite composite, NpgsqlReadBuffer buffer, bool async, CancellationToken cancellationToken = default) { if (_set == null) { ThrowHelper.ThrowInvalidOperationException_NoPropertySetter(typeof(TComposite), MemberInfo); } await buffer.Ensure(sizeof(uint) + sizeof(int), async, cancellationToken); var oid = buffer.ReadUInt32(); Debug.Assert(oid == PostgresType.OID); var length = buffer.ReadInt32(); if (length == -1) { return; } var value = NullableHandler <TMember> .Exists ? await NullableHandler <TMember> .ReadAsync(_handler, buffer, length, async, cancellationToken : cancellationToken) : await _handler.Read <TMember>(buffer, length, async, cancellationToken : cancellationToken); _set(composite, value); }
/// <inheritdoc /> public override DateTimeOffset Read(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription = null) { // Adjust from 1 microsecond to 100ns. Time zone (in seconds) is inverted. var ticks = buf.ReadInt64() * 10; var offset = new TimeSpan(0, 0, -buf.ReadInt32()); return(new DateTimeOffset(ticks + TimeSpan.TicksPerDay, offset)); }
protected override NpgsqlTimeSpan ReadPsv(NpgsqlReadBuffer buf, int len, FieldDescription fieldDescription = null) { if (_integerFormat) { var ticks = buf.ReadInt64(); var day = buf.ReadInt32(); var month = buf.ReadInt32(); return(new NpgsqlTimeSpan(month, day, ticks * 10)); } else { var seconds = buf.ReadDouble(); var day = buf.ReadInt32(); var month = buf.ReadInt32(); return(new NpgsqlTimeSpan(month, day, (long)(seconds * TimeSpan.TicksPerSecond))); } }
// Binary Format: int64 expressing microseconds, int32 expressing timezone in seconds, negative #region Read public override DateTimeOffset Read(NpgsqlReadBuffer buf, int len, FieldDescription fieldDescription = null) { // Adjust from 1 microsecond to 100ns. Time zone (in seconds) is inverted. var ticks = _integerFormat ? buf.ReadInt64() * 10 : (long)(buf.ReadDouble() * TimeSpan.TicksPerSecond); var offset = new TimeSpan(0, 0, -buf.ReadInt32()); return(new DateTimeOffset(ticks, offset)); }
/// <inheritdoc /> public override async ValueTask <BitArray> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4, async); var numBits = buf.ReadInt32(); var result = new BitArray(numBits); var bytesLeft = len - 4; // Remove leading number of bits if (bytesLeft == 0) { return(result); } var bitNo = 0; while (true) { var iterationEndPos = bytesLeft > buf.ReadBytesLeft ? bytesLeft - buf.ReadBytesLeft : 1; for (; bytesLeft > iterationEndPos; bytesLeft--) { // ReSharper disable ShiftExpressionRealShiftCountIsZero var chunk = buf.ReadByte(); result[bitNo++] = (chunk & (1 << 7)) != 0; result[bitNo++] = (chunk & (1 << 6)) != 0; result[bitNo++] = (chunk & (1 << 5)) != 0; result[bitNo++] = (chunk & (1 << 4)) != 0; result[bitNo++] = (chunk & (1 << 3)) != 0; result[bitNo++] = (chunk & (1 << 2)) != 0; result[bitNo++] = (chunk & (1 << 1)) != 0; result[bitNo++] = (chunk & (1 << 0)) != 0; } if (bytesLeft == 1) { break; } Debug.Assert(buf.ReadBytesLeft == 0); await buf.Ensure(Math.Min(bytesLeft, buf.Size), async); } if (bitNo < result.Length) { var remainder = result.Length - bitNo; await buf.Ensure(1, async); var lastChunk = buf.ReadByte(); for (var i = 7; i >= 8 - remainder; i--) { result[bitNo++] = (lastChunk & (1 << i)) != 0; } } return(result); }
async ValueTask <List <NpgsqlRange <TElement> > > INpgsqlTypeHandler <List <NpgsqlRange <TElement> > > .Read( NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription) { await buf.Ensure(4, async); var numRanges = buf.ReadInt32(); var multirange = new List <NpgsqlRange <TElement> >(numRanges); for (var i = 0; i < numRanges; i++) { await buf.Ensure(4, async); var rangeLen = buf.ReadInt32(); multirange.Add(await _rangeHandler.Read(buf, rangeLen, async, fieldDescription)); } return(multirange); }
/// <inheritdoc /> public override async ValueTask <Dictionary <string, string?> > Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null, CancellationToken cancellationToken = default) { await buf.Ensure(4, async, cancellationToken); var numElements = buf.ReadInt32(); return(await ReadInto(new Dictionary <string, string?>(numElements), numElements, buf, async, cancellationToken)); }
public override async ValueTask <NpgsqlRange <TElement>[]> Read( NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4, async); var numRanges = buf.ReadInt32(); var multirange = new NpgsqlRange <TElement> [numRanges]; for (var i = 0; i < numRanges; i++) { await buf.Ensure(4, async); var rangeLen = buf.ReadInt32(); multirange[i] = await _rangeHandler.Read(buf, rangeLen, async, fieldDescription); } return(multirange); }
public ValueTask <bool> MoveNextAsync() { if (_tupleEnumerable.State != RowState.Reading) { throw new ObjectDisposedException(null); } using (NoSynchronizationContextScope.Enter()) return(MoveNextCore()); async ValueTask <bool> MoveNextCore() { // Consume the previous column if (_pos != -1) { await _value.Consume(_cancellationToken); } if (_pos + 1 == _numColumns) { return(false); } _pos++; // Read the next column await _readBuffer.Ensure(1, async : true); var kind = (TupleDataKind)_readBuffer.ReadByte(); int len; switch (kind) { case TupleDataKind.Null: case TupleDataKind.UnchangedToastedValue: len = 0; break; case TupleDataKind.TextValue: case TupleDataKind.BinaryValue: if (_readBuffer.ReadBytesLeft < 4) { using var tokenRegistration = _readBuffer.Connector.StartNestedCancellableOperation(_cancellationToken); await _readBuffer.Ensure(4, async : true); } len = _readBuffer.ReadInt32(); break; default: throw new ArgumentOutOfRangeException(); } _value.Reset(kind, len, _rowDescription[_pos]); return(true); } }
public override Period Read(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription = null) { var microsecondsInDay = buf.ReadInt64(); var days = buf.ReadInt32(); var totalMonths = buf.ReadInt32(); // NodaTime will normalize most things (i.e. nanoseconds to milliseconds, seconds...) // but it will not normalize months to years. var months = totalMonths % 12; var years = totalMonths / 12; return(new PeriodBuilder { Nanoseconds = microsecondsInDay * 1000, Days = days, Months = months, Years = years }.Build().Normalize()); }
async ValueTask <ImmutableDictionary <string, string?> > INpgsqlTypeHandler <ImmutableDictionary <string, string?> > .Read( NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription, CancellationToken cancellationToken) { await buf.Ensure(4, async, cancellationToken); var numElements = buf.ReadInt32(); return((await ReadInto(ImmutableDictionary <string, string?> .Empty.ToBuilder(), numElements, buf, async, cancellationToken)) .ToImmutable()); }
public async ValueTask <T> Read <T>(NpgsqlReadBuffer buffer, bool async, CancellationToken cancellationToken = default) { await buffer.Ensure(sizeof(uint) + sizeof(int), async, cancellationToken); var oid = buffer.ReadUInt32(); var length = buffer.ReadInt32(); if (length == -1) { return(default !);
/// <remarks> /// Copied wholesale from Postgresql backend/utils/adt/datetime.c:j2date /// </remarks> protected override NpgsqlDate ReadPsv(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription = null) { var binDate = buf.ReadInt32(); return(binDate switch { int.MaxValue => NpgsqlDate.Infinity, int.MinValue => NpgsqlDate.NegativeInfinity, _ => new NpgsqlDate(binDate + 730119) });
public override Guid Read(NpgsqlReadBuffer buf, int len, FieldDescription fieldDescription = null) { var a = buf.ReadInt32(); var b = buf.ReadInt16(); var c = buf.ReadInt16(); var d = new byte[8]; buf.ReadBytes(d, 0, 8); return(new Guid(a, b, c, d)); }
/// <inheritdoc /> public override Guid Read(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription = null) { var raw = new GuidRaw { Data1 = buf.ReadInt32(), Data2 = buf.ReadInt16(), Data3 = buf.ReadInt16(), Data4 = buf.ReadInt64(BitConverter.IsLittleEndian) }; return(raw.Value); }
/// <summary> /// Reads an array of element type <typeparamref name="TRequestedElement"/> from the given buffer <paramref name="buf"/>. /// </summary> protected async ValueTask <Array> ReadArray <TRequestedElement>(NpgsqlReadBuffer buf, bool async, int expectedDimensions = 0, bool readAsObject = false) { await buf.Ensure(12, async); var dimensions = buf.ReadInt32(); var containsNulls = buf.ReadInt32() == 1; buf.ReadUInt32(); // Element OID. Ignored. var returnType = readAsObject ? ArrayNullabilityMode switch { ArrayNullabilityMode.Never => ElementTypeInfo <TRequestedElement> .IsNonNullable && containsNulls ? throw new InvalidOperationException(ReadNonNullableCollectionWithNullsExceptionMessage) : typeof(TRequestedElement), ArrayNullabilityMode.Always => ElementTypeInfo <TRequestedElement> .NullableElementType, ArrayNullabilityMode.PerInstance => containsNulls ? ElementTypeInfo <TRequestedElement> .NullableElementType : typeof(TRequestedElement), _ => throw new ArgumentOutOfRangeException() }
async ValueTask <T> ReadInto <T>(T dictionary, int numElements, NpgsqlReadBuffer buf, bool async, CancellationToken cancellationToken = default) where T : IDictionary <string, string?> { for (var i = 0; i < numElements; i++) { await buf.Ensure(4, async, cancellationToken); var keyLen = buf.ReadInt32(); Debug.Assert(keyLen != -1); var key = await _textHandler.Read(buf, keyLen, async, cancellationToken : cancellationToken); await buf.Ensure(4, async, cancellationToken); var valueLen = buf.ReadInt32(); dictionary[key] = valueLen == -1 ? null : await _textHandler.Read(buf, valueLen, async, cancellationToken : cancellationToken); } return(dictionary); }
internal async ValueTask <TAny> ReadWithLength <TAny>(NpgsqlReadBuffer buf, bool async, FieldDescription fieldDescription = null) { await buf.Ensure(4, async); var len = buf.ReadInt32(); if (len == -1) { return(default(TAny)); } return(await Read <TAny>(buf, len, async, fieldDescription)); }