From c4955bc72bcafc2fb8069b121c413cdf78c8ba64 Mon Sep 17 00:00:00 2001 From: zgq <203083679@qq.com> Date: Fri, 28 Jun 2024 22:27:05 +0800 Subject: [PATCH] Revert "optimize MysqlValueProcessor & OracleValueProcessor" This reverts commit 0d80a36a6fc11c6b360387c7a998f602ed2a0ab4. --- .../factory/MysqlValueProcessorFactory.java | 1 + .../mysql/value/sub/MysqlBinaryProcessor.java | 17 +- .../mysql/value/sub/MysqlBitProcessor.java | 24 +- .../value/sub/MysqlDecimalProcessor.java | 4 +- .../value/sub/MysqlGeometryProcessor.java | 15 +- .../mysql/value/sub/MysqlTextProcessor.java | 21 +- .../value/sub/MysqlTimestampProcessor.java | 18 +- .../value/sub/MysqlVarBinaryProcessor.java | 21 +- .../mysql/value/sub/MysqlYearProcessor.java | 62 ++++ .../value/template/MysqlDmlValueTemplate.java | 15 +- .../java/ai/chat2db/plugin/oracle/oracle.json | 8 +- .../oracle/value/OracleValueProcessor.java | 2 +- .../factory/OracleValueProcessorFactory.java | 14 +- .../oracle/value/sub/OracleBlobProcessor.java | 15 +- .../oracle/value/sub/OracleClobProcessor.java | 8 +- .../oracle/value/sub/OracleDateProcessor.java | 13 +- .../value/sub/OracleIntervalDSProcessor.java | 9 +- .../value/sub/OracleIntervalYMProcessor.java | 10 +- .../value/sub/OracleNumberProcessor.java | 4 +- .../value/sub/OracleRawValueProcessor.java | 31 -- .../value/sub/OracleTimeStampProcessor.java | 5 +- .../value/sub/OracleTimeStampTZProcessor.java | 10 +- .../value/sub/OracleXmlValueProcessor.java | 30 -- .../template/OracleDmlValueTemplate.java | 36 +- .../chat2db/spi/jdbc/BaseValueProcessor.java | 23 +- .../ai/chat2db/spi/model/JDBCDataValue.java | 309 ++++++++---------- .../ai/chat2db/spi/model/SQLDataValue.java | 2 +- .../java/ai/chat2db/spi/sql/SQLExecutor.java | 24 +- .../ai/chat2db/spi/util/ResultSetUtils.java | 11 +- 29 files changed, 347 insertions(+), 415 deletions(-) create mode 100644 chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlYearProcessor.java delete mode 100644 chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleRawValueProcessor.java delete mode 100644 chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleXmlValueProcessor.java diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/factory/MysqlValueProcessorFactory.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/factory/MysqlValueProcessorFactory.java index 94367e9a..fe9601c4 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/factory/MysqlValueProcessorFactory.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/factory/MysqlValueProcessorFactory.java @@ -45,6 +45,7 @@ public class MysqlValueProcessorFactory { Map.entry(MysqlColumnTypeEnum.DATETIME.name(), mysqlTimestampProcessor), //others Map.entry(MysqlColumnTypeEnum.BIT.name(), new MysqlBitProcessor()), + Map.entry(MysqlColumnTypeEnum.YEAR.name(), new MysqlYearProcessor()), Map.entry(MysqlColumnTypeEnum.DECIMAL.name(), new MysqlDecimalProcessor()), Map.entry(MysqlColumnTypeEnum.BINARY.name(), new MysqlBinaryProcessor()) ); diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlBinaryProcessor.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlBinaryProcessor.java index 7e41d21d..d35edc70 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlBinaryProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlBinaryProcessor.java @@ -1,6 +1,5 @@ package ai.chat2db.plugin.mysql.value.sub; -import ai.chat2db.plugin.mysql.value.template.MysqlDmlValueTemplate; import ai.chat2db.spi.jdbc.DefaultValueProcessor; import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.SQLDataValue; @@ -13,28 +12,18 @@ public class MysqlBinaryProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - String value = dataValue.getValue(); - if (value.startsWith("0x")) { - return value; - } - return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString()); + return dataValue.getBlobHexString(); } @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - byte[] bytes = dataValue.getBytes(); - if (bytes.length == 1) { - if (bytes[0] >= 32 && bytes[0] <= 126) { - return new String(bytes); - } - } - return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString()); + return dataValue.getBlobHexString(); } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString()); + return dataValue.getBlobHexString(); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlBitProcessor.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlBitProcessor.java index 568d93df..238796e4 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlBitProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlBitProcessor.java @@ -8,7 +8,6 @@ import ai.chat2db.spi.model.SQLDataValue; import org.apache.commons.lang3.StringUtils; import java.util.Objects; -import java.util.function.Function; /** * @author: zgq @@ -24,16 +23,23 @@ public class MysqlBitProcessor extends DefaultValueProcessor { @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - return getValue(dataValue, s -> s); + int precision = dataValue.getPrecision(); + byte[] bytes = dataValue.getBytes(); + if (precision == 1) { + //bit(1) [1 -> true] [0 -> false] + if (bytes.length == 1 && (bytes[0] == 0 || bytes[0] == 1)) { + return String.valueOf(dataValue.getBoolean()); + } + // tinyint(1) + return String.valueOf(dataValue.getInt()); + } + //bit(m) m: 1~64 + return EasyStringUtils.getBitString(bytes, precision); } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return getValue(dataValue, this::wrap); - } - - private String getValue(JDBCDataValue dataValue, Function function) { int precision = dataValue.getPrecision(); byte[] bytes = dataValue.getBytes(); if (precision == 1) { @@ -45,7 +51,7 @@ public class MysqlBitProcessor extends DefaultValueProcessor { return String.valueOf(dataValue.getInt()); } //bit(m) m: 2~64 - return function.apply(EasyStringUtils.getBitString(bytes, precision)); + return wrap(EasyStringUtils.getBitString(bytes, precision)); } public String getString(String value) { @@ -59,10 +65,10 @@ public class MysqlBitProcessor extends DefaultValueProcessor { if (StringUtils.isBlank(value)) { return "NULL"; } - return MysqlDmlValueTemplate.wrapBit(value); + return wrap(value); } private String wrap(String value) { - return MysqlDmlValueTemplate.wrapBit(value); + return String.format(MysqlDmlValueTemplate.BIT_TEMPLATE, value); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlDecimalProcessor.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlDecimalProcessor.java index 2ee2f3d4..781fc863 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlDecimalProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlDecimalProcessor.java @@ -12,7 +12,7 @@ public class MysqlDecimalProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return dataValue.getValue(); + return super.convertSQLValueByType(dataValue); } @@ -24,6 +24,6 @@ public class MysqlDecimalProcessor extends DefaultValueProcessor { @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return dataValue.getBigDecimalString(); + return convertJDBCValueByType(dataValue); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlGeometryProcessor.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlGeometryProcessor.java index 452d0976..76f05f98 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlGeometryProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlGeometryProcessor.java @@ -6,8 +6,6 @@ import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.SQLDataValue; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.io.WKBReader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -19,11 +17,9 @@ import java.io.InputStream; public class MysqlGeometryProcessor extends DefaultValueProcessor { - private static final Logger log = LoggerFactory.getLogger(MysqlGeometryProcessor.class); - @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return MysqlDmlValueTemplate.wrapGeometry(dataValue.getValue()); + return wrap(dataValue.getValue()); } @Override @@ -79,15 +75,18 @@ public class MysqlGeometryProcessor extends DefaultValueProcessor { } return dbGeometry != null ? dbGeometry.toString() : null; } catch (Exception e) { - log.warn("Error converting database geometry", e); - return dataValue.getStringValue(); + return super.getJdbcValue(dataValue); } } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return MysqlDmlValueTemplate.wrapGeometry(convertJDBCValueByType(dataValue)); + return wrap(convertJDBCValueByType(dataValue)); + } + + private String wrap(String value) { + return String.format(MysqlDmlValueTemplate.GEOMETRY_TEMPLATE, value); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlTextProcessor.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlTextProcessor.java index ff1ed2db..2aabdf2f 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlTextProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlTextProcessor.java @@ -4,8 +4,11 @@ import ai.chat2db.server.tools.common.util.EasyStringUtils; import ai.chat2db.spi.jdbc.DefaultValueProcessor; import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.SQLDataValue; +import ai.chat2db.spi.sql.Chat2DBContext; import lombok.extern.slf4j.Slf4j; +import java.util.function.Function; + /** * @author: zgq * @date: 2024年06月05日 0:11 @@ -16,19 +19,31 @@ public class MysqlTextProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return EasyStringUtils.escapeAndQuoteString(dataValue.getValue()); + return wrap(dataValue.getValue()); } @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - return dataValue.getClobString(); + return getClobString(dataValue, super::convertJDBCValueByType); } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return EasyStringUtils.escapeAndQuoteString(dataValue.getClobString()); + return wrap(getClobString(dataValue, super::convertJDBCValueStrByType)); } + private String getClobString(JDBCDataValue dataValue, Function function) { + try { + return dataValue.getClobString(); + } catch (Exception e) { + log.warn("convertJDBCValue error database: {} , error dataType: {} ", + Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e); + return function.apply(dataValue); + } + } + private String wrap(String value) { + return EasyStringUtils.escapeAndQuoteString(value); + } } diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlTimestampProcessor.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlTimestampProcessor.java index 560068d9..93f0897f 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlTimestampProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlTimestampProcessor.java @@ -1,6 +1,6 @@ package ai.chat2db.plugin.mysql.value.sub; -import ai.chat2db.server.tools.common.util.EasyStringUtils; +import ai.chat2db.plugin.mysql.value.template.MysqlDmlValueTemplate; import ai.chat2db.spi.jdbc.DefaultValueProcessor; import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.SQLDataValue; @@ -13,18 +13,28 @@ public class MysqlTimestampProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return dataValue.getValue(); + return super.convertSQLValueByType(dataValue); } @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - return new String(dataValue.getBytes()); + return isValidTimestamp(dataValue) ? new String(dataValue.getBytes()) : "0000-00-00 00:00:00"; } + protected boolean isValidTimestamp(JDBCDataValue data) { + byte[] buffer = data.getBytes(); + String stringValue = new String(buffer); + return stringValue.length() <= 0 + || stringValue.charAt(0) != '0' + || !"0000-00-00".equals(stringValue) + && !"0000-00-00 00:00:00".equals(stringValue) + && !"00000000000000".equals(stringValue) + && !"0".equals(stringValue); + } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return EasyStringUtils.quoteString(new String(dataValue.getBytes())); + return String.format(MysqlDmlValueTemplate.COMMON_TEMPLATE, convertJDBCValueByType(dataValue)); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlVarBinaryProcessor.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlVarBinaryProcessor.java index 71b689ac..bff92115 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlVarBinaryProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlVarBinaryProcessor.java @@ -1,9 +1,10 @@ package ai.chat2db.plugin.mysql.value.sub; -import ai.chat2db.plugin.mysql.value.template.MysqlDmlValueTemplate; import ai.chat2db.spi.jdbc.DefaultValueProcessor; import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.SQLDataValue; +import ai.chat2db.spi.sql.Chat2DBContext; +import ch.qos.logback.core.model.processor.DefaultProcessor; import lombok.extern.slf4j.Slf4j; /** @@ -15,24 +16,26 @@ public class MysqlVarBinaryProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - String value = dataValue.getValue(); - if (value.startsWith("0x")) { - return value; - } - return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString()); + // TODO: insert file + return super.convertSQLValueByType(dataValue); } @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - return dataValue.getBlobString(); + try { + return dataValue.getBlobString(); + } catch (Exception e) { + log.warn("convertJDBCValue error database: {} , error dataType: {} ", + Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e); + return super.convertJDBCValueByType(dataValue); + } } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString()); + return dataValue.getBlobHexString(); } - } diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlYearProcessor.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlYearProcessor.java new file mode 100644 index 00000000..db9f7831 --- /dev/null +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/sub/MysqlYearProcessor.java @@ -0,0 +1,62 @@ +package ai.chat2db.plugin.mysql.value.sub; + +import ai.chat2db.spi.jdbc.DefaultValueProcessor; +import ai.chat2db.spi.model.JDBCDataValue; +import ai.chat2db.spi.model.SQLDataValue; + +import java.sql.Date; +import java.util.Calendar; + +/** + * 功能描述 + * + * @author: zgq + * @date: 2024年06月01日 12:57 + */ +public class MysqlYearProcessor extends DefaultValueProcessor { + + @Override + public String convertSQLValueByType(SQLDataValue dataValue) { + return dataValue.getValue(); + } + + + @Override + public String convertJDBCValueByType(JDBCDataValue dataValue) { + Date date = dataValue.getDate(); + if (!isValidYear(dataValue)) { + return "0000"; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int year = calendar.get(Calendar.YEAR); + String yStr; + String yZerosPadding = "0000"; + if (year < 1000) { + yStr = "" + year; + yStr = yZerosPadding.substring(0, (4 - yStr.length())) + yStr; + } else { + yStr = "" + year; + } + return yStr; + } + + private boolean isValidYear(JDBCDataValue data) { + byte[] buffer = data.getBytes(); + String stringValue = new String(buffer); + return stringValue.length() <= 0 + || stringValue.charAt(0) != '0' + || !"0000-00-00".equals(stringValue) + && !"0000-00-00 00:00:00".equals(stringValue) + && !"00000000000000".equals(stringValue) + && !"0".equals(stringValue) + && !"00000000".equals(stringValue) + && !"0000".equals(stringValue); + } + + + @Override + public String convertJDBCValueStrByType(JDBCDataValue dataValue) { + return getJdbcValue(dataValue); + } +} diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/template/MysqlDmlValueTemplate.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/template/MysqlDmlValueTemplate.java index c43f82be..f3547f62 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/template/MysqlDmlValueTemplate.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/value/template/MysqlDmlValueTemplate.java @@ -6,20 +6,7 @@ package ai.chat2db.plugin.mysql.value.template; */ public class MysqlDmlValueTemplate { + public static final String COMMON_TEMPLATE = "'%s'"; public static final String GEOMETRY_TEMPLATE = "ST_GeomFromText('%s')"; public static final String BIT_TEMPLATE = "b'%s'"; - public static final String HEX_TEMPLATE = "0x%s"; - - - public static String wrapGeometry(String value) { - return String.format(GEOMETRY_TEMPLATE, value); - } - - public static String wrapBit(String value) { - return String.format(BIT_TEMPLATE, value); - } - - public static String wrapHex(String value) { - return String.format(HEX_TEMPLATE, value); - } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/oracle.json b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/oracle.json index a16db8c1..adb455ed 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/oracle.json +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/oracle.json @@ -8,12 +8,10 @@ "custom": false, "defaultDriver": true, "downloadJdbcDriverUrls": [ - "https://cdn.chat2db-ai.com/lib/ojdbc11-21.5.0.0.jar", - "https://cdn.chat2db-ai.com/lib/orai18n-21.5.0.0.jar", - "https://cdn.chat2db-ai.com/lib/xmlparserv2-21.5.0.0.jar", - "https://cdn.chat2db-ai.com/lib/xdb-21.5.0.0.jar" + "https://cdn.chat2db-ai.com/lib/ojdbc8-19.3.0.0.jar", + "https://cdn.chat2db-ai.com/lib/orai18n-19.3.0.0.jar" ], - "jdbcDriver": "ojdbc11-21.5.0.0.jar,orai18n-21.5.0.0.jar,xmlparserv2-21.5.0.0.jar,xdb-21.5.0.0.jar", + "jdbcDriver": "ojdbc8-19.3.0.0.jar,orai18n-19.3.0.0.jar", "jdbcDriverClass": "oracle.jdbc.driver.OracleDriver" } ], diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/OracleValueProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/OracleValueProcessor.java index 495333b4..9f1c2e27 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/OracleValueProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/OracleValueProcessor.java @@ -21,7 +21,7 @@ public class OracleValueProcessor extends DefaultValueProcessor { @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { String type = dataValue.getType(); - return OracleValueProcessorFactory.getValueProcessor(type).convertJDBCValueByType(dataValue); + return OracleValueProcessorFactory.getValueProcessor(dataValue.getType()).convertJDBCValueByType(dataValue); } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/factory/OracleValueProcessorFactory.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/factory/OracleValueProcessorFactory.java index 2cd16da3..2a545ce0 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/factory/OracleValueProcessorFactory.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/factory/OracleValueProcessorFactory.java @@ -9,7 +9,7 @@ import java.util.Map; /** * @author: zgq * @date: 2024年06月03日 23:21 - */ // TODO: 1.空间数据类型 2.动态类型数据 + */ // TODO: 1.空间数据类型 2.XML数据类型 3.动态类型数据 4.ANSI、DB2 和 SQL/DS 数据 public class OracleValueProcessorFactory { private static final Map PROCESSOR_MAP; @@ -17,8 +17,6 @@ public class OracleValueProcessorFactory { static { OracleClobProcessor oracleClobProcessor = new OracleClobProcessor(); OracleTimeStampProcessor oracleTimeStampProcessor = new OracleTimeStampProcessor(); - OracleBlobProcessor oracleBlobProcessor = new OracleBlobProcessor(); - OracleRawValueProcessor oracleRawValueProcessor = new OracleRawValueProcessor(); PROCESSOR_MAP = Map.ofEntries( //clob Map.entry(OracleColumnTypeEnum.CLOB.name(), oracleClobProcessor), @@ -36,18 +34,14 @@ public class OracleValueProcessorFactory { //number Map.entry(OracleColumnTypeEnum.NUMBER.name(), new OracleNumberProcessor()), //blob - Map.entry(OracleColumnTypeEnum.BLOB.name(), oracleBlobProcessor), - //raw - Map.entry(OracleColumnTypeEnum.RAW.name(), oracleRawValueProcessor), - Map.entry(OracleColumnTypeEnum.LONG_RAW.getColumnType().getTypeName(), oracleRawValueProcessor), - //xml - Map.entry("SYS.XMLTYPE", new OracleXmlValueProcessor()) + Map.entry(OracleColumnTypeEnum.BLOB.name(), new OracleBlobProcessor()) ); } public static DefaultValueProcessor getValueProcessor(String type) { - return PROCESSOR_MAP.getOrDefault(type, new DefaultValueProcessor()); + DefaultValueProcessor processor = PROCESSOR_MAP.get(type); + return processor == null ? new DefaultValueProcessor() : processor; } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleBlobProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleBlobProcessor.java index 63b3b54e..e246fdb8 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleBlobProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleBlobProcessor.java @@ -1,9 +1,9 @@ package ai.chat2db.plugin.oracle.value.sub; -import ai.chat2db.server.tools.common.util.EasyStringUtils; import ai.chat2db.spi.jdbc.DefaultValueProcessor; import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.SQLDataValue; +import ai.chat2db.spi.sql.Chat2DBContext; import lombok.extern.slf4j.Slf4j; /** @@ -15,17 +15,24 @@ public class OracleBlobProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return EasyStringUtils.quoteString(dataValue.getBlobHexString()); + return dataValue.getBlobHexString(); } @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - return dataValue.getBlobString(); + try { + return dataValue.getBlobString(); + } catch (Exception e) { + log.warn("convertJDBCValueByType error database: {} , error dataType: {} ", + Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e); + return super.convertJDBCValueByType(dataValue); + } + } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return EasyStringUtils.quoteString(dataValue.getBlobHexString()); + return dataValue.getBlobHexString(); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleClobProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleClobProcessor.java index 9773e6b6..1409efd5 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleClobProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleClobProcessor.java @@ -13,7 +13,7 @@ public class OracleClobProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return EasyStringUtils.escapeAndQuoteString(dataValue.getValue()); + return wrap(dataValue.getValue()); } @@ -25,6 +25,10 @@ public class OracleClobProcessor extends DefaultValueProcessor { @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return EasyStringUtils.escapeAndQuoteString(dataValue.getClobString()); + return wrap(dataValue.getClobString()); + } + + private String wrap(String value) { + return EasyStringUtils.escapeAndQuoteString(value); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleDateProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleDateProcessor.java index 7507e6bd..c807fa67 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleDateProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleDateProcessor.java @@ -21,7 +21,7 @@ public class OracleDateProcessor extends DefaultValueProcessor { */ @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return OracleDmlValueTemplate.wrapDate(dataValue.getValue()); + return wrap(dataValue.getValue()); } /** @@ -41,9 +41,16 @@ public class OracleDateProcessor extends DefaultValueProcessor { } - + /** + * @param dataValue + * @return + */ @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return OracleDmlValueTemplate.wrapDate(convertJDBCValueByType(dataValue)); + return wrap(convertJDBCValueByType(dataValue)); + } + + private String wrap(String value) { + return String.format(OracleDmlValueTemplate.DATE_TEMPLATE, value); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleIntervalDSProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleIntervalDSProcessor.java index 717cea5d..11b619b0 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleIntervalDSProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleIntervalDSProcessor.java @@ -14,19 +14,22 @@ public class OracleIntervalDSProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return OracleDmlValueTemplate.wrapIntervalDayToSecond(dataValue.getValue(), dataValue.getPrecision(), dataValue.getScale()); + return wrap(dataValue.getValue(), dataValue.getPrecision(), dataValue.getScale()); } @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - return dataValue.getStringValue(); + return super.convertJDBCValueByType(dataValue); } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return OracleDmlValueTemplate.wrapIntervalDayToSecond(convertJDBCValueByType(dataValue), dataValue.getPrecision(), dataValue.getScale()); + return wrap(convertJDBCValueByType(dataValue), dataValue.getPrecision(), dataValue.getScale()); } + private String wrap(String value, int precision, int scale) { + return String.format(OracleDmlValueTemplate.INTEGER_DAY_TO_SECOND_TEMPLATE, value, precision, scale); + } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleIntervalYMProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleIntervalYMProcessor.java index 1ae0d557..f11ca212 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleIntervalYMProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleIntervalYMProcessor.java @@ -15,18 +15,22 @@ public class OracleIntervalYMProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return OracleDmlValueTemplate.wrapIntervalYearToMonth(dataValue.getValue(), dataValue.getPrecision()); + return wrap(dataValue.getValue(), dataValue.getPrecision()); } @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - return dataValue.getStringValue(); + return super.convertJDBCValueByType(dataValue); } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return OracleDmlValueTemplate.wrapIntervalYearToMonth(dataValue.getStringValue(), dataValue.getPrecision()); + return wrap(convertJDBCValueByType(dataValue), dataValue.getPrecision()); + } + + public String wrap(String value, int precision) { + return String.format(OracleDmlValueTemplate.INTEGER_YEAR_TO_MONTH_TEMPLATE, value, precision); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleNumberProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleNumberProcessor.java index 2c9952dd..987bdf6d 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleNumberProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleNumberProcessor.java @@ -14,7 +14,7 @@ public class OracleNumberProcessor extends DefaultValueProcessor { @Override public String convertSQLValueByType(SQLDataValue dataValue) { - return dataValue.getValue(); + return super.convertSQLValueByType(dataValue); } @@ -26,6 +26,6 @@ public class OracleNumberProcessor extends DefaultValueProcessor { @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return dataValue.getBigDecimalString(); + return convertJDBCValueByType(dataValue); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleRawValueProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleRawValueProcessor.java deleted file mode 100644 index db651780..00000000 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleRawValueProcessor.java +++ /dev/null @@ -1,31 +0,0 @@ -package ai.chat2db.plugin.oracle.value.sub; - -import ai.chat2db.server.tools.common.util.EasyStringUtils; -import ai.chat2db.spi.jdbc.DefaultValueProcessor; -import ai.chat2db.spi.model.JDBCDataValue; -import ai.chat2db.spi.model.SQLDataValue; - -/** - * @author: zgq - * @date: 2024年06月28日 下午1:59 - */ -public class OracleRawValueProcessor extends DefaultValueProcessor { - - - @Override - public String convertSQLValueByType(SQLDataValue dataValue) { - return EasyStringUtils.quoteString(dataValue.getValue()); - } - - - @Override - public String convertJDBCValueByType(JDBCDataValue dataValue) { - return dataValue.getBinaryDataString(); - } - - - @Override - public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return EasyStringUtils.quoteString(dataValue.getBlobHexString()); - } -} diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleTimeStampProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleTimeStampProcessor.java index eb7ec36e..44a9d8dd 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleTimeStampProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleTimeStampProcessor.java @@ -24,6 +24,7 @@ public class OracleTimeStampProcessor extends DefaultValueProcessor { @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { + // TODO: datagrip对timestampLTZ的处理是不受时区影响的,但其实这个字段就是为了可以协同时区问题的,有待商讨 Timestamp timestamp = dataValue.getTimestamp(); int scale = dataValue.getScale(); LocalDateTime localDateTime = timestamp.toLocalDateTime(); @@ -44,8 +45,8 @@ public class OracleTimeStampProcessor extends DefaultValueProcessor { private String wrap(String value, int scale) { if (scale == 0) { - return OracleDmlValueTemplate.wrapDate(value); + return String.format(OracleDmlValueTemplate.DATE_TEMPLATE, value); } - return OracleDmlValueTemplate.wrapTimestamp(value, scale); + return String.format(OracleDmlValueTemplate.TIMESTAMP_TEMPLATE, value, scale); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleTimeStampTZProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleTimeStampTZProcessor.java index bd0ceee4..7a2d9574 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleTimeStampTZProcessor.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleTimeStampTZProcessor.java @@ -21,19 +21,21 @@ public class OracleTimeStampTZProcessor extends DefaultValueProcessor { @Override public String convertJDBCValueByType(JDBCDataValue dataValue) { - return dataValue.getStringValue(); + // TODO: return:2024-06-05 17:32:52.849 +8:00 but it actually is 2024-06-05 17:32:52.849000 +8:00 + return super.convertJDBCValueByType(dataValue); + } @Override public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return wrap(dataValue.getStringValue(), dataValue.getScale()); + return wrap(convertJDBCValueByType(dataValue), dataValue.getScale()); } private String wrap(String value, int scale) { if (scale == 0) { - return OracleDmlValueTemplate.wrapTimestampTzWithOutNanos(value); + return String.format(OracleDmlValueTemplate.TIMESTAMP_TZ_WITHOUT_NANOS_TEMPLATE, value); } - return OracleDmlValueTemplate.wrapTimestampTz(value, scale); + return String.format(OracleDmlValueTemplate.TIMESTAMP_TZ_TEMPLATE, value, scale); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleXmlValueProcessor.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleXmlValueProcessor.java deleted file mode 100644 index 2d8214cb..00000000 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/sub/OracleXmlValueProcessor.java +++ /dev/null @@ -1,30 +0,0 @@ -package ai.chat2db.plugin.oracle.value.sub; - -import ai.chat2db.plugin.oracle.value.template.OracleDmlValueTemplate; -import ai.chat2db.spi.jdbc.DefaultValueProcessor; -import ai.chat2db.spi.model.JDBCDataValue; -import ai.chat2db.spi.model.SQLDataValue; - -/** - * @author: zgq - * @date: 2024年06月21日 12:55 - */ -public class OracleXmlValueProcessor extends DefaultValueProcessor { - - @Override - public String convertSQLValueByType(SQLDataValue dataValue) { - return OracleDmlValueTemplate.wrapXml(dataValue.getValue()); - } - - - @Override - public String convertJDBCValueByType(JDBCDataValue dataValue) { - return dataValue.getStringValue(); - } - - - @Override - public String convertJDBCValueStrByType(JDBCDataValue dataValue) { - return OracleDmlValueTemplate.wrapXml(dataValue.getString()); - } -} diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/template/OracleDmlValueTemplate.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/template/OracleDmlValueTemplate.java index a0cb8f1b..e9080ae7 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/template/OracleDmlValueTemplate.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/value/template/OracleDmlValueTemplate.java @@ -13,38 +13,6 @@ public class OracleDmlValueTemplate { public static final String TIMESTAMP_TZ_TEMPLATE = "TO_TIMESTAMP_TZ('%s', 'YYYY-MM-DD HH24:MI:SS.FF%d TZH:TZM')"; public static final String TIMESTAMP_TZ_WITHOUT_NANOS_TEMPLATE = "TO_TIMESTAMP_TZ('%s', 'YYYY-MM-DD HH24:MI:SS TZH:TZM')"; - public static final String INTERVAL_YEAR_TO_MONTH_TEMPLATE = "INTERVAL '%s' YEAR(%d) TO MONTH"; - public static final String INTERVAL_DAY_TO_SECOND_TEMPLATE = "INTERVAL '%s' DAY(%d) TO SECOND(%d)"; - - public static final String XML_TEMPLATE = "XMLType('%s')"; - - - public static String wrapDate(String date) { - return String.format(DATE_TEMPLATE, date); - } - - public static String wrapTimestamp(String timestamp, int scale) { - return String.format(TIMESTAMP_TEMPLATE, timestamp, scale); - } - - public static String wrapTimestampTz(String timestamp, int scale) { - return String.format(TIMESTAMP_TZ_TEMPLATE, timestamp, scale); - } - - public static String wrapTimestampTzWithOutNanos(String timestamp) { - return String.format(TIMESTAMP_TZ_WITHOUT_NANOS_TEMPLATE, timestamp); - } - - public static String wrapIntervalYearToMonth(String year, int precision) { - return String.format(INTERVAL_YEAR_TO_MONTH_TEMPLATE, year, precision); - } - - public static String wrapIntervalDayToSecond(String day, int precision, int scale) { - return String.format(INTERVAL_DAY_TO_SECOND_TEMPLATE, day, precision, scale); - } - - public static String wrapXml(String xml) { - return String.format(XML_TEMPLATE, xml); - } - + public static final String INTEGER_YEAR_TO_MONTH_TEMPLATE = "INTERVAL '%s' YEAR(%d) TO MONTH"; + public static final String INTEGER_DAY_TO_SECOND_TEMPLATE = "INTERVAL '%s' DAY(%d) TO SECOND(%d)"; } diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/jdbc/BaseValueProcessor.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/jdbc/BaseValueProcessor.java index 4c209a3c..a0ca6750 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/jdbc/BaseValueProcessor.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/jdbc/BaseValueProcessor.java @@ -4,7 +4,6 @@ import ai.chat2db.server.tools.common.util.EasyStringUtils; import ai.chat2db.spi.ValueProcessor; import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.SQLDataValue; -import ai.chat2db.spi.sql.Chat2DBContext; import org.apache.commons.lang3.StringUtils; import java.util.Objects; @@ -28,19 +27,12 @@ public abstract class BaseValueProcessor implements ValueProcessor { @Override public String getJdbcValue(JDBCDataValue dataValue) { Object value = dataValue.getObject(); - if (Objects.isNull(value)) { - // mysql -> [date]->0000:00:00 - if (Chat2DBContext.getDBConfig().getDbType().equalsIgnoreCase("mysql")) { - String stringValue = dataValue.getStringValue(); - if (Objects.nonNull(stringValue)) { - return stringValue; - } - } + if (Objects.isNull(dataValue.getObject())) { return null; } - if (value instanceof String emptyStr) { - if (StringUtils.isBlank(emptyStr)) { - return emptyStr; + if (value instanceof String emptySry) { + if (StringUtils.isBlank(emptySry)) { + return emptySry; } } return convertJDBCValueByType(dataValue); @@ -51,13 +43,6 @@ public abstract class BaseValueProcessor implements ValueProcessor { public String getJdbcValueString(JDBCDataValue dataValue) { Object value = dataValue.getObject(); if (Objects.isNull(value)) { - // mysql -> [date]->0000:00:00 - if (Chat2DBContext.getDBConfig().getDbType().equalsIgnoreCase("mysql")) { - String stringValue = dataValue.getStringValue(); - if (Objects.nonNull(stringValue)) { - return EasyStringUtils.escapeAndQuoteString(stringValue); - } - } return "NULL"; } if (value instanceof String stringValue) { diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/JDBCDataValue.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/JDBCDataValue.java index 4e3d0a33..420cf1ba 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/JDBCDataValue.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/JDBCDataValue.java @@ -7,16 +7,14 @@ import lombok.Data; import lombok.Getter; import org.apache.tika.Tika; import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; -import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; import java.sql.*; import java.util.Objects; @@ -27,7 +25,6 @@ import java.util.Objects; @Data @AllArgsConstructor public class JDBCDataValue { - private static final Logger log = LoggerFactory.getLogger(JDBCDataValue.class); private ResultSet resultSet; private ResultSetMetaData metaData; private int columnIndex; @@ -37,7 +34,6 @@ public class JDBCDataValue { try { return resultSet.getObject(columnIndex); } catch (Exception e) { - log.warn("Failed to retrieve object from database", e); try { return resultSet.getString(columnIndex); } catch (SQLException ex) { @@ -75,6 +71,7 @@ public class JDBCDataValue { } public int getInt() { + return ResultSetUtils.getInt(resultSet, columnIndex); } @@ -94,8 +91,123 @@ public class JDBCDataValue { return ResultSetUtils.getBlob(resultSet, columnIndex); } + public String getBlobString() { + Blob blob = getBlob(); + LOBInfo blobInfo = getBlobInfo(blob); + String unit = blobInfo.getUnit(); + if (blobInfo.getSize() == 0) { + return ""; + } + + try (InputStream binaryStream = blob.getBinaryStream()) { + Tika tika = new Tika(); + String contentType = tika.detect(binaryStream); + FileTypeEnum fileTypeEnum = FileTypeEnum.fromDescription(contentType); + if (Objects.isNull(fileTypeEnum)) { + if (limitSize && isBigSize(unit)) { + return String.format("[%s] %d %s", getType(), blobInfo.getSize(), unit); + } + return getBlobHexString(); + } + switch (fileTypeEnum) { + case IMAGE: + if (limitSize) { + try (InputStream imageStream = blob.getBinaryStream()) { + BufferedImage bufferedImage = ImageIO.read(imageStream); + return String.format("[%s] %dx%d JPEG image %d %s", + getType(), bufferedImage.getWidth(), + bufferedImage.getHeight(), blobInfo.getSize(), unit); + } + } else { + return getBlobHexString(); + } + case STRING: + if (isBigSize(unit) && limitSize) { + return String.format("[%s] %d %s", getType(), blobInfo.getSize(), unit); + } else { + return new String(binaryStream.readAllBytes()); + } + default: + if (isBigSize(unit) && limitSize) { + return String.format("[%s] %d %s", getType(), blobInfo.getSize(), unit); + } + return getBlobHexString(); + } + } catch (SQLException | IOException e) { + throw new RuntimeException(e); + } + } + + + private LOBInfo getBlobInfo(Blob blob) { + try { + long size = blob.length(); + return getLobInfo(size); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + public String getClobString() { + Clob clob = getClob(); + LOBInfo cLobInfo = getCLobInfo(clob); + int size = cLobInfo.getSize(); + if (size == 0) { + return ""; + } + String unit = cLobInfo.getUnit(); + if (limitSize && isBigSize(unit)) { + return String.format("[%s] %d %s", getType(), size, unit); + } + StringBuilder builder = new StringBuilder(size); + String line; + try (BufferedReader reader = new BufferedReader(clob.getCharacterStream())) { + while ((line = reader.readLine()) != null) { + builder.append(line).append("\n"); + } + } catch (IOException | SQLException e) { + throw new RuntimeException(e); + } + return builder.toString(); + } + + private boolean isBigSize(String unit) { + return LobUnit.G.unit.equals(unit) || LobUnit.M.unit.equals(unit); + } + + public LOBInfo getCLobInfo(Clob clob) { + try { + long size = clob.length(); + return getLobInfo(size); + } catch (SQLException e) { + throw new RuntimeException(e); + } + + } + + @NotNull + private LOBInfo getLobInfo(long size) { + if (size == 0) { + return new LOBInfo(LobUnit.B.unit, 0); + } + return calculateSizeAndUnit(size); + } + + @NotNull + private LOBInfo calculateSizeAndUnit(long size) { + if (size > LobUnit.G.size) { + return new LOBInfo(LobUnit.G.unit, (int) (size / LobUnit.G.size)); + } else if (size > LobUnit.M.size) { + return new LOBInfo(LobUnit.M.unit, (int) (size / LobUnit.M.size)); + } else if (size > LobUnit.K.size) { + return new LOBInfo(LobUnit.K.unit, (int) (size / LobUnit.K.size)); + } else { + return new LOBInfo(LobUnit.B.unit, (int) size); + } + } + public String getBlobHexString() { - return BaseEncoding.base16().encode(getBytes()); + return "0x" + BaseEncoding.base16().encode(getBytes()); } public BigDecimal getBigDecimal() { @@ -107,189 +219,26 @@ public class JDBCDataValue { return bigDecimal == null ? new String(getBytes()) : bigDecimal.toPlainString(); } - - public String getBlobString() { - Blob blob = getBlob(); - try (InputStream binaryStream = blob.getBinaryStream()) { - long length = blob.length(); - return converterBinaryData(length, binaryStream); - } catch (SQLException | IOException e) { - log.warn("Error while reading binary stream", e); - return getString(); - } + @Data + @AllArgsConstructor + public static class LOBInfo { + private String unit; + private int size; } - - public String getClobString() { - Clob clob = getClob(); - try (BufferedReader reader = new BufferedReader(clob.getCharacterStream())) { - long length = clob.length(); - LOBInfo cLobInfo = getLobInfo(length); - double size = cLobInfo.getSize(); - if (size == 0) { - return ""; - } - String unit = cLobInfo.getUnit(); - if (limitSize && isBigSize(unit)) { - return String.format("[%s] %s", getType(), cLobInfo); - } - StringBuilder builder = new StringBuilder((int) (Math.ceil(size))); - String line; - - while ((line = reader.readLine()) != null) { - builder.append(line).append("\n"); - } - return builder.toString(); - } catch (IOException | SQLException e) { - log.warn("Error while reading clob stream", e); - return getStringValue(); - } - } - - private String handleImageType(InputStream imageStream, LOBInfo lobInfo) { - if (limitSize) { - try { - BufferedImage bufferedImage = ImageIO.read(imageStream); - return String.format("[%s] %dx%d JPEG image %s", getType(), bufferedImage.getWidth(), bufferedImage.getHeight(), lobInfo); - } catch (IOException e) { - log.warn("Error while reading image stream", e); - return getStringValue(); - } - } else { - return "0x" + getBlobHexString(); - } - } - - private String handleStringType(InputStream binaryStream, LOBInfo lobInfo) throws IOException { - if (isBigSize(lobInfo.getUnit()) && limitSize) { - return String.format("[%s] %s", getType(), lobInfo); - } else { - return new String(binaryStream.readAllBytes()); - } - } - - private boolean isBigSize(String unit) { - return LobUnit.G.unit.equals(unit) || LobUnit.M.unit.equals(unit); - } - - - @NotNull - private LOBInfo getLobInfo(long size) { - if (size == 0) { - return new LOBInfo(LobUnit.B.unit, 0); - } - return new LOBInfo(size); - } - - public String getStringValue() { - return ResultSetUtils.getStringValue(resultSet, columnIndex); - } - - public String getBinaryDataString() { - InputStream binaryStream = null; - try { - binaryStream = getBinaryStream(); - // 检查流是否支持 mark 操作,不支持则用 BufferedInputStream 包装 - if (!binaryStream.markSupported()) { - binaryStream = new BufferedInputStream(binaryStream); - } - - binaryStream.mark(Integer.MAX_VALUE); - - long size = 0; - byte[] buffer = new byte[8192]; // 缓冲区 - int bytesRead; - while ((bytesRead = binaryStream.read(buffer)) != -1) { - size += bytesRead; - } - binaryStream.reset(); // 重置流到标记的位置 - return converterBinaryData(size, binaryStream); - } catch (SQLException | IOException e) { - log.warn("Error while reading binary stream", e); - return getStringValue(); - } finally { - // 关闭流 - if (binaryStream != null) { - try { - binaryStream.close(); - } catch (IOException e) { - log.warn("Error while closing binary stream", e); - } - } - } - } - - private String converterBinaryData(long size, InputStream binaryStream) throws IOException, SQLException { - LOBInfo lobInfo = getLobInfo(size); - String unit = lobInfo.unit; - if (size == 0) { - return ""; - } - Tika tika = new Tika(); - String contentType = tika.detect(binaryStream); - FileTypeEnum fileTypeEnum = FileTypeEnum.fromDescription(contentType); - if (Objects.isNull(fileTypeEnum)) { - if (isBigSize(unit) && limitSize) { - return String.format("[%s] %s", getType(), lobInfo); - } - return "0x" + getBlobHexString(); - } - - return switch (fileTypeEnum) { - case IMAGE -> handleImageType(binaryStream, lobInfo); - case STRING -> handleStringType(binaryStream, lobInfo); - default -> ""; - }; - } - - @Getter public enum LobUnit { - B("B", 1L), - K("KB", 1024L), - M("MB", 1024L * 1024L), - G("GB", 1024L * 1024L * 1024L); - + B("B", 1), + K("KB", 1024), + M("MB", 1024 * 1024), + G("GB", 1024 * 1024 * 1024); private final String unit; - private final long size; + private final int size; - LobUnit(String unit, long size) { + LobUnit(String unit, int size) { this.unit = unit; this.size = size; } - - } - - @Getter - public static class LOBInfo { - private final String unit; - private final double size; - - public LOBInfo(String unit, double size) { - this.unit = unit; - this.size = size; - } - - public LOBInfo(long size) { - if (size >= LobUnit.G.size) { - this.unit = LobUnit.G.unit; - this.size = (double) size / LobUnit.G.size; - } else if (size >= LobUnit.M.size) { - this.unit = LobUnit.M.unit; - this.size = (double) size / LobUnit.M.size; - } else if (size >= LobUnit.K.size) { - this.unit = LobUnit.K.unit; - this.size = (double) size / LobUnit.K.size; - } else { - this.unit = LobUnit.B.unit; - this.size = (double) size; - } - } - - @Override - public String toString() { - return String.format("%.2f %s", size, unit); - } } @Getter diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/SQLDataValue.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/SQLDataValue.java index 05e95583..f285bc75 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/SQLDataValue.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/SQLDataValue.java @@ -25,6 +25,6 @@ public class SQLDataValue { } public String getBlobHexString() { - return BaseEncoding.base16().encode(value.getBytes()); + return "0x" + BaseEncoding.base16().encode(value.getBytes()); } } diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java index 0503cfa7..b947eb07 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java @@ -1,5 +1,10 @@ package ai.chat2db.spi.sql; +import java.sql.*; +import java.util.*; +import java.util.function.Consumer; +import java.util.stream.Collectors; + import ai.chat2db.server.tools.base.constant.EasyToolsConstant; import ai.chat2db.server.tools.base.enums.DataSourceTypeEnum; import ai.chat2db.server.tools.base.excption.BusinessException; @@ -10,26 +15,25 @@ import ai.chat2db.spi.MetaData; import ai.chat2db.spi.ValueProcessor; import ai.chat2db.spi.enums.DataTypeEnum; import ai.chat2db.spi.enums.SqlTypeEnum; +import ai.chat2db.spi.jdbc.DefaultValueProcessor; import ai.chat2db.spi.model.*; import ai.chat2db.spi.util.JdbcUtils; import ai.chat2db.spi.util.ResultSetUtils; import ai.chat2db.spi.util.SqlUtils; import cn.hutool.core.date.TimeInterval; + import com.alibaba.druid.DbType; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.google.common.collect.Lists; + import lombok.extern.slf4j.Slf4j; + import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.util.Assert; -import java.sql.*; -import java.util.*; -import java.util.function.Consumer; -import java.util.stream.Collectors; - /** * Dbhub unified database connection management * @@ -244,7 +248,7 @@ public class SQLExecutor implements CommandExecutor { continue; } ValueProcessor valueProcessor = Chat2DBContext.getMetaData().getValueProcessor(); - row.add(valueProcessor.getJdbcValue(new JDBCDataValue(rs, rs.getMetaData(), i, limitRowSize))); + row.add(valueProcessor.getJdbcValue(new JDBCDataValue(rs, rs.getMetaData(), i, false))); } if (count != null && count > 0 && rowCount++ >= count) { break; @@ -382,7 +386,7 @@ public class SQLExecutor implements CommandExecutor { tableName, String columnName) { try (ResultSet resultSet = connection.getMetaData().getColumns(databaseName, schemaName, tableName, - columnName)) { + columnName)) { return ResultSetUtils.toObjectList(resultSet, TableColumn.class); } catch (Exception e) { throw new RuntimeException(e); @@ -401,8 +405,8 @@ public class SQLExecutor implements CommandExecutor { public List indexes(Connection connection, String databaseName, String schemaName, String tableName) { List tableIndices = Lists.newArrayList(); try (ResultSet resultSet = connection.getMetaData().getIndexInfo(databaseName, schemaName, tableName, - false, - false)) { + false, + false)) { List tableIndexColumns = ResultSetUtils.toObjectList(resultSet, TableIndexColumn.class); tableIndexColumns.stream().filter(c -> c.getIndexName() != null).collect( Collectors.groupingBy(TableIndexColumn::getIndexName)).entrySet() @@ -578,7 +582,7 @@ public class SQLExecutor implements CommandExecutor { Header rowNumberHeader = Header.builder() .name(I18nUtils.getMessage("sqlResult.rowNumber")) .dataType(DataTypeEnum.CHAT2DB_ROW_NUMBER - .getCode()).build(); + .getCode()).build(); executeResult.setHeaderList(EasyCollectionUtils.union(Arrays.asList(rowNumberHeader), headers)); // Add row number diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/util/ResultSetUtils.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/util/ResultSetUtils.java index 9c872dc0..e26d496e 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/util/ResultSetUtils.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/util/ResultSetUtils.java @@ -1,6 +1,8 @@ package ai.chat2db.spi.util; +import ai.chat2db.server.tools.common.util.I18nUtils; +import cn.hutool.core.io.unit.DataSizeUtil; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -27,6 +29,7 @@ import java.util.Map; public class ResultSetUtils { + public static List getRsHeader(ResultSet rs) { try { ResultSetMetaData resultSetMetaData = rs.getMetaData(); @@ -259,12 +262,4 @@ public class ResultSetUtils { throw new RuntimeException(e); } } - - public static String getStringValue(ResultSet resultSet, int columnIndex) { - try { - return resultSet.getString(columnIndex); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } } \ No newline at end of file