Skip to content

Commit 0b7aecb

Browse files
NinoFlorisroji
andauthored
Handler rework (npgsql#5123)
* Add legacy datetime support * No unsupported resolver exceptions during introspection * Fixes and a little lie about array types to appease the tests * Add money converter * Add hstore converter * Improve range converter * Rework buffer requirements * Add json and jsonb textual reading/writing * Naming * Implement NTS support Some resolution tweaks still needed * Fix extension check * Fix resolution Arrays are still missing * Fix datatypename normalization from NpgsqlDbType * Remove dead code * Add arrays * More ns2.0 fixes again * Check binary size difference * Move abstract up and impl down * Small fixes * Fix datatable crap * Add more text types * Multiranges * Small fixes * Improve handling of sequential access cursor * Bounded column reads * Small fixes and TextReader support * Final changes on bounded reads Also some bug fixes due to bounded reads correctly failing due to unhandled data! * Implement GetChars over TextReader * Implement GetBytes * More test fixes * Handle cancellation retry in Read/ReadAsync buffer stream methods * Netstandard fixes * Another iteration of bounded reads, automatically consume data for column reads ending in an exception Without paying for a try finally or other expensive constructs * Have nested data reader use nested reads as well * Improve nested reader invalidation mechanism * Clarify rereading rules for sequential mode * Add back byte reading fast path * Implement ltree * Change removed property * Colocate sync/async reading * Small fixes after doing a review * Complete some converter resolver todos * Remove test for a mapping that doesn't exist * Add timestamp(tz) range mappings * Add back jagged validation * Breaking change, remove support for non generic list and derived List<T> types * Add byte reading/writing of text and json * Remove roundtripping restrictions on certain bytea mappings * Add jsonpath support * Revert an invalid optimization * Add missed array mappings * Add stream writing support to bytea * Cache parameter size * Add multirange resolver * Small configurability additions to PgTypeInfo And loosen boxing info restriction * Centralize type equality logic * Stream fix * Rationalize unboxing behavior, also opens up ability for arrays to be constrained by IList instead of object * Change array converters to constrain to IList * Add ts and tstzmultirange * Allow null return from converter resolver * Create specialized versions for all the different datetime resolver kinds * And remove the composing resolvers * Add accurate type names in datetime resolver exception * Don't lose stacktrace on break if possible * Add bitstring string writing * Resolve aot warning * Handle a trim warning * Suppress DbDataReader.GetFieldType dynamically accessed members attribute Odbc and OleDb do the same * Remove dead code, add comments and other small iterations * Bring back default name translator * Add unmapped enums * Add valuetuple and tuple records * Bring truncate behavior back as a compat feature And cleanup naming, some todos * Rename method * Cleanup * Package version bumps * Add STJ poco and known types support pg arrays over them is next * Revert nonsense * Fix typo * Improve introspection mode * Make nested writes consistent with reads * Add composite type support * Netstandard fixes * Add STJ arrays * Move field description info cache to reader Shared prepared statements would otherwise thrash each others caches. * Fixes * Add missed configure awaits WriteBuffer will be in a separate commit with the sync over async writes change * Make datatypename have an implicit conversion to string * Fix nullable resolvers * Improve jsondocument sizing somewhat until unknown sizing support is done * Add GeoJSON support * Small improvement * Add Json.NET support * Add comment * Make PgConverterInfo and Bind internal * Implement boxed converter support in composites * Clean up PgTypeInfo api surface * Move delegating GetFieldValue calls to non-GVM GetFieldValueCore * Fix benchmark project errors * Properly respect async flag on nested read disposal (and ConfigureAwait the IAsyncDisposable) * Remove an ensure overload * Add back some friendly errors on missing pg types * Fix cache bleed * Make type info cache code read better * Make multirange mappings conditional on db support * Actually revert AttemptPostgresCancellation and friends after dispose to help replication * Catch race during extension create * Assert null cache * Remove dead reference * Root out more invalid or missing reader state transitions * Fix writer ifdef issue * Fix double converter netstandard code * Fix json type info resolver being null * Disable noda time tests for now * Segregate tests simulating errors to prevent unrelated test from failing under multiplexing mode * Always reset read started * Readability improvements * Centralize parameter info resets * Only reset binding info for size changes * Improve PgTypeInfo api design * Try to prevent more multiplexing issues * Go over some TODOs * Add windows exemption to flaky test * Reduce jsonb text converter bloat * Rename * Shorten BufferData{Async} to Buffer{Async} * Improve nullable handling of sizes * Reduce the amount of types we reference * Create a dgml file to accompany the mstat * Reduce bloat * Small clarifications in abstractions * Move ImmutableDictionary mapping for hstore to extra conversions * And move BigInteger too * Properly remove all traces of ImmutableDictionary from hstore * Only reference if not trimmed * Fix typo * Move out of array and match name instead * Typo * Bump sdk version to preview 7 * Break away the last bits of PGUtil * Remove unused namespaces * Drop extension method * Make ValueMetadata readonly * Fix todo * Current fix * Move unconsumed read error to endread * Sync binary exporter to patterns used in db data reader * Enable all plugin tests and fix GeoJson errors * Fix infinite range bug * Fix some exporter and replication value bugs Also make Skip take an int as it's a saner size bound * Fix remaining nodatime plugin issues * Restructure range resolver to be more priority based * Add transaction for multiplexing to another test * Don't make json types default for reading * Add net6.0 tfm to json.net to work around init prop issues * Allow type predicates to deny default matches Only if the requirement would allow these to match otherwise, 'true' results are ignored for MatchRequirement.All * Fix remaining issues with Json.Net What a kludge... * Fix legacy infinite errors on NodaTime * Fix some incorrect null type predicate results * Reflect removal of silly read default from STJ poco resolver * Simplify infinity conversions again * Check pg dimension bound during array write * Make range and multirange internal and add static factory instead * Actually check length in all cases * Fix returned multirange type * Normalize [] to _ in the constructor * Fix compilation issue * Remove incorrect xmldoc * Improve composite type info error message * Move out some classes * Rename * Speed up representational type resolution * Add missed representational type resolutions * Bring back dev build tfm for Json.Net * Small naming and error message improvements * Make ColumnStream rely on cumulative position for consume during dispose * Improve PgReader Init/Commit StartRead/EndRead code * Remove _readStarted entirely now we have EndRead doing the consumed checks * More readability improvements * Merge version byte prefixed text converter Thanks @roji for the idea * Merge Hstore Read and ReadInto * Move some exceptions to resources * Fast path other read bytes methods * Monomorphize byte array converter * Streamline field read infra * Simplify cleanup * Fix boxing for default converters * Speed up GetInfo and GetFieldValueCore * Add info cache set and load for prepared statements * Speed up reader start/stop init/commit * Speed up primitive reads * Improve message * Remove unused fields * Small speedup * Improve encapsulation of NpgsqlParameter * More parameter streamlining * Small readability improvements * Improve MultiWriteState state clearing behavior * Centralize async helper read logic * Add some missed buffer checks * Remove redundant code * Map streaming onto SizeKind.Unknown instead of Size.Zero to make BufferRequirements properly monoidal * Clarify bufferRequirements' applicability and fix nullable to adhere to it * Reader naming and structure improvements * Fix seek to column in GetFieldValueAsync * Address nits * Make sure boxing infos use GetResolutionAsObject * Rework parameter ValueType code * Reset type info on Value changes for typeof(object) generic parameters * Address more nits * Upgrade to RC1 * Fix a default type fallback issue in the cache lookup * Add array type checks With various fixes Closes npgsql#5137 * Fix some more mappings and tests * Fix the remaining array mapping issues * Fix ensure issue and move PgWriter property to a method * Use full version * Remove nightly feed * Add pragma for new ref readonly warnings Which we can ignore due to consuming it directly in Unsafe.As, which does not write to its ref However overloads cannot be made based on refness so we're stuck with Unsafe.As being ref... * Fix nodatime array/multirange mapping tests * Fix small bug in Json.NET synthetic mappings * Make multirange asserts conditional * Fix debug build issues * Change PgReader 'not exactly consumed' exception and behavior * Replace debug only exception * Tidy up all dynamic mapping code * Implement unmapped ranges * Small tweaks * Don't rely on 'current' data inside GetBytes/GetData * Fix SequentialAccess IsDbNull (resumable) + Get... (some non-resumable op) * Use DateTimeKind.Unspecified and assert on it in tests * Address nits * Use new big endian support in Guid * Add constants for states in BinaryExporter * Add support for unmapped multiranges * Don't try to get an object converter for type = null * Rename TypeCatalog to DatabaseInfo * Use IsAtStart in PgBufferedConverter * Add missed constant uses * Actually implement IDisposable... * Address feedback * Add resolvers check in GlobalTypeMapper (npgsql#15) * Address feedback * Breaking change, move refcursor and jsonpath to DbType.Object * Rework NotSupportedException back to InvalidCastException to align to ADO.NET convention * Make GetPostgresTypeXYZ/GetPgType overloads of GetPostgresType * Message tweak * Improve GetConcreteResolution * Make jsonpath test conditional --------- Co-authored-by: Shay Rojansky <[email protected]>
1 parent 4ffbff1 commit 0b7aecb

File tree

423 files changed

+20463
-17022
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

423 files changed

+20463
-17022
lines changed

.devcontainer/docker-compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version: '3'
33
services:
44
npgsql-dev:
55
# Source for tags: https://mcr.microsoft.com/v2/dotnet/sdk/tags/list
6-
image: mcr.microsoft.com/dotnet/sdk:8.0.100-preview.6
6+
image: mcr.microsoft.com/dotnet/sdk:8.0.100-preview.7
77
volumes:
88
- ..:/workspace:cached
99
tty: true

.github/workflows/build.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ concurrency:
1515
cancel-in-progress: true
1616

1717
env:
18-
dotnet_sdk_version: '8.0.100-preview.6.23330.14'
18+
dotnet_sdk_version: '8.0.100-rc.1.23463.5'
1919
postgis_version: 3
2020
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
2121
# Windows comes with PG pre-installed, and defines the PGPASSWORD environment variable. Remove it as it interferes
@@ -315,7 +315,6 @@ jobs:
315315
run: |
316316
if [ -z "${{ matrix.pg_prerelease }}" ]; then
317317
dotnet test -c ${{ matrix.config }} -f ${{ matrix.test_tfm }} test/Npgsql.PluginTests --logger "GitHubActions;report-warnings=false"
318-
dotnet test -c ${{ matrix.config }} -f ${{ matrix.test_tfm }} test/Npgsql.NodaTime.Tests --logger "GitHubActions;report-warnings=false"
319318
fi
320319
shell: bash
321320

.github/workflows/codeql-analysis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ concurrency:
3232
cancel-in-progress: true
3333

3434
env:
35-
dotnet_sdk_version: '8.0.100-preview.6.23330.14'
35+
dotnet_sdk_version: '8.0.100-rc.1.23463.5'
3636
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
3737

3838
jobs:

.github/workflows/native-aot.yml

+41-26
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,32 @@ concurrency:
1515
cancel-in-progress: true
1616

1717
env:
18-
dotnet_sdk_version: '8.0.100-preview.6.23330.14'
18+
dotnet_sdk_version: '8.0.100-rc.1.23463.5'
1919
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
20-
nuget_config: |
21-
<?xml version="1.0" encoding="utf-8"?>
22-
<configuration>
23-
24-
<packageSources>
25-
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
26-
<add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
27-
</packageSources>
28-
29-
<packageSourceMapping>
30-
<packageSource key="nuget.org">
31-
<package pattern="*" />
32-
</packageSource>
33-
<packageSource key="dotnet8">
34-
<package pattern="runtime.*" />
35-
<package pattern="Microsoft.NETCore.App.Runtime.*" />
36-
<package pattern="Microsoft.AspNetCore.App.Runtime.*" />
37-
<package pattern="Microsoft.NET.ILLink.Tasks" />
38-
<package pattern="Microsoft.DotNet.ILCompiler" />
39-
</packageSource>
40-
</packageSourceMapping>
41-
42-
</configuration>
20+
# Uncomment and edit the following to use nightly/preview builds
21+
# nuget_config: |
22+
# <?xml version="1.0" encoding="utf-8"?>
23+
# <configuration>
24+
#
25+
# <packageSources>
26+
# <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
27+
# <add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
28+
# </packageSources>
29+
#
30+
# <packageSourceMapping>
31+
# <packageSource key="nuget.org">
32+
# <package pattern="*" />
33+
# </packageSource>
34+
# <packageSource key="dotnet8">
35+
# <package pattern="runtime.*" />
36+
# <package pattern="Microsoft.NETCore.App.Runtime.*" />
37+
# <package pattern="Microsoft.AspNetCore.App.Runtime.*" />
38+
# <package pattern="Microsoft.NET.ILLink.Tasks" />
39+
# <package pattern="Microsoft.DotNet.ILCompiler" />
40+
# </packageSource>
41+
# </packageSourceMapping>
42+
#
43+
# </configuration>
4344
jobs:
4445
build:
4546
runs-on: ${{ matrix.os }}
@@ -68,8 +69,8 @@ jobs:
6869
dotnet-version: |
6970
${{ env.dotnet_sdk_version }}
7071
71-
- name: Setup nuget config
72-
run: echo "$nuget_config" > NuGet.config
72+
# - name: Setup nuget config
73+
# run: echo "$nuget_config" > NuGet.config
7374

7475
- name: Setup Native AOT prerequisites
7576
run: sudo apt-get install clang zlib1g-dev
@@ -108,6 +109,20 @@ jobs:
108109
path: "test/Npgsql.NativeAotTests/obj/Release/net8.0/linux-x64/native/Npgsql.NativeAotTests.mstat"
109110
retention-days: 3
110111

112+
- name: Upload codedgen dgml
113+
uses: actions/[email protected]
114+
with:
115+
name: npgsql.codegen.dgml.xml
116+
path: "test/Npgsql.NativeAotTests/obj/Release/net8.0/linux-x64/native/Npgsql.NativeAotTests.codegen.dgml.xml"
117+
retention-days: 3
118+
119+
- name: Upload scan dgml
120+
uses: actions/[email protected]
121+
with:
122+
name: npgsql.scan.dgml.xml
123+
path: "test/Npgsql.NativeAotTests/obj/Release/net8.0/linux-x64/native/Npgsql.NativeAotTests.scan.dgml.xml"
124+
retention-days: 3
125+
111126
- name: Assert binary size
112127
run: |
113128
size="$(ls -l test/Npgsql.NativeAotTests/bin/Release/net8.0/linux-x64/native/Npgsql.NativeAotTests | cut -d ' ' -f 5)"

.github/workflows/rich-code-nav.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
- '*'
1010

1111
env:
12-
dotnet_sdk_version: '8.0.100-preview.6.23330.14'
12+
dotnet_sdk_version: '8.0.100-rc.1.23463.5'
1313
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
1414

1515
jobs:

Directory.Packages.props

+25-28
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,48 @@
11
<Project>
2+
<PropertyGroup>
3+
<SystemVersion>8.0.0-rc.1.23419.4</SystemVersion>
4+
<ExtensionsVersion>$(SystemVersion)</ExtensionsVersion>
5+
</PropertyGroup>
6+
27
<ItemGroup>
3-
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
4-
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
5-
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
6-
8+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(ExtensionsVersion)" />
9+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(ExtensionsVersion)" />
710
<PackageVersion Include="OpenTelemetry.API" Version="1.6.0" />
8-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
911

10-
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
11-
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
12-
<PackageVersion Include="Scriban.Signed" Version="5.9.0 " />
12+
<!-- Compatibility -->
13+
<PackageVersion Include="System.Threading.Channels" Version="$(SystemVersion)" />
14+
<PackageVersion Include="System.Collections.Immutable" Version="$(SystemVersion)" />
15+
<PackageVersion Include="System.Text.Json" Version="$(SystemVersion)" />
16+
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="$(SystemVersion) " />
17+
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
18+
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
1319

14-
<!-- Plugins -->
20+
<!-- Plugin projects -->
1521
<PackageVersion Include="NetTopologySuite" Version="2.5.0" />
1622
<PackageVersion Include="NetTopologySuite.IO.PostGIS" Version="2.1.0" />
1723
<PackageVersion Include="NodaTime" Version="3.1.9" />
1824
<PackageVersion Include="GeoJSON.Net" Version="1.2.19" />
1925
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
2026

27+
<!-- Build -->
28+
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
29+
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
30+
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
31+
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
32+
<PackageVersion Include="Scriban.Signed" Version="5.9.0 " />
33+
2134
<!-- Tests -->
2235
<PackageVersion Include="NUnit" Version="3.13.3" />
23-
<PackageVersion Include="Microsoft.Extensions.Logging" Version="7.0.0" />
24-
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
36+
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(ExtensionsVersion)" />
37+
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(ExtensionsVersion)" />
2538
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
2639
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
2740
<PackageVersion Include="NUnit3TestAdapter" Version="4.5.0" />
2841
<PackageVersion Include="xunit" Version="2.5.1" />
2942
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5" />
3043
<PackageVersion Include="GitHubActionsTestLogger" Version="2.3.3" />
3144
<PackageVersion Include="AdoNet.Specification.Tests" Version="2.0.0-alpha8" />
32-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
45+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(ExtensionsVersion)" />
3346

3447
<!-- Benchmarks -->
3548
<PackageVersion Include="BenchmarkDotNet" Version="0.13.8" />
@@ -39,20 +52,4 @@
3952
<!-- NativeAOT -->
4053
<PackageVersion Include="Mono.Cecil" Version="0.11.5" />
4154
</ItemGroup>
42-
43-
<!-- Compatibility -->
44-
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
45-
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
46-
</ItemGroup>
47-
48-
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' OR '$(TargetFramework)' == 'netstandard2.1' ">
49-
<PackageVersion Include="System.Text.Json" Version="7.0.3" />
50-
<PackageVersion Include="System.Threading.Channels" Version="7.0.0" />
51-
<PackageVersion Include="System.Collections.Immutable" Version="7.0.0" />
52-
</ItemGroup>
53-
54-
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' OR '$(TargetFramework)' == 'netstandard2.1' OR '$(TargetFramework)' == 'net6.0' ">
55-
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
56-
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="7.0.2" />
57-
</ItemGroup>
5855
</Project>

Npgsql.sln

-11
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
3737
EndProject
3838
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npgsql.SourceGenerators", "src\Npgsql.SourceGenerators\Npgsql.SourceGenerators.csproj", "{63026A19-60B8-4906-81CB-216F30E8094B}"
3939
EndProject
40-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npgsql.NodaTime.Tests", "test\Npgsql.NodaTime.Tests\Npgsql.NodaTime.Tests.csproj", "{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}"
41-
EndProject
4240
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npgsql.OpenTelemetry", "src\Npgsql.OpenTelemetry\Npgsql.OpenTelemetry.csproj", "{DA29F063-1828-47D8-B051-800AF7C9A0BE}"
4341
EndProject
4442
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Github", "Github", "{BA7B6F53-D24D-45AC-927A-266857EA8D1E}"
@@ -144,14 +142,6 @@ Global
144142
{63026A19-60B8-4906-81CB-216F30E8094B}.Release|Any CPU.Build.0 = Release|Any CPU
145143
{63026A19-60B8-4906-81CB-216F30E8094B}.Release|x86.ActiveCfg = Release|Any CPU
146144
{63026A19-60B8-4906-81CB-216F30E8094B}.Release|x86.Build.0 = Release|Any CPU
147-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
148-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}.Debug|Any CPU.Build.0 = Debug|Any CPU
149-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}.Debug|x86.ActiveCfg = Debug|Any CPU
150-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}.Debug|x86.Build.0 = Debug|Any CPU
151-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}.Release|Any CPU.ActiveCfg = Release|Any CPU
152-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}.Release|Any CPU.Build.0 = Release|Any CPU
153-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}.Release|x86.ActiveCfg = Release|Any CPU
154-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00}.Release|x86.Build.0 = Release|Any CPU
155145
{DA29F063-1828-47D8-B051-800AF7C9A0BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
156146
{DA29F063-1828-47D8-B051-800AF7C9A0BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
157147
{DA29F063-1828-47D8-B051-800AF7C9A0BE}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -199,7 +189,6 @@ Global
199189
{F7C53EBD-0075-474F-A083-419257D04080} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}
200190
{A77E5FAF-D775-4AB4-8846-8965C2104E60} = {ED612DB1-AB32-4603-95E7-891BACA71C39}
201191
{63026A19-60B8-4906-81CB-216F30E8094B} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}
202-
{C00D2EB1-5719-4372-9E1C-5ED05DC23A00} = {ED612DB1-AB32-4603-95E7-891BACA71C39}
203192
{DA29F063-1828-47D8-B051-800AF7C9A0BE} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}
204193
{BA7B6F53-D24D-45AC-927A-266857EA8D1E} = {004A2E0F-D34A-44D4-8DF0-D2BC63B57073}
205194
{B58E12EB-E43D-4D77-894E-5157D2269836} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}

