From aac6b0330f4cdafe10e021ac0c4ca0238a855552 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 5 Feb 2021 16:22:22 +0100 Subject: [PATCH 1/2] Stop using reflection to map built-in types Just specify them explicitly - simpler and more linker-friendly. Part of #3300 --- .../Internal/TypeHandlers/BitStringHandler.cs | 2 - .../Internal/TypeHandlers/BoolHandler.cs | 1 - .../Internal/TypeHandlers/ByteaHandler.cs | 12 - .../DateTimeHandlers/DateHandler.cs | 1 - .../DateTimeHandlers/IntervalHandler.cs | 1 - .../DateTimeHandlers/TimeHandler.cs | 1 - .../DateTimeHandlers/TimeTzHandler.cs | 1 - .../DateTimeHandlers/TimestampHandler.cs | 1 - .../DateTimeHandlers/TimestampTzHandler.cs | 1 - .../FullTextSearchHandlers/TsQueryHandler.cs | 4 - .../FullTextSearchHandlers/TsVectorHandler.cs | 1 - .../GeometricHandlers/BoxHandler.cs | 1 - .../GeometricHandlers/CircleHandler.cs | 1 - .../GeometricHandlers/LineHandler.cs | 1 - .../GeometricHandlers/LineSegmentHandler.cs | 1 - .../GeometricHandlers/PathHandler.cs | 1 - .../GeometricHandlers/PointHandler.cs | 1 - .../GeometricHandlers/PolygonHandler.cs | 1 - .../Internal/TypeHandlers/HstoreHandler.cs | 10 +- .../InternalTypeHandlers/Int2VectorHandler.cs | 1 - .../InternalCharHandler.cs | 5 +- .../InternalTypeHandlers/OIDVectorHandler.cs | 1 - .../InternalTypeHandlers/PgLsnHandler.cs | 2 - .../InternalTypeHandlers/TidHandler.cs | 1 - .../Internal/TypeHandlers/JsonHandler.cs | 2 - .../Internal/TypeHandlers/JsonPathHandler.cs | 1 - .../{ => LTreeHandlers}/LQueryHandler.cs | 5 +- .../{ => LTreeHandlers}/LTreeHandler.cs | 5 +- .../{ => LTreeHandlers}/LTxtQueryHandler.cs | 5 +- .../NetworkHandlers/CidrHandler.cs | 1 - .../NetworkHandlers/InetHandler.cs | 4 - .../NetworkHandlers/MacaddrHandler.cs | 2 - .../NumericHandlers/DoubleHandler.cs | 1 - .../NumericHandlers/Int16Handler.cs | 1 - .../NumericHandlers/Int32Handler.cs | 1 - .../NumericHandlers/Int64Handler.cs | 1 - .../NumericHandlers/MoneyHandler.cs | 1 - .../NumericHandlers/NumericHandler.cs | 1 - .../NumericHandlers/SingleHandler.cs | 1 - .../NumericHandlers/UInt32Handler.cs | 5 - .../Internal/TypeHandlers/RecordHandler.cs | 1 - .../Internal/TypeHandlers/TextHandler.cs | 14 +- .../Internal/TypeHandlers/UuidHandler.cs | 1 - .../Internal/TypeHandlers/VoidHandler.cs | 1 - .../TypeMapping/EntityFrameworkCoreCompat.cs | 45 -- src/Npgsql/TypeMapping/GlobalTypeMapper.cs | 584 ++++++++++++++++-- src/Npgsql/TypeMapping/NpgsqlTypeMapping.cs | 7 + .../TypeMapping/TypeMappingAttribute.cs | 130 ---- test/Npgsql.Tests/Types/NumericTypeTests.cs | 1 - 49 files changed, 542 insertions(+), 332 deletions(-) rename src/Npgsql/Internal/TypeHandlers/{ => InternalTypeHandlers}/InternalCharHandler.cs (96%) rename src/Npgsql/Internal/TypeHandlers/{ => LTreeHandlers}/LQueryHandler.cs (96%) rename src/Npgsql/Internal/TypeHandlers/{ => LTreeHandlers}/LTreeHandler.cs (96%) rename src/Npgsql/Internal/TypeHandlers/{ => LTreeHandlers}/LTxtQueryHandler.cs (96%) delete mode 100644 src/Npgsql/TypeMapping/EntityFrameworkCoreCompat.cs delete mode 100644 src/Npgsql/TypeMapping/TypeMappingAttribute.cs diff --git a/src/Npgsql/Internal/TypeHandlers/BitStringHandler.cs b/src/Npgsql/Internal/TypeHandlers/BitStringHandler.cs index c3c3586ff9..cbd797f836 100644 --- a/src/Npgsql/Internal/TypeHandlers/BitStringHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/BitStringHandler.cs @@ -26,8 +26,6 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("bit varying", NpgsqlDbType.Varbit, new[] { typeof(BitArray), typeof(BitVector32) })] - [TypeMapping("bit", NpgsqlDbType.Bit)] public class BitStringHandler : NpgsqlTypeHandler, INpgsqlTypeHandler, INpgsqlTypeHandler, INpgsqlTypeHandler { diff --git a/src/Npgsql/Internal/TypeHandlers/BoolHandler.cs b/src/Npgsql/Internal/TypeHandlers/BoolHandler.cs index 8170acf97e..126afffd5b 100644 --- a/src/Npgsql/Internal/TypeHandlers/BoolHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/BoolHandler.cs @@ -17,7 +17,6 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("boolean", NpgsqlDbType.Boolean, DbType.Boolean, typeof(bool))] public class BoolHandler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/ByteaHandler.cs b/src/Npgsql/Internal/TypeHandlers/ByteaHandler.cs index 8b95483830..61eebaad2b 100644 --- a/src/Npgsql/Internal/TypeHandlers/ByteaHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/ByteaHandler.cs @@ -20,18 +20,6 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping( - "bytea", - NpgsqlDbType.Bytea, - DbType.Binary, - new[] { - typeof(byte[]), - typeof(ArraySegment), -#if !NETSTANDARD2_0 - typeof(ReadOnlyMemory), - typeof(Memory) -#endif - })] public class ByteaHandler : NpgsqlTypeHandler, INpgsqlTypeHandler> #if !NETSTANDARD2_0 , INpgsqlTypeHandler>, INpgsqlTypeHandler> diff --git a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/DateHandler.cs b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/DateHandler.cs index 24349f4569..1e459f5c8e 100644 --- a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/DateHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/DateHandler.cs @@ -18,7 +18,6 @@ namespace Npgsql.Internal.TypeHandlers.DateTimeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("date", NpgsqlDbType.Date, DbType.Date, typeof(NpgsqlDate))] public class DateHandlerFactory : NpgsqlTypeHandlerFactory { /// diff --git a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/IntervalHandler.cs b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/IntervalHandler.cs index e01f81d8f3..419ae30aa8 100644 --- a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/IntervalHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/IntervalHandler.cs @@ -17,7 +17,6 @@ namespace Npgsql.Internal.TypeHandlers.DateTimeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("interval", NpgsqlDbType.Interval, new[] { typeof(TimeSpan), typeof(NpgsqlTimeSpan) })] public class IntervalHandlerFactory : NpgsqlTypeHandlerFactory { /// diff --git a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimeHandler.cs b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimeHandler.cs index ba53cffa61..716cd180ed 100644 --- a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimeHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimeHandler.cs @@ -18,7 +18,6 @@ namespace Npgsql.Internal.TypeHandlers.DateTimeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("time without time zone", NpgsqlDbType.Time, new[] { DbType.Time })] public class TimeHandlerFactory : NpgsqlTypeHandlerFactory { /// diff --git a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimeTzHandler.cs b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimeTzHandler.cs index e4e79cd6a9..fd602dcc04 100644 --- a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimeTzHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimeTzHandler.cs @@ -17,7 +17,6 @@ namespace Npgsql.Internal.TypeHandlers.DateTimeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("time with time zone", NpgsqlDbType.TimeTz)] public class TimeTzHandlerFactory : NpgsqlTypeHandlerFactory { /// diff --git a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimestampHandler.cs b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimestampHandler.cs index a315d59518..8536523916 100644 --- a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimestampHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimestampHandler.cs @@ -19,7 +19,6 @@ namespace Npgsql.Internal.TypeHandlers.DateTimeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("timestamp without time zone", NpgsqlDbType.Timestamp, new[] { DbType.DateTime, DbType.DateTime2 }, new[] { typeof(NpgsqlDateTime), typeof(DateTime) }, DbType.DateTime)] public class TimestampHandlerFactory : NpgsqlTypeHandlerFactory { /// diff --git a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimestampTzHandler.cs b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimestampTzHandler.cs index 6dfdff4214..5d9e899196 100644 --- a/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimestampTzHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/DateTimeHandlers/TimestampTzHandler.cs @@ -18,7 +18,6 @@ namespace Npgsql.Internal.TypeHandlers.DateTimeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("timestamp with time zone", NpgsqlDbType.TimestampTz, DbType.DateTimeOffset, typeof(DateTimeOffset))] public class TimestampTzHandlerFactory : NpgsqlTypeHandlerFactory { /// diff --git a/src/Npgsql/Internal/TypeHandlers/FullTextSearchHandlers/TsQueryHandler.cs b/src/Npgsql/Internal/TypeHandlers/FullTextSearchHandlers/TsQueryHandler.cs index 6711e996b7..405a763e2c 100644 --- a/src/Npgsql/Internal/TypeHandlers/FullTextSearchHandlers/TsQueryHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/FullTextSearchHandlers/TsQueryHandler.cs @@ -25,10 +25,6 @@ namespace Npgsql.Internal.TypeHandlers.FullTextSearchHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("tsquery", NpgsqlDbType.TsQuery, new[] { - typeof(NpgsqlTsQuery), typeof(NpgsqlTsQueryAnd), typeof(NpgsqlTsQueryEmpty), typeof(NpgsqlTsQueryFollowedBy), - typeof(NpgsqlTsQueryLexeme), typeof(NpgsqlTsQueryNot), typeof(NpgsqlTsQueryOr), typeof(NpgsqlTsQueryBinOp) }) - ] public class TsQueryHandler : NpgsqlTypeHandler, INpgsqlTypeHandler, INpgsqlTypeHandler, INpgsqlTypeHandler, INpgsqlTypeHandler, diff --git a/src/Npgsql/Internal/TypeHandlers/FullTextSearchHandlers/TsVectorHandler.cs b/src/Npgsql/Internal/TypeHandlers/FullTextSearchHandlers/TsVectorHandler.cs index 72b7f91344..9523e2d3d3 100644 --- a/src/Npgsql/Internal/TypeHandlers/FullTextSearchHandlers/TsVectorHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/FullTextSearchHandlers/TsVectorHandler.cs @@ -22,7 +22,6 @@ namespace Npgsql.Internal.TypeHandlers.FullTextSearchHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("tsvector", NpgsqlDbType.TsVector, typeof(NpgsqlTsVector))] public class TsVectorHandler : NpgsqlTypeHandler { // 2561 = 2046 (max length lexeme string) + (1) null terminator + diff --git a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/BoxHandler.cs b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/BoxHandler.cs index d5eac1c373..1786f5b121 100644 --- a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/BoxHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/BoxHandler.cs @@ -16,7 +16,6 @@ namespace Npgsql.Internal.TypeHandlers.GeometricHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("box", NpgsqlDbType.Box, typeof(NpgsqlBox))] public class BoxHandler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/CircleHandler.cs b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/CircleHandler.cs index d4ec7725ec..48cb08dd67 100644 --- a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/CircleHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/CircleHandler.cs @@ -16,7 +16,6 @@ namespace Npgsql.Internal.TypeHandlers.GeometricHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("circle", NpgsqlDbType.Circle, typeof(NpgsqlCircle))] public class CircleHandler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/LineHandler.cs b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/LineHandler.cs index 73fcba6588..c36eefacb6 100644 --- a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/LineHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/LineHandler.cs @@ -16,7 +16,6 @@ namespace Npgsql.Internal.TypeHandlers.GeometricHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("line", NpgsqlDbType.Line, typeof(NpgsqlLine))] public class LineHandler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/LineSegmentHandler.cs b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/LineSegmentHandler.cs index c3be425f7a..83966cdfdd 100644 --- a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/LineSegmentHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/LineSegmentHandler.cs @@ -16,7 +16,6 @@ namespace Npgsql.Internal.TypeHandlers.GeometricHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("lseg", NpgsqlDbType.LSeg, typeof(NpgsqlLSeg))] public class LineSegmentHandler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PathHandler.cs b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PathHandler.cs index fa101abcfb..94af953cd2 100644 --- a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PathHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PathHandler.cs @@ -19,7 +19,6 @@ namespace Npgsql.Internal.TypeHandlers.GeometricHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("path", NpgsqlDbType.Path, typeof(NpgsqlPath))] public class PathHandler : NpgsqlTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PointHandler.cs b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PointHandler.cs index 15b15ac8f4..c504b59035 100644 --- a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PointHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PointHandler.cs @@ -16,7 +16,6 @@ namespace Npgsql.Internal.TypeHandlers.GeometricHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("point", NpgsqlDbType.Point, typeof(NpgsqlPoint))] public class PointHandler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PolygonHandler.cs b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PolygonHandler.cs index a75e0e4b77..00a681d370 100644 --- a/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PolygonHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/GeometricHandlers/PolygonHandler.cs @@ -18,7 +18,6 @@ namespace Npgsql.Internal.TypeHandlers.GeometricHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("polygon", NpgsqlDbType.Polygon, typeof(NpgsqlPolygon))] public class PolygonHandler : NpgsqlTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/HstoreHandler.cs b/src/Npgsql/Internal/TypeHandlers/HstoreHandler.cs index d8e6a7513d..8a6c42632c 100644 --- a/src/Npgsql/Internal/TypeHandlers/HstoreHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/HstoreHandler.cs @@ -25,14 +25,6 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("hstore", NpgsqlDbType.Hstore, new[] - { - typeof(Dictionary), - typeof(IDictionary), -#if !NETSTANDARD2_0 && !NETSTANDARD2_1 - typeof(ImmutableDictionary) -#endif - })] public class HstoreHandlerFactory : NpgsqlTypeHandlerFactory> { /// @@ -92,7 +84,7 @@ public int ValidateAndGetLength(IDictionary value, ref NpgsqlLe totalLen += _textHandler.ValidateAndGetLength(kv.Value!, ref lengthCache, null); } - return lengthCache.Lengths[pos] = totalLen; + return lengthCache!.Lengths[pos] = totalLen; } /// diff --git a/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/Int2VectorHandler.cs b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/Int2VectorHandler.cs index ed8af28eb0..c172f93249 100644 --- a/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/Int2VectorHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/Int2VectorHandler.cs @@ -7,7 +7,6 @@ namespace Npgsql.Internal.TypeHandlers.InternalTypeHandlers { - [TypeMapping("int2vector", NpgsqlDbType.Int2Vector)] class Int2VectorHandlerFactory : NpgsqlTypeHandlerFactory { public override NpgsqlTypeHandler CreateNonGeneric(PostgresType pgType, NpgsqlConnection conn) diff --git a/src/Npgsql/Internal/TypeHandlers/InternalCharHandler.cs b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/InternalCharHandler.cs similarity index 96% rename from src/Npgsql/Internal/TypeHandlers/InternalCharHandler.cs rename to src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/InternalCharHandler.cs index 88e54cc895..93ab2b05af 100644 --- a/src/Npgsql/Internal/TypeHandlers/InternalCharHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/InternalCharHandler.cs @@ -1,10 +1,8 @@ using Npgsql.BackendMessages; using Npgsql.Internal.TypeHandling; using Npgsql.PostgresTypes; -using Npgsql.TypeMapping; -using NpgsqlTypes; -namespace Npgsql.Internal.TypeHandlers +namespace Npgsql.Internal.TypeHandlers.InternalTypeHandlers { /// /// A type handler for the PostgreSQL "char" type, used only internally. @@ -16,7 +14,6 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("char", NpgsqlDbType.InternalChar)] public class InternalCharHandler : NpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler { diff --git a/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/OIDVectorHandler.cs b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/OIDVectorHandler.cs index 0b75e0ad31..64a8128a9f 100644 --- a/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/OIDVectorHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/OIDVectorHandler.cs @@ -7,7 +7,6 @@ namespace Npgsql.Internal.TypeHandlers.InternalTypeHandlers { - [TypeMapping("oidvector", NpgsqlDbType.Oidvector)] class OIDVectorHandlerFactory : NpgsqlTypeHandlerFactory { public override NpgsqlTypeHandler CreateNonGeneric(PostgresType pgType, NpgsqlConnection conn) diff --git a/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/PgLsnHandler.cs b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/PgLsnHandler.cs index fa716cc04a..3711f18b4b 100644 --- a/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/PgLsnHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/PgLsnHandler.cs @@ -2,12 +2,10 @@ using Npgsql.BackendMessages; using Npgsql.Internal.TypeHandling; using Npgsql.PostgresTypes; -using Npgsql.TypeMapping; using NpgsqlTypes; namespace Npgsql.Internal.TypeHandlers.InternalTypeHandlers { - [TypeMapping("pg_lsn", NpgsqlDbType.PgLsn, typeof(NpgsqlLogSequenceNumber))] class PgLsnHandler : NpgsqlSimpleTypeHandler { public PgLsnHandler(PostgresType postgresType) : base(postgresType) {} diff --git a/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/TidHandler.cs b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/TidHandler.cs index 71e4a07389..c514f05277 100644 --- a/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/TidHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/InternalTypeHandlers/TidHandler.cs @@ -7,7 +7,6 @@ namespace Npgsql.Internal.TypeHandlers.InternalTypeHandlers { - [TypeMapping("tid", NpgsqlDbType.Tid, typeof(NpgsqlTid))] class TidHandler : NpgsqlSimpleTypeHandler { public TidHandler(PostgresType postgresType) : base(postgresType) {} diff --git a/src/Npgsql/Internal/TypeHandlers/JsonHandler.cs b/src/Npgsql/Internal/TypeHandlers/JsonHandler.cs index 30be869527..12e194b330 100644 --- a/src/Npgsql/Internal/TypeHandlers/JsonHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/JsonHandler.cs @@ -21,7 +21,6 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("jsonb", NpgsqlDbType.Jsonb, typeof(JsonDocument))] public class JsonbHandlerFactory : NpgsqlTypeHandlerFactory { readonly JsonSerializerOptions? _serializerOptions; @@ -48,7 +47,6 @@ public override NpgsqlTypeHandler Create(PostgresType postgresType, Npgs /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("json", NpgsqlDbType.Json)] public class JsonHandlerFactory : NpgsqlTypeHandlerFactory { readonly JsonSerializerOptions? _serializerOptions; diff --git a/src/Npgsql/Internal/TypeHandlers/JsonPathHandler.cs b/src/Npgsql/Internal/TypeHandlers/JsonPathHandler.cs index aee001ce18..48d35a30eb 100644 --- a/src/Npgsql/Internal/TypeHandlers/JsonPathHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/JsonPathHandler.cs @@ -20,7 +20,6 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("jsonpath", NpgsqlDbType.JsonPath)] public class JsonPathHandlerFactory : NpgsqlTypeHandlerFactory { /// diff --git a/src/Npgsql/Internal/TypeHandlers/LQueryHandler.cs b/src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LQueryHandler.cs similarity index 96% rename from src/Npgsql/Internal/TypeHandlers/LQueryHandler.cs rename to src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LQueryHandler.cs index 93c58b4bb9..19ed4de726 100644 --- a/src/Npgsql/Internal/TypeHandlers/LQueryHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LQueryHandler.cs @@ -5,12 +5,9 @@ using Npgsql.BackendMessages; using Npgsql.Internal.TypeHandling; using Npgsql.PostgresTypes; -using Npgsql.TypeMapping; -using NpgsqlTypes; -namespace Npgsql.Internal.TypeHandlers +namespace Npgsql.Internal.TypeHandlers.LTreeHandlers { - [TypeMapping("lquery", NpgsqlDbType.LQuery)] class LQueryHandlerFactory : NpgsqlTypeHandlerFactory { public override NpgsqlTypeHandler Create(PostgresType postgresType, NpgsqlConnection conn) diff --git a/src/Npgsql/Internal/TypeHandlers/LTreeHandler.cs b/src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LTreeHandler.cs similarity index 96% rename from src/Npgsql/Internal/TypeHandlers/LTreeHandler.cs rename to src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LTreeHandler.cs index 52e0bd6338..224d9f9df1 100644 --- a/src/Npgsql/Internal/TypeHandlers/LTreeHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LTreeHandler.cs @@ -5,12 +5,9 @@ using Npgsql.BackendMessages; using Npgsql.Internal.TypeHandling; using Npgsql.PostgresTypes; -using Npgsql.TypeMapping; -using NpgsqlTypes; -namespace Npgsql.Internal.TypeHandlers +namespace Npgsql.Internal.TypeHandlers.LTreeHandlers { - [TypeMapping("ltree", NpgsqlDbType.LTree)] class LTreeHandlerFactory : NpgsqlTypeHandlerFactory { public override NpgsqlTypeHandler Create(PostgresType postgresType, NpgsqlConnection conn) diff --git a/src/Npgsql/Internal/TypeHandlers/LTxtQueryHandler.cs b/src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LTxtQueryHandler.cs similarity index 96% rename from src/Npgsql/Internal/TypeHandlers/LTxtQueryHandler.cs rename to src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LTxtQueryHandler.cs index 632090e765..66361a23c4 100644 --- a/src/Npgsql/Internal/TypeHandlers/LTxtQueryHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/LTreeHandlers/LTxtQueryHandler.cs @@ -5,12 +5,9 @@ using Npgsql.BackendMessages; using Npgsql.Internal.TypeHandling; using Npgsql.PostgresTypes; -using Npgsql.TypeMapping; -using NpgsqlTypes; -namespace Npgsql.Internal.TypeHandlers +namespace Npgsql.Internal.TypeHandlers.LTreeHandlers { - [TypeMapping("ltxtquery", NpgsqlDbType.LTxtQuery)] class LTxtQueryHandlerFactory : NpgsqlTypeHandlerFactory { public override NpgsqlTypeHandler Create(PostgresType postgresType, NpgsqlConnection conn) diff --git a/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/CidrHandler.cs b/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/CidrHandler.cs index 8b345c2dd7..02f8e08663 100644 --- a/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/CidrHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/CidrHandler.cs @@ -19,7 +19,6 @@ namespace Npgsql.Internal.TypeHandlers.NetworkHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("cidr", NpgsqlDbType.Cidr)] public class CidrHandler : NpgsqlSimpleTypeHandler<(IPAddress Address, int Subnet)>, INpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/InetHandler.cs b/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/InetHandler.cs index 3ca4693db5..5a36076145 100644 --- a/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/InetHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/InetHandler.cs @@ -24,10 +24,6 @@ namespace Npgsql.Internal.TypeHandlers.NetworkHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping( - "inet", - NpgsqlDbType.Inet, - new[] { typeof(IPAddress), typeof((IPAddress Address, int Subnet)), typeof(NpgsqlInet) })] public class InetHandler : NpgsqlSimpleTypeHandlerWithPsv, INpgsqlSimpleTypeHandler { diff --git a/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/MacaddrHandler.cs b/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/MacaddrHandler.cs index a72ef1b606..d8651d4613 100644 --- a/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/MacaddrHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NetworkHandlers/MacaddrHandler.cs @@ -18,8 +18,6 @@ namespace Npgsql.Internal.TypeHandlers.NetworkHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("macaddr8", NpgsqlDbType.MacAddr8)] - [TypeMapping("macaddr", NpgsqlDbType.MacAddr, typeof(PhysicalAddress))] public class MacaddrHandler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/DoubleHandler.cs b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/DoubleHandler.cs index 49679152ff..96fbb170de 100644 --- a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/DoubleHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/DoubleHandler.cs @@ -17,7 +17,6 @@ namespace Npgsql.Internal.TypeHandlers.NumericHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("double precision", NpgsqlDbType.Double, DbType.Double, typeof(double))] public class DoubleHandler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int16Handler.cs b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int16Handler.cs index 8172fb2300..b586a0deb8 100644 --- a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int16Handler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int16Handler.cs @@ -17,7 +17,6 @@ namespace Npgsql.Internal.TypeHandlers.NumericHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("smallint", NpgsqlDbType.Smallint, new[] { DbType.Int16, DbType.Byte, DbType.SByte }, new[] { typeof(short), typeof(byte), typeof(sbyte) }, DbType.Int16)] public class Int16Handler : NpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler diff --git a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int32Handler.cs b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int32Handler.cs index ad6a5b9656..9fa57b9832 100644 --- a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int32Handler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int32Handler.cs @@ -17,7 +17,6 @@ namespace Npgsql.Internal.TypeHandlers.NumericHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("integer", NpgsqlDbType.Integer, DbType.Int32, typeof(int))] public class Int32Handler : NpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler diff --git a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int64Handler.cs b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int64Handler.cs index 39d310ca65..35df654c37 100644 --- a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int64Handler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/Int64Handler.cs @@ -17,7 +17,6 @@ namespace Npgsql.Internal.TypeHandlers.NumericHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("bigint", NpgsqlDbType.Bigint, DbType.Int64, typeof(long))] public class Int64Handler : NpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler diff --git a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/MoneyHandler.cs b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/MoneyHandler.cs index a35be45ca1..2d178071d4 100644 --- a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/MoneyHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/MoneyHandler.cs @@ -18,7 +18,6 @@ namespace Npgsql.Internal.TypeHandlers.NumericHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("money", NpgsqlDbType.Money, dbType: DbType.Currency)] public class MoneyHandler : NpgsqlSimpleTypeHandler { const int MoneyScale = 2; diff --git a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/NumericHandler.cs b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/NumericHandler.cs index 0a5bd320fb..a580fccb0c 100644 --- a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/NumericHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/NumericHandler.cs @@ -18,7 +18,6 @@ namespace Npgsql.Internal.TypeHandlers.NumericHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("numeric", NpgsqlDbType.Numeric, new[] { DbType.Decimal, DbType.VarNumeric }, typeof(decimal), DbType.Decimal)] public class NumericHandler : NpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler diff --git a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/SingleHandler.cs b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/SingleHandler.cs index 6f681fa350..7b036c59d8 100644 --- a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/SingleHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/SingleHandler.cs @@ -17,7 +17,6 @@ namespace Npgsql.Internal.TypeHandlers.NumericHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("real", NpgsqlDbType.Real, DbType.Single, typeof(float))] public class SingleHandler : NpgsqlSimpleTypeHandler, INpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/UInt32Handler.cs b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/UInt32Handler.cs index 0fd2c45300..7b4dc888b3 100644 --- a/src/Npgsql/Internal/TypeHandlers/NumericHandlers/UInt32Handler.cs +++ b/src/Npgsql/Internal/TypeHandlers/NumericHandlers/UInt32Handler.cs @@ -16,11 +16,6 @@ namespace Npgsql.Internal.TypeHandlers.NumericHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("oid", NpgsqlDbType.Oid)] - [TypeMapping("xid", NpgsqlDbType.Xid)] - [TypeMapping("cid", NpgsqlDbType.Cid)] - [TypeMapping("regtype", NpgsqlDbType.Regtype)] - [TypeMapping("regconfig", NpgsqlDbType.Regconfig)] public class UInt32Handler : NpgsqlSimpleTypeHandler { /// diff --git a/src/Npgsql/Internal/TypeHandlers/RecordHandler.cs b/src/Npgsql/Internal/TypeHandlers/RecordHandler.cs index 69349ec30e..e6c768219a 100644 --- a/src/Npgsql/Internal/TypeHandlers/RecordHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/RecordHandler.cs @@ -8,7 +8,6 @@ namespace Npgsql.Internal.TypeHandlers { - [TypeMapping("record")] class RecordHandlerFactory : NpgsqlTypeHandlerFactory { public override NpgsqlTypeHandler Create(PostgresType pgType, NpgsqlConnection conn) diff --git a/src/Npgsql/Internal/TypeHandlers/TextHandler.cs b/src/Npgsql/Internal/TypeHandlers/TextHandler.cs index 214e389f46..82c07b7e47 100644 --- a/src/Npgsql/Internal/TypeHandlers/TextHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/TextHandler.cs @@ -22,19 +22,7 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("text", NpgsqlDbType.Text, - new[] { DbType.String, DbType.StringFixedLength, DbType.AnsiString, DbType.AnsiStringFixedLength }, - new[] { typeof(string), typeof(char[]), typeof(char), typeof(ArraySegment) }, - DbType.String - )] - [TypeMapping("xml", NpgsqlDbType.Xml, dbType: DbType.Xml)] - - [TypeMapping("character varying", NpgsqlDbType.Varchar, inferredDbType: DbType.String)] - [TypeMapping("character", NpgsqlDbType.Char, inferredDbType: DbType.String)] - [TypeMapping("name", NpgsqlDbType.Name, inferredDbType: DbType.String)] - [TypeMapping("refcursor", NpgsqlDbType.Refcursor, inferredDbType: DbType.String)] - [TypeMapping("citext", NpgsqlDbType.Citext, inferredDbType: DbType.String)] - [TypeMapping("unknown")] + public class TextHandlerFactory : NpgsqlTypeHandlerFactory { /// diff --git a/src/Npgsql/Internal/TypeHandlers/UuidHandler.cs b/src/Npgsql/Internal/TypeHandlers/UuidHandler.cs index 3c3e0edb9c..6925f62ff6 100644 --- a/src/Npgsql/Internal/TypeHandlers/UuidHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/UuidHandler.cs @@ -19,7 +19,6 @@ namespace Npgsql.Internal.TypeHandlers /// should be considered somewhat unstable, and may change in breaking ways, including in non-major releases. /// Use it at your own risk. /// - [TypeMapping("uuid", NpgsqlDbType.Uuid, DbType.Guid, typeof(Guid))] public class UuidHandler : NpgsqlSimpleTypeHandler { // The following table shows .NET GUID vs Postgres UUID (RFC 4122) layouts. diff --git a/src/Npgsql/Internal/TypeHandlers/VoidHandler.cs b/src/Npgsql/Internal/TypeHandlers/VoidHandler.cs index 1ea189f745..0d76eda1f6 100644 --- a/src/Npgsql/Internal/TypeHandlers/VoidHandler.cs +++ b/src/Npgsql/Internal/TypeHandlers/VoidHandler.cs @@ -9,7 +9,6 @@ namespace Npgsql.Internal.TypeHandlers /// /// https://www.postgresql.org/docs/current/static/datatype-boolean.html /// - [TypeMapping("void")] class VoidHandler : NpgsqlSimpleTypeHandler { public VoidHandler(PostgresType postgresType) : base(postgresType) {} diff --git a/src/Npgsql/TypeMapping/EntityFrameworkCoreCompat.cs b/src/Npgsql/TypeMapping/EntityFrameworkCoreCompat.cs deleted file mode 100644 index db347da38e..0000000000 --- a/src/Npgsql/TypeMapping/EntityFrameworkCoreCompat.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Npgsql.TypeMapping; - -// This file contains some pretty awful hacks to make current version of the EF Core provider -// compatible with the new type mapping/handling system introduced in Npgsql 4.0. -// The EF Core provider dynamically loads its type mappings from Npgsql, which allows it to -// automatically support any type supported by Npgsql. Unfortunately, the current loading -// system is very tightly coupled to pre-3.2 type mapping types (e.g. TypeHandlerRegistry), -// and so this shim is required. - -// ReSharper disable once CheckNamespace -namespace Npgsql -{ - [Obsolete("Purely for EF Core backwards compatibility")] - class TypeHandlerRegistry - { - internal static readonly Dictionary HandlerTypes; - - static TypeHandlerRegistry() - { - HandlerTypes = GlobalTypeMapper.Instance.Mappings.Values.ToDictionary( - m => m.PgTypeName, - m => new TypeAndMapping - { - HandlerType = typeof(TypeHandler<>).MakeGenericType(m.TypeHandlerFactory.DefaultValueType), - Mapping = new TypeMappingAttribute(m.PgTypeName, m.NpgsqlDbType, - m.DbTypes, m.ClrTypes, m.InferredDbType) - } - ); - } - } - - // ReSharper disable once UnusedTypeParameter - [Obsolete("Purely for EF Core backwards compatibility")] - class TypeHandler {} - - [Obsolete("Purely for EF Core backwards compatibility")] - struct TypeAndMapping - { - internal Type HandlerType; - internal TypeMappingAttribute Mapping; - } -} diff --git a/src/Npgsql/TypeMapping/GlobalTypeMapper.cs b/src/Npgsql/TypeMapping/GlobalTypeMapper.cs index 2138be1948..197c0f9f6f 100644 --- a/src/Npgsql/TypeMapping/GlobalTypeMapper.cs +++ b/src/Npgsql/TypeMapping/GlobalTypeMapper.cs @@ -1,10 +1,23 @@ using System; +using System.Collections; using System.Collections.Generic; +using System.Collections.Immutable; +using System.Collections.Specialized; using System.Data; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Reflection; +using System.Text.Json; using System.Threading; +using Npgsql.Internal.TypeHandlers; +using Npgsql.Internal.TypeHandlers.DateTimeHandlers; +using Npgsql.Internal.TypeHandlers.FullTextSearchHandlers; +using Npgsql.Internal.TypeHandlers.GeometricHandlers; +using Npgsql.Internal.TypeHandlers.InternalTypeHandlers; +using Npgsql.Internal.TypeHandlers.LTreeHandlers; +using Npgsql.Internal.TypeHandlers.NetworkHandlers; +using Npgsql.Internal.TypeHandlers.NumericHandlers; using Npgsql.Internal.TypeHandling; using Npgsql.NameTranslation; using NpgsqlTypes; @@ -29,7 +42,7 @@ class GlobalTypeMapper : TypeMapperBase static GlobalTypeMapper() { var instance = new GlobalTypeMapper(); - instance.SetupGlobalTypeMapper(); + instance.SetupBuiltInHandlers(); Instance = instance; } @@ -90,7 +103,7 @@ public override void Reset() try { Mappings.Clear(); - SetupGlobalTypeMapper(); + SetupBuiltInHandlers(); RecordChange(); } finally @@ -155,76 +168,537 @@ internal NpgsqlDbType ToNpgsqlDbType(Type type) #region Setup for built-in handlers - void SetupGlobalTypeMapper() + void SetupBuiltInHandlers() { - // Look for TypeHandlerFactories with mappings in our assembly, set them up - foreach (var t in typeof(TypeMapperBase).GetTypeInfo().Assembly.GetTypes().Where(t => typeof(NpgsqlTypeHandlerFactory).IsAssignableFrom(t.GetTypeInfo()))) + SetupNumericHandlers(); + SetupTextHandlers(); + SetupDateTimeHandlers(); + SetupNetworkHandlers(); + SetupFullTextSearchHandlers(); + SetupGeometryHandlers(); + SetupLTreeHandlers(); + SetupUIntHandlers(); + SetupMiscHandlers(); + SetupInternalHandlers(); + + void SetupNumericHandlers() { - var mappingAttributes = t.GetTypeInfo().GetCustomAttributes(typeof(TypeMappingAttribute), false); - if (!mappingAttributes.Any()) - continue; + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "smallint", + NpgsqlDbType = NpgsqlDbType.Smallint, + DbTypes = new[] { DbType.Int16, DbType.Byte, DbType.SByte }, + InferredDbType = DbType.Int16, + ClrTypes = new[] { typeof(short), typeof(byte), typeof(sbyte) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(Int16Handler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "integer", + NpgsqlDbType = NpgsqlDbType.Integer, + DbTypes = new[] { DbType.Int32 }, + ClrTypes = new[] { typeof(int) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(Int32Handler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "bigint", + NpgsqlDbType = NpgsqlDbType.Bigint, + DbTypes = new[] { DbType.Int64 }, + ClrTypes = new[] { typeof(long) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(Int64Handler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "real", + NpgsqlDbType = NpgsqlDbType.Real, + DbTypes = new[] { DbType.Single }, + ClrTypes = new[] { typeof(float) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(SingleHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "double precision", + NpgsqlDbType = NpgsqlDbType.Double, + DbTypes = new[] { DbType.Double }, + ClrTypes = new[] { typeof(double) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(DoubleHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "numeric", + NpgsqlDbType = NpgsqlDbType.Numeric, + DbTypes = new[] { DbType.Decimal, DbType.VarNumeric }, + InferredDbType = DbType.Decimal, + ClrTypes = new[] { typeof(decimal) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(NumericHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "money", + NpgsqlDbType = NpgsqlDbType.Money, + DbTypes = new[] { DbType.Currency }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(MoneyHandler)) + }.Build()); + } + + void SetupTextHandlers() + { + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "text", + NpgsqlDbType = NpgsqlDbType.Text, + DbTypes = new[] { DbType.String, DbType.StringFixedLength, DbType.AnsiString, DbType.AnsiStringFixedLength }, + InferredDbType = DbType.String, + ClrTypes = new[] { typeof(string), typeof(char[]), typeof(char), typeof(ArraySegment) }, + TypeHandlerFactory = new TextHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "xml", + NpgsqlDbType = NpgsqlDbType.Xml, + DbTypes = new[] { DbType.Xml }, + TypeHandlerFactory = new TextHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "character varying", + NpgsqlDbType = NpgsqlDbType.Varchar, + InferredDbType = DbType.String, + TypeHandlerFactory = new TextHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "character", + NpgsqlDbType = NpgsqlDbType.Char, + InferredDbType = DbType.String, + TypeHandlerFactory = new TextHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "name", + NpgsqlDbType = NpgsqlDbType.Name, + InferredDbType = DbType.String, + TypeHandlerFactory = new TextHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "refcursor", + NpgsqlDbType = NpgsqlDbType.Refcursor, + InferredDbType = DbType.String, + TypeHandlerFactory = new TextHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "citext", + NpgsqlDbType = NpgsqlDbType.Citext, + InferredDbType = DbType.String, + TypeHandlerFactory = new TextHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "unknown", + TypeHandlerFactory = new TextHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "jsonb", + NpgsqlDbType = NpgsqlDbType.Jsonb, + ClrTypes = new[] { typeof(JsonDocument) }, + TypeHandlerFactory = new JsonbHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "json", + NpgsqlDbType = NpgsqlDbType.Json, + TypeHandlerFactory = new JsonHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "jsonpath", + NpgsqlDbType = NpgsqlDbType.JsonPath, + TypeHandlerFactory = new JsonPathHandlerFactory() + }.Build()); + + } - var factory = (NpgsqlTypeHandlerFactory)Activator.CreateInstance(t)!; + void SetupDateTimeHandlers() + { + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "timestamp without time zone", + NpgsqlDbType = NpgsqlDbType.Timestamp, + DbTypes = new[] { DbType.DateTime, DbType.DateTime2 }, + ClrTypes = new[] { typeof(NpgsqlDateTime), typeof(DateTime) }, + InferredDbType = DbType.DateTime, + TypeHandlerFactory = new TimestampHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "timestamp with time zone", + NpgsqlDbType = NpgsqlDbType.TimestampTz, + DbTypes = new[] { DbType.DateTimeOffset }, + ClrTypes = new[] { typeof(DateTimeOffset) }, + TypeHandlerFactory = new TimestampTzHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "date", + NpgsqlDbType = NpgsqlDbType.Date, + DbTypes = new[] { DbType.Date }, + ClrTypes = new[] { typeof(NpgsqlDate) }, + TypeHandlerFactory = new DateHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "time without time zone", + NpgsqlDbType = NpgsqlDbType.Time, + DbTypes = new[] { DbType.Time }, + TypeHandlerFactory = new TimeHandlerFactory() + }.Build()); - foreach (TypeMappingAttribute m in mappingAttributes) + AddMapping(new NpgsqlTypeMappingBuilder { - // TODO: Duplication between TypeMappingAttribute and TypeMapping. Look at this later. - AddMapping(new NpgsqlTypeMappingBuilder + PgTypeName = "time with time zone", + NpgsqlDbType = NpgsqlDbType.TimeTz, + TypeHandlerFactory = new TimeTzHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "interval", + NpgsqlDbType = NpgsqlDbType.Interval, + ClrTypes = new[] { typeof(TimeSpan), typeof(NpgsqlTimeSpan) }, + TypeHandlerFactory = new IntervalHandlerFactory() + }.Build()); + } + + void SetupNetworkHandlers() + { + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "cidr", + NpgsqlDbType = NpgsqlDbType.Cidr, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(CidrHandler)) + }.Build()); + + var inetClrTypes = new List + { + typeof(IPAddress), typeof((IPAddress Address, int Subnet)), +#pragma warning disable 618 + typeof(NpgsqlInet) +#pragma warning restore 618 + }; + + // Support ReadOnlyIPAddress, which was added to .NET Core 3.0 as an internal subclass of IPAddress + if (typeof(IPAddress).GetNestedType("ReadOnlyIPAddress", BindingFlags.NonPublic) is Type readOnlyIpType) + inetClrTypes.Add(readOnlyIpType); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "inet", + NpgsqlDbType = NpgsqlDbType.Inet, + ClrTypes = inetClrTypes.ToArray(), + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(InetHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "macaddr8", + NpgsqlDbType = NpgsqlDbType.MacAddr8, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(MacaddrHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "macaddr", + NpgsqlDbType = NpgsqlDbType.MacAddr, + ClrTypes = new[] { typeof(PhysicalAddress) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(MacaddrHandler)) + }.Build()); + } + + void SetupFullTextSearchHandlers() + { + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "tsquery", + NpgsqlDbType = NpgsqlDbType.TsQuery, + ClrTypes = new[] { - PgTypeName = m.PgName, - NpgsqlDbType = m.NpgsqlDbType, - DbTypes = m.DbTypes, - ClrTypes = m.ClrTypes, - InferredDbType = m.InferredDbType, - TypeHandlerFactory = factory, - }.Build()); - } + typeof(NpgsqlTsQuery), typeof(NpgsqlTsQueryAnd), typeof(NpgsqlTsQueryEmpty), typeof(NpgsqlTsQueryFollowedBy), + typeof(NpgsqlTsQueryLexeme), typeof(NpgsqlTsQueryNot), typeof(NpgsqlTsQueryOr), typeof(NpgsqlTsQueryBinOp) + }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(TsQueryHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "tsvector", + NpgsqlDbType = NpgsqlDbType.TsVector, + ClrTypes = new[] { typeof(NpgsqlTsVector) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(TsVectorHandler)) + }.Build()); } - // Look for NpgsqlTypeHandler classes with mappings in our assembly, set them up with the DefaultTypeHandlerFactory. - // This is a shortcut that allows us to not specify a factory for each and every type handler - foreach (var t in typeof(TypeMapperBase).GetTypeInfo().Assembly.GetTypes().Where(t => t.GetTypeInfo().IsSubclassOf(typeof(NpgsqlTypeHandler)))) + void SetupGeometryHandlers() { - var mappingAttributes = t.GetTypeInfo().GetCustomAttributes(typeof(TypeMappingAttribute), false); - if (!mappingAttributes.Any()) - continue; + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "box", + NpgsqlDbType = NpgsqlDbType.Box, + ClrTypes = new[] { typeof(NpgsqlBox) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(BoxHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "circle", + NpgsqlDbType = NpgsqlDbType.Circle, + ClrTypes = new[] { typeof(NpgsqlCircle) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(CircleHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "line", + NpgsqlDbType = NpgsqlDbType.Line, + ClrTypes = new[] { typeof(NpgsqlLine) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(LineHandler)) + }.Build()); - var factory = new DefaultTypeHandlerFactory(t); + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "lseg", + NpgsqlDbType = NpgsqlDbType.LSeg, + ClrTypes = new[] { typeof(NpgsqlLSeg) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(LineSegmentHandler)) + }.Build()); - foreach (TypeMappingAttribute m in mappingAttributes) + AddMapping(new NpgsqlTypeMappingBuilder { - // TODO: Duplication between TypeMappingAttribute and TypeMapping. Look at this later. - AddMapping(new NpgsqlTypeMappingBuilder + PgTypeName = "path", + NpgsqlDbType = NpgsqlDbType.Path, + ClrTypes = new[] { typeof(NpgsqlPath) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(PathHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "point", + NpgsqlDbType = NpgsqlDbType.Point, + ClrTypes = new[] { typeof(NpgsqlPoint) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(PointHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "polygon", + NpgsqlDbType = NpgsqlDbType.Polygon, + ClrTypes = new[] { typeof(NpgsqlPolygon) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(PolygonHandler)) + }.Build()); + } + + void SetupLTreeHandlers() + { + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "lquery", + NpgsqlDbType = NpgsqlDbType.LQuery, + TypeHandlerFactory = new LQueryHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "ltree", + NpgsqlDbType = NpgsqlDbType.LTree, + TypeHandlerFactory = new LQueryHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "ltxtquery", + NpgsqlDbType = NpgsqlDbType.LTxtQuery, + TypeHandlerFactory = new LQueryHandlerFactory() + }.Build()); + } + + void SetupUIntHandlers() + { + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "oid", + NpgsqlDbType = NpgsqlDbType.Oid, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(UInt32Handler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "xid", + NpgsqlDbType = NpgsqlDbType.Xid, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(UInt32Handler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "cid", + NpgsqlDbType = NpgsqlDbType.Cid, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(UInt32Handler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "regtype", + NpgsqlDbType = NpgsqlDbType.Regtype, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(UInt32Handler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "regconfig", + NpgsqlDbType = NpgsqlDbType.Regconfig, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(UInt32Handler)) + }.Build()); + } + + void SetupMiscHandlers() + { + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "boolean", + NpgsqlDbType = NpgsqlDbType.Boolean, + DbTypes = new[] { DbType.Boolean }, + ClrTypes = new[] { typeof(bool) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(BoolHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "bytea", + NpgsqlDbType = NpgsqlDbType.Bytea, + DbTypes = new[] { DbType.Binary }, + ClrTypes = new[] { - PgTypeName = m.PgName, - NpgsqlDbType = m.NpgsqlDbType, - DbTypes = m.DbTypes, - ClrTypes = m.ClrTypes, - InferredDbType = m.InferredDbType, - TypeHandlerFactory = factory - }.Build()); - } + typeof(byte[]), + typeof(ArraySegment), +#if !NETSTANDARD2_0 + typeof(ReadOnlyMemory), + typeof(Memory) +#endif + }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(ByteaHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "bit varying", + NpgsqlDbType = NpgsqlDbType.Varbit, + ClrTypes = new[] { typeof(BitArray), typeof(BitVector32) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(BitStringHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "bit", + NpgsqlDbType = NpgsqlDbType.Bit, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(BitStringHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "hstore", + NpgsqlDbType = NpgsqlDbType.Hstore, + ClrTypes = new[] + { + typeof(Dictionary), + typeof(IDictionary), +#if !NETSTANDARD2_0 && !NETSTANDARD2_1 + typeof(ImmutableDictionary) +#endif + }, + TypeHandlerFactory = new HstoreHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "uuid", + NpgsqlDbType = NpgsqlDbType.Uuid, + DbTypes = new[] { DbType.Guid }, + ClrTypes = new[] { typeof(Guid) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(UuidHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "record", + TypeHandlerFactory = new RecordHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "void", + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(VoidHandler)) + }.Build()); } - // This is an extremely ugly hack to support ReadOnlyIPAddress, which as an internal subclass of IPAddress - // added to .NET Core 3.0 (see https://github.com/dotnet/corefx/issues/33373) - if (_typeToNpgsqlDbType.ContainsKey(typeof(IPAddress)) && - Mappings.TryGetValue("inet", out var inetMapping) && - typeof(IPAddress).GetNestedType("ReadOnlyIPAddress", BindingFlags.NonPublic) is Type readOnlyIpType) + void SetupInternalHandlers() { - _typeToNpgsqlDbType[readOnlyIpType] = _typeToNpgsqlDbType[typeof(IPAddress)]; - var augmentedClrType = new Type[inetMapping.ClrTypes.Length + 1]; - Array.Copy(inetMapping.ClrTypes, augmentedClrType, inetMapping.ClrTypes.Length); - augmentedClrType[augmentedClrType.Length - 1] = readOnlyIpType; - Mappings["inet"] = new NpgsqlTypeMappingBuilder + AddMapping(new NpgsqlTypeMappingBuilder { - PgTypeName = "inet", - NpgsqlDbType = inetMapping.NpgsqlDbType, - DbTypes = inetMapping.DbTypes, - ClrTypes = augmentedClrType, - InferredDbType = inetMapping.InferredDbType, - TypeHandlerFactory = inetMapping.TypeHandlerFactory - }.Build(); + PgTypeName = "int2vector", + NpgsqlDbType = NpgsqlDbType.Int2Vector, + TypeHandlerFactory = new Int2VectorHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "oidvector", + NpgsqlDbType = NpgsqlDbType.Oidvector, + TypeHandlerFactory = new OIDVectorHandlerFactory() + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "pg_lsn", + NpgsqlDbType = NpgsqlDbType.PgLsn, + ClrTypes = new[] { typeof(NpgsqlLogSequenceNumber) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(PgLsnHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "tid", + NpgsqlDbType = NpgsqlDbType.Tid, + ClrTypes = new[] { typeof(NpgsqlTid) }, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(TidHandler)) + }.Build()); + + AddMapping(new NpgsqlTypeMappingBuilder + { + PgTypeName = "char", + NpgsqlDbType = NpgsqlDbType.InternalChar, + TypeHandlerFactory = new DefaultTypeHandlerFactory(typeof(InternalCharHandler)) + }.Build()); } } diff --git a/src/Npgsql/TypeMapping/NpgsqlTypeMapping.cs b/src/Npgsql/TypeMapping/NpgsqlTypeMapping.cs index 0c24fbc4ba..f97c3b2bfc 100644 --- a/src/Npgsql/TypeMapping/NpgsqlTypeMapping.cs +++ b/src/Npgsql/TypeMapping/NpgsqlTypeMapping.cs @@ -67,6 +67,13 @@ public NpgsqlTypeMapping Build() if (TypeHandlerFactory is null) throw new ArgumentException($"{nameof(TypeHandlerFactory)} must refer to a type handler factory"); + if (InferredDbType is null && DbTypes?.Length > 0) + { + if (DbTypes.Length > 1) + throw new ArgumentException($"Multiple DbTypes are defined, an InferredDbType must be provided"); + InferredDbType = DbTypes[0]; + } + return new NpgsqlTypeMapping(PgTypeName!, NpgsqlDbType, DbTypes, ClrTypes, InferredDbType, TypeHandlerFactory); } } diff --git a/src/Npgsql/TypeMapping/TypeMappingAttribute.cs b/src/Npgsql/TypeMapping/TypeMappingAttribute.cs deleted file mode 100644 index 63294fa9f8..0000000000 --- a/src/Npgsql/TypeMapping/TypeMappingAttribute.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System; -using System.Data; -using System.Linq; -using System.Text; -using NpgsqlTypes; - -namespace Npgsql.TypeMapping -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - class TypeMappingAttribute : Attribute - { - /// - /// Maps an Npgsql type handler to a PostgreSQL type. - /// - /// A PostgreSQL type name as it appears in the pg_type table. - /// - /// A member of which represents this PostgreSQL type. - /// An with set to - /// this value will be sent with the type handler mapped by this attribute. - /// - /// - /// All members of which represent this PostgreSQL type. - /// An with set to - /// one of these values will be sent with the type handler mapped by this attribute. - /// - /// - /// Any .NET type which corresponds to this PostgreSQL type. - /// An with set to - /// one of these values will be sent with the type handler mapped by this attribute. - /// - /// - /// The "primary" which best corresponds to this PostgreSQL type. - /// When or - /// set, will be set to this value. - /// - internal TypeMappingAttribute(string pgName, NpgsqlDbType? npgsqlDbType, DbType[]? dbTypes, Type[]? clrTypes, DbType? inferredDbType) - { - if (string.IsNullOrWhiteSpace(pgName)) - throw new ArgumentException("pgName can't be empty", nameof(pgName)); - - PgName = pgName; - NpgsqlDbType = npgsqlDbType; - DbTypes = dbTypes ?? new DbType[0]; - ClrTypes = clrTypes ?? new Type[0]; - InferredDbType = inferredDbType; - } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, DbType[] dbTypes, Type[]? clrTypes, DbType inferredDbType) - : this(pgName, (NpgsqlDbType?)npgsqlDbType, dbTypes, clrTypes, inferredDbType) - { } - - //internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, DbType[] dbTypes=null, Type type=null) - // : this(pgName, npgsqlDbType, dbTypes, type == null ? null : new[] { type }) {} - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType) - : this(pgName, npgsqlDbType, new DbType[0], new Type[0], null) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, DbType inferredDbType) - : this(pgName, npgsqlDbType, new DbType[0], new Type[0], inferredDbType) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, DbType[] dbTypes, Type clrType, DbType inferredDbType) - : this(pgName, npgsqlDbType, dbTypes, new[] { clrType }, inferredDbType) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, DbType[] dbTypes) - : this(pgName, npgsqlDbType, dbTypes, new Type[0], null) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, DbType dbType, Type[] clrTypes) - : this(pgName, npgsqlDbType, new[] { dbType }, clrTypes, dbType) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, DbType dbType, Type? clrType = null) - : this(pgName, npgsqlDbType, new[] { dbType }, clrType == null ? null : new[] { clrType }, dbType) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, Type[] clrTypes, DbType inferredDbType) - : this(pgName, npgsqlDbType, new DbType[0], clrTypes, inferredDbType) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, Type[] clrTypes) - : this(pgName, npgsqlDbType, new DbType[0], clrTypes, null) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, Type clrType, DbType inferredDbType) - : this(pgName, npgsqlDbType, new DbType[0], new[] { clrType }, inferredDbType) - { } - - internal TypeMappingAttribute(string pgName, NpgsqlDbType npgsqlDbType, Type clrType) - : this(pgName, npgsqlDbType, new DbType[0], new[] { clrType }, null) - { } - - /// - /// Read-only parameter - /// - internal TypeMappingAttribute(string pgName) - : this(pgName, null, null, null, null) - { } - - internal string PgName { get; } - internal NpgsqlDbType? NpgsqlDbType { get; } - internal DbType[] DbTypes { get; } - internal Type[] ClrTypes { get; } - internal DbType? InferredDbType { get; } - - /// - /// Returns a string that represents the current object. - /// - /// - public override string ToString() - { - var sb = new StringBuilder(); - sb.AppendFormat("[{0} NpgsqlDbType={1}", PgName, NpgsqlDbType); - if (DbTypes.Length > 0) - { - sb.Append(" DbTypes="); - sb.Append(string.Join(",", DbTypes.Select(t => t.ToString()))); - } - if (ClrTypes.Length > 0) - { - sb.Append(" ClrTypes="); - sb.Append(string.Join(",", ClrTypes.Select(t => t.Name))); - } - sb.AppendFormat("]"); - return sb.ToString(); - } - } -} diff --git a/test/Npgsql.Tests/Types/NumericTypeTests.cs b/test/Npgsql.Tests/Types/NumericTypeTests.cs index 923965265d..b4fa7d6df9 100644 --- a/test/Npgsql.Tests/Types/NumericTypeTests.cs +++ b/test/Npgsql.Tests/Types/NumericTypeTests.cs @@ -3,7 +3,6 @@ using System.Data; using System.Globalization; using System.Threading.Tasks; -using Npgsql.Util; using NpgsqlTypes; using NUnit.Framework; From a98f5af10ed1d32c2b08ba7a26748e3d1b33fbad Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 5 Feb 2021 22:03:13 +0100 Subject: [PATCH 2/2] Fix conditional compilation --- src/Npgsql/TypeMapping/GlobalTypeMapper.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Npgsql/TypeMapping/GlobalTypeMapper.cs b/src/Npgsql/TypeMapping/GlobalTypeMapper.cs index 197c0f9f6f..0a98860da2 100644 --- a/src/Npgsql/TypeMapping/GlobalTypeMapper.cs +++ b/src/Npgsql/TypeMapping/GlobalTypeMapper.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Collections.Immutable; using System.Collections.Specialized; using System.Data; using System.Linq; @@ -633,7 +632,7 @@ void SetupMiscHandlers() typeof(Dictionary), typeof(IDictionary), #if !NETSTANDARD2_0 && !NETSTANDARD2_1 - typeof(ImmutableDictionary) + typeof(System.Collections.Immutable.ImmutableDictionary) #endif }, TypeHandlerFactory = new HstoreHandlerFactory()