Backports HIBSPA-95 HIBSPA-99, HIBSPA-100, HIBSPA-101, HIBSPA-102.

Conflicts:
	hibernate-spatial/databases/mysql5_innodb/resources/hibernate.properties
	hibernate-spatial/hibernate-spatial.gradle
	hibernate-spatial/src/main/java/org/hibernate/spatial/criterion/DWithinExpression.java
	hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/h2geodb/GeoDBDialect.java
	hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/h2geodb/WKB.java
	hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/oracle/OracleJDBCTypeFactory.java
	hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/oracle/OracleSpatial10gDialect.java
	hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/oracle/SDOGeometry.java
	hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/oracle/SDOGeometryTypeDescriptor.java
	hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/oracle/SDOGeometryValueBinder.java
	hibernate-spatial/src/main/java/org/hibernate/spatial/integration/SpatialIntegrator.java
	hibernate-spatial/src/test/java/org/hibernate/spatial/integration/GeomEntity.java
	hibernate-spatial/src/test/java/org/hibernate/spatial/integration/TestSpatialFunctions.java
	hibernate-spatial/src/test/java/org/hibernate/spatial/testing/SpatialFunctionalTestCase.java
	hibernate-spatial/src/test/java/org/hibernate/spatial/testing/TestSupportFactories.java
	hibernate-spatial/src/test/java/org/hibernate/spatial/testing/dialects/h2geodb/GeoDBExpectationsFactory.java
	hibernate-spatial/src/test/java/org/hibernate/spatial/testing/dialects/mysql/MySQLExpectationsFactory.java
	hibernate-spatial/src/test/java/org/hibernate/spatial/testing/dialects/oracle/SDOGeometryExpectationsFactory.java
	hibernate-spatial/src/test/resources/hibernate.properties
This commit is contained in:
Karel Maesen 2013-08-16 19:46:28 +02:00 committed by Steve Ebersole
parent 6e91485549
commit c55d250025
35 changed files with 930 additions and 338 deletions

View File

@ -0,0 +1,24 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
jdbcDependency "mysql:mysql-connector-java:5.1.15"

View File

@ -0,0 +1,42 @@
#
# Hibernate, Relational Persistence for Idiomatic Java
#
# Copyright (c) 2011, Red Hat Inc. or third-party contributors as
# indicated by the @author tags or express copyright attribution
# statements applied by the authors. All third-party contributions are
# distributed under license by Red Hat Inc.
#
# This copyrighted material is made available to anyone wishing to use, modify,
# copy, or redistribute it subject to the terms and conditions of the GNU
# Lesser General Public License, as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this distribution; if not, write to:
# Free Software Foundation, Inc.
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301 USA
#
hibernate.dialect org.hibernate.spatial.dialect.mysql.MySQL56SpatialDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://172.16.1.130/test
hibernate.connection.username HBS
hibernate.connection.password HBS
hibernate.connection.pool_size 5
hibernate.show_sql true
hibernate.format_sql true
hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory

View File

@ -24,7 +24,7 @@
hibernate.test.new_metadata_mappings = true hibernate.test.new_metadata_mappings = true
hibernate.dialect org.hibernate.spatial.dialect.mysql.MySQL5SpatialInnoDBDialect hibernate.dialect org.hibernate.spatial.dialect.mysql.MySQL5InnoDBSpatialDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://localhost/testhbs hibernate.connection.url jdbc:mysql://localhost/testhbs

View File

@ -28,6 +28,9 @@ hibernate.connection.url jdbc:oracle:thin:@oracle11g.geovise.com:1521/orcl11g.ge
hibernate.connection.username HBS hibernate.connection.username HBS
hibernate.connection.password HBS hibernate.connection.password HBS
## uncommenting this will fail a unit test!!
#hibernate.spatial.ogc_strict false
hibernate.connection.pool_size 5 hibernate.connection.pool_size 5
hibernate.show_sql true hibernate.show_sql true

View File

