Skip to content

Commit

Permalink
Address feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
NinoFloris committed Sep 22, 2023
1 parent a18e427 commit 945ad65
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 20 deletions.
19 changes: 12 additions & 7 deletions src/Npgsql/Internal/Converters/BitStringConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,23 @@ public override BitArray Read(PgReader reader)
reader.Buffer(sizeof(int));

var bits = reader.ReadInt32();
return ReadValue(reader.ReadBytes(GetByteLengthFromBits(bits)), bits);
var bytes = new byte[GetByteLengthFromBits(bits)];
reader.ReadBytes(bytes);
return ReadValue(bytes, bits);
}
public override async ValueTask<BitArray> ReadAsync(PgReader reader, CancellationToken cancellationToken = default)
{
if (reader.ShouldBuffer(sizeof(int)))
await reader.BufferAsync(sizeof(int), cancellationToken).ConfigureAwait(false);

var bits = reader.ReadInt32();
return ReadValue(await reader.ReadBytesAsync(GetByteLengthFromBits(bits), cancellationToken).ConfigureAwait(false), bits);
var bytes = new byte[GetByteLengthFromBits(bits)];
await reader.ReadBytesAsync(bytes, cancellationToken).ConfigureAwait(false);
return ReadValue(bytes, bits);
}

