HHH-14454 Add SpatialDialect for CockroachDB

This commit is contained in:
Karel Maesen 2021-03-16 23:18:08 +01:00 committed by Andrea Boriero
parent 3a86b9b697
commit ffc43aadc4
26 changed files with 629 additions and 62 deletions

View File

@ -86,42 +86,42 @@ relevant section.
:no: icon:times[role="red"]
[[spatial-configuration-dialect-features]]
.Hibernate Spatial dialect function support
[cols=",,,,,,," |options="header",]
[cols=",,,,,,,," |options="header",]
|================================
|Function | Description | PostgresSQL | Oracle 10g/11g | MySQL | SQLServer | GeoDB (H2) | DB2
|Basic functions on Geometry | | | | | | |
|`int dimension(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`String geometrytype(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`int srid(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`Geometry envelope(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`String astext(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`byte[] asbinary(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean isempty(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean issimple(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`Geometry boundary(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}
|Functions for testing Spatial Relations between geometric objects | | | | | | |
|`boolean equals(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean disjoint(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean intersects(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean touches(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean crosses(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean within(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean contains(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean overlaps(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean relate(Geometry, Geometry, String)` | SFS §2.1.1.2 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}
|Functions that support Spatial Analysis | | | | | | |
|`double distance(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}
|`Geometry buffer(Geometry, double)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}
|`Geometry convexhull(Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^
|`Geometry intersection(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^
|`Geometry geomunion(Geometry, Geometry)` | SFS §2.1.1.3 (renamed from union) | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^
|`Geometry difference(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^
|`Geometry symdifference(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^
|Common non-SFS functions | | | | | | |
|`boolean dwithin(Geometry, Geometry, double)` | Returns true if the geometries are within the specified distance of one another | {yes} | {yes} | {no} | {no} | {yes} | {yes}
|`Geometry transform(Geometry, int)` | Returns a new geometry with its coordinates transformed to the SRID referenced by the integer parameter | {yes} | {yes} | {no} | {no} | {no} | {no}
|Spatial aggregate Functions | | | | | | |
|`Geometry extent(Geometry)` | Returns a bounding box that bounds the set of returned geometries | {yes} | {yes} | {no} | {no} | {no} | {no}
|Function | Description | PostgresSQL | Oracle 10g/11g | MySQL | SQLServer | GeoDB (H2) | DB2 | CockroachDB
|Basic functions on Geometry | | | | | | | |
|`int dimension(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`String geometrytype(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`int srid(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`Geometry envelope(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`String astext(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`byte[] asbinary(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean isempty(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean issimple(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`Geometry boundary(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {no} | {yes} | {yes} | {yes} | {yes}
|Functions for testing Spatial Relations between geometric objects | | | | | | | |
|`boolean equals(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean disjoint(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean intersects(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean touches(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean crosses(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean within(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean contains(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean overlaps(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} | {yes}
|`boolean relate(Geometry, Geometry, String)` | SFS §2.1.1.2 | {yes} | {yes} | {no} | {yes} | {yes} | {yes} | {yes}
|Functions that support Spatial Analysis | | | | | | | |
|`double distance(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes} | {yes}
|`Geometry buffer(Geometry, double)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes} | {yes}
|`Geometry convexhull(Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^ | {no}
|`Geometry intersection(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^ | {yes}
|`Geometry geomunion(Geometry, Geometry)` | SFS §2.1.1.3 (renamed from union) | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^ | {yes}
|`Geometry difference(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^ | {yes}
|`Geometry symdifference(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^ | {yes}
|Common non-SFS functions | | | | | | | |
|`boolean dwithin(Geometry, Geometry, double)` | Returns true if the geometries are within the specified distance of one another | {yes} | {yes} | {no} | {no} | {yes} | {yes} | {yes}
|`Geometry transform(Geometry, int)` | Returns a new geometry with its coordinates transformed to the SRID referenced by the integer parameter | {yes} | {yes} | {no} | {no} | {no} | {no} | {yes}
|Spatial aggregate Functions | | | | | | | |
|`Geometry extent(Geometry)` | Returns a bounding box that bounds the set of returned geometries | {yes} | {yes} | {no} | {no} | {no} | {no} | {yes}
|================================
^(1)^ Argument Geometries need to have the same dimensionality.
@ -191,6 +191,14 @@ The dialect `SqlServer2008Dialect` supports the `GEOMETRY` type in SQL Server 20
The `GEOGRAPHY` type is not currently supported.
====
CockroachDB::
The dialect `CockroachDB202SpatialDialect` support the `GEOMETRY` type in CockroachDB v20.2 and later.
[NOTE]
====
The `GEOGRAPHY` type is not currently supported.
====
GeoDB (H2)::
The `GeoDBDialect` supports the GeoDB a spatial extension of the H2 in-memory database.
[NOTE]

View File

@ -189,5 +189,14 @@ ext {
// Disable prepared statement caching due to https://www.postgresql.org/message-id/CAEcMXhmmRd4-%2BNQbnjDT26XNdUoXdmntV9zdr8%3DTu8PL9aVCYg%40mail.gmail.com
'jdbc.url' : 'jdbc:postgresql://localhost:26257/defaultdb?sslmode=disable&preparedStatementCacheQueries=0'
],
cockroachdb_spatial : [
'db.dialect' : 'org.hibernate.spatial.dialect.cockroachdb.CockroachDB202SpatialDialect',
// CockroachDB uses the same pgwire protocol as PostgreSQL, so the driver is the same.
'jdbc.driver': 'org.postgresql.Driver',
'jdbc.user' : 'root',
'jdbc.pass' : '',
// Disable prepared statement caching due to https://www.postgresql.org/message-id/CAEcMXhmmRd4-%2BNQbnjDT26XNdUoXdmntV9zdr8%3DTu8PL9aVCYg%40mail.gmail.com
'jdbc.url' : 'jdbc:postgresql://localhost:26257/defaultdb?sslmode=disable&preparedStatementCacheQueries=0'
]
]
}

View File

@ -29,7 +29,7 @@ ext {
assertjVersion = '3.14.0'
geolatteVersion = '1.6.1'
geolatteVersion = '1.8.0'
// Wildfly version targeted by module ZIP; Arquillian/Shrinkwrap versions used for CDI testing and testing the module ZIP
wildflyVersion = '17.0.1.Final'

View File

@ -0,0 +1,45 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.dialect.cockroachdb;
import java.util.Map;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.CockroachDB201Dialect;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.spatial.dialect.postgis.PGGeometryTypeDescriptor;
/**
* An @{code SpatialDialect} for CockroachDB 20.2 and later. CockroachDB's spatial features where introduced in
* that version.
*/
public class CockroachDB202SpatialDialect extends CockroachDB201Dialect implements CockroachSpatialDialectTrait {
public CockroachDB202SpatialDialect() {
super();
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE_WKB_2.getSqlType(),
"GEOMETRY"
);
for ( Map.Entry<String, SQLFunction> entry : functionsToRegister() ) {
registerFunction( entry.getKey(), entry.getValue() );
}
}
@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes(
typeContributions,
serviceRegistry
);
delegateContributeTypes( typeContributions, serviceRegistry );
}
}

View File

@ -0,0 +1,46 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.dialect.cockroachdb;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.spatial.GeolatteGeometryJavaTypeDescriptor;
import org.hibernate.spatial.GeolatteGeometryType;
import org.hibernate.spatial.JTSGeometryJavaTypeDescriptor;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.dialect.postgis.PGGeometryTypeDescriptor;
import org.hibernate.spatial.dialect.postgis.PostgisFunctions;
import org.hibernate.spatial.dialect.postgis.PostgisSupport;
public class CockroachDBSpatialSupport extends PostgisSupport implements SpatialDialect {
CockroachDBSpatialSupport() {
super( new CockroachDBSpatialFunctions() );
}
@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
typeContributions.contributeType( new GeolatteGeometryType( PGGeometryTypeDescriptor.INSTANCE_WKB_2 ) );
typeContributions.contributeType( new JTSGeometryType( PGGeometryTypeDescriptor.INSTANCE_WKB_2 ) );
typeContributions.contributeJavaTypeDescriptor( GeolatteGeometryJavaTypeDescriptor.INSTANCE );
typeContributions.contributeJavaTypeDescriptor( JTSGeometryJavaTypeDescriptor.INSTANCE );
}
}
class CockroachDBSpatialFunctions extends PostgisFunctions {
CockroachDBSpatialFunctions() {
super();
this.functionMap.remove( "geomunion" );
}
}

View File

@ -0,0 +1,77 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.dialect.cockroachdb;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
public interface CockroachSpatialDialectTrait extends SpatialDialect {
CockroachDBSpatialSupport DELEGATE = new CockroachDBSpatialSupport();
default SpatialFunctionsRegistry functionsToRegister() {
return DELEGATE.functionsToRegister();
}
default String getSpatialRelateSQL(String columnName, int spatialRelation) {
return DELEGATE.getSpatialRelateSQL( columnName, spatialRelation );
}
default void delegateContributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
DELEGATE.contributeTypes( typeContributions, serviceRegistry );
}
/**
* Returns the SQL fragment for the SQL WHERE-expression when parsing
* <code>org.hibernate.spatial.criterion.SpatialFilterExpression</code>s
* into prepared statements.
*
* @param columnName The name of the geometry-typed column to which the filter is
* be applied
*
* @return Rhe SQL fragment for the {@code SpatialFilterExpression}
*/
default String getSpatialFilterExpression(String columnName) {
return DELEGATE.getSpatialFilterExpression( columnName );
}
@Override
default String getSpatialAggregateSQL(String columnName, int aggregation) {
return DELEGATE.getSpatialAggregateSQL( columnName, aggregation );
}
@Override
default String getDWithinSQL(String columnName) {
return DELEGATE.getDWithinSQL( columnName );
}
@Override
default String getHavingSridSQL(String columnName) {
return DELEGATE.getHavingSridSQL( columnName );
}
@Override
default String getIsEmptySQL(String columnName, boolean isEmpty) {
return DELEGATE.getIsEmptySQL( columnName, isEmpty );
}
@Override
default boolean supportsFiltering() {
return DELEGATE.supportsFiltering();
}
@Override
default boolean supports(SpatialFunction function) {
return DELEGATE.supports( function );
}
}

View File

@ -0,0 +1,13 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
/**
* {@code SpatialDialect}s for CockroachDB
*/
package org.hibernate.spatial.dialect.cockroachdb;

View File

@ -39,12 +39,18 @@ import org.postgresql.util.PGobject;
public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
/**
* An instance of this class
*/
public static final PGGeometryTypeDescriptor INSTANCE = new PGGeometryTypeDescriptor();
final private Wkb.Dialect wkbDialect;
public static Geometry<?> toGeometry(Object object) {
// Type descriptor instance using EWKB v1 (postgis versions < 2.2.2)
public static final PGGeometryTypeDescriptor INSTANCE_WKB_1 = new PGGeometryTypeDescriptor( Wkb.Dialect.POSTGIS_EWKB_1);
// Type descriptor instance using EWKB v2 (postgis versions >= 2.2.2, see: https://trac.osgeo.org/postgis/ticket/3181)
public static final PGGeometryTypeDescriptor INSTANCE_WKB_2 = new PGGeometryTypeDescriptor(Wkb.Dialect.POSTGIS_EWKB_2);
private PGGeometryTypeDescriptor(Wkb.Dialect dialect) {
wkbDialect = dialect;
}
public Geometry<?> toGeometry(Object object) {
if ( object == null ) {
return null;
}
@ -55,9 +61,8 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
if ( pgValue.startsWith( "00" ) || pgValue.startsWith( "01" ) ) {
//we have a WKB because this pgValue starts with the bit-order byte
buffer = ByteBuffer.from( pgValue );
final WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.POSTGIS_EWKB_1 );
final WkbDecoder decoder = Wkb.newDecoder( wkbDialect );
return decoder.decode( buffer );
}
else {
return parseWkt( pgValue );

View File

@ -24,9 +24,9 @@ import org.hibernate.type.Type;
* <p>
* Created by Karel Maesen, Geovise BVBA on 29/10/16.
*/
class PostgisFunctions extends SpatialFunctionsRegistry {
public class PostgisFunctions extends SpatialFunctionsRegistry {
PostgisFunctions() {
public PostgisFunctions() {
put(
"dimension", new StandardSQLFunction(

View File

@ -23,7 +23,7 @@ public class PostgisNoSQLMM extends PostgisDialect {
public PostgisNoSQLMM() {
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(),
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY"
);

View File

@ -31,7 +31,7 @@ public class PostgisPG82Dialect extends PostgreSQL82Dialect implements SpatialDi
public PostgisPG82Dialect() {
super();
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(),
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY"
);
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) {

View File

@ -31,7 +31,7 @@ public class PostgisPG91Dialect extends PostgreSQL91Dialect implements SpatialDi
public PostgisPG91Dialect() {
super();
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(),
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY"
);
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) {

View File

@ -31,7 +31,7 @@ public class PostgisPG92Dialect extends PostgreSQL92Dialect implements SpatialDi
public PostgisPG92Dialect() {
super();
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(),
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY"
);
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) {

View File

@ -31,7 +31,7 @@ public class PostgisPG93Dialect extends PostgreSQL93Dialect implements SpatialDi
public PostgisPG93Dialect() {
super();
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(),
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY"
);
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) {

View File

@ -31,7 +31,7 @@ public class PostgisPG94Dialect extends PostgreSQL94Dialect implements SpatialDi
public PostgisPG94Dialect() {
super();
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(),
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY"
);
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) {

View File

@ -30,7 +30,7 @@ public class PostgisPG95Dialect extends PostgreSQL95Dialect implements SpatialDi
public PostgisPG95Dialect() {
super();
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(),
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY"
);
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) {

View File

@ -31,7 +31,7 @@ public class PostgisPG9Dialect extends PostgreSQL9Dialect implements SpatialDial
public PostgisPG9Dialect() {
super();
registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(),
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY"
);
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) {

View File

@ -18,24 +18,32 @@ import org.hibernate.spatial.SpatialAggregate;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation;
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
/**
* Created by Karel Maesen, Geovise BVBA on 29/10/16.
*/
public class PostgisSupport implements SpatialDialect, Serializable {
private final SpatialFunctionsRegistry postgisFunctions;
private PostgisFunctions postgisFunctions = new PostgisFunctions();
public PostgisSupport(SpatialFunctionsRegistry functions) {
postgisFunctions = functions;
}
void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
typeContributions.contributeType( new GeolatteGeometryType( PGGeometryTypeDescriptor.INSTANCE ) );
typeContributions.contributeType( new JTSGeometryType( PGGeometryTypeDescriptor.INSTANCE ) );
public PostgisSupport() {
postgisFunctions = new PostgisFunctions();
}
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
typeContributions.contributeType( new GeolatteGeometryType( PGGeometryTypeDescriptor.INSTANCE_WKB_1 ) );
typeContributions.contributeType( new JTSGeometryType( PGGeometryTypeDescriptor.INSTANCE_WKB_1 ) );
typeContributions.contributeJavaTypeDescriptor( GeolatteGeometryJavaTypeDescriptor.INSTANCE );
typeContributions.contributeJavaTypeDescriptor( JTSGeometryJavaTypeDescriptor.INSTANCE );
}
public PostgisFunctions functionsToRegister() {
public SpatialFunctionsRegistry functionsToRegister() {
return postgisFunctions;
}

View File

@ -69,7 +69,7 @@ public class PostgisUnmarshalTest {
public void testCase(String pgValue, Geometry<?> expected) throws SQLException {
PGobject pgo = new PGobject();
pgo.setValue( pgValue );
Geometry<?> received = PGGeometryTypeDescriptor.toGeometry( pgo );
Geometry<?> received = PGGeometryTypeDescriptor.INSTANCE_WKB_1.toGeometry( pgo );
assertEquals( String.format( "Failure on %s", pgValue ), expected, received );
}

View File

@ -522,7 +522,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
}
public void convexhull(String pckg) throws SQLException {
if ( !isSupportedByDialect( SpatialFunction.convexhull ) ) {
if ( !isSupportedByDialect( SpatialFunction.convexhull ) || !isSupportedByDialect( SpatialFunction.geomunion )) {
return;
}
Map<Integer, Geometry> dbexpected = expectationsFactory.getConvexHull( expectationsFactory.getTestPolygon() );

View File

@ -7,9 +7,11 @@
package org.hibernate.spatial.testing;
import org.hibernate.dialect.CockroachDB192Dialect;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.testing.dialects.cockroachdb.CockroachDBTestSupport;
import org.hibernate.spatial.testing.dialects.db2.DB2TestSupport;
import org.hibernate.spatial.testing.dialects.h2geodb.GeoDBTestSupport;
import org.hibernate.spatial.testing.dialects.hana.HANATestSupport;
@ -42,6 +44,11 @@ public class TestSupportFactories {
//this test works because all postgis dialects ultimately derive of the Postgresql82Dialect
return PostgisTestSupport.class;
}
if ( ( dialect instanceof SpatialDialect ) && CockroachDB192Dialect.class.isAssignableFrom( dialect.getClass() ) ){
return CockroachDBTestSupport.class;
}
if ( "org.hibernate.spatial.dialect.h2geodb.GeoDBDialect".equals( canonicalName ) ) {
return GeoDBTestSupport.class;
}

View File

@ -0,0 +1,28 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.testing.dialects.cockroachdb;
import org.hibernate.spatial.dialect.postgis.PGGeometryTypeDescriptor;
import org.hibernate.spatial.testing.DataSourceUtils;
import org.hibernate.spatial.testing.dialects.postgis.PostgisExpectationsFactory;
import org.geolatte.geom.jts.JTS;
import org.locationtech.jts.geom.Geometry;
public class CockroachDBExpectationsFactory extends PostgisExpectationsFactory {
public CockroachDBExpectationsFactory(DataSourceUtils utils) {
super( utils );
}
@Override
protected Geometry decode(Object object) {
org.geolatte.geom.Geometry<?> geometry = PGGeometryTypeDescriptor.INSTANCE_WKB_2.toGeometry( object );
return JTS.to( geometry );
}
}

View File

@ -0,0 +1,45 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.testing.dialects.cockroachdb;
import org.hibernate.spatial.integration.TestGeolatteSpatialPredicates;
import org.hibernate.spatial.integration.TestJTSSpatialPredicates;
import org.hibernate.spatial.integration.TestSpatialFunctions;
import org.hibernate.spatial.integration.TestSpatialRestrictions;
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.DataSourceUtils;
import org.hibernate.spatial.testing.SQLExpressionTemplate;
import org.hibernate.spatial.testing.TestData;
import org.hibernate.spatial.testing.TestSupport;
import org.hibernate.spatial.testing.dialects.postgis.PostgisExpressionTemplate;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
public class CockroachDBTestSupport extends TestSupport {
@Override
public TestData createTestData(BaseCoreFunctionalTestCase testcase) {
Class<? extends BaseCoreFunctionalTestCase> testcaseClass = testcase.getClass();
if ( ( testcaseClass == TestSpatialFunctions.class ) ||
( testcaseClass == TestSpatialRestrictions.class ) ||
( testcaseClass == TestJTSSpatialPredicates.class ) ||
( testcaseClass == TestGeolatteSpatialPredicates.class ) ) {
return TestData.fromFile( "cockroachdb/functions-test.xml" );
}
return TestData.fromFile( "cockroachdb/test-data-set.xml" );
}
@Override
public AbstractExpectationsFactory createExpectationsFactory(DataSourceUtils dataSourceUtils) {
return new CockroachDBExpectationsFactory( dataSourceUtils );
}
@Override
public SQLExpressionTemplate getSQLExpressionTemplate() {
return new PostgisExpressionTemplate();
}
}

View File

@ -238,10 +238,9 @@ public class PostgisExpectationsFactory extends AbstractExpectationsFactory {
);
}
//remove redundancy with toGeometry function in PGGeometryTypeDescriptor
@Override
protected Geometry decode(Object object) {
org.geolatte.geom.Geometry geometry = PGGeometryTypeDescriptor.toGeometry( object );
org.geolatte.geom.Geometry geometry = PGGeometryTypeDescriptor.INSTANCE_WKB_1.toGeometry( object );
return JTS.to( geometry );
}

View File

@ -0,0 +1,64 @@
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<TestData>
<!-- points -->
<Element>
<id>1</id>
<type>POINT</type>
<wkt>SRID=4326;POINT(10 5)</wkt>
</Element>
<Element>
<id>2</id>
<type>POINT</type>
<wkt>SRID=4326;POINT(79 79)</wkt>
</Element>
<Element>
<id>3</id>
<type>POINT</type>
<wkt>SRID=4326;POINT(50 50)</wkt>
</Element>
<Element>
<id>4</id>
<type>POINT</type>
<wkt>SRID=4326;POINT(10 20)</wkt>
</Element>
<Element>
<id>5</id>
<type>POINT</type>
<wkt>SRID=4326;POINT(-4 -5)</wkt>
</Element>
<Element>
<id>6</id>
<type>LINESTRING</type>
<wkt>SRID=4326;LINESTRING(10.0 5.0, 20.0 15.0)</wkt>
</Element>
<Element>
<id>9</id>
<type>MULTILINESTRING</type>
<wkt>SRID=4326;MULTILINESTRING((10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0), (40.0 20.0, 42.0 18.0, 43.0 16.0, 40
14.0))
</wkt>
</Element>
<Element>
<id>10</id>
<type>POLYGON</type>
<wkt>SRID=4326;POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0) )</wkt>
</Element>
<Element>
<id>11</id>
<type>MULTIPOLYGON</type>
<wkt>SRID=4326;MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((15 10, 12 14, 13 13, 15 10)) )</wkt>
</Element>
</TestData>

View File

@ -0,0 +1,213 @@
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<TestData>
<Element>
<id>1</id>
<type>POINT</type>
<wkt>POINT(10 5)</wkt>
</Element>
<Element>
<id>2</id>
<type>POINT</type>
<wkt>SRID=4326;POINT(52.25 2.53)</wkt>
</Element>
<Element>
<id>3</id>
<type>POINT</type>
<wkt>SRID=31370;POINT(150000 200000)</wkt>
</Element>
<Element>
<id>4</id>
<type>LINESTRING</type>
<wkt>SRID=4326;LINESTRING(10.0 5.0, 20.0 15.0)</wkt>
</Element>
<Element>
<id>5</id>
<type>LINESTRING</type>
<wkt>SRID=4326;LINESTRING(10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0)</wkt>
</Element>
<Element>
<id>6</id>
<type>MULTILINESTRING</type>
<wkt>SRID=4326;MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0))</wkt>
</Element>
<Element>
<id>7</id>
<type>MULTILINESTRING</type>
<wkt>SRID=4326;MULTILINESTRING((10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0), (40.0 20.0, 42.0 18.0, 43.0 16.0, 40
14.0))
</wkt>
</Element>
<Element>
<id>8</id>
<type>POLYGON</type>
<wkt>SRID=4326;POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0) )</wkt>
</Element>
<Element>
<id>9</id>
<type>POLYGON</type>
<wkt>SRID=4326;POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 5, 5 5,5 2, 2 2))</wkt>
</Element>
<Element>
<id>10</id>
<type>POLYGON</type>
<wkt>SRID=4326;POLYGON( (110 110, 110 120, 120 120, 120 110, 110 110) )</wkt>
</Element>
<Element>
<id>11</id>
<type>MULTIPOLYGON</type>
<wkt>SRID=4326;MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100, 120 140, 130 134, 105 100)) )</wkt>
</Element>
<Element>
<id>12</id>
<type>MULTIPOLYGON</type>
<wkt>SRID=4326;MULTIPOLYGON(( (0 0, 0 50, 50 50, 50 0, 0 0), (10 10, 10 20, 20 20, 20 10, 10 10) ),((105 100,
120 140, 130
134, 105 100)) )
</wkt>
</Element>
<Element>
<id>13</id>
<type>MULTIPOINT</type>
<wkt>SRID=4326;MULTIPOINT(21 2, 25 5, 30 3)</wkt>
</Element>
<Element>
<id>14</id>
<type>MULTIPOINT</type>
<wkt>SRID=4326;MULTIPOINT(21 2)</wkt>
</Element>
<Element>
<id>15</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3))</wkt>
</Element>
<Element>
<id>16</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0)))</wkt>
</Element>
<Element>
<id>17</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0),(1 1, 2 1,
2 2, 1 2,
1 1)))
</wkt>
</Element>
<Element>
<id>18</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION( MULTIPOINT(21 2, 25 5, 30 3), MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)),
((105 100,
120 140, 130 134, 105 100)) ), MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0)))
</wkt>
</Element>
<Element>
<id>19</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), POINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
</Element>
<Element>
<id>20</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), LINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
</Element>
<Element>
<id>21</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), GEOMETRYCOLLECTION EMPTY, LINESTRING(4 2, 5 3))</wkt>
</Element>
<Element>
<id>22</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), POLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
</Element>
<Element>
<id>23</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), MULTILINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
</Element>
<Element>
<id>24</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), MULTIPOINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
</Element>
<Element>
<id>25</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), MULTIPOLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
</Element>
<Element>
<id>26</id>
<type>POINT</type>
<wkt>POINT EMPTY</wkt>
</Element>
<Element>
<id>27</id>
<type>LINESTRING</type>
<wkt>LINESTRING EMPTY</wkt>
</Element>
<Element>
<id>28</id>
<type>POLYGON</type>
<wkt>POLYGON EMPTY</wkt>
</Element>
<Element>
<id>29</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT EMPTY</wkt>
</Element>
<Element>
<id>30</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING EMPTY</wkt>
</Element>
<Element>
<id>31</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON EMPTY</wkt>
</Element>
<Element>
<id>32</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION EMPTY</wkt>
</Element>
</TestData>