HHH-14808 Basic SpatialPredicates

This commit is contained in:
Karel Maesen 2021-09-04 13:07:23 +02:00
parent 2bdd10389b
commit 5bae2d8196
17 changed files with 372 additions and 74 deletions

View File

View File

@ -13,7 +13,6 @@ package org.hibernate.spatial;
* @author Karel Maesen, Geovise BVBA
* creation-date: 4/18/13
*/
@Deprecated
public interface Spatial {
}

View File

@ -13,12 +13,14 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.spatial.GeolatteGeometryJavaTypeDescriptor;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.BasicBinder;
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.geolatte.geom.ByteBuffer;
@ -29,6 +31,7 @@ import org.geolatte.geom.codec.WkbDecoder;
import org.geolatte.geom.codec.WkbEncoder;
import org.geolatte.geom.codec.Wkt;
import org.geolatte.geom.codec.WktDecoder;
import org.geolatte.geom.jts.JTS;
import org.postgresql.util.PGobject;
/**
@ -46,6 +49,18 @@ public class PGGeometryTypeDescriptor implements JdbcTypeDescriptor {
// 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 );
@Override
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) {
if ( javaTypeDescriptor instanceof GeolatteGeometryJavaTypeDescriptor ) {
return (value, dialect, wrapperOptions) -> "ST_GeomFromEWKT('" + value + "')";
}
return (value, dialect, wrapperOptions) -> "ST_GeomFromEWKT('" + jts2Gl( value ) + "')";
}
private <T> Geometry<?> jts2Gl(T value) {
return JTS.from( (org.locationtech.jts.geom.Geometry) value );
}
private PGGeometryTypeDescriptor(Wkb.Dialect dialect) {
wkbDialect = dialect;
}
@ -78,14 +93,13 @@ public class PGGeometryTypeDescriptor implements JdbcTypeDescriptor {
}
@Override
public int getJdbcTypeCode() {
return Types.OTHER;
}
@Override
public int getDefaultSqlTypeCode(){
public int getDefaultSqlTypeCode() {
return 5432;
}

View File

@ -10,11 +10,20 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.spatial.SpatialFunction;
import org.geolatte.geom.Envelope;
import org.geolatte.geom.Geometry;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CONTAINS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CROSSES;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DISJOINT;
import static org.hibernate.spatial.CommonSpatialFunction.ST_EQUALS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_INTERSECTS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_OVERLAPS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_TOUCHES;
import static org.hibernate.spatial.CommonSpatialFunction.ST_WITHIN;
/**
* {@link JTSSpatialPredicates}, but for geolatte-geom.
*
@ -41,7 +50,7 @@ public class GeolatteSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.equals.toString(), boolean.class,
criteriaBuilder.function( ST_EQUALS.name(), boolean.class,
geometry1, geometry2
)
);
@ -82,9 +91,7 @@ public class GeolatteSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.within.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_WITHIN.name(), boolean.class, geometry1, geometry2 )
);
}
@ -102,8 +109,7 @@ public class GeolatteSpatialPredicates {
public static Predicate within(
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
Geometry geometry2) {
return within( criteriaBuilder, geometry1,
criteriaBuilder.literal( geometry2 )
return within( criteriaBuilder, geometry1, criteriaBuilder.literal( geometry2 )
);
}
@ -123,7 +129,7 @@ public class GeolatteSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.contains.toString(), boolean.class,
criteriaBuilder.function( ST_CONTAINS.name(), boolean.class,
geometry1, geometry2
)
);
@ -164,7 +170,7 @@ public class GeolatteSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.crosses.toString(), boolean.class,
criteriaBuilder.function( ST_CROSSES.name(), boolean.class,
geometry1, geometry2
)
);
@ -205,9 +211,7 @@ public class GeolatteSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.disjoint.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_DISJOINT.name(), boolean.class, geometry1, geometry2 )
);
}
@ -246,9 +250,7 @@ public class GeolatteSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.intersects.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_INTERSECTS.name(), boolean.class, geometry1, geometry2 )
);
}
@ -266,8 +268,7 @@ public class GeolatteSpatialPredicates {
public static Predicate intersects(
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
Geometry geometry2) {
return intersects( criteriaBuilder, geometry1,
criteriaBuilder.literal( geometry2 )
return intersects( criteriaBuilder, geometry1, criteriaBuilder.literal( geometry2 )
);
}
@ -287,9 +288,7 @@ public class GeolatteSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.overlaps.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_OVERLAPS.name(), boolean.class, geometry1, geometry2 )
);
}
@ -307,8 +306,7 @@ public class GeolatteSpatialPredicates {
public static Predicate overlaps(
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
Geometry geometry2) {
return overlaps( criteriaBuilder, geometry1,
criteriaBuilder.literal( geometry2 )
return overlaps( criteriaBuilder, geometry1, criteriaBuilder.literal( geometry2 )
);
}
@ -328,9 +326,7 @@ public class GeolatteSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.touches.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_TOUCHES.name(), boolean.class, geometry1, geometry2 )
);
}
@ -348,8 +344,7 @@ public class GeolatteSpatialPredicates {
public static Predicate touches(
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
Geometry geometry2) {
return touches( criteriaBuilder, geometry1,
criteriaBuilder.literal( geometry2 )
return touches( criteriaBuilder, geometry1, criteriaBuilder.literal( geometry2 )
);
}

View File

@ -10,12 +10,20 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.spatial.SpatialFunction;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CONTAINS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CROSSES;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DISJOINT;
import static org.hibernate.spatial.CommonSpatialFunction.ST_EQUALS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_INTERSECTS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_OVERLAPS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_TOUCHES;
import static org.hibernate.spatial.CommonSpatialFunction.ST_WITHIN;
/**
* A factory for spatial JPA Criteria API {@link Predicate}s.
*
@ -40,7 +48,7 @@ public class JTSSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.equals.toString(), boolean.class, geometry1, geometry2 )
criteriaBuilder.function( ST_EQUALS.name(), boolean.class, geometry1, geometry2 )
);
}
@ -75,7 +83,7 @@ public class JTSSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.within.toString(), boolean.class, geometry1, geometry2 )
criteriaBuilder.function( ST_WITHIN.name(), boolean.class, geometry1, geometry2 )
);
}
@ -110,9 +118,7 @@ public class JTSSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.contains.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_CONTAINS.name(), boolean.class, geometry1, geometry2 )
);
}
@ -149,7 +155,7 @@ public class JTSSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.crosses.toString(), boolean.class,
criteriaBuilder.function( ST_CROSSES.name(), boolean.class,
geometry1, geometry2
)
);
@ -188,9 +194,7 @@ public class JTSSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.disjoint.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_DISJOINT.name(), boolean.class, geometry1, geometry2 )
);
}
@ -227,9 +231,7 @@ public class JTSSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.intersects.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_INTERSECTS.name(), boolean.class, geometry1, geometry2 )
);
}
@ -247,8 +249,7 @@ public class JTSSpatialPredicates {
public static Predicate intersects(
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
Geometry geometry2) {
return intersects( criteriaBuilder, geometry1,
criteriaBuilder.literal( geometry2 )
return intersects( criteriaBuilder, geometry1, criteriaBuilder.literal( geometry2 )
);
}
@ -266,8 +267,7 @@ public class JTSSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.overlaps.toString(), boolean.class,
geometry1, geometry2
criteriaBuilder.function( ST_OVERLAPS.name(), boolean.class, geometry1, geometry2
)
);
}
@ -286,8 +286,7 @@ public class JTSSpatialPredicates {
public static Predicate overlaps(
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
Geometry geometry2) {
return overlaps( criteriaBuilder, geometry1,
criteriaBuilder.literal( geometry2 )
return overlaps( criteriaBuilder, geometry1, criteriaBuilder.literal( geometry2 )
);
}
@ -305,9 +304,7 @@ public class JTSSpatialPredicates {
Expression<? extends Geometry> geometry2) {
return booleanExpressionToPredicate(
criteriaBuilder,
criteriaBuilder.function( SpatialFunction.touches.toString(), boolean.class,
geometry1, geometry2
)
criteriaBuilder.function( ST_TOUCHES.name(), boolean.class, geometry1, geometry2 )
);
}
@ -325,11 +322,11 @@ public class JTSSpatialPredicates {
public static Predicate touches(
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
Geometry geometry2) {
return touches( criteriaBuilder, geometry1,
criteriaBuilder.literal( geometry2 )
);
return touches( criteriaBuilder, geometry1, criteriaBuilder.literal( geometry2 ) );
}
// /**
// * Create a predicate for testing the arguments for bounding box overlap constraint.
// *

View File

@ -5,7 +5,14 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.integration.functions;
/*
* 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.integration;
import java.util.function.Function;
@ -21,36 +28,45 @@ import org.geolatte.geom.jts.JTS;
* T
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
enum Model {
public enum Model {
JTSMODEL(
JtsGeomEntity.class,
JTS::to
JTS::to,
org.locationtech.jts.geom.Geometry.class
),
GLMODEL(
GeomEntity.class,
geom -> geom
geom -> geom,
Geometry.class
);
/**
* Test Entity class
*/
final Class<?> entityClass;
public final Class<?> entityClass;
/**
* How to translate from Geolatte Geometry class to the object class
* expected by the entity geom property
* How to translate from Geolatte Geometry to the geometry type
* expected by the entity in this model
*/
final Function<Geometry, Object> from;
public final Function<Geometry, Object> from;
/**
* The geometry type in this model
*/
public final Class<?> geometryClass;
Model(
Class<?> entityClass,
Function<Geometry, Object> from
Function<Geometry, Object> from,
Class<?> geometryClass
) {
this.entityClass = entityClass;
this.from = from;
this.geometryClass = geometryClass;
}
}