src/Npgsql.GeoJSON/Internal/CrsMap.WellKnown.cs src/Npgsql.GeoJSON/CrsMap.WellKnown.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
namespace Npgsql.GeoJSON.Internal;
1+
namespace Npgsql.GeoJSON;
22

3-
readonly partial struct CrsMap
3+
public partial class CrsMap
44
{
55
/// <summary>
66
/// These entries came from spatial_res_sys. They are used to elide memory allocations
@@ -586,4 +586,4 @@ readonly partial struct CrsMap
586586
new(32766, 32766, "EPSG"),
587587
new(900913, 900913, "spatialreferencing.org"),
588588
};
589-
}
589+
}

src/Npgsql.GeoJSON/CrsMap.cs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
namespace Npgsql.GeoJSON;
3+
4+
/// <summary>
5+
/// A map of entries that map the authority to the inclusive range of SRID.
6+
/// </summary>
7+
public partial class CrsMap
8+
{
9+
readonly CrsMapEntry[]? _overriden;
10+
11+
internal CrsMap(CrsMapEntry[]? overriden)
12+
=> _overriden = overriden;
13+
14+
internal string? GetAuthority(int srid)
15+
=> GetAuthority(_overriden, srid) ?? GetAuthority(WellKnown, srid);
16+
17+
static string? GetAuthority(CrsMapEntry[]? entries, int srid)
18+
{
19+
if (entries == null)
20+
return null;
21+
22+
var left = 0;
23+
var right = entries.Length;
24+
while (left <= right)
25+
{
26+
var middle = left + (right - left) / 2;
27+
var entry = entries[middle];
28+
29+
if (srid < entry.MinSrid)
30+
right = middle - 1;
31+
else
32+
if (srid > entry.MaxSrid)
33+
left = middle + 1;
34+
else
35+
return entry.Authority;
36+
}
37+
38+
return null;
39+
}
40+
}
41+
42+
/// <summary>
43+
/// An entry which maps the authority to the inclusive range of SRID.
44+
/// </summary>
45+
readonly struct CrsMapEntry
46+
{
47+
internal readonly int MinSrid;
48+
internal readonly int MaxSrid;
49+
internal readonly string? Authority;
50+
51+
internal CrsMapEntry(int minSrid, int maxSrid, string? authority)
52+
{
53+
MinSrid = minSrid;
54+
MaxSrid = maxSrid;
55+
Authority = authority != null
56+
? string.IsInterned(authority) ?? authority
57+
: null;
58+
}
59+
}
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System.Threading.Tasks;
2+
using Npgsql.GeoJSON.Internal;
3+
4+
namespace Npgsql.GeoJSON;
5+
6+
/// <summary>
7+
/// Extensions for getting a CrsMap from a database.
8+
/// </summary>
9+
public static class CrsMapExtensions
10+
{
11+
/// <summary>
12+
/// Gets the full crs details from the database.
13+
/// </summary>
14+
/// <param name="dataSource"></param>
15+
public static async Task<CrsMap> GetCrsMapAsync(this NpgsqlDataSource dataSource)
16+
{
17+
var builder = new CrsMapBuilder();
18+
using var cmd = GetCsrCommand(dataSource);
19+
await using var reader = await cmd.ExecuteReaderAsync();
20+
21+
while (await reader.ReadAsync())
22+
builder.Add(new CrsMapEntry(reader.GetInt32(0), reader.GetInt32(1), reader.GetString(2)));
23+
24+
return builder.Build();
25+
}
26+
27+
/// <summary>
28+
/// Gets the full crs details from the database.
29+
/// </summary>
30+
/// <param name="dataSource"></param>
31+
public static CrsMap GetCrsMap(this NpgsqlDataSource dataSource)
32+
{
33+
var builder = new CrsMapBuilder();
34+
using var cmd = GetCsrCommand(dataSource);
35+
using var reader = cmd.ExecuteReader();
36+
37+
while (reader.Read())
38+
builder.Add(new CrsMapEntry(reader.GetInt32(0), reader.GetInt32(1), reader.GetString(2)));
39+
40+
return builder.Build();
41+
}
42+
43+
static NpgsqlCommand GetCsrCommand(NpgsqlDataSource dataSource)
44+
=> dataSource.CreateCommand("""
45+
SELECT min(srid), max(srid), auth_name
46+
FROM(SELECT srid, auth_name, srid - rank() OVER(PARTITION BY auth_name ORDER BY srid) AS range FROM spatial_ref_sys) AS s
47+
GROUP BY range, auth_name
48+
ORDER BY 1;
49+
""");
50+
}

0 commit comments

Comments
 (0)