| // SPDX-License-Identifier: LGPL-2.1-or-later |
| // Copyright (c) 2012-2014 Monty Program Ab |
| // Copyright (c) 2015-2021 MariaDB Corporation Ab |
| |
| package org.mariadb.jdbc.integration.codec; |
| |
| import static org.junit.jupiter.api.Assertions.*; |
| |
| import java.io.InputStream; |
| import java.io.Reader; |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.sql.*; |
| import org.junit.jupiter.api.AfterAll; |
| import org.junit.jupiter.api.Assumptions; |
| import org.junit.jupiter.api.BeforeAll; |
| import org.junit.jupiter.api.Test; |
| import org.mariadb.jdbc.Statement; |
| import org.mariadb.jdbc.client.result.CompleteResult; |
| import org.mariadb.jdbc.type.*; |
| import org.mariadb.jdbc.util.constants.Capabilities; |
| |
| public class GeometryCollectionCodecTest extends CommonCodecTest { |
| public static org.mariadb.jdbc.Connection geoConn; |
| |
| final GeometryCollection geo1 = |
| new GeometryCollection( |
| new Geometry[] { |
| new Point(0, 0), |
| new LineString( |
| new Point[] { |
| new Point(10, 10), |
| new Point(20, 10), |
| new Point(20, 20), |
| new Point(10, 20), |
| new Point(10, 10) |
| }, |
| true) |
| }); |
| final GeometryCollection geo2 = |
| new GeometryCollection( |
| new Geometry[] { |
| new Polygon( |
| new LineString[] { |
| new LineString( |
| new Point[] { |
| new Point(0, 0), |
| new Point(50, 0), |
| new Point(50, 50), |
| new Point(0, 50), |
| new Point(0, 0) |
| }, |
| false), |
| new LineString( |
| new Point[] { |
| new Point(10, 10), |
| new Point(20, 10), |
| new Point(20, 20), |
| new Point(10, 20), |
| new Point(10, 10) |
| }, |
| false) |
| }), |
| new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}) |
| }); |
| final GeometryCollection geo3 = |
| new GeometryCollection( |
| new Geometry[] { |
| new MultiLineString( |
| new LineString[] { |
| new LineString( |
| new Point[] { |
| new Point(0, 0), new Point(50, 0), new Point(50, 50), new Point(0, 50) |
| }, |
| true), |
| new LineString( |
| new Point[] { |
| new Point(10, 10), new Point(20, 10), new Point(20, 20), new Point(10, 20) |
| }, |
| true) |
| }), |
| new MultiPolygon( |
| new Polygon[] { |
| new Polygon( |
| new LineString[] { |
| new LineString( |
| new Point[] { |
| new Point(1, 1), |
| new Point(1, 8), |
| new Point(4, 9), |
| new Point(6, 9), |
| new Point(9, 3), |
| new Point(7, 2), |
| new Point(1, 1) |
| }, |
| false), |
| }) |
| }) |
| }); |
| |
| @BeforeAll |
| public static void beforeAll2() throws Exception { |
| drop(); |
| // xpand doesn't recognized GeometryCollection |
| Assumptions.assumeFalse(isXpand()); |
| Statement stmt = sharedConn.createStatement(); |
| stmt.execute( |
| "CREATE TABLE GeometryCollectionCodec (t1 GeometryCollection, t2 GeometryCollection, t3" |
| + " GeometryCollection, t4 GeometryCollection)"); |
| stmt.execute( |
| "INSERT INTO GeometryCollectionCodec VALUES (ST_GeomFromText('GeometryCollection(POINT (0" |
| + " 0), LINESTRING(10 10,20 10,20 20,10 20,10 10))')," |
| + " ST_GeomFromText('GeometryCollection(POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20" |
| + " 10,20 20,10 20,10 10)), MULTIPOINT(0 0,0 10,10 0))')," |
| + " ST_GeomFromText('GeometryCollection(MULTILINESTRING((0 0,50 0,50 50,0 50), (10" |
| + " 10,20 10,20 20,10 20)), MULTIPOLYGON(((1 1, 1 8,4 9,6 9,9 3,7 2, 1 1))))'), null)"); |
| stmt.execute( |
| "CREATE TABLE GeometryCollectionCodec2 (id int not null primary key auto_increment, t1" |
| + " GeometryCollection)"); |
| stmt.execute("FLUSH TABLES"); |
| String binUrl = |
| mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "geometryDefaultType=default"; |
| geoConn = (org.mariadb.jdbc.Connection) DriverManager.getConnection(binUrl); |
| } |
| |
| @AfterAll |
| public static void drop() throws SQLException { |
| Statement stmt = sharedConn.createStatement(); |
| stmt.execute("DROP TABLE IF EXISTS GeometryCollectionCodec"); |
| stmt.execute("DROP TABLE IF EXISTS GeometryCollectionCodec2"); |
| if (geoConn != null) geoConn.close(); |
| } |
| |
| private ResultSet get() throws SQLException { |
| Statement stmt = sharedConn.createStatement(); |
| stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER |
| ResultSet rs = |
| stmt.executeQuery( |
| "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from" |
| + " GeometryCollectionCodec"); |
| assertTrue(rs.next()); |
| sharedConn.commit(); |
| return rs; |
| } |
| |
| private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException { |
| java.sql.Statement stmt = con.createStatement(); |
| stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER |
| PreparedStatement preparedStatement = |
| con.prepareStatement( |
| "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from" |
| + " GeometryCollectionCodec WHERE 1 > ?"); |
| preparedStatement.closeOnCompletion(); |
| preparedStatement.setInt(1, 0); |
| CompleteResult rs = (CompleteResult) preparedStatement.executeQuery(); |
| assertTrue(rs.next()); |
| con.commit(); |
| return rs; |
| } |
| |
| @Test |
| public void getObject() throws Exception { |
| getObject(get(), false); |
| } |
| |
| @Test |
| public void getObjectPrepare() throws Exception { |
| getObject(getPrepare(sharedConn), false); |
| getObject(getPrepare(sharedConnBinary), false); |
| getObject(getPrepare(geoConn), true); |
| } |
| |
| public void getObject(ResultSet rs, boolean defaultGeo) throws SQLException { |
| if (defaultGeo && hasCapability(Capabilities.EXTENDED_TYPE_INFO)) { |
| assertEquals(geo1, rs.getObject(1)); |
| assertFalse(rs.wasNull()); |
| assertEquals(geo2, rs.getObject(2)); |
| assertFalse(rs.wasNull()); |
| assertEquals(geo3, rs.getObject(3)); |
| assertFalse(rs.wasNull()); |
| assertNull(rs.getObject(4)); |
| assertTrue(rs.wasNull()); |
| } else { |
| assertEquals(geo1, rs.getObject(1, GeometryCollection.class)); |
| assertFalse(rs.wasNull()); |
| assertEquals(geo2, rs.getObject(2, GeometryCollection.class)); |
| assertFalse(rs.wasNull()); |
| assertEquals(geo3, rs.getObject(3, GeometryCollection.class)); |
| assertFalse(rs.wasNull()); |
| assertNull(rs.getObject(4)); |
| assertTrue(rs.wasNull()); |
| } |
| } |
| |
| @Test |
| public void getObjectType() throws Exception { |
| getObjectType(get()); |
| } |
| |
| @Test |
| public void getObjectTypePrepare() throws Exception { |
| getObjectType(getPrepare(sharedConn)); |
| getObjectType(getPrepare(sharedConnBinary)); |
| } |
| |
| public void getObjectType(ResultSet rs) throws Exception { |
| testErrObject(rs, Integer.class, 1); |
| testErrObject(rs, String.class, 1); |
| testErrObject(rs, Long.class, 1); |
| testErrObject(rs, Short.class, 1); |
| testErrObject(rs, BigDecimal.class, 1); |
| testErrObject(rs, BigInteger.class, 1); |
| testErrObject(rs, LineString.class, 1); |
| testErrObject(rs, Point.class, 1); |
| testErrObject(rs, Polygon.class, 1); |
| testErrObject(rs, MultiLineString.class, 1); |
| testErrObject(rs, MultiPoint.class, 1); |
| testErrObject(rs, MultiPolygon.class, 1); |
| testErrObject(rs, Double.class, 1); |
| testErrObject(rs, Float.class, 1); |
| testErrObject(rs, Byte.class, 1); |
| |
| String hexa = |
| "000000000107000000020000000101000000000000000000000000000000000000000102000000050000000000000000002440000000000000244000000000000034400000000000002440000000000000344000000000000034400000000000002440000000000000344000000000000024400000000000002440"; |
| testArrObject(rs, MultiPolygonCodecTest.decodeHexString(hexa), 1); |
| |
| testErrObject(rs, Boolean.class, 1); |
| testErrObject(rs, Clob.class, 1); |
| testErrObject(rs, NClob.class, 1); |
| testErrObject(rs, InputStream.class, 1); |
| testErrObject(rs, Reader.class, 1); |
| testErrObject(rs, java.util.Date.class, 1); |
| } |
| |
| @Test |
| public void getMetaData() throws SQLException { |
| getMetaData(sharedConn, false); |
| try (org.mariadb.jdbc.Connection con = createCon("geometryDefaultType=default")) { |
| getMetaData(con, true); |
| } |
| } |
| |
| private void getMetaData(org.mariadb.jdbc.Connection con, boolean geoDefault) |
| throws SQLException { |
| ResultSet rs = getPrepare(con); |
| ResultSetMetaData meta = rs.getMetaData(); |
| if (hasCapability(Capabilities.EXTENDED_TYPE_INFO)) { |
| assertEquals("GEOMETRYCOLLECTION", meta.getColumnTypeName(1)); |
| } else { |
| assertEquals("GEOMETRY", meta.getColumnTypeName(1)); |
| } |
| assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1)); |
| assertEquals( |
| geoDefault ? GeometryCollection.class.getName() : "byte[]", meta.getColumnClassName(1)); |
| assertEquals("t1alias", meta.getColumnLabel(1)); |
| assertEquals("t1", meta.getColumnName(1)); |
| assertEquals(Types.VARBINARY, meta.getColumnType(1)); |
| assertEquals(4, meta.getColumnCount()); |
| assertEquals(0, meta.getScale(1)); |
| assertEquals("", meta.getSchemaName(1)); |
| } |
| |
| @Test |
| public void sendParam() throws Exception { |
| sendParam(sharedConn); |
| sendParam(sharedConnBinary); |
| } |
| |
| private void sendParam(Connection con) throws Exception { |
| java.sql.Statement stmt = con.createStatement(); |
| stmt.execute("TRUNCATE TABLE GeometryCollectionCodec2"); |
| stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER |
| try (PreparedStatement prep = |
| con.prepareStatement("INSERT INTO GeometryCollectionCodec2(t1) VALUES (?)")) { |
| prep.setObject(1, geo1); |
| prep.execute(); |
| prep.setObject(1, (GeometryCollection) null); |
| prep.execute(); |
| |
| prep.setObject(1, geo2); |
| prep.addBatch(); |
| prep.setObject(1, geo3); |
| prep.addBatch(); |
| prep.executeBatch(); |
| } |
| |
| ResultSet rs = |
| con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE) |
| .executeQuery("SELECT * FROM GeometryCollectionCodec2"); |
| assertTrue(rs.next()); |
| assertEquals(geo1, rs.getObject(2, GeometryCollection.class)); |
| rs.updateNull(2); |
| rs.updateRow(); |
| assertNull(rs.getObject(2, GeometryCollection.class)); |
| |
| assertTrue(rs.next()); |
| assertNull(rs.getObject(2, GeometryCollection.class)); |
| rs.updateObject(2, geo2); |
| rs.updateRow(); |
| assertEquals(geo2, rs.getObject(2, GeometryCollection.class)); |
| assertTrue(rs.next()); |
| |
| assertEquals(geo2, rs.getObject(2, GeometryCollection.class)); |
| assertTrue(rs.next()); |
| assertEquals(geo3, rs.getObject(2, GeometryCollection.class)); |
| con.commit(); |
| } |
| |
| @Test |
| public void equal() { |
| assertEquals(geo1, geo1); |
| assertEquals( |
| new GeometryCollection( |
| new Geometry[] { |
| new Point(0, 0), |
| new LineString( |
| new Point[] { |
| new Point(10, 10), |
| new Point(20, 10), |
| new Point(20, 20), |
| new Point(10, 20), |
| new Point(10, 10) |
| }, |
| true) |
| }), |
| geo1); |
| assertEquals( |
| new GeometryCollection( |
| new Geometry[] { |
| new Point(0, 0), |
| new LineString( |
| new Point[] { |
| new Point(10, 10), |
| new Point(20, 10), |
| new Point(20, 20), |
| new Point(10, 20), |
| new Point(10, 10) |
| }, |
| true) |
| }) |
| .hashCode(), |
| geo1.hashCode()); |
| assertFalse(geo1.equals(null)); |
| assertFalse(geo1.equals("")); |
| assertNotEquals( |
| new GeometryCollection( |
| new Geometry[] { |
| new Point(0, 10), |
| new LineString( |
| new Point[] { |
| new Point(10, 10), |
| new Point(20, 10), |
| new Point(20, 20), |
| new Point(10, 20), |
| new Point(10, 10) |
| }, |
| true) |
| }), |
| geo1); |
| } |
| } |