HHH-14807 Refactor function contribution

This commit is contained in:
Karel Maesen 2022-01-05 11:24:23 +01:00 committed by Steve Ebersole
parent 355694342d
commit d560d81988
25 changed files with 935 additions and 1406 deletions

View File

@ -1,39 +0,0 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
/**
* Implements OGC function dimension for HQL.
*/
class GetDimensionFunction extends SDOObjectMethod {
GetDimensionFunction() {
super( "Get_Dims", StandardBasicTypes.INTEGER );
}
public String render(Type firstArgumentType, final List args, final SessionFactoryImplementor factory) {
final StringBuilder buf = new StringBuilder();
if ( args.isEmpty() ) {
throw new IllegalArgumentException(
"First Argument in arglist must be object to "
+ "which method is applied"
);
}
buf.append( args.get( 0 ) ).append( "." ).append(
getName()
).append( "()" );
return buf.toString();
}
}

View File

@ -1,50 +0,0 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
/**
* HQL Implementation for the geometry ype function.
*/
class GetGeometryTypeFunction extends SDOObjectMethod {
GetGeometryTypeFunction() {
super( "Get_GType", StandardBasicTypes.STRING );
}
public String render(Type firstArgumentType, final List args, final SessionFactoryImplementor factory) {
final StringBuilder buf = new StringBuilder();
if ( args.isEmpty() ) {
throw new IllegalArgumentException(
"First Argument in arglist must be object to which"
+ " method is applied"
);
}
buf.append( "CASE " ).append( args.get( 0 ) ).append( "." ).append(
getName()
).append( "()" );
buf.append( " WHEN 1 THEN 'POINT'" ).append(
" WHEN 2 THEN 'LINESTRING'"
).append(
" WHEN 3 THEN 'POLYGON'"
).append(
" WHEN 5 THEN 'MULTIPOINT'"
).append(
" WHEN 6 THEN 'MULTILINE'"
).append(
" WHEN 7 THEN 'MULTIPOLYGON'"
).append( " END" );
return buf.toString();
}
}

View File

@ -7,19 +7,17 @@
package org.hibernate.spatial.dialect.oracle;
import java.util.Map;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.spatial.HSMessageLogger;
import org.hibernate.spatial.HibernateSpatialConfigurationSettings;
import org.hibernate.spatial.KeyedSqmFunctionDescriptors;
import org.hibernate.spatial.contributor.ContributorImplementor;
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
import org.geolatte.geom.codec.db.oracle.ConnectionFinder;
import org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory;
@ -67,11 +65,19 @@ public class OracleDialectContributor implements ContributorImplementor {
StandardConverters.BOOLEAN,
false
);
OracleSDOSupport sdoSupport = new OracleSDOSupport( isOgcStrict );
SpatialFunctionsRegistry entries = sdoSupport.functionsToRegister();
for( Map.Entry<String, SqmFunctionDescriptor> funcToRegister : entries ) {
functionContributions.getFunctionRegistry().register( funcToRegister.getKey(), funcToRegister.getValue() );
KeyedSqmFunctionDescriptors functionDescriptors;
if (isOgcStrict)
functionDescriptors = new OracleSQLMMFunctionDescriptors( functionContributions);
else {
functionDescriptors = new OracleSDOFunctionDescriptors( functionContributions );
}
SqmFunctionRegistry functionRegistry = functionContributions.getFunctionRegistry();
functionDescriptors.asMap().forEach( (key, funcDescr) -> {
functionRegistry.register( key.getName(), funcDescr );
key.getAltName().ifPresent( altName -> functionRegistry.register( altName, funcDescr ) );
} );
}
@Override

View File

