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"] :no: icon:times[role="red"]
[[spatial-configuration-dialect-features]] [[spatial-configuration-dialect-features]]
.Hibernate Spatial dialect function support .Hibernate Spatial dialect function support
[cols=",,,,,,," |options="header",] [cols=",,,,,,,," |options="header",]
|================================ |================================
|Function | Description | PostgresSQL | Oracle 10g/11g | MySQL | SQLServer | GeoDB (H2) | DB2 |Function | Description | PostgresSQL | Oracle 10g/11g | MySQL | SQLServer | GeoDB (H2) | DB2 | CockroachDB
|Basic functions on Geometry | | | | | | | |Basic functions on Geometry | | | | | | | |
|`int dimension(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} |`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} |`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} |`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} |`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} |`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} |`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} |`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} |`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} |`Geometry boundary(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {no} | {yes} | {yes} | {yes} | {yes}
|Functions for testing Spatial Relations between geometric objects | | | | | | | |Functions for testing Spatial Relations between geometric objects | | | | | | | |
|`boolean equals(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} | {yes} |`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} |`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} |`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} |`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} |`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} |`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} |`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} |`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} |`boolean relate(Geometry, Geometry, String)` | SFS §2.1.1.2 | {yes} | {yes} | {no} | {yes} | {yes} | {yes} | {yes}
|Functions that support Spatial Analysis | | | | | | | |Functions that support Spatial Analysis | | | | | | | |
|`double distance(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes} |`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} |`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)^ |`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)^ |`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)^ |`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)^ |`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)^ |`Geometry symdifference(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} | {yes}^(1)^ | {yes}
|Common non-SFS functions | | | | | | | |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} |`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} |`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 | | | | | | | |Spatial aggregate Functions | | | | | | | |
|`Geometry extent(Geometry)` | Returns a bounding box that bounds the set of returned geometries | {yes} | {yes} | {no} | {no} | {no} | {no} |`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. ^(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. 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):: GeoDB (H2)::
The `GeoDBDialect` supports the GeoDB a spatial extension of the H2 in-memory database. The `GeoDBDialect` supports the GeoDB a spatial extension of the H2 in-memory database.
[NOTE] [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 // 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' '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' 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 // Wildfly version targeted by module ZIP; Arquillian/Shrinkwrap versions used for CDI testing and testing the module ZIP
wildflyVersion = '17.0.1.Final' 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 { public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
/** final private Wkb.Dialect wkbDialect;
* An instance of this class
*/
public static final PGGeometryTypeDescriptor INSTANCE = new PGGeometryTypeDescriptor();
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 ) { if ( object == null ) {
return null; return null;
} }
@ -55,9 +61,8 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
if ( pgValue.startsWith( "00" ) || pgValue.startsWith( "01" ) ) { if ( pgValue.startsWith( "00" ) || pgValue.startsWith( "01" ) ) {
//we have a WKB because this pgValue starts with the bit-order byte //we have a WKB because this pgValue starts with the bit-order byte
buffer = ByteBuffer.from( pgValue ); buffer = ByteBuffer.from( pgValue );
final WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.POSTGIS_EWKB_1 ); final WkbDecoder decoder = Wkb.newDecoder( wkbDialect );
return decoder.decode( buffer ); return decoder.decode( buffer );
} }
else { else {
return parseWkt( pgValue ); return parseWkt( pgValue );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,7 +31,7 @@ public class PostgisPG9Dialect extends PostgreSQL9Dialect implements SpatialDial
public PostgisPG9Dialect() { public PostgisPG9Dialect() {
super(); super();
registerColumnType( registerColumnType(
PGGeometryTypeDescriptor.INSTANCE.getSqlType(), PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(),
"GEOMETRY" "GEOMETRY"
); );
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) { 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.SpatialDialect;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation; import org.hibernate.spatial.SpatialRelation;
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
/** /**
* Created by Karel Maesen, Geovise BVBA on 29/10/16. * Created by Karel Maesen, Geovise BVBA on 29/10/16.
*/ */
public class PostgisSupport implements SpatialDialect, Serializable { 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) { public PostgisSupport() {
typeContributions.contributeType( new GeolatteGeometryType( PGGeometryTypeDescriptor.INSTANCE ) ); postgisFunctions = new PostgisFunctions();
typeContributions.contributeType( new JTSGeometryType( PGGeometryTypeDescriptor.INSTANCE ) ); }
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( GeolatteGeometryJavaTypeDescriptor.INSTANCE );
typeContributions.contributeJavaTypeDescriptor( JTSGeometryJavaTypeDescriptor.INSTANCE ); typeContributions.contributeJavaTypeDescriptor( JTSGeometryJavaTypeDescriptor.INSTANCE );
} }
public PostgisFunctions functionsToRegister() { public SpatialFunctionsRegistry functionsToRegister() {
return postgisFunctions; return postgisFunctions;
} }

View File

@ -69,7 +69,7 @@ public class PostgisUnmarshalTest {
public void testCase(String pgValue, Geometry<?> expected) throws SQLException { public void testCase(String pgValue, Geometry<?> expected) throws SQLException {
PGobject pgo = new PGobject(); PGobject pgo = new PGobject();
pgo.setValue( pgValue ); 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 ); 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 { public void convexhull(String pckg) throws SQLException {
if ( !isSupportedByDialect( SpatialFunction.convexhull ) ) { if ( !isSupportedByDialect( SpatialFunction.convexhull ) || !isSupportedByDialect( SpatialFunction.geomunion )) {
return; return;
} }
Map<Integer, Geometry> dbexpected = expectationsFactory.getConvexHull( expectationsFactory.getTestPolygon() ); Map<Integer, Geometry> dbexpected = expectationsFactory.getConvexHull( expectationsFactory.getTestPolygon() );

View File

@ -7,9 +7,11 @@
package org.hibernate.spatial.testing; package org.hibernate.spatial.testing;
import org.hibernate.dialect.CockroachDB192Dialect;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.PostgreSQL82Dialect; import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.spatial.SpatialDialect; 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.db2.DB2TestSupport;
import org.hibernate.spatial.testing.dialects.h2geodb.GeoDBTestSupport; import org.hibernate.spatial.testing.dialects.h2geodb.GeoDBTestSupport;
import org.hibernate.spatial.testing.dialects.hana.HANATestSupport; 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 //this test works because all postgis dialects ultimately derive of the Postgresql82Dialect
return PostgisTestSupport.class; return PostgisTestSupport.class;
} }
if ( ( dialect instanceof SpatialDialect ) && CockroachDB192Dialect.class.isAssignableFrom( dialect.getClass() ) ){
return CockroachDBTestSupport.class;
}
if ( "org.hibernate.spatial.dialect.h2geodb.GeoDBDialect".equals( canonicalName ) ) { if ( "org.hibernate.spatial.dialect.h2geodb.GeoDBDialect".equals( canonicalName ) ) {
return GeoDBTestSupport.class; 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 @Override
protected Geometry decode(Object object) { 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 ); 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>