View File

@ -18,6 +18,7 @@ import org.hibernate.spatial.testing.datareader.TestData;
import org.hibernate.spatial.testing.datareader.TestDataElement;
import org.hibernate.spatial.testing.datareader.TestSupport;
import org.hibernate.spatial.testing.dialects.NativeSQLTemplates;
import org.hibernate.spatial.testing.dialects.PredicateRegexes;
import org.hibernate.spatial.testing.domain.GeomEntityLike;
import org.hibernate.testing.orm.junit.DialectContext;
@ -29,6 +30,7 @@ import static org.hibernate.spatial.testing.datareader.TestSupport.TestDataPurpo
public class SpatialTestDataProvider {
protected final static String JTS = "jts";
protected final NativeSQLTemplates templates;
protected final PredicateRegexes predicateRegexes;
protected final Map<CommonSpatialFunction, String> hqlOverrides;
private final TestData funcTestData;
protected TestData testData;
@ -38,6 +40,7 @@ public class SpatialTestDataProvider {
try {
TestSupport support = TestSupportFactories.instance().getTestSupportFactory( DialectContext.getDialect() );
templates = support.templates();
predicateRegexes = support.predicateRegexes();
hqlOverrides = support.hqlOverrides();
codec = support.codec();
testData = support.createTestData( StoreRetrieveData );

View File

@ -16,8 +16,10 @@ package org.hibernate.spatial.integration.functions;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Stream;
import org.hibernate.spatial.integration.Model;
import org.hibernate.spatial.testing.IsSupportedBySpatial;
import org.hibernate.spatial.testing.SpatialTestBase;
import org.hibernate.spatial.testing.datareader.TestSupport;
@ -42,14 +44,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
* </ul>
* </p>
*/
@SuppressWarnings("ALL")
@SuppressWarnings("rawtypes")
@RequiresDialectFeature(feature = IsSupportedBySpatial.class)
@SessionFactory
public class CommonFunctionTests extends SpatialTestBase {
public final static TestSupport.TestDataPurpose PURPOSE = TestSupport.TestDataPurpose.SpatialFunctionsData;
List received;
List expected;
@ -58,7 +60,6 @@ public class CommonFunctionTests extends SpatialTestBase {
return PURPOSE;
}
@TestFactory
public Stream<DynamicTest> testFunction() {
@ -73,13 +74,12 @@ public class CommonFunctionTests extends SpatialTestBase {
}
protected Stream<DynamicTest> buildTests(FunctionTestTemplate template) {
return Stream.of(
template.getFunctionName(),
template.getAltFunctionName()
)
.filter( s -> s != null )
.filter( Objects::nonNull )
.map( fn -> DynamicTest.dynamicTest(
displayName( template, fn ), executableTest( template, fn )
) );
@ -94,12 +94,11 @@ public class CommonFunctionTests extends SpatialTestBase {
);
}
protected <T> Executable executableTest(FunctionTestTemplate template, String fnName) {
Executable testF = () -> {
protected Executable executableTest(FunctionTestTemplate template, String fnName) {
return () -> {
expected = template.executeNativeQuery( scope );
received = template.executeHQL( scope, fnName );
assertEquals( expected, received );
};
return testF;
}
}

View File

@ -25,6 +25,7 @@ import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hibernate.spatial.CommonSpatialFunction;
import org.hibernate.spatial.GeomCodec;
import org.hibernate.spatial.integration.Model;
import org.hibernate.spatial.testing.HQLTemplate;
import org.hibernate.spatial.testing.NativeSQLTemplate;
import org.hibernate.type.StandardBasicTypes;

View File

@ -0,0 +1,154 @@
/*
* 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.integration.predicates;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Root;
import org.hibernate.spatial.integration.Model;
import org.hibernate.spatial.predicate.GeolatteSpatialPredicates;
import org.hibernate.spatial.predicate.JTSSpatialPredicates;
import org.hibernate.spatial.testing.HSReflectionUtil;
import org.hibernate.spatial.testing.IsSupportedBySpatial;
import org.hibernate.spatial.testing.SpatialTestBase;
import org.hibernate.spatial.testing.datareader.TestSupport;
import org.hibernate.testing.jdbc.SQLStatementInspector;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.function.Executable;
import org.junit.platform.commons.JUnitException;
import org.geolatte.geom.G2D;
import org.geolatte.geom.Polygon;
import static org.geolatte.geom.builder.DSL.g;
import static org.geolatte.geom.builder.DSL.polygon;
import static org.geolatte.geom.builder.DSL.ring;
import static org.geolatte.geom.crs.CoordinateReferenceSystems.WGS84;
import static org.junit.jupiter.api.Assertions.assertTrue;
@SuppressWarnings({ "unchecked", "rawtypes" })
@RequiresDialectFeature(feature = IsSupportedBySpatial.class)
@SessionFactory
public class GeolatteSpatialPredicatesTest extends SpatialTestBase {
public final static TestSupport.TestDataPurpose PURPOSE = TestSupport.TestDataPurpose.SpatialFunctionsData;
static final Polygon<G2D> filter = polygon(
WGS84,
ring( g( 0, 0 ), g( 0, 10 ), g( 10, 10 ), g( 10, 0 ), g( 0, 0 ) )
);
@Override
public TestSupport.TestDataPurpose purpose() {
return PURPOSE;
}
@TestFactory
public Stream<DynamicTest> testFactory() {
return
predicateRegexes.all()
.flatMap( entry -> Stream.of(
new Args( entry.getKey(), entry.getValue(), Model.GLMODEL ),
new Args( entry.getKey(), entry.getValue(), Model.JTSMODEL )
) )
.map( args -> DynamicTest.dynamicTest(
displayName( args ),
testPredicate(
args.method,
args.regex,
args.model
)
) );
}
@SuppressWarnings("rawtypes")
public Executable testPredicate(final String key, final String regex, Model model) {
return () -> scope.inSession( session -> {
SQLStatementInspector inspector = SQLStatementInspector.extractFromSession( session );
inspector.clear();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery query = getCriteriaQuery(
key,
criteriaBuilder,
model
);
List resultList = session.createQuery( query ).getResultList();
String stmt = inspector.getSqlQueries()
.get( 0 )
.toLowerCase( Locale.ROOT );
//TODO -- can't we use a (hamcrest) matcher here?
assertTrue( stmt.matches( regex ) );
} );
}
private CriteriaQuery getCriteriaQuery(
String key,
CriteriaBuilder criteriaBuilder, Model model) {
CriteriaQuery query = criteriaBuilder.createQuery( model.entityClass );
Root root = query.from( model.entityClass );
Method method = predicateMethod( key, model );
finalizeQuery( criteriaBuilder, model, query, root, method );
return query;
}
private void finalizeQuery(
CriteriaBuilder criteriaBuilder,
Model model,
CriteriaQuery query,
Root root,
Method method) {
try {
query.select( root )
.where( (Expression<Boolean>) method.invoke(
null, criteriaBuilder, root.get( "geom" ), model.from.apply( filter ) ) );
}
catch (IllegalAccessException | InvocationTargetException e) {
throw new JUnitException( "Failure to invoke Geometry Predicate", e );
}
}
@SuppressWarnings("rawtypes")
private Method predicateMethod(String key, Model model) {
Class predicateFactoryClass = model == Model.JTSMODEL ?
JTSSpatialPredicates.class :
GeolatteSpatialPredicates.class;
return HSReflectionUtil.getStaticMethod(
predicateFactoryClass,
key,
CriteriaBuilder.class, Expression.class, model.geometryClass
);
}
private String displayName(Args args) {
return String.format( "Predicate %s on %s", args.method, args.model.entityClass.getSimpleName() );
}
}
class Args {
final String method;
final String regex;
final Model model;
public Args(String method, String regex, Model model) {
this.method = method;
this.regex = regex;
this.model = model;
}
}

View File

@ -0,0 +1,33 @@
/*
* 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;
import java.lang.reflect.Method;
//TODO -- fold this into ReflectionUtil
public class HSReflectionUtil {
/**
* Get target method
*
* @param target target class
* @param methodName method name
* @param parameterTypes method parameter types
*
* @return return value
*/
public static Method getStaticMethod(Class target, String methodName, Class... parameterTypes) {
try {
return target.getMethod( methodName, parameterTypes );
}
catch (NoSuchMethodException e) {
throw new IllegalArgumentException( e );
}
}
}

View File

@ -13,6 +13,13 @@ import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.testing.orm.junit.DialectFeatureCheck;
/**
* Checks if the Dialect is actually supported by Spatial
*
* Note: the tests in this module need to be explicitly enabled in the gradle build config. So this check is
* maybe no longer needed.
*
*/
public class IsSupportedBySpatial implements DialectFeatureCheck {
@Override
public boolean apply(Dialect dialect) {

View File

@ -22,6 +22,7 @@ import org.hibernate.spatial.CommonSpatialFunction;
import org.hibernate.spatial.GeomCodec;
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.dialects.NativeSQLTemplates;
import org.hibernate.spatial.testing.dialects.PredicateRegexes;
/**
@ -36,6 +37,11 @@ public abstract class TestSupport {
return null;
}
//TODO -- make this abstract
public PredicateRegexes predicateRegexes() {
return null;
}
public Map<CommonSpatialFunction, String> hqlOverrides() {
return new HashMap<>();
}

View File

@ -0,0 +1,61 @@
/*
* 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;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class PredicateRegexes {
protected final Map<String, String> regexes = new HashMap<>();
// Note that we alias the function invocation so that
// we can map the return value to the required type
public PredicateRegexes() {
regexes.put(
"overlaps",
"select .* from .* where st_overlaps\\(.*geom\\s*,.*st_geomfromewkt\\(.*\\)\\s*=\\?.*"
);
regexes.put(
"intersects",
"select .* from .* where st_intersects\\(.*geom\\s*,.*st_geomfromewkt\\(.*\\)\\s*=\\?.*"
);
regexes.put(
"crosses",
"select .* from .* where st_crosses\\(.*geom\\s*,.*st_geomfromewkt\\(.*\\)\\s*=\\?.*"
);
regexes.put(
"contains",
"select .* from .* where st_contains\\(.*geom\\s*,.*st_geomfromewkt\\(.*\\)\\s*=\\?.*"
);
regexes.put(
"disjoint",
"select .* from .* where st_disjoint\\(.*geom\\s*,.*st_geomfromewkt\\(.*\\)\\s*=\\?.*"
);
regexes.put(
"touches",
"select .* from .* where st_touches\\(.*geom\\s*,.*st_geomfromewkt\\(.*\\)\\s*=\\?.*"
);
regexes.put(
"within",
"select .* from .* where st_within\\(.*geom\\s*,.*st_geomfromewkt\\(.*\\)\\s*=\\?.*"
);
regexes.put(
"eq",
"select .* from .* where st_equals\\(.*geom\\s*,.*st_geomfromewkt\\(.*\\)\\s*=\\?.*"
);
}
public Stream<Map.Entry<String, String>> all() {
return this.regexes.entrySet().stream();
}
}

View File

@ -13,6 +13,7 @@ import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.datareader.TestData;
import org.hibernate.spatial.testing.datareader.TestSupport;
import org.hibernate.spatial.testing.dialects.NativeSQLTemplates;
import org.hibernate.spatial.testing.dialects.PredicateRegexes;
import org.hibernate.spatial.testing.dialects.postgis.PostgisNativeSQLTemplates;
import org.geolatte.geom.Geometry;
@ -25,6 +26,11 @@ public class CockroachDBTestSupport extends TestSupport {
return new PostgisNativeSQLTemplates();
}
@Override
public PredicateRegexes predicateRegexes() {
return new CrPredicateRegexes();
}
@Override
public TestData createTestData(TestDataPurpose purpose) {
switch ( purpose ) {
@ -50,3 +56,5 @@ public class CockroachDBTestSupport extends TestSupport {
}
}
class CrPredicateRegexes extends PredicateRegexes{ }

View File

@ -18,6 +18,7 @@ import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.datareader.TestData;
import org.hibernate.spatial.testing.datareader.TestSupport;
import org.hibernate.spatial.testing.dialects.NativeSQLTemplates;
import org.hibernate.spatial.testing.dialects.PredicateRegexes;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.codec.Wkt;
@ -35,6 +36,9 @@ public class PostgisTestSupport extends TestSupport {
return new PostgisNativeSQLTemplates();
}
@Override
public PredicateRegexes predicateRegexes(){ return new PostgisPredicateRegexes();}
//TODO put this in its own class (analogous to NativeSQLTemplates)
@Override
public Map<CommonSpatialFunction, String> hqlOverrides() {
@ -68,3 +72,5 @@ public class PostgisTestSupport extends TestSupport {
}
}
class PostgisPredicateRegexes extends PredicateRegexes { }

View File

@ -34,7 +34,6 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa
#hibernate.connection.username hibernate_orm_test
#hibernate.connection.password hibernate_orm_test
>>>>>>> 5aae4945cb (Update CockroachDB support for 6)
## GeoDb (H2 spatial extension)
##
#hibernate.dialect org.hibernate.spatial.dialect.h2geodb.GeoDBDialect