11using System ;
22using System . Collections . Generic ;
3- using System . Text ;
4- using System . Text . RegularExpressions ;
53using GeoAPI . Geometries ;
64using JetBrains . Annotations ;
75using Microsoft . EntityFrameworkCore . Storage ;
@@ -13,18 +11,6 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal
1311{
1412 public class NpgsqlNetTopologySuiteTypeMappingSourcePlugin : IRelationalTypeMappingSourcePlugin
1513 {
16- static readonly Dictionary < string , Type > _storeTypeMappings = new Dictionary < string , Type > ( StringComparer . OrdinalIgnoreCase )
17- {
18- { "GEOMETRY" , typeof ( IGeometry ) } ,
19- { "GEOMETRYCOLLECTION" , typeof ( IGeometryCollection ) } ,
20- { "LINESTRING" , typeof ( ILineString ) } ,
21- { "MULTILINESTRING" , typeof ( IMultiLineString ) } ,
22- { "MULTIPOINT" , typeof ( IMultiPoint ) } ,
23- { "MULTIPOLYGON" , typeof ( IMultiPolygon ) } ,
24- { "POINT" , typeof ( IPoint ) } ,
25- { "POLYGON" , typeof ( IPolygon ) }
26- } ;
27-
2814 // Note: we reference the options rather than copying IsGeographyDefault out, because that field is initialized
2915 // rather late by SingletonOptionsInitializer
3016 readonly INpgsqlNetTopologySuiteOptions _options ;
@@ -35,96 +21,17 @@ public NpgsqlNetTopologySuiteTypeMappingSourcePlugin([NotNull] INpgsqlNetTopolog
3521 public virtual RelationalTypeMapping FindMapping ( in RelationalTypeMappingInfo mappingInfo )
3622 {
3723 var clrType = mappingInfo . ClrType ;
38- var storeType = mappingInfo . StoreTypeName ;
24+ var storeTypeName = mappingInfo . StoreTypeName ;
3925
4026 // TODO: Array
41- // TODO: SRID (https://github.com/aspnet/EntityFrameworkCore/issues/14000)
42-
43- if ( clrType != null )
44- {
45- if ( typeof ( IGeometry ) . IsAssignableFrom ( clrType ) &&
46- ( storeType != null || TryGetStoreType ( clrType , _options . IsGeographyDefault , null , out storeType ) ) )
47- {
48- return ( RelationalTypeMapping ) Activator . CreateInstance (
49- typeof ( NpgsqlGeometryTypeMapping < > ) . MakeGenericType ( clrType ) ,
50- storeType ) ;
51- }
52- }
53- else if ( storeType != null )
54- {
55- var x = ParseGeometryStoreType ( storeType ) ;
56- if ( ! x . HasValue )
57- return null ;
58-
59- if ( ! _storeTypeMappings . TryGetValue ( x . Value . SpatialType ?? "geometry" , out clrType ) )
60- return null ;
61-
62- return ( RelationalTypeMapping ) Activator . CreateInstance (
63- typeof ( NpgsqlGeometryTypeMapping < > ) . MakeGenericType ( clrType ) ,
64- storeType ) ;
65- }
66-
67- return null ;
68- }
69-
70- static readonly Regex _storeTypeRegex = new Regex ( @"^(GEOMETRY|GEOGRAPHY)\s*(\(\s*(\w+)(\s*,\s*(\d+))?\s*\))?$" , RegexOptions . IgnoreCase ) ;
71-
72- /// <summary>
73- /// Given a PostgreSQL store type, attempts to parse it down to its components.
74- /// </summary>
75- /// <param name="storeType">A PostgreSQL store type string representation (e.g. GEOMETRY (POINT,4269))</param>
76- /// <returns>The different components of the store type, or null if <paramref name="storeType"/> isn't a spatial type.</returns>
77- public static ( bool IsGeography , string SpatialType , int ? Srid ) ? ParseGeometryStoreType ( string storeType )
78- {
79- var m = _storeTypeRegex . Match ( storeType ) ;
80- if ( ! m . Success )
81- return null ;
82-
83- return (
84- string . Equals ( m . Groups [ 1 ] . Value , "GEOGRAPHY" , StringComparison . OrdinalIgnoreCase ) ,
85- m . Groups [ 3 ] . Success ? m . Groups [ 3 ] . Value : null ,
86- m . Groups [ 5 ] . Success ? ( int ? ) int . Parse ( m . Groups [ 5 ] . Value ) : null ) ;
87- }
88-
89- static bool TryGetStoreType ( Type clrType , bool isGeography , int ? srid , out string storeType )
90- {
91- var sb = new StringBuilder ( isGeography ? "GEOGRAPHY" : "GEOMETRY" ) ;
92- if ( typeof ( ILineString ) . IsAssignableFrom ( clrType ) )
93- sb . Append ( " (LINESTRING" ) ;
94- else if ( typeof ( IMultiLineString ) . IsAssignableFrom ( clrType ) )
95- sb . Append ( " (MULTILINESTRING" ) ;
96- else if ( typeof ( IMultiPoint ) . IsAssignableFrom ( clrType ) )
97- sb . Append ( " (MULTIPOINT" ) ;
98- else if ( typeof ( IMultiPolygon ) . IsAssignableFrom ( clrType ) )
99- sb . Append ( " (MULTIPOLYGON" ) ;
100- else if ( typeof ( IPoint ) . IsAssignableFrom ( clrType ) )
101- sb . Append ( " (POINT" ) ;
102- else if ( typeof ( IPolygon ) . IsAssignableFrom ( clrType ) )
103- sb . Append ( " (POLYGON" ) ;
104- else if ( typeof ( IGeometryCollection ) . IsAssignableFrom ( clrType ) )
105- sb . Append ( " (GEOMETRYCOLLECTION" ) ;
106- else if ( typeof ( IGeometry ) . IsAssignableFrom ( clrType ) )
107- {
108- if ( ! srid . HasValue )
109- {
110- storeType = sb . ToString ( ) ;
111- return true ;
112- }
113-
114- sb . Append ( " (GEOMETRY" ) ;
115- }
116- else
117- {
118- storeType = null ;
119- return false ;
120- }
121-
122- if ( srid . HasValue )
123- sb . Append ( ',' ) . Append ( srid . Value ) ;
124- sb . Append ( ')' ) ;
125-
126- storeType = sb . ToString ( ) ;
127- return true ;
27+ return clrType != null && typeof ( IGeometry ) . IsAssignableFrom ( clrType ) ||
28+ storeTypeName != null && (
29+ storeTypeName . Equals ( "geometry" , StringComparison . OrdinalIgnoreCase ) ||
30+ storeTypeName . Equals ( "geography" , StringComparison . OrdinalIgnoreCase ) )
31+ ? ( RelationalTypeMapping ) Activator . CreateInstance (
32+ typeof ( NpgsqlGeometryTypeMapping < > ) . MakeGenericType ( clrType ?? typeof ( IGeometry ) ) ,
33+ storeTypeName ?? ( _options . IsGeographyDefault ? "geography" : "geometry" ) )
34+ : null ;
12835 }
12936 }
13037}
0 commit comments