@ -0,0 +1,254 @@
/*
* 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.oracle;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.spatial.CommonSpatialFunction;
import org.hibernate.spatial.FunctionKey;
import org.hibernate.spatial.KeyedSqmFunctionDescriptors;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors {
private final Map<FunctionKey, SqmFunctionDescriptor> map = new HashMap<>();
private final BasicTypeRegistry typeRegistry;
public OracleSDOFunctionDescriptors(FunctionContributions functionContributions) {
typeRegistry = functionContributions.getTypeConfiguration().getBasicTypeRegistry();
registerSDOFunctions();
}
@Override
public Map<FunctionKey, SqmFunctionDescriptor> asMap() {
return Collections.unmodifiableMap( map );
}
private void registerSDOFunctions() {
map.put( CommonSpatialFunction.ST_ASTEXT.getKey(), new NamedSqmFunctionDescriptor(
"SDO_UTIL.TO_WKTGEOMETRY",
false,
StandardArgumentsValidators.exactly(
1 ),
StandardFunctionReturnTypeResolvers.invariant(
typeRegistry.resolve(
StandardBasicTypes.STRING ) )
) );
map.put( CommonSpatialFunction.ST_GEOMETRYTYPE.getKey(), new SDOGetGeometryType( typeRegistry ) );
map.put( CommonSpatialFunction.ST_DIMENSION.getKey(), new SDOMethodDescriptor(
"Get_Dims",
StandardArgumentsValidators.exactly(
1 ),
StandardFunctionReturnTypeResolvers.invariant(
typeRegistry.resolve(
StandardBasicTypes.INTEGER ) )
) );
map.put(
CommonSpatialFunction.ST_ENVELOPE.getKey(),
new NamedSqmFunctionDescriptor(
"SDO_GEOM.SDO_MBR",
true,
StandardArgumentsValidators.exactly( 1 ),
null
)
);
map.put(
CommonSpatialFunction.ST_SRID.getKey(),
new SDOMethodDescriptor(
"SDO_SRID",
false,
StandardArgumentsValidators.exactly( 1 ),
StandardFunctionReturnTypeResolvers.invariant(
typeRegistry.resolve(
StandardBasicTypes.INTEGER
)
)
)
);
map.put(
CommonSpatialFunction.ST_ASBINARY.getKey(),
new SDOMethodDescriptor(
"Get_WKB",
true,
StandardArgumentsValidators.exactly( 1 ),
StandardFunctionReturnTypeResolvers.invariant( typeRegistry.resolve( StandardBasicTypes.BINARY ) )
)
);
map.put(
CommonSpatialFunction.ST_ISSIMPLE.getKey(),
new OracleSpatialSQLMMFunction(
"ST_ISSIMPLE",
"ST_ISSIMPLE",
1,
StandardFunctionReturnTypeResolvers.invariant(
typeRegistry.resolve( StandardBasicTypes.BOOLEAN )
),
false
)
);
map.put(
CommonSpatialFunction.ST_ISEMPTY.getKey(),
new OracleSpatialSQLMMFunction(
"ST_ISEMPTY",
"ST_ISEMPTY",
1,
StandardFunctionReturnTypeResolvers.invariant(
typeRegistry.resolve( StandardBasicTypes.BOOLEAN )
),
false
)
);
map.put(
CommonSpatialFunction.ST_BOUNDARY.getKey(),
new OracleSpatialSQLMMFunction(
"ST_BOUNDARY",
"ST_BOUNDARY",
1,
null,
true
)
);
map.put(
CommonSpatialFunction.ST_OVERLAPS.getKey(),
new SDORelateFunction( List.of( "CONTAINS" ), typeRegistry )
);
map.put(
CommonSpatialFunction.ST_CROSSES.getKey(),
new OracleSpatialSQLMMFunction(
"ST_CROSSES",
"ST_CROSSES",
2,
StandardFunctionReturnTypeResolvers.invariant(
typeRegistry.resolve( StandardBasicTypes.BOOLEAN )
),
false
)
);
map.put(
CommonSpatialFunction.ST_INTERSECTS.getKey(),
new SDORelateFunction( List.of( "OVERLAPBDYDISJOINT", "OVERLAPBDYINTERSECT" ), typeRegistry )
);
map.put(
CommonSpatialFunction.ST_CONTAINS.getKey(),
new SDORelateFunction( List.of( "CONTAINS" ), typeRegistry )
);
map.put(
CommonSpatialFunction.ST_DISJOINT.getKey(),
new SDORelateFunction( List.of( "DISJOINT" ), typeRegistry )
);
map.put( CommonSpatialFunction.ST_RELATE.getKey(), new STRelateFunction( typeRegistry ) );
map.put(
CommonSpatialFunction.ST_TOUCHES.getKey(),
new SDORelateFunction( List.of( "TOUCH" ), typeRegistry )
);
map.put(
CommonSpatialFunction.ST_WITHIN.getKey(),
new SDORelateFunction( List.of( "COVERS", "CONTAINS" ), typeRegistry )
);
map.put(
CommonSpatialFunction.ST_EQUALS.getKey(),
new SDORelateFunction( List.of( "EQUAL" ), typeRegistry )
);
map.put(
CommonSpatialFunction.ST_DISTANCE.getKey(),
new NamedSqmFunctionDescriptor(
"SDO_GEOM.SDO_DISTANCE",
true,
StandardArgumentsValidators.exactly( 2 ),
StandardFunctionReturnTypeResolvers.invariant( typeRegistry.resolve( StandardBasicTypes.DOUBLE ) )
)
);
map.put(
CommonSpatialFunction.ST_BUFFER.getKey(),
new NamedSqmFunctionDescriptor(
"SDO_GEOM.SDO_BUFFER",
true,
StandardArgumentsValidators.exactly( 2 ),
null
)
);
map.put(
CommonSpatialFunction.ST_CONVEXHULL.getKey(),
new NamedSqmFunctionDescriptor(
"SDO_GEOM.SDO_CONVEXHULL",
true,
StandardArgumentsValidators.exactly( 1 ),
null
)
);
map.put(
CommonSpatialFunction.ST_DIFFERENCE.getKey(),
new NamedSqmFunctionDescriptor(
"SDO_GEOM.SDO_DIFFERENCE",
true,
StandardArgumentsValidators.exactly( 2 ),
null
)
);
map.put(
CommonSpatialFunction.ST_INTERSECTION.getKey(),
new NamedSqmFunctionDescriptor(
"SDO_GEOM.SDO_INTERSECTION",
true,
StandardArgumentsValidators.exactly( 2 ),
null
)
);
map.put(
CommonSpatialFunction.ST_SYMDIFFERENCE.getKey(),
new NamedSqmFunctionDescriptor(
"SDO_GEOM.SDO_XOR",
true,
StandardArgumentsValidators.exactly( 2 ),
null
)
);
map.put(
CommonSpatialFunction.ST_UNION.getKey(),
new NamedSqmFunctionDescriptor(
"SDO_GEOM.SDO_UNION",
true,
StandardArgumentsValidators.exactly( 2 ),
null
)
);
}
}

View File

@ -1,11 +0,0 @@
/*
* 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.oracle;
public class OracleSDOSqmFunctionDescriptors {
}

View File

@ -1,332 +0,0 @@
/*
* 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.oracle;
import java.io.Serializable;
import java.util.Locale;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.spatial.HSMessageLogger;
import org.hibernate.spatial.HibernateSpatialConfigurationSettings;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation;
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
import org.hibernate.spatial.dialect.WithCustomJPAFilter;
import org.jboss.logging.Logger;
import org.geolatte.geom.codec.db.oracle.ConnectionFinder;
import org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory;
/**
* SDO Geometry support for Oracle dialects
* <p>
* Created by Karel Maesen, Geovise BVBA on 01/11/16.
*/
class OracleSDOSupport implements SpatialDialect, Serializable, WithCustomJPAFilter {
private static final HSMessageLogger log = Logger.getMessageLogger(
HSMessageLogger.class,
OracleSpatial10gDialect.class.getName()
);
private final SpatialFunctionsRegistry sdoFunctions;
OracleSDOSupport(boolean isOgcStrict) {
this.sdoFunctions = new OracleSpatialFunctions( isOgcStrict, this );
}
SpatialFunctionsRegistry functionsToRegister() {
return this.sdoFunctions;
}
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
final SDOGeometryType sdoGeometryTypeDescriptor = mkSdoGeometryTypeDescriptor( serviceRegistry );
}
private SDOGeometryType mkSdoGeometryTypeDescriptor(ServiceRegistry serviceRegistry) {
final ConfigurationService cfgService = serviceRegistry.getService( ConfigurationService.class );
final StrategySelector strategySelector = serviceRegistry.getService( StrategySelector.class );
final ConnectionFinder connectionFinder = strategySelector.resolveStrategy(
ConnectionFinder.class,
cfgService.getSetting(
HibernateSpatialConfigurationSettings.CONNECTION_FINDER,
String.class,
"org.geolatte.geom.codec.db.oracle.DefaultConnectionFinder"
)
);
log.connectionFinder( connectionFinder.getClass().getCanonicalName() );
return new SDOGeometryType(
new OracleJDBCTypeFactory(
connectionFinder
)
);
}
/**
* Returns the SQL fragment for the SQL WHERE-clause when parsing
* <code>org.hibernatespatial.criterion.SpatialRelateExpression</code>s
* into prepared statements.
* <p/>
*
* @param columnName The name of the geometry-typed column to which the relation is
* applied
* @param spatialRelation The type of spatial relation (as defined in
* <code>SpatialRelation</code>).
*
* @return SQL fragment {@code SpatialRelateExpression}
*/
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
String sql = getOGCSpatialRelateSQL( columnName, "?", spatialRelation ) + " = 1";
sql += " and " + columnName + " is not null";
return sql;
}
public String getOGCSpatialRelateSQL(String arg1, String arg2, int spatialRelation) {
final StringBuilder ogcFunction = new StringBuilder( "MDSYS." );
switch ( spatialRelation ) {
case SpatialRelation.INTERSECTS:
ogcFunction.append( "OGC_INTERSECTS" );
break;
case SpatialRelation.CONTAINS:
ogcFunction.append( "OGC_CONTAINS" );
break;
case SpatialRelation.CROSSES:
ogcFunction.append( "OGC_CROSS" );
break;
case SpatialRelation.DISJOINT:
ogcFunction.append( "OGC_DISJOINT" );
break;
case SpatialRelation.EQUALS:
ogcFunction.append( "OGC_EQUALS" );
break;
case SpatialRelation.OVERLAPS:
ogcFunction.append( "OGC_OVERLAP" );
break;
case SpatialRelation.TOUCHES:
ogcFunction.append( "OGC_TOUCH" );
break;
case SpatialRelation.WITHIN:
ogcFunction.append( "OGC_WITHIN" );
break;
default:
throw new IllegalArgumentException(
"Unknown SpatialRelation ("
+ spatialRelation + ")."
);
}
ogcFunction.append( "(" ).append( "MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(" )
.append( arg1 ).append( ")," ).append(
"MDSYS.ST_GEOMETRY.FROM_SDO_GEOM("
).append( arg2 )
.append( ")" ).append( ")" );
return ogcFunction.toString();
}
/**
* Returns the SQL fragment for the SQL WHERE-clause when parsing
* <code>org.hibernatespatial.criterion.SpatialRelateExpression</code>s
* into prepared statements.
* <p/>
*
* @param columnName The name of the geometry-typed column to which the relation is
* applied
* @param spatialRelation The type of spatial relation (as defined in
* <code>SpatialRelation</code>).
*
* @return SQL fragment {@code SpatialRelateExpression}
*/
public String getSDOSpatialRelateSQL(String columnName, int spatialRelation) {
String sql = getNativeSpatialRelateSQL( columnName, "?", spatialRelation ) + " = 1";
sql += " and " + columnName + " is not null";
return sql;
}
String getNativeSpatialRelateSQL(String arg1, String arg2, int spatialRelation) {
String mask;
boolean negate = false;
switch ( spatialRelation ) {
case SpatialRelation.INTERSECTS:
mask = "ANYINTERACT";
break;
case SpatialRelation.CONTAINS:
mask = "CONTAINS+COVERS";
break;
case SpatialRelation.CROSSES:
throw new UnsupportedOperationException(
"Oracle Spatial does't have equivalent CROSSES relationship"
);
case SpatialRelation.DISJOINT:
mask = "ANYINTERACT";
negate = true;
break;
case SpatialRelation.EQUALS:
mask = "EQUAL";
break;
case SpatialRelation.OVERLAPS:
mask = "OVERLAPBDYDISJOINT+OVERLAPBDYINTERSECT";
break;
case SpatialRelation.TOUCHES:
mask = "TOUCH";
break;
case SpatialRelation.WITHIN:
mask = "INSIDE+COVEREDBY";
break;
default:
throw new IllegalArgumentException(
"undefined SpatialRelation passed (" + spatialRelation
+ ")"
);
}
final StringBuilder buffer = new StringBuilder( "CASE SDO_RELATE(" ).append( arg1 )
.append( "," )
.append( arg2 )
.append( ",'mask=" )
.append( mask )
.append( "') " );
if ( !negate ) {
buffer.append( " WHEN 'TRUE' THEN 1 ELSE 0 END" );
}
else {
buffer.append( " WHEN 'TRUE' THEN 0 ELSE 1 END" );
}
return buffer.toString();
}
/**
* 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}
*/
public String getSpatialFilterExpression(String columnName) {
final StringBuilder buffer = new StringBuilder( "SDO_FILTER(" );
buffer.append( columnName );
buffer.append( ",?) = 'TRUE' " );
return buffer.toString();
}
/**
* Returns the SQL fragment for the specfied Spatial aggregate expression.
*
* @param columnName The name of the Geometry property
* @param aggregation The type of <code>SpatialAggregate</code>
*
* @return The SQL fragment for the projection
*/
public String getSpatialAggregateSQL(String columnName, int aggregation) {
final StringBuilder aggregateFunction = new StringBuilder();
final SpatialAggregateImpl sa = new SpatialAggregateImpl( aggregation );
if ( sa.getAggregateSyntax() == null ) {
throw new IllegalArgumentException(
"Unknown Spatial Aggregation ("
+ aggregation + ")."
);
}
aggregateFunction.append( sa.getAggregateSyntax() );
aggregateFunction.append( "(" );
if ( sa.isAggregateType() ) {
aggregateFunction.append( "SDOAGGRTYPE(" );
}
aggregateFunction.append( columnName );
// Can we make tolerance configurable
if ( sa.isAggregateType() ) {
aggregateFunction.append( ", " ).append( .001 ).append( ")" );
}
aggregateFunction.append( ")" );
return aggregateFunction.toString();
}
/**
* Returns The SQL fragment when parsing a <code>DWithinExpression</code>.
*
* @param columnName The geometry column to test against
*
* @return The SQL fragment when parsing a <code>DWithinExpression</code>.
*/
public String getDWithinSQL(String columnName) {
return "SDO_WITHIN_DISTANCE (" + columnName + ",?, ?) = 'TRUE' ";
}
/**
* Returns the SQL fragment when parsing a <code>HavingSridExpression</code>.
*
* @param columnName The geometry column to test against
*
* @return The SQL fragment for a <code>HavingSridExpression</code>.
*/
public String getHavingSridSQL(String columnName) {
return String.format( Locale.ENGLISH, " (MDSYS.ST_GEOMETRY(%s).ST_SRID() = ?)", columnName );
}
/**
* Returns the SQL fragment when parsing a <code>IsEmptyExpression</code> or
* <code>IsNotEmpty</code> expression.
*
* @param columnName The geometry column
* @param isEmpty Whether the geometry is tested for empty or non-empty
*
* @return The SQL fragment for the isempty function
*/
public String getIsEmptySQL(String columnName, boolean isEmpty) {
return String.format(
Locale.ENGLISH,
"( MDSYS.ST_GEOMETRY(%s).ST_ISEMPTY() = %d )",
columnName,
isEmpty ? 1 : 0
);
}
/**
* Returns true if this <code>SpatialDialect</code> supports a specific filtering function.
* <p> This is intended to signal DB-support for fast window queries, or MBR-overlap queries.</p>
*
* @return True if filtering is supported
*/
public boolean supportsFiltering() {
return true;
}
/**
* Does this dialect supports the specified <code>SpatialFunction</code>.
*
* @param function <code>SpatialFunction</code>
*
* @return True if this <code>SpatialDialect</code> supports the spatial function specified by the function parameter.
*/
public boolean supports(SpatialFunction function) {
return false;
}
@Override
public String filterExpression(String geometryParam, String filterParam) {
return SpatialFunction.filter.name() + "(" + geometryParam + ", " + filterParam + ") = 'TRUE' ";
}
}

