Skip to content

Commit

Permalink
Generate non-generic write logic with source generators
Browse files Browse the repository at this point in the history
Part of npgsql#2940
Part of npgsql#3300
  • Loading branch information
roji committed Feb 8, 2021
1 parent be31084 commit 9320022
Show file tree
Hide file tree
Showing 68 changed files with 551 additions and 395 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<ItemGroup>
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Version="4.6.0" />
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
<PackageReference Update="System.Threading.Tasks.Extensions" Version="4.5.3" />
<PackageReference Update="System.Memory" Version="4.5.3" />
<PackageReference Update="System.ValueTuple" Version="4.5.0" />
Expand Down
11 changes: 11 additions & 0 deletions Npgsql.sln
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Directory.Build.targets = Directory.Build.targets
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npgsql.SourceGenerators", "src\Npgsql.SourceGenerators\Npgsql.SourceGenerators.csproj", "{63026A19-60B8-4906-81CB-216F30E8094B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -123,6 +125,14 @@ Global
{A77E5FAF-D775-4AB4-8846-8965C2104E60}.Release|Any CPU.Build.0 = Release|Any CPU
{A77E5FAF-D775-4AB4-8846-8965C2104E60}.Release|x86.ActiveCfg = Release|Any CPU
{A77E5FAF-D775-4AB4-8846-8965C2104E60}.Release|x86.Build.0 = Release|Any CPU
{63026A19-60B8-4906-81CB-216F30E8094B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63026A19-60B8-4906-81CB-216F30E8094B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63026A19-60B8-4906-81CB-216F30E8094B}.Debug|x86.ActiveCfg = Debug|Any CPU
{63026A19-60B8-4906-81CB-216F30E8094B}.Debug|x86.Build.0 = Debug|Any CPU
{63026A19-60B8-4906-81CB-216F30E8094B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63026A19-60B8-4906-81CB-216F30E8094B}.Release|Any CPU.Build.0 = Release|Any CPU
{63026A19-60B8-4906-81CB-216F30E8094B}.Release|x86.ActiveCfg = Release|Any CPU
{63026A19-60B8-4906-81CB-216F30E8094B}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -138,6 +148,7 @@ Global
{6CB12050-DC9B-4155-BADD-BFDD54CDD70F} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}
{F7C53EBD-0075-474F-A083-419257D04080} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}
{A77E5FAF-D775-4AB4-8846-8965C2104E60} = {ED612DB1-AB32-4603-95E7-891BACA71C39}
{63026A19-60B8-4906-81CB-216F30E8094B} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C90AEECD-DB4C-4BE6-B506-16A449852FB8}
Expand Down
38 changes: 38 additions & 0 deletions src/Npgsql.GeoJSON/Internal/GeoJSONHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,44 @@ static async Task WritePosition(IPosition coordinate, NpgsqlWriteBuffer buf, boo
buf.WriteDouble(altitude.Value);
}

