Explorar el Código

!322 merge
Merge pull request !322 from AE86/v_2.0

AE86 hace 4 meses
padre
commit
c23119407d
Se han modificado 31 ficheros con 604 adiciones y 147 borrados
  1. 5 0
      dbsyncer-connector/dbsyncer-connector-mysql/pom.xml
  2. 5 0
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/deserializer/DeleteDeserializer.java
  3. 5 0
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/deserializer/UpdateDeserializer.java
  4. 5 0
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/deserializer/WriteDeserializer.java
  5. 2 12
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLBooleanType.java
  6. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLByteType.java
  7. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLBytesType.java
  8. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLDateType.java
  9. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLDecimalType.java
  10. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLDoubleType.java
  11. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLFloatType.java
  12. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLIntType.java
  13. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLLongType.java
  14. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLShortType.java
  15. 33 21
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLStringType.java
  16. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLTimeType.java
  17. 0 10
      dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLTimestampType.java
  18. 68 0
      dbsyncer-connector/dbsyncer-connector-mysql/src/test/java/GeometryTest.java
  19. 39 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/OracleSchemaResolver.java
  20. 52 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleBytesType.java
  21. 50 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleDateType.java
  22. 51 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleDecimalType.java
  23. 49 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleDoubleType.java
  24. 49 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleFloatType.java
  25. 34 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleIntType.java
  26. 34 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleLongType.java
  27. 57 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleStringType.java
  28. 52 0
      dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleTimestampType.java
  29. 1 1
      dbsyncer-sdk/src/main/java/org/dbsyncer/sdk/connector/AbstractConnector.java
  30. 7 3
      dbsyncer-sdk/src/main/java/org/dbsyncer/sdk/schema/AbstractDataType.java
  31. 6 0
      pom.xml

+ 5 - 0
dbsyncer-connector/dbsyncer-connector-mysql/pom.xml

@@ -26,6 +26,11 @@
             <artifactId>mysql-connector-java</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.vividsolutions</groupId>
+            <artifactId>jts</artifactId>
+        </dependency>
+
         <!-- binlog -->
         <dependency>
             <groupId>com.zendesk</groupId>

+ 5 - 0
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/deserializer/DeleteDeserializer.java

@@ -25,6 +25,11 @@ public final class DeleteDeserializer extends DeleteRowsEventDataDeserializer {
         return inputStream.readInteger(1);
     }
 