internal static BitArray ReadValue(ReadOnlySequence<byte> byteSeq, int bits)
internal static BitArray ReadValue(byte[] bytes, int bits)
{
var bytes = byteSeq.ToArray();
for (var i = 0; i < bytes.Length; i++)
{
ref var b = ref bytes[i];
Expand Down Expand Up @@ -176,9 +179,11 @@ async ValueTask<string> Read(bool async, PgReader reader, CancellationToken canc
await reader.Buffer(async, sizeof(int), cancellationToken).ConfigureAwait(false);

var bits = reader.ReadInt32();
var bytes = async
? await reader.ReadBytesAsync(GetByteLengthFromBits(bits), cancellationToken).ConfigureAwait(false)
: reader.ReadBytes(GetByteLengthFromBits(bits));
var bytes = new byte[GetByteLengthFromBits(bits)];
if (async)
await reader.ReadBytesAsync(bytes, cancellationToken).ConfigureAwait(false);
else
reader.ReadBytes(bytes);

var bitArray = BitArrayBitStringConverter.ReadValue(bytes, bits);
var sb = new StringBuilder(bits);
Expand Down
2 changes: 2 additions & 0 deletions src/Npgsql/Internal/Converters/EnumConverter.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;

namespace Npgsql.Internal.Converters;

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
sealed class EnumConverter<TEnum> : PgBufferedConverter<TEnum> where TEnum : struct, Enum
{
readonly Dictionary<TEnum, string> _enumToLabel;
Expand Down
1 change: 0 additions & 1 deletion src/Npgsql/Internal/Converters/RangeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ async ValueTask<NpgsqlRange<TSubtype>> Read(bool async, PgReader reader, Cancell
var lowerBound = default(TSubtype);
var upperBound = default(TSubtype);

var readRequirement = _subtypeRequirements.Read;
var converter = _subtypeConverter;
if ((flags & RangeFlags.LowerBoundInfinite) == 0)
{
Expand Down
3 changes: 2 additions & 1 deletion src/Npgsql/Internal/PgBufferedConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ protected PgBufferedConverter(bool customDbNullPredicate = false) : base(customD
protected abstract T ReadCore(PgReader reader);
protected abstract void WriteCore(PgWriter writer, T value);

public override Size GetSize(SizeContext context, T value, ref object? writeState) => throw new NotImplementedException();
public override Size GetSize(SizeContext context, T value, ref object? writeState)
=> throw new NotSupportedException();

public sealed override T Read(PgReader reader)
{
Expand Down
11 changes: 8 additions & 3 deletions src/Npgsql/Internal/PgConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,23 +94,28 @@ public abstract class PgConverter<T> : PgConverter
private protected PgConverter(bool customDbNullPredicate)
: base(typeof(T), default(T) is null, customDbNullPredicate) { }

protected virtual bool IsDbNullValue(T? value) => throw new NotImplementedException();
protected virtual bool IsDbNullValue(T? value) => throw new NotSupportedException();

// Object null semantics as follows, if T is a struct (so excluding nullable) report false for null values, don't throw on the cast.
// As a result this creates symmetry with IsDbNull when we're dealing with a struct T, as it cannot be passed null at all.
private protected override bool IsDbNullValueAsObject(object? value)
=> (default(T) is null || value is not null) && IsDbNullValue(Downcast(value));

public bool IsDbNull([NotNullWhen(false)] T? value)
=> DbNullPredicateKind switch
{
return DbNullPredicateKind switch
{
DbNullPredicate.Null => value is null,
DbNullPredicate.None => false,
DbNullPredicate.PolymorphicNull => value is null or DBNull,
// We do the null check to keep the NotNullWhen(false) invariant.
_ => IsDbNullValue(value) || (value is null && ThrowInvalidNullValue())
DbNullPredicate.Custom => IsDbNullValue(value) || (value is null && ThrowInvalidNullValue()),
_ => ThrowOutOfRange()
};

bool ThrowOutOfRange() => throw new ArgumentOutOfRangeException(nameof(DbNullPredicateKind), "Unknown case", DbNullPredicateKind.ToString());
}

public abstract T Read(PgReader reader);
public abstract ValueTask<T> ReadAsync(PgReader reader, CancellationToken cancellationToken = default);

Expand Down
2 changes: 1 addition & 1 deletion src/Npgsql/PostgresDatabaseInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ typtype IN ('b', 'r', 'm', 'e', 'd') OR -- Base, range, multirange, enum, domain
(typtype = 'p' AND typname IN ('record', 'void', 'unknown')) OR -- Some special supported pseudo-types
(typtype = 'a' AND ( -- Array of...
elemtyptype IN ('b', 'r', 'm', 'e', 'd') OR -- Array of base, range, multirange, enum, domain
(elemtyptype = 'p' AND elemtypname IN ('record', 'void', 'unknown')) OR -- Arrays of special supported pseudo-types
(elemtyptype = 'p' AND elemtypname IN ('record', 'void')) OR -- Arrays of special supported pseudo-types
(elemtyptype = 'c' AND {(loadTableComposites ? "ns.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')" : "elemrelkind='c'")}) -- Array of user-defined free-standing composites (not table composites) by default
))
ORDER BY CASE
Expand Down
14 changes: 11 additions & 3 deletions src/Npgsql/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ Npgsql.NpgsqlDataSource.OpenConnection() -> Npgsql.NpgsqlConnection!
Npgsql.NpgsqlDataSource.OpenConnectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask<Npgsql.NpgsqlConnection!>
Npgsql.NpgsqlDataSource.Password.set -> void
Npgsql.NpgsqlDataSourceBuilder
Npgsql.NpgsqlDataSourceBuilder.AddTypeResolverFactory(Npgsql.Internal.TypeHandling.TypeHandlerResolverFactory! resolverFactory) -> void
Npgsql.NpgsqlDataSourceBuilder.Build() -> Npgsql.NpgsqlDataSource!
Npgsql.NpgsqlDataSourceBuilder.BuildMultiHost() -> Npgsql.NpgsqlMultiHostDataSource!
Npgsql.NpgsqlDataSourceBuilder.ConnectionString.get -> string!
Expand Down Expand Up @@ -673,6 +674,8 @@ Npgsql.NpgsqlParameter
Npgsql.NpgsqlParameter.Clone() -> Npgsql.NpgsqlParameter!
Npgsql.NpgsqlParameter.Collection.get -> Npgsql.NpgsqlParameterCollection?
Npgsql.NpgsqlParameter.Collection.set -> void
Npgsql.NpgsqlParameter.ConvertedValue.get -> object?
Npgsql.NpgsqlParameter.ConvertedValue.set -> void
Npgsql.NpgsqlParameter.DataTypeName.get -> string?
Npgsql.NpgsqlParameter.DataTypeName.set -> void
Npgsql.NpgsqlParameter.NpgsqlDbType.get -> NpgsqlTypes.NpgsqlDbType
Expand Down Expand Up @@ -800,9 +803,9 @@ Npgsql.PostgresNotice.Where.get -> string?
Npgsql.PostgresNotice.Where.set -> void
Npgsql.PostgresTypes.PostgresArrayType
Npgsql.PostgresTypes.PostgresArrayType.Element.get -> Npgsql.PostgresTypes.PostgresType!
Npgsql.PostgresTypes.PostgresArrayType.PostgresArrayType(string! ns, string! name, uint oid, Npgsql.PostgresTypes.PostgresType! elementPostgresType) -> void
Npgsql.PostgresTypes.PostgresArrayType.PostgresArrayType(string! ns, string! internalName, uint oid, Npgsql.PostgresTypes.PostgresType! elementPostgresType) -> void
Npgsql.PostgresTypes.PostgresBaseType
Npgsql.PostgresTypes.PostgresBaseType.PostgresBaseType(string! ns, string! name, uint oid) -> void
Npgsql.PostgresTypes.PostgresBaseType.PostgresBaseType(string! ns, string! internalName, uint oid) -> void
Npgsql.PostgresTypes.PostgresCompositeType
Npgsql.PostgresTypes.PostgresCompositeType.Field
Npgsql.PostgresTypes.PostgresCompositeType.Field.Name.get -> string!
Expand Down Expand Up @@ -830,6 +833,8 @@ Npgsql.PostgresTypes.PostgresType.InternalName.get -> string!
Npgsql.PostgresTypes.PostgresType.Name.get -> string!
Npgsql.PostgresTypes.PostgresType.Namespace.get -> string!
Npgsql.PostgresTypes.PostgresType.OID.get -> uint
Npgsql.PostgresTypes.PostgresType.PostgresType(string! ns, string! name, string! internalName, uint oid) -> void
Npgsql.PostgresTypes.PostgresType.PostgresType(string! ns, string! name, uint oid) -> void
Npgsql.PostgresTypes.PostgresType.Range.get -> Npgsql.PostgresTypes.PostgresRangeType?
Npgsql.PostgresTypes.UnknownBackendType
Npgsql.ProvideClientCertificatesCallback
Expand Down Expand Up @@ -1159,11 +1164,13 @@ Npgsql.StatementType.Select = 1 -> Npgsql.StatementType
Npgsql.StatementType.Unknown = 0 -> Npgsql.StatementType
Npgsql.StatementType.Update = 4 -> Npgsql.StatementType
Npgsql.TypeMapping.INpgsqlTypeMapper
Npgsql.TypeMapping.INpgsqlTypeMapper.AddTypeResolverFactory(Npgsql.Internal.TypeHandling.TypeHandlerResolverFactory! resolverFactory) -> void
Npgsql.TypeMapping.INpgsqlTypeMapper.DefaultNameTranslator.get -> Npgsql.INpgsqlNameTranslator!
Npgsql.TypeMapping.INpgsqlTypeMapper.DefaultNameTranslator.set -> void
Npgsql.TypeMapping.INpgsqlTypeMapper.MapComposite(System.Type! clrType, string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> Npgsql.TypeMapping.INpgsqlTypeMapper!
Npgsql.TypeMapping.INpgsqlTypeMapper.MapComposite<T>(string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> Npgsql.TypeMapping.INpgsqlTypeMapper!
Npgsql.TypeMapping.INpgsqlTypeMapper.MapEnum<TEnum>(string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> Npgsql.TypeMapping.INpgsqlTypeMapper!
Npgsql.TypeMapping.INpgsqlTypeMapper.Reset() -> void
Npgsql.TypeMapping.INpgsqlTypeMapper.UnmapComposite(System.Type! clrType, string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> bool
Npgsql.TypeMapping.INpgsqlTypeMapper.UnmapComposite<T>(string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> bool
Npgsql.TypeMapping.INpgsqlTypeMapper.UnmapEnum<TEnum>(string? pgName = null, Npgsql.INpgsqlNameTranslator? nameTranslator = null) -> bool
Expand Down Expand Up @@ -1834,6 +1841,7 @@ static Npgsql.NameTranslation.NpgsqlSnakeCaseNameTranslator.ConvertToSnakeCase(s
static Npgsql.NpgsqlCommandBuilder.DeriveParameters(Npgsql.NpgsqlCommand! command) -> void
static Npgsql.NpgsqlConnection.ClearAllPools() -> void
static Npgsql.NpgsqlConnection.ClearPool(Npgsql.NpgsqlConnection! connection) -> void
static Npgsql.NpgsqlConnection.GlobalTypeMapper.get -> Npgsql.TypeMapping.INpgsqlTypeMapper!
static Npgsql.NpgsqlDataSource.Create(Npgsql.NpgsqlConnectionStringBuilder! connectionStringBuilder) -> Npgsql.NpgsqlDataSource!
static Npgsql.NpgsqlDataSource.Create(string! connectionString) -> Npgsql.NpgsqlDataSource!
static Npgsql.NpgsqlLoggingConfiguration.InitializeLogging(Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory, bool parameterLoggingEnabled = false) -> void
Expand All @@ -1850,7 +1858,7 @@ static NpgsqlTypes.NpgsqlCircle.operator !=(NpgsqlTypes.NpgsqlCircle x, NpgsqlTy
static NpgsqlTypes.NpgsqlCircle.operator ==(NpgsqlTypes.NpgsqlCircle x, NpgsqlTypes.NpgsqlCircle y) -> bool
static NpgsqlTypes.NpgsqlCircle.Parse(string! s) -> NpgsqlTypes.NpgsqlCircle
static NpgsqlTypes.NpgsqlInet.explicit operator System.Net.IPAddress!(NpgsqlTypes.NpgsqlInet inet) -> System.Net.IPAddress!
static NpgsqlTypes.NpgsqlInet.explicit operator NpgsqlTypes.NpgsqlInet(System.Net.IPAddress! ip) -> NpgsqlTypes.NpgsqlInet
static NpgsqlTypes.NpgsqlInet.implicit operator NpgsqlTypes.NpgsqlInet(System.Net.IPAddress! ip) -> NpgsqlTypes.NpgsqlInet
static NpgsqlTypes.NpgsqlInet.operator !=(NpgsqlTypes.NpgsqlInet x, NpgsqlTypes.NpgsqlInet y) -> bool
static NpgsqlTypes.NpgsqlInet.operator ==(NpgsqlTypes.NpgsqlInet x, NpgsqlTypes.NpgsqlInet y) -> bool
static NpgsqlTypes.NpgsqlInet.ToIPAddress(NpgsqlTypes.NpgsqlInet inet) -> System.Net.IPAddress!
Expand Down
14 changes: 12 additions & 2 deletions src/Npgsql/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ Npgsql.NpgsqlSlimDataSourceBuilder.UseRootCertificate(System.Security.Cryptograp
Npgsql.NpgsqlSlimDataSourceBuilder.UseRootCertificateCallback(System.Func<System.Security.Cryptography.X509Certificates.X509Certificate2!>? rootCertificateCallback) -> Npgsql.NpgsqlSlimDataSourceBuilder!
Npgsql.NpgsqlSlimDataSourceBuilder.UseSystemTextJson(System.Text.Json.JsonSerializerOptions? serializerOptions = null, System.Type![]? jsonbClrTypes = null, System.Type![]? jsonClrTypes = null) -> Npgsql.NpgsqlSlimDataSourceBuilder!
Npgsql.NpgsqlSlimDataSourceBuilder.UseUserCertificateValidationCallback(System.Net.Security.RemoteCertificateValidationCallback! userCertificateValidationCallback) -> Npgsql.NpgsqlSlimDataSourceBuilder!
Npgsql.PostgresTypes.PostgresArrayType.PostgresArrayType(string! ns, string! name, uint oid, Npgsql.PostgresTypes.PostgresType! elementPostgresType) -> void
Npgsql.PostgresTypes.PostgresBaseType.PostgresBaseType(string! ns, string! name, uint oid) -> void
Npgsql.Replication.PhysicalReplicationConnection.StartReplication(Npgsql.Replication.PhysicalReplicationSlot? slot, NpgsqlTypes.NpgsqlLogSequenceNumber walLocation, System.Threading.CancellationToken cancellationToken, uint timeline = 0) -> System.Collections.Generic.IAsyncEnumerable<Npgsql.Replication.XLogDataMessage!>!
Npgsql.Replication.PhysicalReplicationConnection.StartReplication(NpgsqlTypes.NpgsqlLogSequenceNumber walLocation, System.Threading.CancellationToken cancellationToken, uint timeline = 0) -> System.Collections.Generic.IAsyncEnumerable<Npgsql.Replication.XLogDataMessage!>!
Npgsql.Replication.PhysicalReplicationSlot.PhysicalReplicationSlot(string! slotName, NpgsqlTypes.NpgsqlLogSequenceNumber? restartLsn = null, uint? restartTimeline = null) -> void
Npgsql.Replication.PhysicalReplicationSlot.RestartTimeline.get -> uint?
Npgsql.TypeMapping.INpgsqlTypeMapper.AddTypeInfoResolver(Npgsql.Internal.IPgTypeInfoResolver! resolver) -> void
Npgsql.TypeMapping.INpgsqlTypeMapper.Reset() -> void
Npgsql.TypeMapping.UserTypeMapping
Npgsql.TypeMapping.UserTypeMapping.ClrType.get -> System.Type!
Npgsql.TypeMapping.UserTypeMapping.PgTypeName.get -> string!
Expand Down Expand Up @@ -103,8 +104,17 @@ override Npgsql.NpgsqlBatch.Dispose() -> void
*REMOVED*Npgsql.Replication.PhysicalReplicationSlot.PhysicalReplicationSlot(string! slotName, NpgsqlTypes.NpgsqlLogSequenceNumber? restartLsn = null, ulong? restartTimeline = null) -> void
*REMOVED*Npgsql.Replication.PhysicalReplicationSlot.RestartTimeline.get -> ulong?
override NpgsqlTypes.NpgsqlCidr.ToString() -> string!
static Npgsql.NpgsqlConnection.GlobalTypeMapper.get -> Npgsql.TypeMapping.INpgsqlTypeMapper!
*REMOVED*static NpgsqlTypes.NpgsqlInet.operator !=(NpgsqlTypes.NpgsqlInet x, NpgsqlTypes.NpgsqlInet y) -> bool
*REMOVED*static NpgsqlTypes.NpgsqlInet.operator ==(NpgsqlTypes.NpgsqlInet x, NpgsqlTypes.NpgsqlInet y) -> bool
*REMOVED*static NpgsqlTypes.NpgsqlInet.ToIPAddress(NpgsqlTypes.NpgsqlInet inet) -> System.Net.IPAddress!
*REMOVED*static NpgsqlTypes.NpgsqlInet.ToNpgsqlInet(System.Net.IPAddress? ip) -> NpgsqlTypes.NpgsqlInet
*REMOVED*Npgsql.NpgsqlDataSourceBuilder.AddTypeResolverFactory(Npgsql.Internal.TypeHandling.TypeHandlerResolverFactory! resolverFactory) -> void
static NpgsqlTypes.NpgsqlInet.explicit operator NpgsqlTypes.NpgsqlInet(System.Net.IPAddress! ip) -> NpgsqlTypes.NpgsqlInet
*REMOVED*Npgsql.NpgsqlParameter.ConvertedValue.get -> object?
*REMOVED*Npgsql.NpgsqlParameter.ConvertedValue.set -> void
*REMOVED*Npgsql.PostgresTypes.PostgresArrayType.PostgresArrayType(string! ns, string! internalName, uint oid, Npgsql.PostgresTypes.PostgresType! elementPostgresType) -> void
*REMOVED*Npgsql.PostgresTypes.PostgresBaseType.PostgresBaseType(string! ns, string! internalName, uint oid) -> void
*REMOVED*static NpgsqlTypes.NpgsqlInet.implicit operator NpgsqlTypes.NpgsqlInet(System.Net.IPAddress! ip) -> NpgsqlTypes.NpgsqlInet
*REMOVED*Npgsql.PostgresTypes.PostgresType.PostgresType(string! ns, string! name, string! internalName, uint oid) -> void
*REMOVED*Npgsql.PostgresTypes.PostgresType.PostgresType(string! ns, string! name, uint oid) -> void
*REMOVED*Npgsql.TypeMapping.INpgsqlTypeMapper.AddTypeResolverFactory(Npgsql.Internal.TypeHandling.TypeHandlerResolverFactory! resolverFactory) -> void
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;

namespace NpgsqlTypes;
namespace Npgsql.Replication;

static class PgDateTime
{
Expand Down
1 change: 0 additions & 1 deletion test/Npgsql.Tests/Types/MiscTypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Npgsql.Tests.Types;
/// Tests on PostgreSQL types which don't fit elsewhere
/// </summary>
class MiscTypeTests : MultiplexingTestBase

{
[Test]
public async Task Boolean()
Expand Down

0 comments on commit 945ad65

Please sign in to comment.