public override int ValidateObjectAndGetLength(object value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)
=> value switch
{
Point converted => ((INpgsqlTypeHandler<Point>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
MultiPoint converted => ((INpgsqlTypeHandler<MultiPoint>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
Polygon converted => ((INpgsqlTypeHandler<Polygon>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
MultiPolygon converted => ((INpgsqlTypeHandler<MultiPolygon>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
LineString converted => ((INpgsqlTypeHandler<LineString>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
MultiLineString converted => ((INpgsqlTypeHandler<MultiLineString>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
GeometryCollection converted => ((INpgsqlTypeHandler<GeometryCollection>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
GeoJSONObject converted => ((INpgsqlTypeHandler<GeoJSONObject>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
IGeoJSONObject converted => ((INpgsqlTypeHandler<IGeoJSONObject>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
IGeometryObject converted => ((INpgsqlTypeHandler<IGeometryObject>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),

DBNull => -1,
null => -1,
_ => throw new InvalidCastException($"Can't write CLR type {value.GetType()} with handler type GeoJsonHandler")
};

public override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
=> value switch
{
Point converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
MultiPoint converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
Polygon converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
MultiPolygon converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
LineString converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
MultiLineString converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
GeometryCollection converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
GeoJSONObject converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
IGeoJSONObject converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
IGeometryObject converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),

DBNull => WriteWithLengthInternal(DBNull.Value, buf, lengthCache, parameter, async, cancellationToken),
null => WriteWithLengthInternal(DBNull.Value, buf, lengthCache, parameter, async, cancellationToken),
_ => throw new InvalidCastException($"Can't write CLR type {value.GetType()} with handler type GeoJsonHandler")
};

#endregion

#region Crs
Expand Down
4 changes: 2 additions & 2 deletions src/Npgsql.Json.NET/Internal/JsonHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ protected override Task WriteWithLength<T2>(T2 value, NpgsqlWriteBuffer buf, Npg
return base.WriteWithLength(serialized, buf, lengthCache, parameter, async, cancellationToken);
}

protected override int ValidateObjectAndGetLength(object value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)
public override int ValidateObjectAndGetLength(object value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)
{
if (value is DBNull ||
value is string ||
Expand All @@ -91,7 +91,7 @@ value is char ||
return ValidateAndGetLength(value, ref lengthCache, parameter);
}

protected override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
public override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
{
if (value is DBNull ||
value is string ||
Expand Down
4 changes: 2 additions & 2 deletions src/Npgsql.Json.NET/Internal/JsonbHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ protected override Task WriteWithLength<T2>(T2 value, NpgsqlWriteBuffer buf, Npg
return base.WriteWithLength(serialized, buf, lengthCache, parameter, async, cancellationToken);
}

protected override int ValidateObjectAndGetLength(object value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)
public override int ValidateObjectAndGetLength(object value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)
{
if (value is DBNull ||
value is string ||
Expand All @@ -91,7 +91,7 @@ value is char ||
return ValidateAndGetLength(value, ref lengthCache, parameter);
}

protected override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
public override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
{
if (value is DBNull ||
value is string ||
Expand Down
34 changes: 34 additions & 0 deletions src/Npgsql.LegacyPostgis/Internal/LegacyPostgisHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,40 @@ public Task Write(PostgisMultiLineString value, NpgsqlWriteBuffer buf, NpgsqlLen
public Task Write(PostgisGeometryCollection value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
=> Write((PostgisGeometry)value, buf, lengthCache, parameter, async, cancellationToken);

public override int ValidateObjectAndGetLength(object value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)
=> value switch
{
PostgisPoint converted => ((INpgsqlTypeHandler<PostgisPoint>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
PostgisMultiPoint converted => ((INpgsqlTypeHandler<PostgisMultiPoint>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
PostgisLineString converted => ((INpgsqlTypeHandler<PostgisLineString>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
PostgisMultiLineString converted => ((INpgsqlTypeHandler<PostgisMultiLineString>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
PostgisPolygon converted => ((INpgsqlTypeHandler<PostgisPolygon>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
PostgisMultiPolygon converted => ((INpgsqlTypeHandler<PostgisMultiPolygon>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
PostgisGeometryCollection converted => ((INpgsqlTypeHandler<PostgisGeometryCollection>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
PostgisGeometry converted => ((INpgsqlTypeHandler<PostgisGeometry>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),

DBNull => -1,
null => -1,
_ => throw new InvalidCastException($"Can't write CLR type {value.GetType()} with handler type LegacyPostgisHandler")
};

public override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
=> value switch
{
PostgisPoint converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
PostgisMultiPoint converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
PostgisLineString converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
PostgisMultiLineString converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
PostgisPolygon converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
PostgisMultiPolygon converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
PostgisGeometryCollection converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
PostgisGeometry converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
DBNull => WriteWithLengthInternal(DBNull.Value, buf, lengthCache, parameter, async, cancellationToken),
null => WriteWithLengthInternal(DBNull.Value, buf, lengthCache, parameter, async, cancellationToken),
_ => throw new InvalidCastException($"Can't write CLR type {value.GetType()} with handler type LegacyPostgisHandler")
};

#endregion Write
}
}
34 changes: 34 additions & 0 deletions src/Npgsql.NetTopologySuite/Internal/NetTopologySuiteHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,23 @@ int ValidateAndGetLengthCore(Geometry value)
return (int)_lengthStream.Length;
}

public override int ValidateObjectAndGetLength(object value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)
=> value switch
{
Point converted => ((INpgsqlTypeHandler<Point>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
LineString converted => ((INpgsqlTypeHandler<LineString>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
Polygon converted => ((INpgsqlTypeHandler<Polygon>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
MultiPoint converted => ((INpgsqlTypeHandler<MultiPoint>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
MultiLineString converted => ((INpgsqlTypeHandler<MultiLineString>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
MultiPolygon converted => ((INpgsqlTypeHandler<MultiPolygon>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
GeometryCollection converted => ((INpgsqlTypeHandler<GeometryCollection>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),
Geometry converted => ((INpgsqlTypeHandler<Geometry>)this).ValidateAndGetLength(converted, ref lengthCache, parameter),

DBNull => -1,
null => -1,
_ => throw new InvalidCastException($"Can't write CLR type {value.GetType()} with handler type NetTopologySuiteHandler")
};

sealed class LengthStream : Stream
{
long _length;
Expand Down Expand Up @@ -164,6 +181,23 @@ Task WriteCore(Geometry value, NpgsqlWriteBuffer buf)
return Task.CompletedTask;
}

public override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
=> value switch
{
Point converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
LineString converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
Polygon converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
MultiPoint converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
MultiLineString converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
MultiPolygon converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
GeometryCollection converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
Geometry converted => WriteWithLengthInternal(converted, buf, lengthCache, parameter, async, cancellationToken),
DBNull => WriteWithLengthInternal(DBNull.Value, buf, lengthCache, parameter, async, cancellationToken),
null => WriteWithLengthInternal(DBNull.Value, buf, lengthCache, parameter, async, cancellationToken),
_ => throw new InvalidCastException($"Can't write CLR type {value.GetType()} with handler type NetTopologySuiteHandler")
};

#endregion
}
}
2 changes: 1 addition & 1 deletion src/Npgsql.NodaTime/Internal/DateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public override NpgsqlTypeHandler<LocalDate> Create(PostgresType postgresType, N
}
}

sealed class DateHandler : NpgsqlSimpleTypeHandler<LocalDate>, INpgsqlSimpleTypeHandler<DateTime>, INpgsqlSimpleTypeHandler<NpgsqlDate>
sealed partial class DateHandler : NpgsqlSimpleTypeHandler<LocalDate>, INpgsqlSimpleTypeHandler<DateTime>, INpgsqlSimpleTypeHandler<NpgsqlDate>
{
/// <summary>
/// Whether to convert positive and negative infinity values to Instant.{Max,Min}Value when
Expand Down
2 changes: 1 addition & 1 deletion src/Npgsql.NodaTime/Internal/IntervalHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public override NpgsqlTypeHandler<Period> Create(PostgresType postgresType, Npgs
: throw new NotSupportedException($"The deprecated floating-point date/time format is not supported by {nameof(Npgsql)}.");
}

sealed class IntervalHandler :
sealed partial class IntervalHandler :
NpgsqlSimpleTypeHandler<Period>,
INpgsqlSimpleTypeHandler<Duration>,
INpgsqlSimpleTypeHandler<NpgsqlTimeSpan>,
Expand Down
4 changes: 3 additions & 1 deletion src/Npgsql.NodaTime/Internal/TimeHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using NodaTime;
using Npgsql.BackendMessages;
using Npgsql.Internal;
Expand All @@ -17,7 +19,7 @@ public override NpgsqlTypeHandler<LocalTime> Create(PostgresType postgresType, N
: throw new NotSupportedException($"The deprecated floating-point date/time format is not supported by {nameof(Npgsql)}.");
}

sealed class TimeHandler : NpgsqlSimpleTypeHandler<LocalTime>, INpgsqlSimpleTypeHandler<TimeSpan>
sealed partial class TimeHandler : NpgsqlSimpleTypeHandler<LocalTime>, INpgsqlSimpleTypeHandler<TimeSpan>
{
readonly BclTimeHandler _bclHandler;

Expand Down
2 changes: 1 addition & 1 deletion src/Npgsql.NodaTime/Internal/TimeTzHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override NpgsqlTypeHandler<OffsetTime> Create(PostgresType postgresType,
: throw new NotSupportedException($"The deprecated floating-point date/time format is not supported by {nameof(Npgsql)}.");
}

sealed class TimeTzHandler : NpgsqlSimpleTypeHandler<OffsetTime>, INpgsqlSimpleTypeHandler<DateTimeOffset>,
sealed partial class TimeTzHandler : NpgsqlSimpleTypeHandler<OffsetTime>, INpgsqlSimpleTypeHandler<DateTimeOffset>,
INpgsqlSimpleTypeHandler<DateTime>, INpgsqlSimpleTypeHandler<TimeSpan>
{
readonly BclTimeTzHandler _bclHandler;
Expand Down
2 changes: 1 addition & 1 deletion src/Npgsql.NodaTime/Internal/TimestampHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public override NpgsqlTypeHandler<Instant> Create(PostgresType postgresType, Npg
}
}

sealed class TimestampHandler : NpgsqlSimpleTypeHandler<Instant>, INpgsqlSimpleTypeHandler<LocalDateTime>, INpgsqlSimpleTypeHandler<DateTime>
sealed partial class TimestampHandler : NpgsqlSimpleTypeHandler<Instant>, INpgsqlSimpleTypeHandler<LocalDateTime>, INpgsqlSimpleTypeHandler<DateTime>
{
static readonly Instant Instant0 = Instant.FromUtc(1, 1, 1, 0, 0, 0);
static readonly Instant Instant2000 = Instant.FromUtc(2000, 1, 1, 0, 0, 0);
Expand Down
2 changes: 1 addition & 1 deletion src/Npgsql.NodaTime/Internal/TimestampTzHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public override NpgsqlTypeHandler<Instant> Create(PostgresType postgresType, Npg
}
}

sealed class TimestampTzHandler : NpgsqlSimpleTypeHandler<Instant>, INpgsqlSimpleTypeHandler<ZonedDateTime>,
sealed partial class TimestampTzHandler : NpgsqlSimpleTypeHandler<Instant>, INpgsqlSimpleTypeHandler<ZonedDateTime>,
INpgsqlSimpleTypeHandler<OffsetDateTime>, INpgsqlSimpleTypeHandler<DateTimeOffset>,
INpgsqlSimpleTypeHandler<DateTime>
{
Expand Down
3 changes: 3 additions & 0 deletions src/Npgsql.NodaTime/Npgsql.NodaTime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Npgsql\Npgsql.csproj" />
<ProjectReference Include="../Npgsql.SourceGenerators/Npgsql.SourceGenerators.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>
</Project>
Loading

0 comments on commit 9320022

Please sign in to comment.