View File

@ -0,0 +1,104 @@
/*
* 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.oracle;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.spatial.CommonSpatialFunction;
import org.hibernate.spatial.FunctionKey;
import org.hibernate.spatial.KeyedSqmFunctionDescriptors;
import org.hibernate.type.BasicTypeReference;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
public class OracleSQLMMFunctionDescriptors implements KeyedSqmFunctionDescriptors {
private final Map<FunctionKey, SqmFunctionDescriptor> map = new HashMap<>();
private final BasicTypeRegistry typeRegistry;
public OracleSQLMMFunctionDescriptors(FunctionContributions functionContributions) {
typeRegistry = functionContributions.getTypeConfiguration().getBasicTypeRegistry();
registerSQLMMFunctions();
}
private void registerSQLMMFunctions() {
addSTFunction( CommonSpatialFunction.ST_ASTEXT, "GET_WKT", StandardBasicTypes.STRING );
addSTFunction( CommonSpatialFunction.ST_GEOMETRYTYPE, StandardBasicTypes.STRING );
addSTFunction( CommonSpatialFunction.ST_ASBINARY, "GET_WKB", StandardBasicTypes.BINARY );
addSTFunction( CommonSpatialFunction.ST_DIMENSION, StandardBasicTypes.INTEGER );
addSTFunction( CommonSpatialFunction.ST_ISEMPTY, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_SRID, StandardBasicTypes.INTEGER );
addSTFunction( CommonSpatialFunction.ST_ISSIMPLE, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_OVERLAPS, "ST_OVERLAP", StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_INTERSECTS, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_CONTAINS, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_DISJOINT, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_CROSSES, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_CONTAINS, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_TOUCHES, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_WITHIN, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_EQUALS, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_DISTANCE, StandardBasicTypes.DOUBLE );
addSTFunction( CommonSpatialFunction.ST_RELATE, new STRelateFunction( typeRegistry ) );
addSTFunction( CommonSpatialFunction.ST_DIFFERENCE );
addSTFunction( CommonSpatialFunction.ST_INTERSECTION );
addSTFunction( CommonSpatialFunction.ST_SYMDIFFERENCE );
addSTFunction( CommonSpatialFunction.ST_BUFFER );
addSTFunction( CommonSpatialFunction.ST_UNION );
addSTFunction( CommonSpatialFunction.ST_BOUNDARY );
addSTFunction( CommonSpatialFunction.ST_CONVEXHULL );
addSTFunction( CommonSpatialFunction.ST_ENVELOPE );
}
private <T> void addSTFunction(CommonSpatialFunction func, String stMethod, BasicTypeReference<T> tpe) {
map.put( func.getKey(), new OracleSpatialSQLMMFunction(
func.getKey().getName(),
stMethod,
func.getNumArgs(),
StandardFunctionReturnTypeResolvers.invariant(
typeRegistry.resolve( tpe ) )
) );
}
private void addSTFunction(CommonSpatialFunction func, String stMethod) {
map.put(
func.getKey(),
new OracleSpatialSQLMMFunction( func.getKey().getName(), stMethod, func.getNumArgs(), null, true )
);
}
private <T> void addSTFunction(CommonSpatialFunction func, BasicTypeReference<T> tpe) {
addSTFunction( func, func.getKey().getName().toUpperCase( Locale.ROOT ), tpe );
}
private void addSTFunction(CommonSpatialFunction func) {
addSTFunction( func, func.getKey().getName().toUpperCase( Locale.ROOT ) );
}
private void addSTFunction(CommonSpatialFunction func, OracleSpatialFunction descriptor) {
map.put( func.getKey(), descriptor );
}
@Override
public Map<FunctionKey, SqmFunctionDescriptor> asMap() {
return Collections.unmodifiableMap( map );
}
}

View File

@ -0,0 +1,30 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
public class OracleSpatialFunction extends NamedSqmFunctionDescriptor {
public OracleSpatialFunction(String name, boolean useParenthesesWhenNoArgs, ArgumentsValidator argValidator, FunctionReturnTypeResolver returnTypeResolver){
super( name, useParenthesesWhenNoArgs, argValidator, returnTypeResolver );
}
@Override
public void render(
SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
super.render( sqlAppender, sqlAstArguments, walker );
}
}

View File

@ -1,357 +0,0 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.QueryException;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.spatial.SpatialAnalysis;
import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation;
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
import org.hibernate.type.BasicTypeReference;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
/**
* Helper class to register functions in the Oracle Spatial Dialects
* Created by Karel Maesen, Geovise BVBA on 02/03/16.
*/
class OracleSpatialFunctions extends SpatialFunctionsRegistry {
OracleSpatialFunctions(boolean strictOgc, OracleSDOSupport sdoSupport) {
put( "dimension", new GetDimensionFunction() );
put( "geometrytype", new GetGeometryTypeFunction() );
put( "srid", new SDOObjectProperty( "SDO_SRID", StandardBasicTypes.INTEGER ) );
put( "envelope", new StandardSQLFunction( "SDO_GEOM.SDO_MBR" ) );
put( "astext", new AsTextFunction() );
put(
"asbinary",
new StandardSQLFunction( "SDO_UTIL.TO_WKBGEOMETRY", StandardBasicTypes.BINARY )
);
put(
"isempty",
new WrappedOGCFunction( "OGC_ISEMPTY", StandardBasicTypes.BOOLEAN, new boolean[] { true } )
);
put(
"issimple",
new WrappedOGCFunction( "OGC_ISSIMPLE", StandardBasicTypes.BOOLEAN, new boolean[] { true } )
);
put( "boundary", new WrappedOGCFunction( "OGC_BOUNDARY", new boolean[] { true } ) );
// put("area", new AreaFunction());
// Register functions for spatial relation constructs
// section 2.1.1.2
put(
"overlaps",
new SpatialRelateFunction( "overlaps", SpatialRelation.OVERLAPS, strictOgc, sdoSupport )
);
put(
"intersects",
new SpatialRelateFunction( "intersects", SpatialRelation.INTERSECTS, strictOgc, sdoSupport )
);
put(
"contains",
new SpatialRelateFunction( "contains", SpatialRelation.CONTAINS, strictOgc, sdoSupport )
);
put(
"crosses",
new SpatialRelateFunction( "crosses", SpatialRelation.CROSSES, strictOgc, sdoSupport )
);
put(
"disjoint",
new SpatialRelateFunction( "disjoint", SpatialRelation.DISJOINT, strictOgc, sdoSupport )
);
put(
"equals",
new SpatialRelateFunction( "equals", SpatialRelation.EQUALS, strictOgc, sdoSupport )
);
put(
"touches",
new SpatialRelateFunction( "touches", SpatialRelation.TOUCHES, strictOgc, sdoSupport )
);
put(
"within",
new SpatialRelateFunction( "within", SpatialRelation.WITHIN, strictOgc, sdoSupport )
);
put(
"relate",
new WrappedOGCFunction( "OGC_RELATE", StandardBasicTypes.BOOLEAN, new boolean[] { true, true, false } )
);
// Register spatial analysis functions.
// Section 2.1.1.3
put(
"distance",
new SpatialAnalysisFunction(
"distance",
StandardBasicTypes.DOUBLE,
SpatialAnalysis.DISTANCE,
strictOgc
)
);
put(
"buffer",
new SpatialAnalysisFunction( "buffer", SpatialAnalysis.BUFFER, strictOgc )
);
put(
"convexhull",
new SpatialAnalysisFunction( "convexhull", SpatialAnalysis.CONVEXHULL, strictOgc )
);
put(
"difference",
new SpatialAnalysisFunction( "difference", SpatialAnalysis.DIFFERENCE, strictOgc )
);
put(
"intersection",
new SpatialAnalysisFunction(
"intersection",
SpatialAnalysis.INTERSECTION,
strictOgc
)
);
put(
"symdifference",
new SpatialAnalysisFunction(
"symdifference",
SpatialAnalysis.SYMDIFFERENCE,
strictOgc
)
);
put(
"geomunion",
new SpatialAnalysisFunction( "union", SpatialAnalysis.UNION, strictOgc )
);
// we rename OGC union to geomunion because union is a reserved SQL
// keyword. (See also postgis documentation).
// portable spatial aggregate functions
put(
"extent",
new SpatialAggregationFunction( "extent", OracleSpatialAggregate.EXTENT, sdoSupport )
);
// spatial filter function
put(
SpatialFunction.filter.name(),
new StandardSQLFunction( "SDO_FILTER" )
);
//other common functions
put( "transform", new StandardSQLFunction( "SDO_CS.TRANSFORM" ) );
// Oracle specific Aggregate functions
put(
"centroid",
new SpatialAggregationFunction( "extent", OracleSpatialAggregate.CENTROID, sdoSupport )
);
put(
"concat_lines",
new SpatialAggregationFunction( "extent", OracleSpatialAggregate.CONCAT_LINES, sdoSupport )
);
put(
"aggr_convexhull",
new SpatialAggregationFunction( "extent", OracleSpatialAggregate.CONVEXHULL, sdoSupport )
);
put(
"aggr_union",
new SpatialAggregationFunction( "extent", OracleSpatialAggregate.UNION, sdoSupport )
);
put(
"lrs_concat",
new SpatialAggregationFunction( "lrsconcat", OracleSpatialAggregate.LRS_CONCAT, sdoSupport )
);
}
static String getOGCSpatialAnalysisSQL(List args, int spatialAnalysisFunction) {
boolean[] geomArgs;
final StringBuilder ogcFunction = new StringBuilder( "MDSYS." );
boolean isGeomReturn = true;
switch ( spatialAnalysisFunction ) {
case SpatialAnalysis.BUFFER:
ogcFunction.append( "OGC_BUFFER" );
geomArgs = new boolean[] { true, false };
break;
case SpatialAnalysis.CONVEXHULL:
ogcFunction.append( "OGC_CONVEXHULL" );
geomArgs = new boolean[] { true };
break;
case SpatialAnalysis.DIFFERENCE:
ogcFunction.append( "OGC_DIFFERENCE" );
geomArgs = new boolean[] { true, true };
break;
case SpatialAnalysis.DISTANCE:
ogcFunction.append( "OGC_DISTANCE" );
geomArgs = new boolean[] { true, true };
isGeomReturn = false;
break;
case SpatialAnalysis.INTERSECTION:
ogcFunction.append( "OGC_INTERSECTION" );
geomArgs = new boolean[] { true, true };
break;
case SpatialAnalysis.SYMDIFFERENCE:
ogcFunction.append( "OGC_SYMMETRICDIFFERENCE" );
geomArgs = new boolean[] { true, true };
break;
case SpatialAnalysis.UNION:
ogcFunction.append( "OGC_UNION" );
geomArgs = new boolean[] { true, true };
break;
default:
throw new IllegalArgumentException(
"Unknown SpatialAnalysisFunction ("
+ spatialAnalysisFunction + ")."
);
}
if ( args.size() < geomArgs.length ) {
throw new QueryException(
"Insufficient arguments for spatial analysis function (function type: "
+ spatialAnalysisFunction + ")."
);
}
ogcFunction.append( "(" );
for ( int i = 0; i < geomArgs.length; i++ ) {
if ( i > 0 ) {
ogcFunction.append( "," );
}
if ( geomArgs[i] ) {
wrapInSTGeometry( (String) args.get( i ), ogcFunction );
}
else {
ogcFunction.append( args.get( i ) );
}
}
ogcFunction.append( ")" );
if ( isGeomReturn ) {
ogcFunction.append( ".geom" );
}
return ogcFunction.toString();
}
private static StringBuilder wrapInSTGeometry(String geomColumn, StringBuilder toAdd) {
return toAdd.append( "MDSYS.ST_GEOMETRY(" ).append( geomColumn )
.append( ")" );
}
static String getNativeSpatialAnalysisSQL(List args, int spatialAnalysis) {
return getOGCSpatialAnalysisSQL( args, spatialAnalysis );
}
static String getSpatialAnalysisSQL(List args, int spatialAnalysisFunction) {
return getOGCSpatialAnalysisSQL( args, spatialAnalysisFunction );
}
/**
* Implementation of the OGC astext function for HQL.
*/
private static class AsTextFunction extends StandardSQLFunction {
private AsTextFunction() {
super( "astext", StandardBasicTypes.STRING );
}
public String render(Type firstArgumentType, final List args, final SessionFactoryImplementor factory) {
final StringBuilder buf = new StringBuilder();
if ( args.isEmpty() ) {
throw new IllegalArgumentException( "First Argument in arglist must be object " + "to which method is applied" );
}
buf.append( "TO_CHAR(SDO_UTIL.TO_WKTGEOMETRY(" ).append( args.get( 0 ) ).append( "))" );
return buf.toString();
}
}
/**
* HQL Spatial relation function.
*/
private static class SpatialRelateFunction extends StandardSQLFunction {
private final int relation;
private final boolean isOGCStrict;
private OracleSDOSupport sdo;
private SpatialRelateFunction(
final String name,
final int relation,
final boolean isOGCStrict,
OracleSDOSupport sdo) {
super( name, StandardBasicTypes.BOOLEAN );
this.relation = relation;
this.isOGCStrict = isOGCStrict;
this.sdo = sdo;
}
public String render(Type firstArgumentType, final List args, final SessionFactoryImplementor factory) {
if ( args.size() < 2 ) {
throw new QueryException(
"Spatial relate functions require at least two arguments"
);
}
return isOGCStrict ?
sdo.getOGCSpatialRelateSQL(
(String) args.get( 0 ),
(String) args.get( 1 ), this.relation
) :
sdo.getNativeSpatialRelateSQL(
(String) args.get( 0 ),
(String) args.get( 1 ), this.relation
);
}
}
private static class SpatialAnalysisFunction extends StandardSQLFunction {
private final int analysis;
private final boolean isOGCStrict;
private SpatialAnalysisFunction(String name, BasicTypeReference<?> returnType, int analysis, boolean isOGCStrict) {
super( name, returnType );
this.analysis = analysis;
this.isOGCStrict = isOGCStrict;
}
private SpatialAnalysisFunction(String name, int analysis, boolean isOGCStrict) {
this( name, null, analysis, isOGCStrict );
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return isOGCStrict ? getSpatialAnalysisSQL( args, this.analysis ) : getNativeSpatialAnalysisSQL(
args,
analysis
);
}
}
static class SpatialAggregationFunction extends StandardSQLFunction {
private final int aggregation;
private final OracleSDOSupport sdo;
private SpatialAggregationFunction(String name, int aggregation, OracleSDOSupport dialect) {
super( name );
this.aggregation = aggregation;
this.sdo = dialect;
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return sdo.getSpatialAggregateSQL(
(String) args.get( 0 ),
this.aggregation
);
}
}
}