@ -22,8 +22,6 @@
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'hibernate-matrix-testing' apply plugin: 'hibernate-matrix-testing'
//apply plugin: org.hibernate.build.gradle.testing.matrix.MatrixTestingPlugin
dependencies { dependencies {
compile(project(':hibernate-core')) compile(project(':hibernate-core'))
compile([group: 'postgresql', name: 'postgresql', version: '8.4-701.jdbc4']) compile([group: 'postgresql', name: 'postgresql', version: '8.4-701.jdbc4'])
@ -35,6 +33,7 @@ dependencies {
} }
testCompile(libraries.junit) testCompile(libraries.junit)
testCompile(project(':hibernate-testing')) testCompile(project(':hibernate-testing'))
testCompile([group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4']) testCompile([group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4'])

View File

@ -0,0 +1,69 @@
package org.hibernate.spatial;
import org.hibernate.spatial.dialect.oracle.ConnectionFinder;
/**
* A global configuration object that is is used by
* some Dialects during construction.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/16/13
*/
public class HibernateSpatialConfiguration {
private static final Log LOG = LogFactory.make();
private Boolean isOgcStrict = Boolean.TRUE;
private ConnectionFinder connectionFinder;
/**
* Holds the configuration for Hibernate Spatial dialects.
*/
public HibernateSpatialConfiguration() {
}
/**
* Creates a Configuration for Hibernate spatial
*
* @param ogcStrict true for OGC Strict mode
* @param connectionFinder the fully-qualified Class name for the {@code ConnectionFinder}
*/
public HibernateSpatialConfiguration(Boolean ogcStrict, ConnectionFinder connectionFinder) {
if ( ogcStrict != null ) {
this.isOgcStrict = ogcStrict;
LOG.info( String.format( "Setting OGC_STRICT mode for Oracle Spatial dialect to %s.", ogcStrict ) );
}
if ( connectionFinder != null ) {
this.connectionFinder = connectionFinder;
LOG.info(
String.format(
"Using ConnectionFinder implementation: %s (only relevant for Oracle Spatial dialect).",
connectionFinder.getClass().getCanonicalName()
)
);
}
}
public Boolean isOgcStrictMode() {
return isOgcStrict;
}
public ConnectionFinder getConnectionFinder() {
return connectionFinder;
}
/**
* Collects the property names for Hibernate Spatial configuration properties.
*/
public static class AvailableSettings {
/**
* Determines whether or nog to use the OracleSpatial10gDialect in OGC_STRICT mode or not (values: true or false)
*/
public static final String OGC_STRICT = "hibernate.spatial.ogc_strict";
/**
* The canonical class name to use as Oracle ConnectionFinder implementation.
*/
public static final String CONNECTION_FINDER = "hibernate.spatial.connection_finder";
}
}

View File

@ -30,6 +30,7 @@ import org.hibernate.criterion.Criterion;
import org.hibernate.engine.spi.TypedValue; import org.hibernate.engine.spi.TypedValue;
import org.hibernate.spatial.SpatialDialect; import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
/** /**
@ -71,9 +72,14 @@ public class DWithinExpression implements Criterion {
@Override @Override
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
final SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect( criteriaQuery, SpatialFunction.dwithin );
TypedValue typedDistanceValue = new TypedValue( StandardBasicTypes.DOUBLE, distance );
if ( spatialDialect instanceof OracleSpatial10gDialect ) {
typedDistanceValue = new TypedValue( StandardBasicTypes.STRING, "distance=" + distance );
}
return new TypedValue[] { return new TypedValue[] {
criteriaQuery.getTypedValue( criteria, propertyName, geometry ), criteriaQuery.getTypedValue( criteria, propertyName, geometry ),
new TypedValue( StandardBasicTypes.DOUBLE, distance ) typedDistanceValue
}; };
} }
} }

View File

@ -39,50 +39,6 @@ import org.hibernate.type.StandardBasicTypes;
*/ */
public class GeoDBDialect extends H2Dialect implements SpatialDialect { public class GeoDBDialect extends H2Dialect implements SpatialDialect {
/*
Contents of GeoDB's spatial registration script (geodb.sql):
CREATE ALIAS AddGeometryColumn for "geodb.GeoDB.AddGeometryColumn"
CREATE ALIAS CreateSpatialIndex for "geodb.GeoDB.CreateSpatialIndex"
CREATE ALIAS DropGeometryColumn for "geodb.GeoDB.DropGeometryColumn"
CREATE ALIAS DropGeometryColumns for "geodb.GeoDB.DropGeometryColumns"
CREATE ALIAS DropSpatialIndex for "geodb.GeoDB.DropSpatialIndex"
CREATE ALIAS EnvelopeAsText for "geodb.GeoDB.EnvelopeAsText"
CREATE ALIAS GeometryType for "geodb.GeoDB.GeometryType"
CREATE ALIAS ST_Area FOR "geodb.GeoDB.ST_Area"
CREATE ALIAS ST_AsEWKB FOR "geodb.GeoDB.ST_AsEWKB"
CREATE ALIAS ST_AsEWKT FOR "geodb.GeoDB.ST_AsEWKT"
CREATE ALIAS ST_AsHexEWKB FOR "geodb.GeoDB.ST_AsHexEWKB"
CREATE ALIAS ST_AsText FOR "geodb.GeoDB.ST_AsText"
CREATE ALIAS ST_BBOX FOR "geodb.GeoDB.ST_BBox"
CREATE ALIAS ST_Buffer FOR "geodb.GeoDB.ST_Buffer"
CREATE ALIAS ST_Centroid FOR "geodb.GeoDB.ST_Centroid"
CREATE ALIAS ST_Crosses FOR "geodb.GeoDB.ST_Crosses"
CREATE ALIAS ST_Contains FOR "geodb.GeoDB.ST_Contains"
CREATE ALIAS ST_DWithin FOR "geodb.GeoDB.ST_DWithin"
CREATE ALIAS ST_Disjoint FOR "geodb.GeoDB.ST_Disjoint"
CREATE ALIAS ST_Distance FOR "geodb.GeoDB.ST_Distance"
CREATE ALIAS ST_Envelope FOR "geodb.GeoDB.ST_Envelope"
CREATE ALIAS ST_Equals FOR "geodb.GeoDB.ST_Equals"
CREATE ALIAS ST_GeoHash FOR "geodb.GeoDB.ST_GeoHash"
CREATE ALIAS ST_GeomFromEWKB FOR "geodb.GeoDB.ST_GeomFromEWKB"
CREATE ALIAS ST_GeomFromEWKT FOR "geodb.GeoDB.ST_GeomFromEWKT"
CREATE ALIAS ST_GeomFromText FOR "geodb.GeoDB.ST_GeomFromText"
CREATE ALIAS ST_GeomFromWKB FOR "geodb.GeoDB.ST_GeomFromWKB"
CREATE ALIAS ST_Intersects FOR "geodb.GeoDB.ST_Intersects"
CREATE ALIAS ST_IsEmpty FOR "geodb.GeoDB.ST_IsEmpty"
CREATE ALIAS ST_IsSimple FOR "geodb.GeoDB.ST_IsSimple"
CREATE ALIAS ST_IsValid FOR "geodb.GeoDB.ST_IsValid"
CREATE ALIAS ST_MakePoint FOR "geodb.GeoDB.ST_MakePoint"
CREATE ALIAS ST_MakeBox2D FOR "geodb.GeoDB.ST_MakeBox2D"
CREATE ALIAS ST_Overlaps FOR "geodb.GeoDB.ST_Overlaps"
CREATE ALIAS ST_SRID FOR "geodb.GeoDB.ST_SRID"
CREATE ALIAS ST_SetSRID FOR "geodb.GeoDB.ST_SetSRID"
CREATE ALIAS ST_Simplify FOR "geodb.GeoDB.ST_Simplify"
CREATE ALIAS ST_Touches FOR "geodb.GeoDB.ST_Touches"
CREATE ALIAS ST_Within FOR "geodb.GeoDB.ST_Within"
CREATE ALIAS Version FOR "geodb.GeoDB.Version"
*/
/** /**
@ -103,9 +59,12 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
); );
// Register functions that operate on spatial types // Register functions that operate on spatial types
// NOT YET AVAILABLE IN GEODB registerFunction(
// registerFunction("dimension", new StandardSQLFunction("dimension", "dimension", new StandardSQLFunction(
// Hibernate.INTEGER)); "ST_Dimension",
StandardBasicTypes.INTEGER
)
);
registerFunction( registerFunction(
"geometrytype", new StandardSQLFunction( "geometrytype", new StandardSQLFunction(
"GeometryType", StandardBasicTypes.STRING "GeometryType", StandardBasicTypes.STRING
@ -117,11 +76,7 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
StandardBasicTypes.INTEGER StandardBasicTypes.INTEGER
) )
); );
registerFunction( registerFunction( "envelope", new StandardSQLFunction( "ST_Envelope" ) );
"envelope", new StandardSQLFunction(
"ST_Envelope"
)
);
registerFunction( registerFunction(
"astext", new StandardSQLFunction( "astext", new StandardSQLFunction(
"ST_AsText", "ST_AsText",
@ -146,9 +101,7 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
StandardBasicTypes.BOOLEAN StandardBasicTypes.BOOLEAN
) )
); );
// NOT YET AVAILABLE IN GEODB registerFunction( "boundary", new StandardSQLFunction( "ST_Boundary" ) );
// registerFunction("boundary", new StandardSQLFunction("boundary",
// new CustomType(GeoDBGeometryUserType.class, null)));
// Register functions for spatial relation constructs // Register functions for spatial relation constructs
registerFunction( registerFunction(
@ -199,10 +152,12 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
StandardBasicTypes.BOOLEAN StandardBasicTypes.BOOLEAN
) )
); );
// NOT YET AVAILABLE IN GEODB registerFunction(
// registerFunction("relate", new StandardSQLFunction("relate", "relate", new StandardSQLFunction(
// Hibernate.BOOLEAN)); "ST_Relate",
StandardBasicTypes.BOOLEAN
)
);
// register the spatial analysis functions // register the spatial analysis functions
registerFunction( registerFunction(
"distance", new StandardSQLFunction( "distance", new StandardSQLFunction(
@ -210,28 +165,12 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
StandardBasicTypes.DOUBLE StandardBasicTypes.DOUBLE
) )
); );
registerFunction( registerFunction( "buffer", new StandardSQLFunction( "ST_Buffer" ) );
"buffer", new StandardSQLFunction( registerFunction( "convexhull", new StandardSQLFunction( "ST_ConvexHull" ) );
"ST_Buffer" registerFunction( "difference", new StandardSQLFunction( "ST_Difference" ) );
) registerFunction( "intersection", new StandardSQLFunction( "ST_Intersection" ) );
); registerFunction( "symdifference", new StandardSQLFunction( "ST_SymDifference" ) );
// NOT YET AVAILABLE IN GEODB registerFunction( "geomunion", new StandardSQLFunction( "ST_Union" ) );
// registerFunction("convexhull", new StandardSQLFunction("convexhull",
// new CustomType(GeoDBGeometryUserType.class, null)));
// registerFunction("difference", new StandardSQLFunction("difference",
// new CustomType(GeoDBGeometryUserType.class, null)));
// registerFunction("intersection", new StandardSQLFunction(
// "intersection", new CustomType(GeoDBGeometryUserType.class, null)));
// registerFunction("symdifference",
// new StandardSQLFunction("symdifference", new CustomType(
// GeoDBGeometryUserType.class, null)));
// registerFunction("geomunion", new StandardSQLFunction("geomunion",
// new CustomType(GeoDBGeometryUserType.class, null)));
//register Spatial Aggregate funciton
// NOT YET AVAILABLE IN GEODB
// registerFunction("extent", new StandardSQLFunction("extent",
// new CustomType(GeoDBGeometryUserType.class, null)));
registerFunction( registerFunction(
"dwithin", new StandardSQLFunction( "dwithin", new StandardSQLFunction(

View File

@ -0,0 +1,47 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.hibernate.spatial.dialect.mysql;
/**
* Spatial Dialect for MySQL 5.6 with InnoDB engine.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 9/13/13
*/
public class MySQL56InnoDBSpatialDialect extends MySQL56SpatialDialect {
@Override
public boolean supportsCascadeDelete() {
return true;
}
@Override
public String getTableTypeString() {
return " ENGINE=InnoDB";
}
@Override
public boolean hasSelfReferentialForeignKeyBug() {
return true;
}
}

View File

@ -0,0 +1,132 @@
package org.hibernate.spatial.dialect.mysql;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 10/9/13
*/
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.dialect.MySQL5Dialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* Extends the MySQL5Dialect by including support for the spatial operators.
*
* This <code>SpatialDialect</code> uses the ST_* spatial operators that operate on exact geometries which have been
* added in MySQL version 5.6.1. Previous versions of MySQL only supported operators that operated on Minimum Bounding
* Rectangles (MBR's). This dialect my therefore produce different results than the other MySQL spatial dialects.
*
* @author Karel Maesen
*/
public class MySQL56SpatialDialect extends MySQL5Dialect implements SpatialDialect {
private MySQLSpatialDialect dialectDelegate = new MySQLSpatialDialect();
/**
* Constructs the dialect
*/
public MySQL56SpatialDialect() {
super();
registerColumnType(
MySQLGeometryTypeDescriptor.INSTANCE.getSqlType(),
"GEOMETRY"
);
final MySQLSpatialFunctions functionsToRegister = overrideObjectShapeFunctions( new MySQLSpatialFunctions() );
for ( Map.Entry<String, StandardSQLFunction> entry : functionsToRegister ) {
registerFunction( entry.getKey(), entry.getValue() );
}
}
private MySQLSpatialFunctions overrideObjectShapeFunctions(MySQLSpatialFunctions mysqlFunctions) {
mysqlFunctions.put( "contains", new StandardSQLFunction( "ST_Contains", StandardBasicTypes.BOOLEAN ) );
mysqlFunctions.put( "crosses", new StandardSQLFunction( "ST_Crosses", StandardBasicTypes.BOOLEAN ) );
mysqlFunctions.put( "disjoint", new StandardSQLFunction( "ST_Disjoint", StandardBasicTypes.BOOLEAN ) );
mysqlFunctions.put( "equals", new StandardSQLFunction( "ST_Equals", StandardBasicTypes.BOOLEAN ) );
mysqlFunctions.put( "intersects", new StandardSQLFunction( "ST_Intersects", StandardBasicTypes.BOOLEAN ) );
mysqlFunctions.put( "overlaps", new StandardSQLFunction( "ST_Overlaps", StandardBasicTypes.BOOLEAN ) );
mysqlFunctions.put( "touches", new StandardSQLFunction( "ST_Touches", StandardBasicTypes.BOOLEAN ) );
mysqlFunctions.put( "within", new StandardSQLFunction( "ST_Within", StandardBasicTypes.BOOLEAN ) );
return mysqlFunctions;
}
@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
return dialectDelegate.remapSqlTypeDescriptor( sqlTypeDescriptor );
}
@Override
public String getTypeName(int code, long length, int precision, int scale) throws HibernateException {
return dialectDelegate.getTypeName( code, length, precision, scale );
}
@Override
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
switch ( spatialRelation ) {
case SpatialRelation.WITHIN:
return " ST_Within(" + columnName + ",?)";
case SpatialRelation.CONTAINS:
return " ST_Contains(" + columnName + ", ?)";
case SpatialRelation.CROSSES:
return " ST_Crosses(" + columnName + ", ?)";
case SpatialRelation.OVERLAPS:
return " ST_Overlaps(" + columnName + ", ?)";
case SpatialRelation.DISJOINT:
return " ST_Disjoint(" + columnName + ", ?)";
case SpatialRelation.INTERSECTS:
return " ST_Intersects(" + columnName + ", ?)";
case SpatialRelation.TOUCHES:
return " ST_Touches(" + columnName + ", ?)";
case SpatialRelation.EQUALS:
return " ST_Equals(" + columnName + ", ?)";
default:
throw new IllegalArgumentException(
"Spatial relation is not known by this dialect"
);
}
}
@Override
public String getSpatialFilterExpression(String columnName) {
return dialectDelegate.getSpatialFilterExpression( columnName );
}
@Override
public String getSpatialAggregateSQL(String columnName, int aggregation) {
return dialectDelegate.getSpatialAggregateSQL( columnName, aggregation );
}
@Override
public String getDWithinSQL(String columnName) {
return dialectDelegate.getDWithinSQL( columnName );
}
@Override
public String getHavingSridSQL(String columnName) {
return dialectDelegate.getHavingSridSQL( columnName );
}
@Override
public String getIsEmptySQL(String columnName, boolean isEmpty) {
return dialectDelegate.getIsEmptySQL( columnName, isEmpty );
}
@Override
public boolean supportsFiltering() {
return dialectDelegate.supportsFiltering();
}
@Override
public boolean supports(SpatialFunction function) {
return dialectDelegate.supports( function );
}
}

View File

@ -17,14 +17,14 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
* @author Karel Maesen, Geovise BVBA * @author Karel Maesen, Geovise BVBA
* *
*/ */
public class MySQL5SpatialInnoDBDialect extends MySQL5InnoDBDialect implements SpatialDialect { public class MySQL5InnoDBSpatialDialect extends MySQL5InnoDBDialect implements SpatialDialect {
private MySQLSpatialDialect dialectDelegate = new MySQLSpatialDialect(); private MySQLSpatialDialect dialectDelegate = new MySQLSpatialDialect();
/** /**
* Constructs an instance * Constructs an instance
*/ */
public MySQL5SpatialInnoDBDialect() { public MySQL5InnoDBSpatialDialect() {
super(); super();
registerColumnType( registerColumnType(
MySQLGeometryTypeDescriptor.INSTANCE.getSqlType(), MySQLGeometryTypeDescriptor.INSTANCE.getSqlType(),

View File

@ -165,6 +165,10 @@ class MySQLSpatialFunctions implements Iterable<Map.Entry<String, StandardSQLFun
// ); // );
} }
public void put(String name, StandardSQLFunction function ) {
this.functionsToRegister.put( name, function );
}
@Override @Override
public Iterator<Map.Entry<String, StandardSQLFunction>> iterator() { public Iterator<Map.Entry<String, StandardSQLFunction>> iterator() {
return functionsToRegister.entrySet().iterator(); return functionsToRegister.entrySet().iterator();

View File

@ -35,6 +35,7 @@ import org.hibernate.spatial.helper.FinderStrategy;
* a wrapper. Implementations of this interface attempt to retrieve the * a wrapper. Implementations of this interface attempt to retrieve the
* <code>OracleConnection</code> from the wrapper in such cases. * <code>OracleConnection</code> from the wrapper in such cases.
* </p> * </p>
* <p>Implementations should be thread-safe, and have a default (no-args) constructor.</p>
* *
* @author Karel Maesen * @author Karel Maesen
*/ */

View File

@ -44,19 +44,29 @@ import org.hibernate.spatial.helper.FinderException;
*/ */
public class OracleJDBCTypeFactory implements SQLTypeFactory { public class OracleJDBCTypeFactory implements SQLTypeFactory {
private static Class<?> datumClass; private final Class<?> datumClass;
private static Class<?> numberClass; private final Class<?> numberClass;
private static Class<?> arrayClass; private final Class<?> arrayClass;
private static Class<?> structClass; private final Class<?> structClass;
private static Class<?> arrayDescriptorClass; private final Class<?> arrayDescriptorClass;
private static Class<?> structDescriptorClass; private final Class<?> structDescriptorClass;
private static Method structDescriptorCreator; private final Method structDescriptorCreator;
private static Method arrayDescriptorCreator; private final Method arrayDescriptorCreator;
private static Constructor<?> numberConstructor; private final Constructor<?> numberConstructor;
private static Constructor<?> arrayConstructor; private final Constructor<?> arrayConstructor;
private static Constructor<?> structConstructor; private final Constructor<?> structConstructor;
private final ConnectionFinder connectionFinder;
static { /**
* Constructs an instance.
*
* @param connectionFinder the {@code ConnectionFinder} the use for retrieving the {@code OracleConnection} instance.
*/
public OracleJDBCTypeFactory(ConnectionFinder connectionFinder) {
if ( connectionFinder == null ) {
throw new HibernateException( "ConnectionFinder cannot be null" );
}
this.connectionFinder = connectionFinder;
Object[] obj = findDescriptorCreator( "oracle.sql.StructDescriptor" ); Object[] obj = findDescriptorCreator( "oracle.sql.StructDescriptor" );
structDescriptorClass = (Class<?>) obj[0]; structDescriptorClass = (Class<?>) obj[0];
structDescriptorCreator = (Method) obj[1]; structDescriptorCreator = (Method) obj[1];
@ -73,9 +83,7 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
structConstructor = findConstructor( structClass, structDescriptorClass, Connection.class, Object[].class ); structConstructor = findConstructor( structClass, structDescriptorClass, Connection.class, Object[].class );
} }
private static ConnectionFinder connectionFinder = new DefaultConnectionFinder(); private Constructor<?> findConstructor(Class clazz, Class<?>... arguments) {
private static Constructor<?> findConstructor(Class clazz, Class<?>... arguments) {
try { try {
return clazz.getConstructor( arguments ); return clazz.getConstructor( arguments );
} }
@ -84,7 +92,7 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
} }
} }
private static Class<?> findClass(String name) { private Class<?> findClass(String name) {
try { try {
return ReflectHelper.classForName( name ); return ReflectHelper.classForName( name );
} }
@ -93,7 +101,7 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
} }
} }
private static Object[] findDescriptorCreator(String className) { private Object[] findDescriptorCreator(String className) {
try { try {
final Class clazz = ReflectHelper.classForName( className ); final Class clazz = ReflectHelper.classForName( className );
final Method m = clazz.getMethod( "createDescriptor", String.class, Connection.class ); final Method m = clazz.getMethod( "createDescriptor", String.class, Connection.class );
@ -107,14 +115,6 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
} }
} }
static ConnectionFinder getConnectionFinder() {
return connectionFinder;
}
static void setConnectionFinder(ConnectionFinder finder) {
connectionFinder = finder;
}
@Override @Override
public Struct createStruct(SDOGeometry geom, Connection conn) throws SQLException { public Struct createStruct(SDOGeometry geom, Connection conn) throws SQLException {
Connection oracleConnection = null; Connection oracleConnection = null;

View File

@ -20,14 +20,10 @@
*/ */
package org.hibernate.spatial.dialect.oracle; package org.hibernate.spatial.dialect.oracle;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable; import java.io.Serializable;
import java.net.URL; import java.sql.Types;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.hibernate.QueryException; import org.hibernate.QueryException;
import org.hibernate.dialect.Oracle10gDialect; import org.hibernate.dialect.Oracle10gDialect;
@ -36,15 +32,13 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.spi.TypeContributions; import org.hibernate.metamodel.spi.TypeContributions;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
import org.hibernate.spatial.GeolatteGeometryType; import org.hibernate.spatial.GeolatteGeometryType;
import org.hibernate.spatial.HibernateSpatialConfiguration;
import org.hibernate.spatial.JTSGeometryType; import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.Log;
import org.hibernate.spatial.LogFactory;
import org.hibernate.spatial.SpatialAnalysis; import org.hibernate.spatial.SpatialAnalysis;
import org.hibernate.spatial.SpatialDialect; import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation; import org.hibernate.spatial.SpatialRelation;
import org.hibernate.spatial.dialect.oracle.criterion.OracleSpatialAggregate; import org.hibernate.spatial.dialect.oracle.criterion.OracleSpatialAggregate;
import org.hibernate.spatial.helper.PropertyFileReader;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type; import org.hibernate.type.Type;
@ -56,33 +50,31 @@ import org.hibernate.type.Type;
public class OracleSpatial10gDialect extends Oracle10gDialect implements public class OracleSpatial10gDialect extends Oracle10gDialect implements
SpatialDialect, Serializable { SpatialDialect, Serializable {
private final boolean isOgcStrict;
private final ConnectionFinder connectionFinder;
/** /**
* Short name for this dialect * Constructs the dialect with a default configuration
*/
public static final String SHORT_NAME = "oraclespatial";
private static final String CONNECTION_FINDER_PROPERTY = "CONNECTION-FINDER";
private static final Log LOG = LogFactory.make();
private String ogcStrict = "OGC_STRICT";
private Map<String, Boolean> features = new HashMap<String, Boolean>();
/**
* Creates a dialect instance
*/ */
public OracleSpatial10gDialect() { public OracleSpatial10gDialect() {
super(); this( new HibernateSpatialConfiguration() );
// initialise features to default }
features.put( ogcStrict, new Boolean( true ) );
/**
* Constructs the dialect with the specified configuration
*
* @param config the {@code HibernateSpatialConfiguration} that configures this dialect.
*/
public OracleSpatial10gDialect(HibernateSpatialConfiguration config) {
super();
this.isOgcStrict = config.isOgcStrictMode();
final ConnectionFinder finder = config.getConnectionFinder();
this.connectionFinder = finder == null ? new DefaultConnectionFinder() : finder;
// read configuration information from
// classpath
configure();
// register geometry type // register geometry type
registerColumnType( registerColumnType( Types.STRUCT, "MDSYS.SDO_GEOMETRY" );
SDOGeometryTypeDescriptor.INSTANCE.getSqlType(),
SDOGeometryTypeDescriptor.INSTANCE.getTypeName()
);
// registering OGC functions // registering OGC functions
// (spec_simplefeatures_sql_99-04.pdf) // (spec_simplefeatures_sql_99-04.pdf)
@ -143,6 +135,7 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
registerFunction( "extent", new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.EXTENT ) ); registerFunction( "extent", new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.EXTENT ) );
//other common functions //other common functions
registerFunction( "transform", new StandardSQLFunction( "SDO_CS.TRANSFORM" ) ); registerFunction( "transform", new StandardSQLFunction( "SDO_CS.TRANSFORM" ) );
// Oracle specific Aggregate functions // Oracle specific Aggregate functions
@ -174,8 +167,16 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
typeContributions, typeContributions,
serviceRegistry serviceRegistry
); );
typeContributions.contributeType( new GeolatteGeometryType( SDOGeometryTypeDescriptor.INSTANCE ) );
typeContributions.contributeType( new JTSGeometryType( SDOGeometryTypeDescriptor.INSTANCE ) ); final SDOGeometryTypeDescriptor sdoGeometryTypeDescriptor = new SDOGeometryTypeDescriptor(
new OracleJDBCTypeFactory(
this.connectionFinder
)
);
typeContributions.contributeType( new GeolatteGeometryType( sdoGeometryTypeDescriptor ) );
typeContributions.contributeType( new JTSGeometryType( sdoGeometryTypeDescriptor ) );
} }
String getNativeSpatialRelateSQL(String arg1, String arg2, int spatialRelation) { String getNativeSpatialRelateSQL(String arg1, String arg2, int spatialRelation) {
@ -214,19 +215,15 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
+ ")" + ")"
); );
} }
StringBuffer buffer; final StringBuffer buffer = new StringBuffer( "CASE SDO_RELATE(" ).append( arg1 )
if ( negate ) { .append( "," )
buffer = new StringBuffer( "CASE WHEN SDO_RELATE(" ); .append( arg2 )
.append( ",'mask=" + mask + "') " );
if ( !negate ) {
buffer.append( " WHEN 'TRUE' THEN 1 ELSE 0 END" );
} }
else { else {
buffer = new StringBuffer( "SDO_RELATE(" ); buffer.append( " WHEN 'TRUE' THEN 0 ELSE 1 END" );
}
buffer.append( arg1 );
buffer.append( "," ).append( arg2 ).append( ",'mask=" + mask + "') " );
if ( negate ) {
buffer.append( " = 'TRUE' THEN 'FALSE' ELSE 'TRUE' END" );
} }
return buffer.toString(); return buffer.toString();
} }
@ -308,9 +305,6 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
@Override @Override
public String getSpatialFilterExpression(String columnName) { public String getSpatialFilterExpression(String columnName) {
final StringBuffer buffer = new StringBuffer( "SDO_FILTER(" ); final StringBuffer buffer = new StringBuffer( "SDO_FILTER(" );
// String pureColumnName =
// columnName.substring(columnName.lastIndexOf(".")+1);
// buffer.append("\"" + pureColumnName.toUpperCase() + "\"");
buffer.append( columnName ); buffer.append( columnName );
buffer.append( ",?) = 'TRUE' " ); buffer.append( ",?) = 'TRUE' " );
return buffer.toString(); return buffer.toString();
@ -318,12 +312,9 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
@Override @Override
public String getSpatialRelateSQL(String columnName, int spatialRelation) { public String getSpatialRelateSQL(String columnName, int spatialRelation) {
String sql = ( isOGCStrict() ? ( getOGCSpatialRelateSQL( String sql = ( isOGCStrict() ?
columnName, "?", getOGCSpatialRelateSQL( columnName, "?", spatialRelation ) :
spatialRelation getNativeSpatialRelateSQL( columnName, "?", spatialRelation ) ) + " = 1";
) + " = 1" ) : ( getNativeSpatialRelateSQL(
columnName, "?", spatialRelation
) + "= 'TRUE'" ) );
sql += " and " + columnName + " is not null"; sql += " and " + columnName + " is not null";
return sql; return sql;
} }
@ -342,7 +333,7 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
@Override @Override
public String getDWithinSQL(String columnName) { public String getDWithinSQL(String columnName) {
throw new UnsupportedOperationException( "No DWithin in this dialect" ); return "SDO_WITHIN_DISTANCE (" + columnName + ",?, ?) = 'TRUE' ";
} }
@Override @Override
@ -426,55 +417,26 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
return getOGCSpatialAnalysisSQL( args, spatialAnalysis ); return getOGCSpatialAnalysisSQL( args, spatialAnalysis );
} }
boolean isOGCStrict() { /**
return this.features.get( ogcStrict ); * Reports whether this dialect is in OGC_STRICT mode or not.
*
* This method is for testing purposes.
*
* @return true if in OGC_STRICT mode, false otherwise
*/
public boolean isOGCStrict() {
return isOgcStrict;
} }
private void configure() { /**
final ClassLoader loader = Thread.currentThread().getContextClassLoader(); * Reports the ConnectionFinder used by this Dialect (or rather its associated TypeDescriptor).
final String propfileLoc = getClass().getCanonicalName() + ".properties"; *
final URL propfile = loader.getResource( propfileLoc ); * This method is mainly used for testing purposes.
if ( propfile != null ) { *
InputStream is = null; * @return the ConnectionFinder in use
LOG.info( "properties file found: " + propfile ); */
try { public ConnectionFinder getConnectionFinder() {
loader.getResource( getClass().getCanonicalName() ); return connectionFinder;
is = propfile.openStream();
final PropertyFileReader reader = new PropertyFileReader( is );
final Properties props = reader.getProperties();
// checking for connectionfinder
final String ccn = props.getProperty( CONNECTION_FINDER_PROPERTY );
if ( ccn != null ) {
try {
final Class clazz = Thread.currentThread().getContextClassLoader().loadClass( ccn );
final ConnectionFinder cf = (ConnectionFinder) clazz.newInstance();
OracleJDBCTypeFactory.setConnectionFinder( cf );
LOG.info( "Setting ConnectionFinder to " + ccn );
}
catch ( ClassNotFoundException e ) {
LOG.warn( "Tried to set ConnectionFinder to " + ccn + ", but class not found." );
}
catch ( InstantiationException e ) {
LOG.warn( "Tried to set ConnectionFinder to " + ccn + ", but couldn't instantiate." );
}
catch ( IllegalAccessException e ) {
LOG.warn( "Tried to set ConnectionFinder to " + ccn + ", but got IllegalAcessException on instantiation." );
}
}
}
catch ( IOException e ) {
LOG.warn( "Problem reading properties file " + e );
}
finally {
try {
is.close();
}
catch ( Exception e ) {
}
}
}
} }
@Override @Override
@ -490,7 +452,7 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
/** /**
* Implementation of the OGC astext function for HQL. * Implementation of the OGC astext function for HQL.
*/ */
private class AsTextFunction extends StandardSQLFunction { private static class AsTextFunction extends StandardSQLFunction {
private AsTextFunction() { private AsTextFunction() {
super( "astext", StandardBasicTypes.STRING ); super( "astext", StandardBasicTypes.STRING );

View File

@ -22,14 +22,11 @@
package org.hibernate.spatial.dialect.oracle; package org.hibernate.spatial.dialect.oracle;
import java.sql.Array; import java.sql.Array;
import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Struct; import java.sql.Struct;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.hibernate.spatial.helper.FinderException;
/** /**
* @author Karel Maesen, Geovise BVBA * @author Karel Maesen, Geovise BVBA
* creation-date: Jun 30, 2010 * creation-date: Jun 30, 2010
@ -37,7 +34,6 @@ import org.hibernate.spatial.helper.FinderException;
class SDOGeometry { class SDOGeometry {
private static final SQLTypeFactory TYPE_FACTORY = new OracleJDBCTypeFactory();
private static final String SQL_TYPE_NAME = "MDSYS.SDO_GEOMETRY"; private static final String SQL_TYPE_NAME = "MDSYS.SDO_GEOMETRY";
private SDOGType gtype; private SDOGType gtype;
private int srid; private int srid;
@ -102,33 +98,6 @@ class SDOGeometry {
return sdoCollection; return sdoCollection;
} }
public static SDOGeometry load(Struct struct) {
Object[] data;
try {
data = struct.getAttributes();
}
catch ( SQLException e ) {
throw new RuntimeException( e );
}
final SDOGeometry geom = new SDOGeometry();
geom.setGType( SDOGType.parse( data[0] ) );
geom.setSRID( data[1] );
if ( data[2] != null ) {
geom.setPoint( new SDOPoint( (Struct) data[2] ) );
}
geom.setInfo( new ElemInfo( (Array) data[3] ) );
geom.setOrdinates( new Ordinates( (Array) data[4] ) );
return geom;
}
public static Struct store(SDOGeometry geom, Connection conn)
throws SQLException, FinderException {
return TYPE_FACTORY.createStruct( geom, conn );
}
private static void shiftOrdinateOffset(ElemInfo elemInfo, int offset) { private static void shiftOrdinateOffset(ElemInfo elemInfo, int offset) {
for ( int i = 0; i < elemInfo.getSize(); i++ ) { for ( int i = 0; i < elemInfo.getSize(); i++ ) {
final int newOffset = elemInfo.getOrdinatesOffset( i ) + offset; final int newOffset = elemInfo.getOrdinatesOffset( i ) + offset;
@ -171,6 +140,28 @@ class SDOGeometry {
} }
} }
public static SDOGeometry load(Struct struct) {
Object[] data;
try {
data = struct.getAttributes();
}
catch ( SQLException e ) {
throw new RuntimeException( e );
}
final SDOGeometry geom = new SDOGeometry();
geom.setGType( SDOGType.parse( data[0] ) );
geom.setSRID( data[1] );
if ( data[2] != null ) {
geom.setPoint( new SDOPoint( (Struct) data[2] ) );
}
geom.setInfo( new ElemInfo( (Array) data[3] ) );
geom.setOrdinates( new Ordinates( (Array) data[4] ) );
return geom;
}
public ElemInfo getInfo() { public ElemInfo getInfo() {
return info; return info;
} }
@ -207,23 +198,23 @@ class SDOGeometry {
return srid; return srid;
} }
public void setSRID(int srid) {
this.srid = srid;
}
private void setSRID(Object datum) { private void setSRID(Object datum) {
if ( datum == null ) { if ( datum == null ) {
this.srid = 0; this.srid = 0;
return; return;
} }
try { try {
this.srid = new Integer( ( (Number) datum ).intValue() ); this.srid = ( (Number) datum ).intValue();
} }
catch ( Exception e ) { catch ( Exception e ) {
throw new RuntimeException( e ); throw new RuntimeException( e );
} }
} }
public void setSRID(int srid) {
this.srid = srid;
}
public boolean isLRSGeometry() { public boolean isLRSGeometry() {
return gtype.isLRSGeometry(); return gtype.isLRSGeometry();
} }

View File

@ -36,10 +36,16 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
*/ */
public class SDOGeometryTypeDescriptor implements SqlTypeDescriptor { public class SDOGeometryTypeDescriptor implements SqlTypeDescriptor {
private final OracleJDBCTypeFactory typeFactory;
/** /**
* An instance of this class * Constructs a {@code SqlTypeDescriptor} for the Oracle SDOGeometry type.
*
* @param typeFactory the type factory to use.
*/ */
public static final SDOGeometryTypeDescriptor INSTANCE = new SDOGeometryTypeDescriptor(); public SDOGeometryTypeDescriptor(OracleJDBCTypeFactory typeFactory) {
this.typeFactory = typeFactory;
}
@Override @Override
public int getSqlType() { public int getSqlType() {
@ -53,14 +59,18 @@ public class SDOGeometryTypeDescriptor implements SqlTypeDescriptor {
@Override @Override
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) { public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
return new SDOGeometryValueBinder<X>( javaTypeDescriptor ); return (ValueBinder<X>) new SDOGeometryValueBinder( javaTypeDescriptor, this, typeFactory );
} }
@Override @Override
public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) { public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
return (ValueExtractor<X>) new SDOGeometryValueExtractor( javaTypeDescriptor ); return (ValueExtractor<X>) new SDOGeometryValueExtractor( javaTypeDescriptor, this );
} }
/**
* Returns the Oracle type name for SDOGeometry.
* @return the Oracle type name
*/
public String getTypeName() { public String getTypeName() {
return "MDSYS.SDO_GEOMETRY"; return "MDSYS.SDO_GEOMETRY";
} }

View File

@ -24,6 +24,7 @@ package org.hibernate.spatial.dialect.oracle;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types;
import com.vividsolutions.jts.algorithm.CGAlgorithms; import com.vividsolutions.jts.algorithm.CGAlgorithms;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
@ -37,13 +38,11 @@ import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.Polygon;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.spatial.Log;
import org.hibernate.spatial.LogFactory;
import org.hibernate.spatial.helper.FinderException; import org.hibernate.spatial.helper.FinderException;
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/** /**
* @author Karel Maesen, Geovise BVBA * @author Karel Maesen, Geovise BVBA
@ -51,55 +50,36 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
*/ */
class SDOGeometryValueBinder<J> implements ValueBinder<J> { class SDOGeometryValueBinder<J> implements ValueBinder<J> {
private static final Log LOG = LogFactory.make();
private static final String BIND_MSG_TEMPLATE = "binding parameter [%s] as [%s] - %s";
private static final String NULL_BIND_MSG_TEMPLATE = "binding parameter [%s] as [%s] - <null>";
private final JavaTypeDescriptor<J> javaDescriptor;
private final OracleJDBCTypeFactory typeFactory;
private final JavaTypeDescriptor<J> javaTypeDescriptor;
public SDOGeometryValueBinder(JavaTypeDescriptor<J> javaDescriptor) { public SDOGeometryValueBinder(JavaTypeDescriptor<J> javaTypeDescriptor, SqlTypeDescriptor sqlTypeDescriptor, OracleJDBCTypeFactory typeFactory) {
this.javaDescriptor = javaDescriptor; this.javaTypeDescriptor = javaTypeDescriptor;
this.typeFactory = typeFactory;
} }
public final void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException { @Override
public void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException {
if ( value == null ) { if ( value == null ) {
if ( LOG.isTraceEnabled() ) { st.setNull( index, Types.STRUCT, SDOGeometry.getTypeName() );
LOG.trace(
String.format(
NULL_BIND_MSG_TEMPLATE,
index,
JdbcTypeNameMapper.getTypeName( SDOGeometryTypeDescriptor.INSTANCE.getSqlType() )
)
);
}
st.setNull(
index,
SDOGeometryTypeDescriptor.INSTANCE.getSqlType(),
SDOGeometryTypeDescriptor.INSTANCE.getTypeName()
);
} }
else { else {
if ( LOG.isTraceEnabled() ) { final Geometry jtsGeom = javaTypeDescriptor.unwrap( value, Geometry.class, options );
LOG.trace(
String.format(
BIND_MSG_TEMPLATE,
index,
JdbcTypeNameMapper.getTypeName( SDOGeometryTypeDescriptor.INSTANCE.getSqlType() ),
javaDescriptor.extractLoggableRepresentation( value )
)
);
}
final Geometry jtsGeom = javaDescriptor.unwrap( value, Geometry.class, options );
final Object dbGeom = toNative( jtsGeom, st.getConnection() ); final Object dbGeom = toNative( jtsGeom, st.getConnection() );
st.setObject( index, dbGeom ); st.setObject( index, dbGeom );
} }
} }
protected Object toNative(Geometry jtsGeom, Connection connection) { public Object store(SDOGeometry geom, Connection conn) throws SQLException, FinderException {
return typeFactory.createStruct( geom, conn );
}
private Object toNative(Geometry jtsGeom, Connection connection) {
final SDOGeometry geom = convertJTSGeometry( jtsGeom ); final SDOGeometry geom = convertJTSGeometry( jtsGeom );
if ( geom != null ) { if ( geom != null ) {
try { try {
return SDOGeometry.store( geom, connection ); return store( geom, connection );
} }
catch ( SQLException e ) { catch ( SQLException e ) {
throw new HibernateException( throw new HibernateException(

View File

@ -44,6 +44,7 @@ import org.hibernate.spatial.jts.Circle;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicExtractor; import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
//TODO -- requires cleanup and must be made package local //TODO -- requires cleanup and must be made package local
@ -62,10 +63,11 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
/** /**
* Creates instance * Creates instance
* *
* @param javaDescriptor javadescriptor to use * @param javaDescriptor the {@code JavaTypeDescriptor} to use
* @param sqlTypeDescriptor the {@code SqlTypeDescriptor} to use
*/ */
public SDOGeometryValueExtractor(JavaTypeDescriptor<X> javaDescriptor) { public SDOGeometryValueExtractor(JavaTypeDescriptor<X> javaDescriptor, SqlTypeDescriptor sqlTypeDescriptor ) {
super( javaDescriptor, SDOGeometryTypeDescriptor.INSTANCE ); super( javaDescriptor, sqlTypeDescriptor );
} }
@Override @Override

View File

@ -20,6 +20,8 @@
*/ */
package org.hibernate.spatial.helper; package org.hibernate.spatial.helper;
import java.io.Serializable;
/** /**
* A <code>FinderStrategy</code> is used to find a specific feature. It is * A <code>FinderStrategy</code> is used to find a specific feature. It is
* useful in cases where reflection is used to determine some property of a * useful in cases where reflection is used to determine some property of a
@ -30,7 +32,7 @@ package org.hibernate.spatial.helper;
* *
* @author Karel Maesen * @author Karel Maesen
*/ */
public interface FinderStrategy<T, S> { public interface FinderStrategy<T, S> extends Serializable {
/** /**
* Find a feature or property of a subject * Find a feature or property of a subject

View File

@ -0,0 +1,44 @@
package org.hibernate.spatial.integration;
import java.sql.Connection;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl;
import org.hibernate.spatial.HibernateSpatialConfiguration;
import org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect;
/**
* A {@code DialectFactory} that may inject configuration into {@code SpatialDialect}s.
*
* This implementation extends the Standard Hibernate {@code DialectFactory}. It is currently only used for the
* {@code OracleSpatial10gDialect}.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/23/13
*/
public class SpatialDialectFactory extends DialectFactoryImpl {
private final HibernateSpatialConfiguration configuration;
/**
* Constructs an instance with the specified configuration
* @param configuration the {@HibernateSpatialConfiguration} to use.
*/
public SpatialDialectFactory(HibernateSpatialConfiguration configuration) {
super();
this.configuration = configuration;
}
@Override
public Dialect buildDialect(Map configValues, Connection connection) throws HibernateException {
final Dialect dialect = super.buildDialect( configValues, connection );
if (dialect instanceof OracleSpatial10gDialect) {
return new OracleSpatial10gDialect( configuration );
}
else {
return dialect;
}
}
}

View File

@ -0,0 +1,89 @@
package org.hibernate.spatial.integration;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.boot.registry.StandardServiceInitiator;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.dialect.spi.DialectFactory;
import org.hibernate.service.Service;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.spatial.HibernateSpatialConfiguration;
import org.hibernate.spatial.dialect.oracle.ConnectionFinder;
/**
* The {@code ServiceInitiator} for Hibernate Spatial.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/23/13
*/
public class SpatialInitiator implements StandardServiceInitiator {
@Override
public Class getServiceInitiated() {
return DialectFactory.class;
}
@Override
public Service initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
final HibernateSpatialConfiguration configuration = configure( registry );
return new SpatialDialectFactory( configuration );
}
private HibernateSpatialConfiguration configure(ServiceRegistry serviceRegistry) {
final ConfigurationService configService = serviceRegistry.getService( ConfigurationService.class );
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
return new HibernateSpatialConfiguration(
readOgcStrict( configService ),
readConnectionFinder( configService, classLoaderService )
);
}
/**
* Reads the configured property (if present), otherwise returns null
*/
private Boolean readOgcStrict(ConfigurationService configService) {
final String ogcStrictKey = HibernateSpatialConfiguration.AvailableSettings.OGC_STRICT;
return configService.getSetting(
ogcStrictKey,
new ConfigurationService.Converter<Boolean>() {
@Override
public Boolean convert(Object value) {
return Boolean.parseBoolean( value.toString() );
}
}, null
);
}
/**
* Reads the configured property (if present), otherwise returns null
*/
private ConnectionFinder readConnectionFinder(ConfigurationService configService, ClassLoaderService classLoaderService) {
final String cfKey = HibernateSpatialConfiguration.AvailableSettings.CONNECTION_FINDER;
final String className = configService.getSetting(
cfKey,
new ConfigurationService.Converter<String>() {
@Override
public String convert(Object value) {
if ( value instanceof String ) {
return (String) value;
}
return value.toString();
}
}, null
);
if ( className == null ) {
return null;
}
try {
return (ConnectionFinder) classLoaderService.classForName( className ).newInstance();
}
catch ( Exception e ) {
throw new HibernateException( " Could not instantiate ConnectionFinder: " + className, e );
}
}
}

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 Geovise BVBA
~
~ This library is free software; you can redistribute it and/or
~ modify it under the terms of the GNU Lesser General Public
~ License as published by the Free Software Foundation; either
~ version 2.1 of the License, or (at your option) any later version.
~
~ This library is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this library; if not, write to the Free Software
~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<html>
<head></head>
<body>
<p>
This package contains the integration classes to hook into Hibernate-ORM.
</p>
</body>
</html>

View File

@ -0,0 +1,12 @@
package org.hibernate.spatial.dialect.oracle;
import java.sql.Connection;
import org.hibernate.spatial.helper.FinderException;
public class MockConnectionFinder implements ConnectionFinder {
@Override
public Connection find(Connection subject) throws FinderException {
return null;
}
}

View File

@ -0,0 +1,77 @@
package org.hibernate.spatial.dialect.oracle;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.Dialect;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.spatial.HibernateSpatialConfiguration;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@RequiresDialect(OracleSpatial10gDialect.class)
public class OracleSpatial10gConfigurationTest extends BaseCoreFunctionalTestCase{
private Configuration addToConfiguration(Configuration cfg, Boolean ogcStrict, String connFinderClassName) {
cfg.setProperty( HibernateSpatialConfiguration.AvailableSettings.CONNECTION_FINDER, connFinderClassName );
cfg.setProperty( HibernateSpatialConfiguration.AvailableSettings.OGC_STRICT, ogcStrict.toString() );
return cfg;
}
private void createdOracleSpatialDialect(Boolean ogcStrict, String connFinderClassName) {
createdOracleSpatialDialect( ogcStrict, connFinderClassName, true );
}
private void createdOracleSpatialDialect(Boolean ogcStrict, String connFinderClassName, boolean doConfiguration) {
Configuration cfg = new Configuration();
if (doConfiguration){
addToConfiguration( cfg, ogcStrict, connFinderClassName );
}
cfg.setProperty( AvailableSettings.DIALECT, OracleSpatial10gDialect.class.getCanonicalName() );
StandardServiceRegistry serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() );
SessionFactory sessionFactory = cfg.buildSessionFactory( serviceRegistry );
Dialect d = ( (SessionFactoryImpl) sessionFactory ).getDialect();
OracleSpatial10gDialect osd = (OracleSpatial10gDialect) d;
Assert.assertTrue( ogcStrict == osd.isOGCStrict() );
ConnectionFinder finder = osd.getConnectionFinder();
Assert.assertNotNull( finder );
Assert.assertEquals( connFinderClassName, finder.getClass().getCanonicalName() );
}
@Test
public void testOgcStrictMockFinder() {
createdOracleSpatialDialect( true, MockConnectionFinder.class.getCanonicalName() );
}
@Test
public void testOgcNonStrictMockFinder() {
createdOracleSpatialDialect( false, MockConnectionFinder.class.getCanonicalName() );
}
@Test
public void testOgcStrictDefaultFinder() {
createdOracleSpatialDialect( true, DefaultConnectionFinder.class.getCanonicalName() );
}
@Test
public void testOgcNonStrictDefaultFinder() {
createdOracleSpatialDialect( false, DefaultConnectionFinder.class.getCanonicalName() );
}
@Test(expected = HibernateException.class)
public void testOgcStrictNonExistentClass() {
createdOracleSpatialDialect( false, "doesntexist" );
}
@Test
public void testNoConfiguration(){
createdOracleSpatialDialect( true, DefaultConnectionFinder.class.getCanonicalName(), false );
}
}

View File

@ -34,9 +34,12 @@ import org.hibernate.Transaction;
import org.hibernate.spatial.Log; import org.hibernate.spatial.Log;
import org.hibernate.spatial.LogFactory; import org.hibernate.spatial.LogFactory;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.dialect.h2geodb.GeoDBDialect;
import org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect;
import org.hibernate.spatial.testing.SpatialDialectMatcher; import org.hibernate.spatial.testing.SpatialDialectMatcher;
import org.hibernate.spatial.testing.SpatialFunctionalTestCase; import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
import org.hibernate.testing.Skip; import org.hibernate.testing.Skip;
import org.hibernate.testing.SkipForDialect;
import static java.lang.String.format; import static java.lang.String.format;
@ -494,16 +497,18 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
@Test @Test @SkipForDialect( value = GeoDBDialect.class)
public void test_intersection_on_jts()throws SQLException { public void test_intersection_on_jts()throws SQLException {
intersection( JTS ); intersection( JTS );
} }
@Test @Test @SkipForDialect( value = GeoDBDialect.class)
public void test_intersection_on_geolatte()throws SQLException { public void test_intersection_on_geolatte()throws SQLException {
intersection( GEOLATTE); intersection( GEOLATTE);
} }
//skipped for GeoDBDialect because GeoDB throws exceptions in case the intersection is empty.
// (Error message is "Empty Points cannot be represented in WKB")
public void intersection(String pckg) throws SQLException { public void intersection(String pckg) throws SQLException {
if ( !isSupportedByDialect( SpatialFunction.intersection ) ) { if ( !isSupportedByDialect( SpatialFunction.intersection ) ) {
return; return;
@ -601,7 +606,15 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
"org.hibernate.spatial.integration.%s.GeomEntity where dwithin(geom, :filter, :distance) = true " + "org.hibernate.spatial.integration.%s.GeomEntity where dwithin(geom, :filter, :distance) = true " +
"and srid(geom) = 4326", pckg); "and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPoint() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPoint() );
params.put( "distance", 30.0 ); if ( getDialect() instanceof OracleSpatial10gDialect ) {
//because this uses the weird syntax and conventions of SDO_WITHIN_DISTANCE which returns a string (really)
// we use a different boolean expression guaranteed to be true, and we set the third parameter to key/value string
hql = "SELECT id, issimple(geom) from org.hibernate.spatial.integration.GeomEntity where dwithin(geom, :filter, :distance) = true and srid(geom) = 4326";
params.put( "distance", "distance = 30" );
}
else {
params.put( "distance", 30.0 );
}
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }

View File

@ -49,7 +49,6 @@ import static org.junit.Assert.fail;
*/ */
public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCase { public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCase {
protected static String JTS = "jts"; protected static String JTS = "jts";
protected static String GEOLATTE = "geolatte"; protected static String GEOLATTE = "geolatte";

View File

@ -23,6 +23,7 @@ package org.hibernate.spatial.testing;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.spatial.testing.dialects.h2geodb.GeoDBTestSupport; import org.hibernate.spatial.testing.dialects.h2geodb.GeoDBTestSupport;
import org.hibernate.spatial.testing.dialects.mysql.MySQL56TestSupport;
import org.hibernate.spatial.testing.dialects.mysql.MySQLTestSupport; import org.hibernate.spatial.testing.dialects.mysql.MySQLTestSupport;
import org.hibernate.spatial.testing.dialects.oracle.OracleSDOTestSupport; import org.hibernate.spatial.testing.dialects.oracle.OracleSDOTestSupport;
import org.hibernate.spatial.testing.dialects.postgis.PostgisTestSupport; import org.hibernate.spatial.testing.dialects.postgis.PostgisTestSupport;
@ -44,7 +45,6 @@ public class TestSupportFactories {
private TestSupportFactories() { private TestSupportFactories() {
} }
public TestSupport getTestSupportFactory(Dialect dialect) throws InstantiationException, IllegalAccessException { public TestSupport getTestSupportFactory(Dialect dialect) throws InstantiationException, IllegalAccessException {
if ( dialect == null ) { if ( dialect == null ) {
throw new IllegalArgumentException( "Dialect argument is required." ); throw new IllegalArgumentException( "Dialect argument is required." );
@ -63,9 +63,6 @@ public class TestSupportFactories {
return this.getClass().getClassLoader(); return this.getClass().getClassLoader();
} }
//TODO -- find a better way to initialize and inject the TestSupport class.
//This whole class can probably be made obsolete.
private static Class<? extends TestSupport> getSupportFactoryClass(Dialect dialect) { private static Class<? extends TestSupport> getSupportFactoryClass(Dialect dialect) {
String canonicalName = dialect.getClass().getCanonicalName(); String canonicalName = dialect.getClass().getCanonicalName();
if ( "org.hibernate.spatial.dialect.postgis.PostgisDialect".equals( canonicalName ) ) { if ( "org.hibernate.spatial.dialect.postgis.PostgisDialect".equals( canonicalName ) ) {
@ -78,10 +75,13 @@ public class TestSupportFactories {
return SQLServerTestSupport.class; return SQLServerTestSupport.class;
} }
if ( "org.hibernate.spatial.dialect.mysql.MySQLSpatialDialect".equals( canonicalName ) || if ( "org.hibernate.spatial.dialect.mysql.MySQLSpatialDialect".equals( canonicalName ) ||
"org.hibernate.spatial.dialect.mysql.MySQLSpatialInnoDBDialect".equals( canonicalName ) || "org.hibernate.spatial.dialect.mysql.MySQL5InnoDBSpatialDialect".equals( canonicalName ) ) {
"org.hibernate.spatial.dialect.mysql.MySQL5SpatialInnoDBDialect".equals( canonicalName ) ) {
return MySQLTestSupport.class; return MySQLTestSupport.class;
} }
if ( "org.hibernate.spatial.dialect.mysql.MySQLSpatial56Dialect".equals( canonicalName ) ||
"org.hibernate.spatial.dialect.mysql.MySQL56InnoDBSpatialDialect".equals( canonicalName ) ) {
return MySQL56TestSupport.class;
}
if ( "org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect".equals( canonicalName ) ) { if ( "org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect".equals( canonicalName ) ) {
return OracleSDOTestSupport.class; return OracleSDOTestSupport.class;
} }

View File

@ -57,9 +57,7 @@ public class GeoDBExpectationsFactory extends AbstractExpectationsFactory {
@Override @Override
protected NativeSQLStatement createNativeBoundaryStatement() { protected NativeSQLStatement createNativeBoundaryStatement() {
throw new UnsupportedOperationException( return createNativeSQLStatement("select id, ST_Boundary(geom) from GEOMTEST");
"Method ST_Bounday() is not implemented in the current version of GeoDB."
);
} }
@Override @Override
@ -80,8 +78,9 @@ public class GeoDBExpectationsFactory extends AbstractExpectationsFactory {
@Override @Override
protected NativeSQLStatement createNativeConvexHullStatement(Geometry geom) { protected NativeSQLStatement createNativeConvexHullStatement(Geometry geom) {
throw new UnsupportedOperationException( return createNativeSQLStatementAllWKTParams(
"Method ST_ConvexHull() is not implemented in the current version of GeoDB." "select t.id, ST_ConvexHull(ST_Union(t.geom, ST_GeomFromText(?, 4326))) from GeomTest t where ST_SRID(t.geom) = 4326",
geom.toText()
); );
} }
@ -102,9 +101,7 @@ public class GeoDBExpectationsFactory extends AbstractExpectationsFactory {
@Override @Override
protected NativeSQLStatement createNativeDimensionSQL() { protected NativeSQLStatement createNativeDimensionSQL() {
throw new UnsupportedOperationException( return createNativeSQLStatement("select id, ST_Dimension(geom) from GEOMTEST");
"Method ST_Dimension() is not implemented in the current version of GeoDB."
);
} }
@Override @Override
@ -193,8 +190,9 @@ public class GeoDBExpectationsFactory extends AbstractExpectationsFactory {
@Override @Override
protected NativeSQLStatement createNativeGeomUnionStatement(Geometry geom) { protected NativeSQLStatement createNativeGeomUnionStatement(Geometry geom) {
throw new UnsupportedOperationException( return createNativeSQLStatementAllWKTParams(
"Method ST_GeomUnion() is not implemented in the current version of GeoDB." "select t.id, ST_Union(t.geom, ST_GeomFromText(?, 4326)) from GEOMTEST t where ST_SRID(t.geom) = 4326",
geom.toText()
); );
} }
@ -219,8 +217,9 @@ public class GeoDBExpectationsFactory extends AbstractExpectationsFactory {
@Override @Override
protected NativeSQLStatement createNativeIntersectionStatement(Geometry geom) { protected NativeSQLStatement createNativeIntersectionStatement(Geometry geom) {
throw new UnsupportedOperationException( return createNativeSQLStatementAllWKTParams(
"Method ST_Intersection() is not implemented in the current version of GeoDB." "select t.id, ST_Intersection(t.geom, ST_GeomFromText(?, 4326)) from GEOMTEST t where ST_SRID(t.geom) = 4326",
geom.toText()
); );
} }
@ -294,9 +293,8 @@ public class GeoDBExpectationsFactory extends AbstractExpectationsFactory {
@Override @Override
protected NativeSQLStatement createNativeRelateStatement(Geometry geom, protected NativeSQLStatement createNativeRelateStatement(Geometry geom,
String matrix) { String matrix) {
throw new UnsupportedOperationException( String sql = "select t.id, ST_Relate(t.geom, ST_GeomFromText(?, 4326), '" + matrix + "' ) from GEOMTEST t where ST_Relate(t.geom, ST_GeomFromText(?, 4326), '" + matrix + "') = 'true' and ST_SRID(t.geom) = 4326";
"Method ST_Relate() is not implemented in the current version of GeoDB." return createNativeSQLStatementAllWKTParams(sql, geom.toText());
);
} }
@Override @Override
@ -331,8 +329,9 @@ public class GeoDBExpectationsFactory extends AbstractExpectationsFactory {
@Override @Override
protected NativeSQLStatement createNativeSymDifferenceStatement( protected NativeSQLStatement createNativeSymDifferenceStatement(
Geometry geom) { Geometry geom) {
throw new UnsupportedOperationException( return createNativeSQLStatementAllWKTParams(
"Method ST_SymDifference() is not implemented in the current version of GeoDB." "select t.id, ST_SymDifference(t.geom, ST_GeomFromText(?, 4326)) from GEOMTEST t where ST_SRID(t.geom) = 4326",
geom.toText()
); );
} }

View File

@ -40,6 +40,7 @@ import org.hibernate.spatial.testing.NativeSQLStatement;
* *
* @author Jan Boonen, Geodan IT b.v. * @author Jan Boonen, Geodan IT b.v.
*/ */
@Deprecated //Class no longer used. Remove.
public class GeoDBNoSRIDExpectationsFactory extends AbstractExpectationsFactory { public class GeoDBNoSRIDExpectationsFactory extends AbstractExpectationsFactory {
public GeoDBNoSRIDExpectationsFactory(GeoDBDataSourceUtils dataSourceUtils) { public GeoDBNoSRIDExpectationsFactory(GeoDBDataSourceUtils dataSourceUtils) {

View File

@ -0,0 +1,75 @@
package org.hibernate.spatial.testing.dialects.mysql;
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.spatial.testing.DataSourceUtils;
import org.hibernate.spatial.testing.NativeSQLStatement;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 10/9/13
*/
public class MySQL56ExpectationsFactory extends MySQLExpectationsFactory {
public MySQL56ExpectationsFactory(DataSourceUtils dataSourceUtils) {
super( dataSourceUtils );
}
@Override
protected NativeSQLStatement createNativeTouchesStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, ST_Touches(t.geom, GeomFromText(?, 4326)) from GEOMTEST t where ST_Touches(t.geom, geomFromText(?, 4326)) = 1 and srid(t.geom) = 4326",
geom.toText());
}
@Override
protected NativeSQLStatement createNativeOverlapsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, ST_overlaps(t.geom, GeomFromText(?, 4326)) from GEOMTEST t where ST_Overlaps(t.geom, geomFromText(?, 4326)) = 1 and srid(t.geom) = 4326",
geom.toText());
}
@Override
protected NativeSQLStatement createNativeIntersectsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, ST_Intersects(t.geom, GeomFromText(?, 4326)) from GEOMTEST t where ST_Intersects(t.geom, geomFromText(?, 4326)) = 1 and srid(t.geom) = 4326",
geom.toText());
}
@Override
protected NativeSQLStatement createNativeWithinStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, ST_Within(t.geom, GeomFromText(?, 4326)) from GEOMTEST t where ST_Within(t.geom, geomFromText(?, 4326)) = 1 and srid(t.geom) = 4326",
geom.toText());
}
@Override
protected NativeSQLStatement createNativeEqualsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, ST_Equals(t.geom, GeomFromText(?, 4326)) from GEOMTEST t where ST_Equals(t.geom, geomFromText(?, 4326)) = 1 and srid(t.geom) = 4326",
geom.toText());
}
@Override
protected NativeSQLStatement createNativeCrossesStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, ST_Crosses(t.geom, GeomFromText(?, 4326)) from GEOMTEST t where ST_Crosses(t.geom, geomFromText(?, 4326)) = 1 and srid(t.geom) = 4326",
geom.toText());
}
@Override
protected NativeSQLStatement createNativeContainsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, ST_Contains(t.geom, GeomFromText(?, 4326)) from GEOMTEST t where ST_Contains(t.geom, geomFromText(?, 4326)) = 1 and srid(t.geom) = 4326",
geom.toText());
}
@Override
protected NativeSQLStatement createNativeDisjointStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, ST_Disjoint(t.geom, GeomFromText(?, 4326)) from GEOMTEST t where ST_Disjoint(t.geom, geomFromText(?, 4326)) = 1 and srid(t.geom) = 4326",
geom.toText());
}
}

View File

@ -0,0 +1,16 @@
package org.hibernate.spatial.testing.dialects.mysql;
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.DataSourceUtils;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 10/9/13
*/
public class MySQL56TestSupport extends MySQLTestSupport {
@Override
public AbstractExpectationsFactory createExpectationsFactory(DataSourceUtils dataSourceUtils) {
return new MySQL56ExpectationsFactory( dataSourceUtils );
}
}

View File

@ -37,7 +37,7 @@ import org.hibernate.spatial.testing.NativeSQLStatement;
*/ */
public class SDOGeometryExpectationsFactory extends AbstractExpectationsFactory { public class SDOGeometryExpectationsFactory extends AbstractExpectationsFactory {
private final SDOGeometryValueExtractor decoder = new SDOGeometryValueExtractor( JTSGeometryJavaTypeDescriptor.INSTANCE ); private final SDOGeometryValueExtractor decoder = new SDOGeometryValueExtractor( JTSGeometryJavaTypeDescriptor.INSTANCE, null );
public SDOGeometryExpectationsFactory(DataSourceUtils dataSourceUtils) { public SDOGeometryExpectationsFactory(DataSourceUtils dataSourceUtils) {
super( dataSourceUtils ); super( dataSourceUtils );
@ -69,7 +69,10 @@ public class SDOGeometryExpectationsFactory extends AbstractExpectationsFactory
@Override @Override
protected NativeSQLStatement createNativeDwithinStatement(Point geom, double distance) { protected NativeSQLStatement createNativeDwithinStatement(Point geom, double distance) {
throw new UnsupportedOperationException(); 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 @Override

View File

@ -50,13 +50,17 @@ hibernate.connection.username sa
#hibernate.connection.username hibbrtru #hibernate.connection.username hibbrtru
#hibernate.connection.password hibbrtru #hibernate.connection.password hibbrtru
## Oracle 10g ##
#hibernate.dialect org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect ## GeoDb (H2 spatial extension)
#hibernate.connection.driver_class oracle.jdbc.driver.OracleDriver ##
#hibernate.connection.url jdbc:oracle:thin:@oracle.geovise.com/ORCL #hibernate.dialect org.hibernate.spatial.dialect.h2geodb.GeoDBDialect
#hibernate.connection.username hbs #hibernate.connection.driver_class org.h2.Driver
#hibernate.connection.password hbs #hibernate.connection.url jdbc:h2:mem:testhbs;DB_CLOSE_DELAY=-1;MVCC=true
#hibernate.connection.username sa
#hibernate.connection.password sa
##
## Oracle 11g ## Oracle 11g
## ##
#hibernate.dialect org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect #hibernate.dialect org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect
@ -65,8 +69,23 @@ hibernate.connection.username sa
#hibernate.connection.username HBS #hibernate.connection.username HBS
#hibernate.connection.password HBS #hibernate.connection.password HBS
##
## Test Oracle ogc_strict property setting
##
#hibernate.spatial.ogc_strict false
## Sql Server 2008 ##
## Oracle 10g
##
#hibernate.dialect org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect
#hibernate.connection.driver_class oracle.jdbc.driver.OracleDriver
#hibernate.connection.url jdbc:oracle:thin:@oracle.geovise.com/ORCL
#hibernate.connection.username hbs
#hibernate.connection.password hbs
##
## MS SQL Server dialect
## ##
#hibernate.dialect org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect #hibernate.dialect org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect
#hibernate.connection.driver_class com.microsoft.sqlserver.jdbc.SQLServerDriver #hibernate.connection.driver_class com.microsoft.sqlserver.jdbc.SQLServerDriver
@ -84,19 +103,20 @@ hibernate.connection.username sa
#hibernate.connection.username hibernate #hibernate.connection.username hibernate
#hibernate.connection.password hibernate #hibernate.connection.password hibernate
#hibernate.dialect org.hibernate.spatial.dialect.mysql.MySQL5SpatialInnoDBDialect ##
## MySQL 5 InnoDDB dialect
##
#hibernate.dialect org.hibernate.spatial.dialect.mysql.MySQLSpatial5InnoDBDialect
#hibernate.connection.driver_class com.mysql.jdbc.Driver #hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:mysql://localhost/testhbs #hibernate.connection.url jdbc:mysql://localhost/testhbs
#hibernate.connection.username hibernate #hibernate.connection.username hibernate
#hibernate.connection.password hibernate #hibernate.connection.password hibernate
## ##
##GeoDB dialect ## MySQL 5.6.1 dialect
## ##
#hibernate.dialect org.hibernate.spatial.dialect.h2geodb.GeoDBDialect #hibernate.dialect org.hibernate.spatial.dialect.mysql.MySQL56SpatialDialect
#hibernate.connection.driver_class org.h2.Driver #hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:h2:mem:testhbs;DB_CLOSE_DELAY=-1;MVCC=true #hibernate.connection.url jdbc:mysql://172.16.1.130/test
#hibernate.connection.username sa #hibernate.connection.username HBS
#hibernate.connection.password sa #hibernate.connection.password HBS

View File

@ -5,5 +5,6 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=info, stdout log4j.rootLogger=info, stdout
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.spatial=debug log4j.logger.org.hibernate.spatial=debug