mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-07-30 19:22:58 +08:00
Revert "optimize MysqlValueProcessor & OracleValueProcessor"
This reverts commit 0d80a36a6fc11c6b360387c7a998f602ed2a0ab4.
This commit is contained in:
@ -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())
|
||||
);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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<String, String> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<JDBCDataValue, String> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
],
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<String, DefaultValueProcessor> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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)";
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -25,6 +25,6 @@ public class SQLDataValue {
|
||||
}
|
||||
|
||||
public String getBlobHexString() {
|
||||
return BaseEncoding.base16().encode(value.getBytes());
|
||||
return "0x" + BaseEncoding.base16().encode(value.getBytes());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<String> 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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user