+    @Override
+    protected Serializable deserializeShort(ByteArrayInputStream inputStream) throws IOException {
+        return inputStream.readInteger(2);
+    }
+
     @Override
     protected Serializable deserializeDatetimeV2(int meta, ByteArrayInputStream inputStream) throws IOException {
         return datetimeV2Deserialize.deserializeDatetimeV2(meta, inputStream);

+ 5 - 0
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/deserializer/UpdateDeserializer.java

@@ -25,6 +25,11 @@ public final class UpdateDeserializer extends UpdateRowsEventDataDeserializer {
         return inputStream.readInteger(1);
     }
 
+    @Override
+    protected Serializable deserializeShort(ByteArrayInputStream inputStream) throws IOException {
+        return inputStream.readInteger(2);
+    }
+
     @Override
     protected Serializable deserializeDatetimeV2(int meta, ByteArrayInputStream inputStream) throws IOException {
         return datetimeV2Deserialize.deserializeDatetimeV2(meta, inputStream);

+ 5 - 0
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/deserializer/WriteDeserializer.java

@@ -25,6 +25,11 @@ public final class WriteDeserializer extends WriteRowsEventDataDeserializer {
         return inputStream.readInteger(1);
     }
 
+    @Override
+    protected Serializable deserializeShort(ByteArrayInputStream inputStream) throws IOException {
+        return inputStream.readInteger(2);
+    }
+
     @Override
     protected Serializable deserializeDatetimeV2(int meta, ByteArrayInputStream inputStream) throws IOException {
         return datetimeV2Deserialize.deserializeDatetimeV2(meta, inputStream);

+ 2 - 12
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLBooleanType.java

@@ -29,8 +29,8 @@ public final class MySQLBooleanType extends BooleanType {
 
     @Override
     protected Boolean merge(Object val, Field field) {
-        if (val instanceof Integer) {
-            return (Integer) val == 1;
+        if (val instanceof Number) {
+            return ((Number) val).shortValue() == 1;
         }
         if (val instanceof BitSet) {
             BitSet bitSet = (BitSet) val;
@@ -39,11 +39,6 @@ public final class MySQLBooleanType extends BooleanType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Boolean getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Boolean) {
@@ -53,9 +48,4 @@ public final class MySQLBooleanType extends BooleanType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLByteType.java

@@ -34,11 +34,6 @@ public final class MySQLByteType extends ByteType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Byte getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Byte) {
@@ -47,9 +42,4 @@ public final class MySQLByteType extends ByteType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLBytesType.java

@@ -45,11 +45,6 @@ public final class MySQLBytesType extends BytesType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected byte[] getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof byte[]) {
@@ -58,9 +53,4 @@ public final class MySQLBytesType extends BytesType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLDateType.java

@@ -32,11 +32,6 @@ public final class MySQLDateType extends DateType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Date getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Date) {
@@ -45,9 +40,4 @@ public final class MySQLDateType extends DateType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLDecimalType.java

@@ -51,11 +51,6 @@ public final class MySQLDecimalType extends DecimalType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected BigDecimal getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Number) {
@@ -64,9 +59,4 @@ public final class MySQLDecimalType extends DecimalType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLDoubleType.java

@@ -52,11 +52,6 @@ public final class MySQLDoubleType extends DoubleType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Double getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Number) {
@@ -65,9 +60,4 @@ public final class MySQLDoubleType extends DoubleType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLFloatType.java

@@ -46,11 +46,6 @@ public final class MySQLFloatType extends FloatType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Float getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Number) {
@@ -59,9 +54,4 @@ public final class MySQLFloatType extends FloatType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLIntType.java

@@ -59,11 +59,6 @@ public final class MySQLIntType extends IntType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Integer getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Number) {
@@ -72,9 +67,4 @@ public final class MySQLIntType extends IntType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLLongType.java

@@ -47,11 +47,6 @@ public final class MySQLLongType extends LongType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Long getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Number) {
@@ -60,9 +55,4 @@ public final class MySQLLongType extends LongType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLShortType.java

@@ -46,11 +46,6 @@ public final class MySQLShortType extends ShortType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Short getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Number) {
@@ -59,9 +54,4 @@ public final class MySQLShortType extends ShortType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 33 - 21
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLStringType.java

@@ -3,9 +3,14 @@
  */
 package org.dbsyncer.connector.mysql.schema.support;
 
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.*;
+import org.dbsyncer.connector.mysql.MySQLException;
 import org.dbsyncer.sdk.model.Field;
 import org.dbsyncer.sdk.schema.support.StringType;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Set;
@@ -26,7 +31,7 @@ public final class MySQLStringType extends StringType {
         MEDIUMTEXT, // 可变长度,最多2的24次方-1个字符,16M
         LONGTEXT, // 可变长度,最多2的32次方-1个字符,4GB
         ENUM, // 2字节,最大可达65535个不同的枚举值
-        JSON, GEOMETRY, POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION;
+        JSON, GEOMETRY; // POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION
     }
 
     @Override
@@ -36,41 +41,48 @@ public final class MySQLStringType extends StringType {
 
     @Override
     protected String merge(Object val, Field field) {
-        if (val instanceof byte[]) {
-            return new String((byte[]) val, StandardCharsets.UTF_8);
-        }
         switch (TypeEnum.valueOf(field.getTypeName())) {
-            case CHAR:
-            case VARCHAR:
-            case TINYTEXT:
-            case TEXT:
-            case MEDIUMTEXT:
-            case LONGTEXT:
+            case GEOMETRY:
+                return deserializeGeometry((byte[]) val);
             case ENUM:
-            case JSON:
                 return String.valueOf(val);
-
             default:
-                return throwUnsupportedException(val, field);
+               break;
         }
-    }
-
-    @Override
-    protected String getDefaultMergedVal() {
-        return null;
+        if (val instanceof byte[]) {
+            return new String((byte[]) val, StandardCharsets.UTF_8);
+        }
+        return throwUnsupportedException(val, field);
     }
 
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof String) {
+            if (TypeEnum.valueOf(field.getTypeName()) == TypeEnum.GEOMETRY) {
+                return serializeGeometry((String) val);
+            }
             return val;
         }
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
+    private String deserializeGeometry(byte[] bytes) {
+        try {
+            byte[] geometryBytes = ByteBuffer.allocate(bytes.length - 4).order(ByteOrder.LITTLE_ENDIAN).put(bytes, 4, bytes.length - 4).array();
+            WKBReader reader = new WKBReader();
+            return reader.read(geometryBytes).toText();
+        } catch (ParseException e) {
+            throw new MySQLException(e);
+        }
     }
 
+    private byte[] serializeGeometry(String wellKnownText) {
+        try {
+            Geometry geometry = new WKTReader().read(wellKnownText);
+            byte[] bytes = new WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN).write(geometry);
+            return ByteBuffer.allocate(bytes.length + 4).order(ByteOrder.LITTLE_ENDIAN).putInt(geometry.getSRID()).put(bytes).array();
+        } catch (ParseException e) {
+            throw new MySQLException(e);
+        }
+    }
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLTimeType.java

@@ -32,11 +32,6 @@ public final class MySQLTimeType extends TimeType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Time getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Time) {
@@ -45,9 +40,4 @@ public final class MySQLTimeType extends TimeType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 0 - 10
dbsyncer-connector/dbsyncer-connector-mysql/src/main/java/org/dbsyncer/connector/mysql/schema/support/MySQLTimestampType.java

@@ -33,11 +33,6 @@ public final class MySQLTimestampType extends TimestampType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Timestamp getDefaultMergedVal() {
-        return null;
-    }
-
     @Override
     protected Object convert(Object val, Field field) {
         if (val instanceof Timestamp) {
@@ -46,9 +41,4 @@ public final class MySQLTimestampType extends TimestampType {
         return throwUnsupportedException(val, field);
     }
 
-    @Override
-    protected Object getDefaultConvertedVal() {
-        return null;
-    }
-
 }

+ 68 - 0
dbsyncer-connector/dbsyncer-connector-mysql/src/test/java/GeometryTest.java

@@ -0,0 +1,68 @@
+/**
+ * DBSyncer Copyright 2020-2025 All Rights Reserved.
+ */
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.*;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2025-01-04 13:22
+ */
+public class GeometryTest {
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Test
+    public void testGeometry() throws Exception {
+        // POINT (121.474103 31.232862)
+        byte[] point = new byte[]{0, 0, 0, 0, 1, 1, 0, 0, 0, -33, -5, 27, -76, 87, 94, 94, 64, 45, 123, 18, -40, -100, 59, 63, 64};
+        testGeometry("point", point);
+
+        // LINESTRING (121.474103 31.232862, 121.472462 31.231339, 121.471984 31.232821)
+        byte[] linestring = new byte[]{0, 0, 0, 0, 1, 2, 0, 0, 0, 3, 0, 0, 0, -33, -5, 27, -76, 87, 94, 94, 64, 45, 123, 18, -40, -100, 59, 63, 64, -109, -90, 65, -47, 60, 94, 94, 64, 18, 74, 95, 8, 57, 59, 63, 64, 15, 15, 97, -4, 52, 94, 94, 64, 112, -46, 52, 40, -102, 59, 63, 64};
+        testGeometry("linestring", linestring);
+
+        // POLYGON ((121.474243 31.234504, 121.471775 31.233348, 121.470724 31.23155, 121.471603 31.230229, 121.472655 31.230357, 121.475777 31.232045, 121.474243 31.234504))
+        byte[] polygon = new byte[]{0, 0, 0, 0, 1, 3, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, -40, -42, 79, -1, 89, 94, 94, 64, -4, -57, 66, 116, 8, 60, 63, 64, -127, 4, -59, -113, 49, 94, 94, 64, 70, -106, -52, -79, -68, 59, 63, 64, 79, 92, -114, 87, 32, 94, 94, 64, -120, 99, 93, -36, 70, 59, 63, 64, -125, 108, 89, -66, 46, 94, 94, 64, 62, -105, -87, 73, -16, 58, 63, 64, -98, -46, -63, -6, 63, 94, 94, 64, -103, 103, 37, -83, -8, 58, 63, 64, 24, -52, 95, 33, 115, 94, 94, 64, 72, 51, 22, 77, 103, 59, 63, 64, -40, -42, 79, -1, 89, 94, 94, 64, -4, -57, 66, 116, 8, 60, 63, 64};
+        testGeometry("polygon", polygon);
+
+        // MULTIPOINT ((103 35), (104 34), (105 35))
+        byte[] multipoint = new byte[]{0, 0, 0, 0, 1, 4, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, -128, 65, 64, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 64, 0, 0, 0, 0, 0, 0, 65, 64, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 90, 64, 0, 0, 0, 0, 0, -128, 65, 64};
+        testGeometry("multipoint", multipoint);
+
+        // MULTILINESTRING ((103 35, 104 35), (105 36, 105 37))
+        byte[] multilinestring = new byte[]{0, 0, 0, 0, 1, 5, 0, 0, 0, 2, 0, 0, 0, 1, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, -128, 65, 64, 0, 0, 0, 0, 0, 0, 90, 64, 0, 0, 0, 0, 0, -128, 65, 64, 1, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 64, 90, 64, 0, 0, 0, 0, 0, 0, 66, 64, 0, 0, 0, 0, 0, 64, 90, 64, 0, 0, 0, 0, 0, -128, 66, 64};
+        testGeometry("multilinestring", multilinestring);
+
+        // MULTIPOLYGON (((103 35, 104 35, 104 36, 103 36, 103 35)), ((103 36, 104 36, 104 37, 103 36)))
+        byte[] multipolygon = new byte[]{0, 0, 0, 0, 1, 6, 0, 0, 0, 2, 0, 0, 0, 1, 3, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, -128, 65, 64, 0, 0, 0, 0, 0, 0, 90, 64, 0, 0, 0, 0, 0, -128, 65, 64, 0, 0, 0, 0, 0, 0, 90, 64, 0, 0, 0, 0, 0, 0, 66, 64, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, 0, 66, 64, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, -128, 65, 64, 1, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, 0, 66, 64, 0, 0, 0, 0, 0, 0, 90, 64, 0, 0, 0, 0, 0, 0, 66, 64, 0, 0, 0, 0, 0, 0, 90, 64, 0, 0, 0, 0, 0, -128, 66, 64, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, 0, 66, 64};
+        testGeometry("multipolygon", multipolygon);
+
+        // GEOMETRYCOLLECTION (POINT (103 35), LINESTRING (103 35, 103 37))
+        byte[] geometrycollection = new byte[]{0, 0, 0, 0, 1, 7, 0, 0, 0, 2, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, -128, 65, 64, 1, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, -128, 65, 64, 0, 0, 0, 0, 0, -64, 89, 64, 0, 0, 0, 0, 0, -128, 66, 64};
+        testGeometry("geometrycollection", geometrycollection);
+    }
+
+    private void testGeometry(String typeName, byte[] bytes) throws ParseException {
+        // 序列化
+        byte[] geometryBytes = ByteBuffer.allocate(bytes.length - 4).order(ByteOrder.LITTLE_ENDIAN).put(bytes, 4, bytes.length - 4).array();
+        WKBReader reader = new WKBReader();
+        String text = reader.read(geometryBytes).toText();
+        logger.info("test {}:{}", typeName, text);
+
+        // 反序列化
+        Geometry geometry = new WKTReader().read(text);
+        byte[] bytesArray = new WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN).write(geometry);
+        byte[] array = ByteBuffer.allocate(bytesArray.length + 4).order(ByteOrder.LITTLE_ENDIAN).putInt(geometry.getSRID()).put(bytesArray).array();
+        logger.info(Arrays.toString(array));
+        logger.info("test {}:{}", typeName, Arrays.equals(bytes, array));
+        assert Arrays.equals(bytes, array);
+    }
+}

+ 39 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/OracleSchemaResolver.java

@@ -0,0 +1,39 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema;
+
+import org.dbsyncer.connector.oracle.OracleException;
+import org.dbsyncer.connector.oracle.schema.support.*;
+import org.dbsyncer.sdk.schema.AbstractSchemaResolver;
+import org.dbsyncer.sdk.schema.DataType;
+
+import java.util.Map;
+import java.util.stream.Stream;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-24 23:45
+ */
+public final class OracleSchemaResolver extends AbstractSchemaResolver {
+    @Override
+    protected void initDataTypeMapping(Map<String, DataType> mapping) {
+        Stream.of(
+                new OracleBytesType(),
+                new OracleDateType(),
+                new OracleDecimalType(),
+                new OracleDoubleType(),
+                new OracleFloatType(),
+                new OracleIntType(),
+                new OracleLongType(),
+                new OracleStringType(),
+                new OracleTimestampType()
+        ).forEach(t -> t.getSupportedTypeName().forEach(typeName -> {
+            if (mapping.containsKey(typeName)) {
+                throw new OracleException("Duplicate type name: " + typeName);
+            }
+            mapping.put(typeName, t);
+        }));
+    }
+}

+ 52 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleBytesType.java

@@ -0,0 +1,52 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.BytesType;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleBytesType extends BytesType {
+
+    private enum TypeEnum {
+        BLOB("BLOB"),
+        RAW("RAW"),
+        LONG_RAW("LONG RAW"),
+        BFILE("BFILE");
+
+        private final String value;
+
+        TypeEnum(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Arrays.stream(TypeEnum.values()).map(TypeEnum::getValue).collect(Collectors.toSet());
+    }
+
+    @Override
+    protected byte[] merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 50 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleDateType.java

@@ -0,0 +1,50 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.DateType;
+
+import java.sql.Date;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleDateType extends DateType {
+
+    private enum TypeEnum {
+        DATE("DATE");
+
+        private final String value;
+
+        TypeEnum(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Arrays.stream(TypeEnum.values()).map(TypeEnum::getValue).collect(Collectors.toSet());
+    }
+
+    @Override
+    protected Date merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 51 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleDecimalType.java

@@ -0,0 +1,51 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.DecimalType;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleDecimalType extends DecimalType {
+
+    private enum TypeEnum {
+        NUMBER("NUMBER"),
+        FLOAT("FLOAT");
+
+        private final String value;
+
+        TypeEnum(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Arrays.stream(TypeEnum.values()).map(TypeEnum::getValue).collect(Collectors.toSet());
+    }
+
+    @Override
+    protected BigDecimal merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 49 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleDoubleType.java

@@ -0,0 +1,49 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.DoubleType;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleDoubleType extends DoubleType {
+
+    private enum TypeEnum {
+        BINARY_DOUBLE("BINARY_DOUBLE");
+
+        private final String value;
+
+        TypeEnum(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Arrays.stream(TypeEnum.values()).map(TypeEnum::getValue).collect(Collectors.toSet());
+    }
+
+    @Override
+    protected Double merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 49 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleFloatType.java

@@ -0,0 +1,49 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.FloatType;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleFloatType extends FloatType {
+
+    private enum TypeEnum {
+        BINARY_FLOAT("BINARY_FLOAT");
+
+        private final String value;
+
+        TypeEnum(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Arrays.stream(TypeEnum.values()).map(TypeEnum::getValue).collect(Collectors.toSet());
+    }
+
+    @Override
+    protected Float merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 34 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleIntType.java

@@ -0,0 +1,34 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.IntType;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleIntType extends IntType {
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    protected Integer merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 34 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleLongType.java

@@ -0,0 +1,34 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.LongType;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleLongType extends LongType {
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    protected Long merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 57 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleStringType.java

@@ -0,0 +1,57 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.StringType;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleStringType extends StringType {
+
+    private enum TypeEnum {
+        CHAR("CHAR"),
+        NCHAR("NCHAR"),
+        VARCHAR2("VARCHAR2"),
+        NVARCHAR2("NVARCHAR2"),
+        CLOB("CLOB"),
+        NCLOB("NCLOB"),
+        LONG("LONG"),
+        ROWID("ROWID"),
+        UROWID("UROWID");
+
+        private final String value;
+
+        TypeEnum(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Arrays.stream(TypeEnum.values()).map(TypeEnum::getValue).collect(Collectors.toSet());
+    }
+
+    @Override
+    protected String merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 52 - 0
dbsyncer-connector/dbsyncer-connector-oracle/src/main/java/org/dbsyncer/connector/oracle/schema/support/OracleTimestampType.java

@@ -0,0 +1,52 @@
+/**
+ * DBSyncer Copyright 2020-2024 All Rights Reserved.
+ */
+package org.dbsyncer.connector.oracle.schema.support;
+
+import org.dbsyncer.sdk.model.Field;
+import org.dbsyncer.sdk.schema.support.TimestampType;
+
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @Author 穿云
+ * @Version 1.0.0
+ * @Date 2024-12-25 00:03
+ */
+public final class OracleTimestampType extends TimestampType {
+
+    private enum TypeEnum {
+        TIMESTAMP("TIMESTAMP(6)"),
+        TIMESTAMP_WITH_TIME_ZONE("TIMESTAMP(6) WITH TIME ZONE"),
+        TIMESTAMP_WITH_LOCAL_TIME_ZONE("TIMESTAMP(6) WITH LOCAL TIME ZONE");
+
+        private final String value;
+
+        TypeEnum(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+    @Override
+    public Set<String> getSupportedTypeName() {
+        return Arrays.stream(TypeEnum.values()).map(TypeEnum::getValue).collect(Collectors.toSet());
+    }
+
+    @Override
+    protected Timestamp merge(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+    @Override
+    protected Object convert(Object val, Field field) {
+        return throwUnsupportedException(val, field);
+    }
+
+}

+ 1 - 1
dbsyncer-sdk/src/main/java/org/dbsyncer/sdk/connector/AbstractConnector.java

@@ -142,7 +142,7 @@ public abstract class AbstractConnector {
                     Object o = resolver.merge(row.get(f.getName()), f);
                     row.put(f.getName(), resolver.convert(o, f));
                 } catch (Exception e) {
-                    logger.error("convert value error: ({}, {}, {}, {})", config.getTableName(), f.getName(), row.get(f.getName()), e);
+                    logger.error(String.format("convert value error: (%s, %s, %s)", config.getTableName(), f.getName(), row.get(f.getName())), e);
                     throw new SdkException(e);
                 }
             }

+ 7 - 3
dbsyncer-sdk/src/main/java/org/dbsyncer/sdk/schema/AbstractDataType.java

@@ -35,7 +35,9 @@ public abstract class AbstractDataType<T> implements DataType {
      *
      * @return
      */
-    protected abstract T getDefaultMergedVal();
+    protected T getDefaultMergedVal() {
+        return null;
+    }
 
     /**
      * 转换为指定数据类型
@@ -51,7 +53,9 @@ public abstract class AbstractDataType<T> implements DataType {
      *
      * @return
      */
-    protected abstract Object getDefaultConvertedVal();
+    protected Object getDefaultConvertedVal() {
+        return null;
+    }
 
     @Override
     public Object mergeValue(Object val, Field field) {
@@ -76,7 +80,7 @@ public abstract class AbstractDataType<T> implements DataType {
     }
 
     protected T throwUnsupportedException(Object val, Field field) {
-        throw new SdkException(String.format("%s does not support type [%s] convert to [%s], val [%s]", getClass().getSimpleName(), val.getClass(), field.getTypeName(), val));
+        throw new SdkException(String.format("%s does not support type [%s] convert to %s(%s), val [%s]", getClass().getSimpleName(), val.getClass(), field.getName(), field.getTypeName(), val));
     }
 
 }

+ 6 - 0
pom.xml

@@ -40,6 +40,7 @@
         <ojdbc8.version>21.6.0.0</ojdbc8.version>
         <!--<mysql.version>5.1.40</mysql.version>-->
         <mysql.version>8.0.21</mysql.version>
+        <jts.version>1.13</jts.version>
         <mysql-binlog.version>0.27.0</mysql-binlog.version>
         <mssql-jdbc.version>7.4.1.jre8</mssql-jdbc.version>
         <antlr4-runtime.version>4.7.2</antlr4-runtime.version>
@@ -139,6 +140,11 @@
                 <artifactId>mysql-connector-java</artifactId>
                 <version>${mysql.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.vividsolutions</groupId>
+                <artifactId>jts</artifactId>
+                <version>${jts.version}</version>
+            </dependency>
 
             <!-- oracle-driver -->
             <dependency>