View File

@ -0,0 +1,88 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.SqlTypes;
public class OracleSpatialSQLMMFunction extends OracleSpatialFunction {
private final String stMethod;
private final boolean addGeomAccessor;
public OracleSpatialSQLMMFunction(
String name,
String stMethod,
int numArgs,
FunctionReturnTypeResolver returnTypeResolver,
boolean addGeomAccessor) {
super(
name,
true,
StandardArgumentsValidators.exactly( numArgs ),
returnTypeResolver
);
this.stMethod = stMethod;
this.addGeomAccessor = addGeomAccessor;
}
public OracleSpatialSQLMMFunction(
String name,
String stMethod,
int numArgs,
FunctionReturnTypeResolver returnTypeResolver) {
this(
name,
stMethod,
numArgs,
returnTypeResolver,
false
);
}
@Override
public void render(
SqlAppender sqlAppender,
List<? extends SqlAstNode> arguments,
SqlAstTranslator<?> walker) {
final Expression geometry = (Expression) arguments.get( 0 );
sqlAppender.appendSql( "ST_GEOMETRY(" );
walker.render( geometry, SqlAstNodeRenderingMode.DEFAULT);
sqlAppender.appendSql( ")." );
sqlAppender.appendSql( stMethod );
sqlAppender.appendSql( "(" );
for ( int i = 1; i < arguments.size(); i++ ) {
Expression param = (Expression) arguments.get( i );
if ( param.getExpressionType().getJdbcMappings().get( 0 ).getJdbcTypeDescriptor()
.getDefaultSqlTypeCode() == SqlTypes.GEOMETRY ) {
sqlAppender.appendSql( "ST_GEOMETRY(" );
walker.render( param, SqlAstNodeRenderingMode.DEFAULT);
sqlAppender.appendSql( ")" );
}
else {
walker.render( param, SqlAstNodeRenderingMode.DEFAULT);
}
}
sqlAppender.appendSql( ")" );
if ( addGeomAccessor ) {
sqlAppender.appendSql( ".geom " );
}
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
public class SDOGetGeometryType extends OracleSpatialFunction {
public SDOGetGeometryType(BasicTypeRegistry typeRegistry) {
super( "GetGeometryType", true, StandardArgumentsValidators.exactly( 1 ),
StandardFunctionReturnTypeResolvers.invariant( typeRegistry.resolve( StandardBasicTypes.STRING ) ) );
}
@Override
public void render(
SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
sqlAppender.appendSql( "CASE " );
( (Expression) sqlAstArguments.get( 0 ) ).accept( walker );
sqlAppender.appendSql( ".Get_GType() " );
sqlAppender.appendSql( " WHEN 1 THEN 'ST_POINT'" );
sqlAppender.appendSql( " WHEN 2 THEN 'ST_LINESTRING'" );
sqlAppender.appendSql( " WHEN 3 THEN 'ST_POLYGON'" );
sqlAppender.appendSql( " WHEN 5 THEN 'ST_MULTIPOINT'" );
sqlAppender.appendSql( " WHEN 6 THEN 'ST_MULTILINESTRING'" );
sqlAppender.appendSql( " WHEN 7 THEN 'ST_MULTIPOLYGON'" );
sqlAppender.appendSql( " END" );
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
public class SDOMethodDescriptor extends OracleSpatialFunction {
public SDOMethodDescriptor(
String name,
boolean useParenthesesWhenNoArgs,
ArgumentsValidator argValidator,
FunctionReturnTypeResolver returnTypeResolver) {
super( name, useParenthesesWhenNoArgs, argValidator, returnTypeResolver );
}
public SDOMethodDescriptor(
String name,
ArgumentsValidator argValidator,
FunctionReturnTypeResolver returnTypeResolver) {
this( name, true, argValidator, returnTypeResolver );
}
@Override
public void render(
SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
sqlAstArguments.get(0).accept( walker );
sqlAppender.appendSql( "." );
sqlAppender.appendSql( getName() );
//First argument is target of the method invocation
if (this.alwaysIncludesParentheses() || sqlAstArguments.size() > 1) {
sqlAppender.append( "()" );
}
}
}

View File

@ -1,88 +0,0 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.QueryException;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.BasicTypeReference;
import org.hibernate.type.Type;
/**
* Special SQLFunction implementation for Oracle object methods
*
* @author Karel Maesen
*/
class SDOObjectMethod extends StandardSQLFunction {
private final BasicTypeReference<?> type;
private final String name;
public SDOObjectMethod(String name, BasicTypeReference<?> type) {
super(name);
this.type = type;
this.name = name;
}
public BasicTypeReference<?> getReturnType(BasicTypeReference<?> columnType, Mapping mapping)
throws QueryException {
return type == null ? columnType : type;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#hasArguments()
*/
public boolean hasArguments() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#hasParenthesesIfNoArguments()
*/
public boolean hasParenthesesIfNoArguments() {
return true;
}
public String getName() {
return this.name;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#render(java.util.List,
* org.hibernate.engine.SessionFactoryImplementor)
*/
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException {
final StringBuilder buf = new StringBuilder();
if ( args.isEmpty() ) {
throw new QueryException(
"First Argument in arglist must be object to which method is applied"
);
}
buf.append( args.get( 0 ) ).append( "." ).append( name ).append( '(' );
for ( int i = 1; i < args.size(); i++ ) {
buf.append( args.get( i ) );
if ( i < args.size() - 1 ) {
buf.append( ", " );
}
}
return buf.append( ')' ).toString();
}
}

View File

@ -1,151 +0,0 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.QueryException;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.type.BasicTypeReference;
import org.hibernate.type.Type;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Special function for accessing a member variable of an Oracle Object
*
* @author Karel Maesen
*/
class SDOObjectProperty implements SqmFunctionDescriptor {
private final BasicTypeReference<?> type;
private final String name;
public SDOObjectProperty(String name, BasicTypeReference<?> type) {
this.type = type;
this.name = name;
}
public BasicTypeReference<?> getReturnType(BasicTypeReference<?> columnType, Mapping mapping)
throws QueryException {
return type == null ? columnType : type;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#hasArguments()
*/
public boolean hasArguments() {
return true;
}
@Override
public ArgumentsValidator getArgumentsValidator() {
return null;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#hasParenthesesIfNoArguments()
*/
public boolean hasParenthesesIfNoArguments() {
return false;
}
public String getName() {
return this.name;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#render(java.util.List,
* org.hibernate.engine.SessionFactoryImplementor)
*/
public String render(Type firstArgtype, List args, SessionFactoryImplementor factory)
throws QueryException {
final StringBuilder buf = new StringBuilder();
if ( args.isEmpty() ) {
throw new QueryException(
"First Argument in arglist must be object of which property is queried"
);
}
buf.append( args.get( 0 ) ).append( "." ).append( name );
return buf.toString();
}
@Override
public <T> SelfRenderingSqmFunction<T> generateSqmExpression(
List<? extends SqmTypedNode<?>> arguments,
ReturnableType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
throw new NotYetImplementedException();
}
@Override
public <T> SelfRenderingSqmFunction<T> generateAggregateSqmExpression(
List<? extends SqmTypedNode<?>> arguments,
SqmPredicate filter,
ReturnableType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
return SqmFunctionDescriptor.super.generateAggregateSqmExpression(
arguments,
filter,
impliedResultType,
queryEngine,
typeConfiguration
);
}
@Override
public <T> SelfRenderingSqmFunction<T> generateSqmExpression(
SqmTypedNode<?> argument,
ReturnableType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
return SqmFunctionDescriptor.super.generateSqmExpression(
argument,
impliedResultType,
queryEngine,
typeConfiguration
);
}
@Override
public <T> SelfRenderingSqmFunction<T> generateSqmExpression(
ReturnableType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
return SqmFunctionDescriptor.super.generateSqmExpression( impliedResultType, queryEngine, typeConfiguration );
}
@Override
public boolean alwaysIncludesParentheses() {
return SqmFunctionDescriptor.super.alwaysIncludesParentheses();
}
@Override
public String getSignature(String name) {
return SqmFunctionDescriptor.super.getSignature( name );
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.dialect.OracleSqlAstTranslator;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
public class SDORelateFunction extends OracleSpatialFunction {
final private List<String> masks;
public SDORelateFunction(List<String> masks, BasicTypeRegistry typeRegistry) {
super(
"SDO_GEOM.RELATE",
false,
StandardArgumentsValidators.exactly( 2 ),
StandardFunctionReturnTypeResolvers.invariant( typeRegistry.resolve(
StandardBasicTypes.BOOLEAN ) )
);
this.masks = masks;
}
@Override
public void render(
SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
Expression geom1 = (Expression) sqlAstArguments.get( 0 );
Expression geom2 = (Expression) sqlAstArguments.get( 1 );
String maskExpression = String.join( "+", masks );
sqlAppender.appendSql( "CASE " );
sqlAppender.appendSql( getName() );
sqlAppender.appendSql( "(" );
walker.render( geom1, SqlAstNodeRenderingMode.DEFAULT );
sqlAppender.appendSql( ", '" );
sqlAppender.appendSql( maskExpression );
sqlAppender.appendSql( "', " );
walker.render( geom2, SqlAstNodeRenderingMode.DEFAULT );
sqlAppender.appendSql( ")" );
sqlAppender.appendSql( " WHEN 'FALSE' THEN 0 ");
sqlAppender.appendSql( " ELSE 1 " );
sqlAppender.appendSql( " END" );
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
public class STRelateFunction extends OracleSpatialFunction {
public STRelateFunction(BasicTypeRegistry typeRegistry) {
super(
"ST_RELATE",
false,
StandardArgumentsValidators.exactly( 2 ),
StandardFunctionReturnTypeResolvers.invariant( typeRegistry.resolve( StandardBasicTypes.STRING ) )
);
}
@Override
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> arguments, SqlAstTranslator<?> walker) {
final Expression geom1 = (Expression) arguments.get( 0 );
final Expression geom2 = (Expression) arguments.get( 1 );
sqlAppender.appendSql( "ST_GEOMETRY(" );
walker.render( geom1, SqlAstNodeRenderingMode.DEFAULT );
sqlAppender.appendSql( ").ST_RELATE( ST_GEOMETRY(" );
walker.render( geom2, SqlAstNodeRenderingMode.DEFAULT );
sqlAppender.appendSql( ") , 'DETERMINE' ) " );
}
}

View File

@ -1,82 +0,0 @@
/*
* 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.oracle;
import java.util.List;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.spatial.Spatial;
import org.hibernate.type.BasicTypeReference;
import org.hibernate.type.Type;
/**
* An HQL function that is implemented using Oracle's OGC compliance
* package.
*/
class WrappedOGCFunction extends StandardSQLFunction {
private final boolean[] geomArrays;
private final boolean isGeometryTyped;
/**
* Creates a functions that does not have a {@code Spatial} return type
*
* @param name function name
* @param type return type of the function
* @param geomArrays indicates which argument places are occupied by
* sdo_geometries
*/
WrappedOGCFunction(final String name, final BasicTypeReference<?> type, final boolean[] geomArrays) {
super( name, type );
if ( isSpatial( type ) ) {
throw new IllegalArgumentException(
"This constructor is only valid for functions returning non-spatial values."
);
}
this.geomArrays = geomArrays;
this.isGeometryTyped = false;
}
/**
* @param name function name
* @param geomArrays indicates which argument places are occupied by
* sdo_geometries
*/
WrappedOGCFunction(final String name, final boolean[] geomArrays) {
super( name );
this.geomArrays = geomArrays;
this.isGeometryTyped = true;
}
public String render(Type firstArgumentType, final List args, final SessionFactoryImplementor factory) {
final StringBuilder buf = new StringBuilder();
buf.append( "MDSYS." ).append( getName() ).append( "(" );
for ( int i = 0; i < args.size(); i++ ) {
if ( i > 0 ) {
buf.append( "," );
}
if ( geomArrays[i] ) {
buf.append( "MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(" ).append(
args.get( i )
).append( ")" );
}
else {
buf.append( args.get( i ) );
}
}
buf.append( ")" );
return ( isGeometryTyped ) ? buf
.append( ".geom" ).toString() : buf.toString();
}
private boolean isSpatial(BasicTypeReference<?> type) {
return Spatial.class.isAssignableFrom( type.getClass() );
}
}

View File

@ -31,7 +31,7 @@ import static org.hibernate.spatial.testing.datareader.TestSupport.TestDataPurpo
@Deprecated
public class SpatialTestDataProvider {
protected final static String JTS = "jts";
protected final NativeSQLTemplates templates;
protected NativeSQLTemplates templates;
protected final PredicateRegexes predicateRegexes;
protected final Map<CommonSpatialFunction, String> hqlOverrides;
protected final Geometry<?> filterGeometry;

View File

@ -14,6 +14,7 @@
package org.hibernate.spatial.integration.functions;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@ -52,8 +53,8 @@ public class CommonFunctionTests extends SpatialTestBase {
public final static TestSupport.TestDataPurpose PURPOSE = TestSupport.TestDataPurpose.SpatialFunctionsData;
List received;
List expected;
List received = new ArrayList();
List expected = new ArrayList();
@Override
public TestSupport.TestDataPurpose purpose() {
@ -97,6 +98,8 @@ public class CommonFunctionTests extends SpatialTestBase {
protected Executable executableTest(FunctionTestTemplate template, String fnName) {
return () -> {
expected.clear();
received.clear();
expected = template.executeNativeQuery( scope );
received = template.executeHQL( scope, fnName );
if ( !expected.equals( received ) ) {

View File

@ -0,0 +1,29 @@
/*
* 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.functions;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.spatial.HibernateSpatialConfigurationSettings;
import org.hibernate.spatial.testing.dialects.oracle.OracleSTNativeSqlTemplates;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.Setting;
/**
* Only for Oracle: run the tests in "OGC_STRICT" mode (i.e. using the SQL MultiMedia functions)
*/
@RequiresDialect( value = OracleDialect.class)
@ServiceRegistry(settings = {
@Setting(name = HibernateSpatialConfigurationSettings.ORACLE_OGC_STRICT, value = "true")
})
public class OracleSQLMMFunctionTests extends CommonFunctionTests{
public OracleSQLMMFunctionTests() {
this.templates = new OracleSTNativeSqlTemplates();
}
}

View File

@ -9,5 +9,102 @@ package org.hibernate.spatial.testing.dialects.oracle;
import org.hibernate.spatial.testing.dialects.NativeSQLTemplates;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ASBINARY;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ASTEXT;
import static org.hibernate.spatial.CommonSpatialFunction.ST_BOUNDARY;
import static org.hibernate.spatial.CommonSpatialFunction.ST_BUFFER;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CONTAINS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CONVEXHULL;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CROSSES;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DIFFERENCE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DIMENSION;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DISJOINT;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DISTANCE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ENVELOPE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_EQUALS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_GEOMETRYTYPE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_INTERSECTION;
import static org.hibernate.spatial.CommonSpatialFunction.ST_INTERSECTS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ISEMPTY;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ISSIMPLE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_OVERLAPS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_RELATE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_SRID;
import static org.hibernate.spatial.CommonSpatialFunction.ST_SYMDIFFERENCE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_TOUCHES;
import static org.hibernate.spatial.CommonSpatialFunction.ST_UNION;
import static org.hibernate.spatial.CommonSpatialFunction.ST_WITHIN;
public class OracleSDONativeSqlTemplates extends NativeSQLTemplates {
public OracleSDONativeSqlTemplates() {
sqls.clear();
sqls.put( ST_ASTEXT, "select t.ID, t.GEOM.GET_WKT() as result from %s t" );
sqls.put( ST_GEOMETRYTYPE, "select t.ID, ST_Geometry(t.GEOM).st_geometrytype() as result from %s t" );
sqls.put( ST_DIMENSION, "select id, t.GEOM.Get_Dims() as result from %s t" );
sqls.put( ST_ENVELOPE, "select id, SDO_GEOM.SDO_MBR(t.geom) as result from %s t" );
sqls.put( ST_SRID, "select id, t.geom.sdo_srid as result from %s t" );
sqls.put( ST_ASBINARY, "select id, t.geom.Get_WKB() as result from %s t" );
sqls.put( ST_ISEMPTY, "select id, ST_Geometry(t.geom).st_isempty() as result from %s t" );
sqls.put( ST_ISSIMPLE, "select id, ST_Geometry(t.geom).st_issimple() as result from %s t" );
sqls.put( ST_BOUNDARY, "select id, ST_Geometry(t.geom).st_boundary().geom as result from %s t" );
sqls.put(
ST_OVERLAPS,
"select t.id, SDO_GEOM.relate( t.geom, 'CONTAINS', ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom, 0.005) as result from %s T"
);
sqls.put(
ST_INTERSECTS,
"select id, case SDO_GEOM.relate(t.geom, 'OVERLAPBDYDISJOINT + OVERLAPBDYINTERSECT', ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom, 0.005) when 'FALSE' THEN 0 ELSE 1 END as result from %s T"
);
sqls.put(
ST_CROSSES,
"select id, ST_GEOMETRY(t.geom).st_crosses(ST_GEOMETRY.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put(
ST_CONTAINS,
"select id, CASE SDO_GEOM.relate(t.geom, 'CONTAINS', ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom, 0.005) when 'FALSE' THEN 0 ELSE 1 END as result from %s T"
);
sqls.put(
ST_DISJOINT,
"select id, CASE SDO_GEOM.relate(t.geom, 'DISJOINT', ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom, 0.005) when 'FALSE' THEN 0 ELSE 1 END as result from %s T"
);
sqls.put(
ST_RELATE,
"select id, ST_GEOMETRY(t.geom).st_relate(ST_GEOMETRY.FROM_WKT(:filter, 4326), 'DETERMINE') as result from %s t"
);
sqls.put(
ST_TOUCHES,
"select id, CASE SDO_GEOM.relate(t.geom, 'TOUCH', ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom, 0.005) when 'FALSE' THEN 0 ELSE 1 END as result from %s T"
);
sqls.put(
ST_WITHIN,
"select id, CASE SDO_GEOM.relate(t.geom, 'COVERS+CONTAINS', ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom, 0.005) when 'FALSE' THEN 0 ELSE 1 END as result from %s T"
);
sqls.put(
ST_EQUALS,
"select id, CASE SDO_GEOM.relate(t.geom, 'EQUAL', ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom, 0.005) when 'FALSE' THEN 0 ELSE 1 END as result from %s T"
);
sqls.put(
ST_DISTANCE,
"select id, SDO_GEOM.SDO_DISTANCE(t.geom, ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom) as result from %s t"
);
sqls.put( ST_BUFFER, "select id, SDO_GEOM.SDO_BUFFER(t.geom, 2) as result from %s t" );
sqls.put( ST_CONVEXHULL, "select id, SDO_GEOM.SDO_CONVEXHULL(t.geom) as result from %s t" );
sqls.put(
ST_DIFFERENCE,
"select id, SDO_GEOM.SDO_DIFFERENCE(t.geom, ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom) as result from %s t"
);
sqls.put(
ST_INTERSECTION,
"select id, SDO_GEOM.SDO_INTERSECTION(t.geom, ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom) as result from %s t"
);
sqls.put(
ST_SYMDIFFERENCE,
"select id, SDO_GEOM.SDO_XOR(t.geom, ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom) as result from %s t"
);
sqls.put(
ST_UNION,
"select id, SDO_GEOM.SDO_UNION(t.geom, ST_GEOMETRY.FROM_WKT(:filter, 4326).Geom) as result from %s t"
);
}
}

View File

@ -8,9 +8,8 @@
package org.hibernate.spatial.testing.dialects.oracle;
import java.util.Map;
import java.sql.Struct;
import org.hibernate.spatial.CommonSpatialFunction;
import org.hibernate.spatial.GeomCodec;
import org.hibernate.spatial.testing.datareader.TestData;
import org.hibernate.spatial.testing.datareader.TestSupport;
@ -46,7 +45,8 @@ public class OracleSDOTestSupport extends TestSupport {
return new GeomCodec() {
@Override
public Geometry<?> toGeometry(Object in) {
return Decoders.decode( (SDOGeometry) in );
SDOGeometry geom = SDOGeometry.load( (Struct) in );
return Decoders.decode( geom );
}
};
}

View File

@ -0,0 +1,108 @@
/*
* 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.oracle;
import org.hibernate.spatial.testing.dialects.NativeSQLTemplates;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ASBINARY;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ASTEXT;
import static org.hibernate.spatial.CommonSpatialFunction.ST_BOUNDARY;
import static org.hibernate.spatial.CommonSpatialFunction.ST_BUFFER;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CONTAINS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CONVEXHULL;
import static org.hibernate.spatial.CommonSpatialFunction.ST_CROSSES;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DIFFERENCE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DIMENSION;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DISJOINT;
import static org.hibernate.spatial.CommonSpatialFunction.ST_DISTANCE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ENVELOPE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_EQUALS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_GEOMETRYTYPE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_INTERSECTION;
import static org.hibernate.spatial.CommonSpatialFunction.ST_INTERSECTS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ISEMPTY;
import static org.hibernate.spatial.CommonSpatialFunction.ST_ISSIMPLE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_OVERLAPS;
import static org.hibernate.spatial.CommonSpatialFunction.ST_RELATE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_SRID;
import static org.hibernate.spatial.CommonSpatialFunction.ST_SYMDIFFERENCE;
import static org.hibernate.spatial.CommonSpatialFunction.ST_TOUCHES;
import static org.hibernate.spatial.CommonSpatialFunction.ST_UNION;
import static org.hibernate.spatial.CommonSpatialFunction.ST_WITHIN;
public class OracleSTNativeSqlTemplates extends NativeSQLTemplates {
public OracleSTNativeSqlTemplates() {
sqls.clear();
sqls.put( ST_ASTEXT, "select t.ID, t.GEOM.GET_WKT() as result from %s t" );
sqls.put( ST_GEOMETRYTYPE, "select t.ID, ST_GEOMETRY(t.GEOM).ST_GEOMETRYTYPE() as result from %s t" );
sqls.put( ST_DIMENSION, "select id, ST_GEOMETRY(t.GEOM).ST_DIMENSION() as result from %s t" );
sqls.put( ST_ENVELOPE, "select id, ST_GEOMETRY(t.GEOM).ST_ENVELOPE().geom as result from %s t" );
sqls.put( ST_ASBINARY, "select id, ST_GEOMETRY(t.GEOM).GET_WKB() as result from %s t" );
sqls.put( ST_SRID, "select t.id, ST_GEOMETRY(t.GEOM).ST_SRID() as result from %s t" );
sqls.put( ST_ISEMPTY, "select id, ST_GEOMETRY(t.GEOM).ST_ISEMPTY() as result from %s t" );
sqls.put( ST_ISSIMPLE, "select id, ST_GEOMETRY(t.GEOM).ST_ISSIMPLE() as result from %s t" );
sqls.put( ST_BOUNDARY, "select id, ST_GEOMETRY(t.GEOM).ST_BOUNDARY().Geom as result from %s t" );
sqls.put(
ST_OVERLAPS,
"select id, ST_GEOMETRY(t.GEOM).ST_OVERLAP(ST_Geometry.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put(
ST_INTERSECTS,
"select id, ST_GEOMETRY(t.GEOM).st_intersects(ST_Geometry.From_WKT(:filter, 4326)) as result from %s t"
);
sqls.put(
ST_CROSSES,
"select id, ST_GEOMETRY(t.GEOM).st_crosses(ST_GEOMETRY.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put(
ST_CONTAINS,
"select id, ST_GEOMETRY(t.GEOM).ST_CONTAINS(ST_GEOMETRY.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put(
ST_DISJOINT,
"select id, ST_GEOMETRY(t.GEOM).ST_DISJOINT(ST_GEOMETRY.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put( ST_RELATE,
"select id, ST_GEOMETRY(t.GEOM).st_relate(st_geometry.from_wkt(:filter, 4326), 'DETERMINE') as result from %s t" );
sqls.put(
ST_TOUCHES,
"select id, ST_GEOMETRY(t.GEOM).ST_TOUCHES(ST_GEOMETRY.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put(
ST_WITHIN,
"select id, ST_GEOMETRY(t.GEOM).ST_WITHIN(ST_GEOMETRY.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put(
ST_EQUALS,
"select id, ST_GEOMETRY(t.GEOM).ST_EQUALS( ST_GEOMETRY.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put(
ST_DISTANCE,
"select id, ST_GEOMETRY(t.GEOM).st_distance(ST_Geometry.FROM_WKT(:filter, 4326)) as result from %s t"
);
sqls.put( ST_BUFFER, "select id,ST_GEOMETRY(t.GEOM).ST_BUFFER( 2 ).Geom as result from %s t" );
sqls.put( ST_CONVEXHULL, "select id, ST_GEOMETRY(t.GEOM).st_convexhull().Geom as result from %s t" );
sqls.put(
ST_DIFFERENCE,
"select id, ST_GEOMETRY(t.GEOM).st_difference(ST_GEOMETRY.FROM_WKT(:filter, 4326)).Geom as result from %s t"
);
sqls.put(
ST_INTERSECTION,
"select id, ST_GEOMETRY(t.geom).st_intersection(ST_GEOMETRY.FROM_WKT(:filter, 4326)).Geom as result from %s t"
);
sqls.put(
ST_SYMDIFFERENCE,
"select id, ST_GEOMETRY(t.GEOM).st_symdifference(ST_GEOMETRY.FROM_WKT(:filter, 4326)).Geom as result from %s t"
);
sqls.put(
ST_UNION,
"select id, ST_GEOMETRY(t.geom).st_union(ST_GEOMETRY.FROM_WKT(:filter, 4326)).Geom as result from %s t"
);
}
}

View File

@ -1,260 +0,0 @@
/*
* 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.oracle;
import org.hibernate.spatial.JTSGeometryJavaType;
import org.hibernate.spatial.dialect.oracle.SDOGeometryValueExtractor;
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.NativeSQLStatement;
import org.geolatte.geom.jts.JTS;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
/**
* Expectations factory for Oracle 10g (SDOGeometry).
*
* @Author Karel Maesen, Geovise BVBA
*/
public class SDOGeometryExpectationsFactory extends AbstractExpectationsFactory {
private final SDOGeometryValueExtractor decoder = new SDOGeometryValueExtractor(
JTSGeometryJavaType.GEOMETRY_INSTANCE,
null
);
public SDOGeometryExpectationsFactory() {
super();
}
@Override
public NativeSQLStatement createNativeTouchesStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Touch(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Touch(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeOverlapsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Overlap(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Overlap(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeRelateStatement(Geometry geom, String matrix) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Relate(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326), '" + matrix + "') from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Relate(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326), '" + matrix + "') = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeDwithinStatement(Point geom, double distance) {
return createNativeSQLStatementAllWKTParams(
"select t.id, 1 from GEOMTEST T where MDSYS.SDO_WITHIN_DISTANCE(t.GEOM, SDO_GEOMETRY(? , 4326), 'distance = " + distance + "') = 'TRUE' and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeIntersectsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Intersects(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Intersects(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeFilterStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, 1 from GEOMTEST t where SDO_FILTER(t.GEOM, MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326).GEOM) = 'TRUE' ",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeDistanceStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Distance(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeDimensionSQL() {
return createNativeSQLStatement(
"select ID, MDSYS.OGC_DIMENSION(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM( T.GEOM)) FROM GEOMTEST T"
);
}
@Override
public NativeSQLStatement createNativeBufferStatement(Double distance) {
return createNativeSQLStatement(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Buffer(?).GEOM from GEOMTEST T where t.GEOM.SDO_SRID = 4326",
new Double[] { distance }
);
}
@Override
public NativeSQLStatement createNativeConvexHullStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Union(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)).ST_ConvexHull().GEOM from GEOMTEST T where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeIntersectionStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Intersection(MDSYS.ST_GEOMETRY.FROM_WKT(?,4326)).GEOM FROM GEOMTEST t where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeDifferenceStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Difference(MDSYS.ST_GEOMETRY.FROM_WKT(?,4326)).GEOM FROM GEOMTEST t where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeSymDifferenceStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_SymmetricDifference(MDSYS.ST_GEOMETRY.FROM_WKT(?,4326)).GEOM FROM GEOMTEST t where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeGeomUnionStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Union(MDSYS.ST_GEOMETRY.FROM_WKT(?,4326)).GEOM FROM GEOMTEST t where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeAsTextStatement() {
return createNativeSQLStatement( "select t.ID, t.GEOM.GET_WKT() FROM GEOMTEST T" );
}
@Override
public NativeSQLStatement createNativeSridStatement() {
return createNativeSQLStatement( "SELECT t.ID, t.GEOM.SDO_SRID FROM GEOMTEST t" );
}
@Override
public NativeSQLStatement createNativeIsSimpleStatement() {
return createNativeSQLStatement(
"SELECT t.ID, MDSYS.OGC_ISSIMPLE(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)) FROM GEOMTEST t where MDSYS.OGC_ISSIMPLE(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)) = 1"
);
}
@Override
public NativeSQLStatement createNativeIsEmptyStatement() {
return createNativeSQLStatement(
"SELECT t.ID, MDSYS.OGC_ISEMPTY(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)) FROM GEOMTEST t"
);
}
@Override
public NativeSQLStatement createNativeIsNotEmptyStatement() {
return createNativeSQLStatement(
"SELECT t.ID, CASE MDSYS.OGC_ISEMPTY(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)) WHEN 0 THEN 1 ELSE 0 END FROM GEOMTEST t"
);
}
@Override
public NativeSQLStatement createNativeBoundaryStatement() {
return createNativeSQLStatement(
"SELECT t.ID, MDSYS.OGC_BOUNDARY(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)).GEOM FROM GEOMTEST t"
);
}
@Override
public NativeSQLStatement createNativeEnvelopeStatement() {
return createNativeSQLStatement(
"SELECT t.ID, MDSYS.OGC_ENVELOPE(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)).GEOM FROM GEOMTEST t"
);
}
@Override
public NativeSQLStatement createNativeAsBinaryStatement() {
return createNativeSQLStatement( "select t.ID, t.GEOM.GET_WKB() FROM GEOMTEST T" );
}
@Override
public NativeSQLStatement createNativeGeometryTypeStatement() {
return createNativeSQLStatement(
"select t.id, CASE t.geom.Get_GType() WHEN 1 THEN 'POINT' WHEN 2 THEN 'LINESTRING' WHEN 3 THEN 'POLYGON' WHEN 5 THEN 'MULTIPOINT' WHEN 6 THEN 'MULTILINE' WHEN 7 THEN 'MULTIPOLYGON' END from GEOMTEST t"
);
}
@Override
public NativeSQLStatement createNativeWithinStatement(Geometry testPolygon) {
return createNativeSQLStatementAllWKTParams(
"select t.id, mdsys.OGC_WITHIN( MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM), MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where mdsys.OGC_WITHIN( MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM), MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
testPolygon.toText()
);
}
@Override
public NativeSQLStatement createNativeEqualsStatement(Geometry testPolygon) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Equals(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Equals(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
testPolygon.toText()
);
}
@Override
public NativeSQLStatement createNativeCrossesStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Cross(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Cross(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeContainsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Contains(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Contains(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeDisjointStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Disjoint(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Disjoint(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
public NativeSQLStatement createNativeTransformStatement(int epsg) {
return createNativeSQLStatement(
"select t.id, MDSYS.SDO_CS.transform(t.geom," + epsg + ") from GeomTest t where t.geom.SDO_SRID = 4326"
);
}
@Override
public NativeSQLStatement createNativeHavingSRIDStatement(int srid) {
return createNativeSQLStatement( "select t.id, 1 from GeomTest t where t.geom.SDO_SRID = " + srid );
}
@Override
protected Geometry decode(Object o) {
return ( o != null ) ? JTS.to( decoder.convert( o ) ) : null;
}
}

View File

@ -24,44 +24,31 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa
#
## NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
#hibernate.jdbc.batch_versioned_data true
## Configs for spatial databases (used during testing on local dev environment).
#
#hibernate.dialect org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect
## Postgis
##
#hibernate.dialect org.hibernate.dialect.PostgreSQLDialect
#hibernate.connection.driver_class org.postgresql.Driver
#hibernate.connection.url jdbc:postgresql://localhost:5432/hibernate_orm_test?preparedStatementCacheQueries=0
#hibernate.connection.username hibernate_orm_test
#hibernate.connection.password hibernate_orm_test
#
## MariaDB
##
#hibernate.dialect org.hibernate.dialect.MariaDBDialect
#hibernate.connection.driver_class org.mariadb.jdbc.Driver
#hibernate.connection.url jdbc:mariadb://localhost/hibernate_orm_test
#hibernate.connection.username hibernate_orm_test
#hibernate.connection.password hibernate_orm_test
## GeoDb (H2 spatial extension)
##
#hibernate.dialect org.hibernate.spatial.dialect.h2geodb.GeoDBDialect
#hibernate.connection.driver_class org.h2.Driver
#hibernate.connection.url jdbc:h2:mem:testhbs;DB_CLOSE_DELAY=-1;MVCC=true
#hibernate.connection.username sa
#hibernate.connection.password sa
##
## Oracle 11g
## Oracle
##
#hibernate.spatial.connection_finder org.hibernate.spatial.dialect.oracle.TestConnectionFinder
#hibernate.dialect org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect
#hibernate.dialect org.hibernate.dialect.OracleDialect
#hibernate.connection.driver_class oracle.jdbc.OracleDriver
#hibernate.connection.url jdbc:oracle:thin:@localhost:1521/orcl12c
#hibernate.connection.username C##hibernate
#hibernate.connection.password hibernate
#hibernate.dialect org.hibernate.spatial.dialect.oracle.OracleSpatialSDO10gDialect
#hibernate.connection.driver_class oracle.jdbc.OracleDriver
#hibernate.connection.url jdbc:oracle:thin:@localhost:1521/orcl12c
#hibernate.connection.username C##hibernate
#hibernate.connection.password hibernate
#hibernate.connection.url jdbc:oracle:thin:@localhost:1521:XE
#hibernate.connection.username SYSTEM
#hibernate.connection.password Oracle18
#
##
## MS SQL Server dialect