Skip to content

Commit e9dd160

Browse files
committed
HHH-14090 Add MariaDB103SpatialDialect
1 parent 725faa2 commit e9dd160

File tree

11 files changed

+647
-4
lines changed

11 files changed

+647
-4
lines changed

gradle/databases.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ ext {
9191
'jdbc.pass' : 'hibernate_orm_test',
9292
'jdbc.url' : 'jdbc:mariadb://' + dbHost + '/hibernate_orm_test'
9393
],
94+
mariadb_spatial_ci : [
95+
'db.dialect' : 'org.hibernate.spatial.dialect.mariadb.MariaDB103SpatialDialect',
96+
'jdbc.driver': 'org.mariadb.jdbc.Driver',
97+
'jdbc.user' : 'root',
98+
'jdbc.pass' : 'hibernate_orm_test',
99+
'jdbc.url' : 'jdbc:mariadb://' + dbHost + '/hibernate_orm_test'
100+
],
94101
postgis : [
95102
'db.dialect' : 'org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect',
96103
'jdbc.driver': 'org.postgresql.Driver',
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
8+
package org.hibernate.spatial.dialect.mariadb;
9+
10+
import java.util.Map;
11+
12+
import org.hibernate.boot.model.TypeContributions;
13+
import org.hibernate.dialect.MariaDB103Dialect;
14+
import org.hibernate.dialect.function.SQLFunction;
15+
import org.hibernate.service.ServiceRegistry;
16+
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
17+
18+
public class MariaDB103SpatialDialect extends MariaDB103Dialect implements MariaDBSpatialDialectTrait {
19+
20+
final private SpatialFunctionsRegistry spatialFunctions = new MariaDB103SpatialFunctions();
21+
22+
public MariaDB103SpatialDialect() {
23+
super();
24+
registerColumnType(
25+
MariaDBGeometryTypeDescriptor.INSTANCE.getSqlType(),
26+
"GEOMETRY"
27+
);
28+
for ( Map.Entry<String, SQLFunction> entry : spatialFunctions ) {
29+
registerFunction( entry.getKey(), entry.getValue() );
30+
}
31+
}
32+
33+
@Override
34+
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
35+
delegateContributeTypes( typeContributions, serviceRegistry );
36+
}
37+
38+
@Override
39+
public SpatialFunctionsRegistry spatialFunctions() {
40+
return spatialFunctions;
41+
}
42+
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
8+
package org.hibernate.spatial.dialect.mariadb;
9+
10+
import org.hibernate.dialect.function.StandardSQLFunction;
11+
import org.hibernate.spatial.SpatialFunction;
12+
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
13+
import org.hibernate.type.StandardBasicTypes;
14+
15+
class MariaDB103SpatialFunctions extends SpatialFunctionsRegistry {
16+
17+
public MariaDB103SpatialFunctions() {
18+
functionMap.put(
19+
"dimension", new StandardSQLFunction(
20+
"ST_Dimension",
21+
StandardBasicTypes.INTEGER
22+
)
23+
);
24+
functionMap.put(
25+
"geometrytype", new StandardSQLFunction(
26+
"ST_GeometryType", StandardBasicTypes.STRING
27+
)
28+
);
29+
functionMap.put(
30+
"srid", new StandardSQLFunction(
31+
"ST_SRID",
32+
StandardBasicTypes.INTEGER
33+
)
34+
);
35+
functionMap.put(
36+
"envelope", new StandardSQLFunction(
37+
"ST_Envelope"
38+
)
39+
);
40+
functionMap.put(
41+
"astext", new StandardSQLFunction(
42+
"ST_Astext",
43+
StandardBasicTypes.STRING
44+
)
45+
);
46+
functionMap.put(
47+
"asbinary", new StandardSQLFunction(
48+
"ST_Asbinary",
49+
StandardBasicTypes.BINARY
50+
)
51+
);
52+
functionMap.put(
53+
"isempty", new StandardSQLFunction(
54+
"ST_IsEmpty",
55+
StandardBasicTypes.BOOLEAN
56+
)
57+
);
58+
functionMap.put(
59+
"issimple", new StandardSQLFunction(
60+
"ST_IsSimple",
61+
StandardBasicTypes.BOOLEAN
62+
)
63+
);
64+
functionMap.put(
65+
"boundary", new StandardSQLFunction(
66+
"ST_Boundary"
67+
)
68+
);
69+
70+
// Register functions for spatial relation constructs
71+
functionMap.put(
72+
"overlaps", new StandardSQLFunction(
73+
"ST_Overlaps",
74+
StandardBasicTypes.BOOLEAN
75+
)
76+
);
77+
functionMap.put(
78+
"intersects", new StandardSQLFunction(
79+
"ST_Intersects",
80+
StandardBasicTypes.BOOLEAN
81+
)
82+
);
83+
functionMap.put(
84+
"equals", new StandardSQLFunction(
85+
"ST_Equals",
86+
StandardBasicTypes.BOOLEAN
87+
)
88+
);
89+
functionMap.put(
90+
"contains", new StandardSQLFunction(
91+
"ST_Contains",
92+
StandardBasicTypes.BOOLEAN
93+
)
94+
);
95+
functionMap.put(
96+
"crosses", new StandardSQLFunction(
97+
"ST_Crosses",
98+
StandardBasicTypes.BOOLEAN
99+
)
100+
);
101+
functionMap.put(
102+
"disjoint", new StandardSQLFunction(
103+
"ST_Disjoint",
104+
StandardBasicTypes.BOOLEAN
105+
)
106+
);
107+
functionMap.put(
108+
"touches", new StandardSQLFunction(
109+
"ST_Touches",
110+
StandardBasicTypes.BOOLEAN
111+
)
112+
);
113+
functionMap.put(
114+
"within", new StandardSQLFunction(
115+
"ST_Within",
116+
StandardBasicTypes.BOOLEAN
117+
)
118+
);
119+
functionMap.put(
120+
"relate", new StandardSQLFunction(
121+
"ST_Relate",
122+
StandardBasicTypes.BOOLEAN
123+
)
124+
);
125+
126+
// register the spatial analysis functions
127+
functionMap.put(
128+
"distance", new StandardSQLFunction(
129+
"ST_Distance",
130+
StandardBasicTypes.DOUBLE
131+
)
132+
);
133+
134+
functionMap.put(
135+
"buffer", new StandardSQLFunction(
136+
"ST_Buffer"
137+
)
138+
);
139+
140+
functionMap.put(
141+
"convexhull", new StandardSQLFunction(
142+
"ST_ConvexHull"
143+
)
144+
);
145+
146+
functionMap.put(
147+
"difference", new StandardSQLFunction(
148+
"ST_Difference"
149+
)
150+
);
151+
152+
functionMap.put(
153+
"intersection", new StandardSQLFunction(
154+
"ST_Intersection"
155+
)
156+
);
157+
158+
functionMap.put(
159+
"symdifference", new StandardSQLFunction(
160+
"ST_SymDifference"
161+
)
162+
);
163+
164+
functionMap.put(
165+
"geomunion", new StandardSQLFunction(
166+
"ST_Union"
167+
)
168+
);
169+
170+
functionMap.put(
171+
SpatialFunction.filter.name(), new StandardSQLFunction(
172+
"MBRIntersects",
173+
StandardBasicTypes.BOOLEAN
174+
)
175+
);
176+
}
177+
178+
}
179+
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
8+
package org.hibernate.spatial.dialect.mariadb;
9+
10+
import java.sql.CallableStatement;
11+
import java.sql.PreparedStatement;
12+
import java.sql.ResultSet;
13+
import java.sql.SQLException;
14+
import java.sql.Types;
15+
16+
import org.hibernate.type.descriptor.ValueBinder;
17+
import org.hibernate.type.descriptor.ValueExtractor;
18+
import org.hibernate.type.descriptor.WrapperOptions;
19+
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
20+
import org.hibernate.type.descriptor.sql.BasicBinder;
21+
import org.hibernate.type.descriptor.sql.BasicExtractor;
22+
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
23+
24+
import org.geolatte.geom.ByteBuffer;
25+
import org.geolatte.geom.ByteOrder;
26+
import org.geolatte.geom.Geometry;
27+
import org.geolatte.geom.codec.Wkb;
28+
import org.geolatte.geom.codec.WkbDecoder;
29+
import org.geolatte.geom.codec.WkbEncoder;
30+
31+
public class MariaDBGeometryTypeDescriptor implements SqlTypeDescriptor {
32+
33+
public static final MariaDBGeometryTypeDescriptor INSTANCE = new MariaDBGeometryTypeDescriptor();
34+
final WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.MYSQL_WKB );
35+
final WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.MYSQL_WKB );
36+
37+
@Override
38+
public int getSqlType() {
39+
return Types.ARRAY;
40+
}
41+
42+
@Override
43+
public boolean canBeRemapped() {
44+
return false;
45+
}
46+
47+
@Override
48+
public <X> ValueBinder<X> getBinder(JavaTypeDescriptor<X> javaTypeDescriptor) {
49+
50+
return new BasicBinder<X>( javaTypeDescriptor, this ) {
51+
@Override
52+
protected void doBind(
53+
PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
54+
final byte[] bytes = valueToByteArray( value, options );
55+
st.setBytes( index, bytes );
56+
}
57+
58+
@Override
59+
protected void doBind(
60+
CallableStatement st, X value, String name, WrapperOptions options) throws SQLException {
61+
final byte[] bytes = valueToByteArray( value, options );
62+
st.setBytes( name, bytes );
63+
}
64+
65+
private byte[] valueToByteArray(X value, WrapperOptions options) {
66+
final Geometry<?> geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
67+
final ByteBuffer buffer = encoder.encode( geometry, ByteOrder.NDR );
68+
return buffer == null ? null : buffer.toByteArray();
69+
}
70+
};
71+
}
72+
73+
@Override
74+
public <X> ValueExtractor<X> getExtractor(JavaTypeDescriptor<X> javaTypeDescriptor) {
75+
return new BasicExtractor<X>( javaTypeDescriptor, this ) {
76+
77+
@Override
78+
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
79+
return getJavaDescriptor().wrap( toGeometry( rs.getBytes( name ) ), options );
80+
}
81+
82+
@Override
83+
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
84+
return getJavaDescriptor().wrap( toGeometry( statement.getBytes( index ) ), options );
85+
}
86+
87+
@Override
88+
protected X doExtract(CallableStatement statement, String name, WrapperOptions options)
89+
throws SQLException {
90+
return getJavaDescriptor().wrap( toGeometry( statement.getBytes( name ) ), options );
91+
}
92+
};
93+
}
94+
95+
private Geometry<?> toGeometry(byte[] bytes) {
96+
if ( bytes == null ) {
97+
return null;
98+
}
99+
final ByteBuffer buffer = ByteBuffer.from( bytes );
100+
return decoder.decode( buffer );
101+
}
102+
}

0 commit comments

Comments
 (0)