/*
* 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.mysql;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 10/9/13
*/
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.MySQL55Dialect;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.service.ServiceRegistry;
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 MySQL55Dialect 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, SQLFunction> 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 );
}
/**
* Allows the Dialect to contribute additional types
*
* @param typeContributions Callback to contribute the types
* @param serviceRegistry The service registry
*/
@Override
public void contributeTypes(
TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes( typeContributions, serviceRegistry );
dialectDelegate.contributeTypes( typeContributions, serviceRegistry );
}
@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 );
}
}