Revert "optimize MysqlValueProcessor & OracleValueProcessor"

This reverts commit 0d80a36a6fc11c6b360387c7a998f602ed2a0ab4.
This commit is contained in:
zgq
2024-06-28 22:27:05 +08:00
parent 0d80a36a6f
commit c4955bc72b
29 changed files with 347 additions and 415 deletions

View File

@ -45,6 +45,7 @@ public class MysqlValueProcessorFactory {
Map.entry(MysqlColumnTypeEnum.DATETIME.name(), mysqlTimestampProcessor), Map.entry(MysqlColumnTypeEnum.DATETIME.name(), mysqlTimestampProcessor),
//others //others
Map.entry(MysqlColumnTypeEnum.BIT.name(), new MysqlBitProcessor()), Map.entry(MysqlColumnTypeEnum.BIT.name(), new MysqlBitProcessor()),
Map.entry(MysqlColumnTypeEnum.YEAR.name(), new MysqlYearProcessor()),
Map.entry(MysqlColumnTypeEnum.DECIMAL.name(), new MysqlDecimalProcessor()), Map.entry(MysqlColumnTypeEnum.DECIMAL.name(), new MysqlDecimalProcessor()),
Map.entry(MysqlColumnTypeEnum.BINARY.name(), new MysqlBinaryProcessor()) Map.entry(MysqlColumnTypeEnum.BINARY.name(), new MysqlBinaryProcessor())
); );

View File

@ -1,6 +1,5 @@
package ai.chat2db.plugin.mysql.value.sub; 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.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue; import ai.chat2db.spi.model.SQLDataValue;
@ -13,28 +12,18 @@ public class MysqlBinaryProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
String value = dataValue.getValue(); return dataValue.getBlobHexString();
if (value.startsWith("0x")) {
return value;
}
return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString());
} }
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { public String convertJDBCValueByType(JDBCDataValue dataValue) {
byte[] bytes = dataValue.getBytes(); return dataValue.getBlobHexString();
if (bytes.length == 1) {
if (bytes[0] >= 32 && bytes[0] <= 126) {
return new String(bytes);
}
}
return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString());
} }
@Override @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString()); return dataValue.getBlobHexString();
} }
} }

View File

@ -8,7 +8,6 @@ import ai.chat2db.spi.model.SQLDataValue;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.Objects; import java.util.Objects;
import java.util.function.Function;
/** /**
* @author: zgq * @author: zgq
@ -24,16 +23,23 @@ public class MysqlBitProcessor extends DefaultValueProcessor {
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { 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 @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return getValue(dataValue, this::wrap);
}
private String getValue(JDBCDataValue dataValue, Function<String, String> function) {
int precision = dataValue.getPrecision(); int precision = dataValue.getPrecision();
byte[] bytes = dataValue.getBytes(); byte[] bytes = dataValue.getBytes();
if (precision == 1) { if (precision == 1) {
@ -45,7 +51,7 @@ public class MysqlBitProcessor extends DefaultValueProcessor {
return String.valueOf(dataValue.getInt()); return String.valueOf(dataValue.getInt());
} }
//bit(m) m: 2~64 //bit(m) m: 2~64
return function.apply(EasyStringUtils.getBitString(bytes, precision)); return wrap(EasyStringUtils.getBitString(bytes, precision));
} }
public String getString(String value) { public String getString(String value) {
@ -59,10 +65,10 @@ public class MysqlBitProcessor extends DefaultValueProcessor {
if (StringUtils.isBlank(value)) { if (StringUtils.isBlank(value)) {
return "NULL"; return "NULL";
} }
return MysqlDmlValueTemplate.wrapBit(value); return wrap(value);
} }
private String wrap(String value) { private String wrap(String value) {
return MysqlDmlValueTemplate.wrapBit(value); return String.format(MysqlDmlValueTemplate.BIT_TEMPLATE, value);
} }
} }

View File

@ -12,7 +12,7 @@ public class MysqlDecimalProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return dataValue.getValue(); return super.convertSQLValueByType(dataValue);
} }
@ -24,6 +24,6 @@ public class MysqlDecimalProcessor extends DefaultValueProcessor {
@Override @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return dataValue.getBigDecimalString(); return convertJDBCValueByType(dataValue);
} }
} }

View File

@ -6,8 +6,6 @@ import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue; import ai.chat2db.spi.model.SQLDataValue;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKBReader; import org.locationtech.jts.io.WKBReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
@ -19,11 +17,9 @@ import java.io.InputStream;
public class MysqlGeometryProcessor extends DefaultValueProcessor { public class MysqlGeometryProcessor extends DefaultValueProcessor {
private static final Logger log = LoggerFactory.getLogger(MysqlGeometryProcessor.class);
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return MysqlDmlValueTemplate.wrapGeometry(dataValue.getValue()); return wrap(dataValue.getValue());
} }
@Override @Override
@ -79,15 +75,18 @@ public class MysqlGeometryProcessor extends DefaultValueProcessor {
} }
return dbGeometry != null ? dbGeometry.toString() : null; return dbGeometry != null ? dbGeometry.toString() : null;
} catch (Exception e) { } catch (Exception e) {
log.warn("Error converting database geometry", e); return super.getJdbcValue(dataValue);
return dataValue.getStringValue();
} }
} }
@Override @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { 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);
} }
} }

View File

@ -4,8 +4,11 @@ import ai.chat2db.server.tools.common.util.EasyStringUtils;
import ai.chat2db.spi.jdbc.DefaultValueProcessor; import ai.chat2db.spi.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue; import ai.chat2db.spi.model.SQLDataValue;
import ai.chat2db.spi.sql.Chat2DBContext;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.function.Function;
/** /**
* @author: zgq * @author: zgq
* @date: 2024年06月05日 0:11 * @date: 2024年06月05日 0:11
@ -16,19 +19,31 @@ public class MysqlTextProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return EasyStringUtils.escapeAndQuoteString(dataValue.getValue()); return wrap(dataValue.getValue());
} }
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { public String convertJDBCValueByType(JDBCDataValue dataValue) {
return dataValue.getClobString(); return getClobString(dataValue, super::convertJDBCValueByType);
} }
@Override @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { 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);
}
} }

View File

@ -1,6 +1,6 @@
package ai.chat2db.plugin.mysql.value.sub; 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.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue; import ai.chat2db.spi.model.SQLDataValue;
@ -13,18 +13,28 @@ public class MysqlTimestampProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return dataValue.getValue(); return super.convertSQLValueByType(dataValue);
} }
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { 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 @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return EasyStringUtils.quoteString(new String(dataValue.getBytes())); return String.format(MysqlDmlValueTemplate.COMMON_TEMPLATE, convertJDBCValueByType(dataValue));
} }
} }

View File

@ -1,9 +1,10 @@
package ai.chat2db.plugin.mysql.value.sub; 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.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue; 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; import lombok.extern.slf4j.Slf4j;
/** /**
@ -15,24 +16,26 @@ public class MysqlVarBinaryProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
String value = dataValue.getValue(); // TODO: insert file
if (value.startsWith("0x")) { return super.convertSQLValueByType(dataValue);
return value;
}
return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString());
} }
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { 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 @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return MysqlDmlValueTemplate.wrapHex(dataValue.getBlobHexString()); return dataValue.getBlobHexString();
} }
} }

View File

@ -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);
}
}

View File

@ -6,20 +6,7 @@ package ai.chat2db.plugin.mysql.value.template;
*/ */
public class MysqlDmlValueTemplate { public class MysqlDmlValueTemplate {
public static final String COMMON_TEMPLATE = "'%s'";
public static final String GEOMETRY_TEMPLATE = "ST_GeomFromText('%s')"; public static final String GEOMETRY_TEMPLATE = "ST_GeomFromText('%s')";
public static final String BIT_TEMPLATE = "b'%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);
}
} }

View File

@ -8,12 +8,10 @@
"custom": false, "custom": false,
"defaultDriver": true, "defaultDriver": true,
"downloadJdbcDriverUrls": [ "downloadJdbcDriverUrls": [
"https://cdn.chat2db-ai.com/lib/ojdbc11-21.5.0.0.jar", "https://cdn.chat2db-ai.com/lib/ojdbc8-19.3.0.0.jar",
"https://cdn.chat2db-ai.com/lib/orai18n-21.5.0.0.jar", "https://cdn.chat2db-ai.com/lib/orai18n-19.3.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"
], ],
"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" "jdbcDriverClass": "oracle.jdbc.driver.OracleDriver"
} }
], ],

View File

@ -21,7 +21,7 @@ public class OracleValueProcessor extends DefaultValueProcessor {
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { public String convertJDBCValueByType(JDBCDataValue dataValue) {
String type = dataValue.getType(); String type = dataValue.getType();
return OracleValueProcessorFactory.getValueProcessor(type).convertJDBCValueByType(dataValue); return OracleValueProcessorFactory.getValueProcessor(dataValue.getType()).convertJDBCValueByType(dataValue);
} }

View File

@ -9,7 +9,7 @@ import java.util.Map;
/** /**
* @author: zgq * @author: zgq
* @date: 2024年06月03日 23:21 * @date: 2024年06月03日 23:21
*/ // TODO: 1.空间数据类型 2.动态类型数据 */ // TODO: 1.空间数据类型 2.XML数据类型 3.动态类型数据 4.ANSI、DB2 和 SQL/DS 数据
public class OracleValueProcessorFactory { public class OracleValueProcessorFactory {
private static final Map<String, DefaultValueProcessor> PROCESSOR_MAP; private static final Map<String, DefaultValueProcessor> PROCESSOR_MAP;
@ -17,8 +17,6 @@ public class OracleValueProcessorFactory {
static { static {
OracleClobProcessor oracleClobProcessor = new OracleClobProcessor(); OracleClobProcessor oracleClobProcessor = new OracleClobProcessor();
OracleTimeStampProcessor oracleTimeStampProcessor = new OracleTimeStampProcessor(); OracleTimeStampProcessor oracleTimeStampProcessor = new OracleTimeStampProcessor();
OracleBlobProcessor oracleBlobProcessor = new OracleBlobProcessor();
OracleRawValueProcessor oracleRawValueProcessor = new OracleRawValueProcessor();
PROCESSOR_MAP = Map.ofEntries( PROCESSOR_MAP = Map.ofEntries(
//clob //clob
Map.entry(OracleColumnTypeEnum.CLOB.name(), oracleClobProcessor), Map.entry(OracleColumnTypeEnum.CLOB.name(), oracleClobProcessor),
@ -36,18 +34,14 @@ public class OracleValueProcessorFactory {
//number //number
Map.entry(OracleColumnTypeEnum.NUMBER.name(), new OracleNumberProcessor()), Map.entry(OracleColumnTypeEnum.NUMBER.name(), new OracleNumberProcessor()),
//blob //blob
Map.entry(OracleColumnTypeEnum.BLOB.name(), oracleBlobProcessor), Map.entry(OracleColumnTypeEnum.BLOB.name(), new OracleBlobProcessor())
//raw
Map.entry(OracleColumnTypeEnum.RAW.name(), oracleRawValueProcessor),
Map.entry(OracleColumnTypeEnum.LONG_RAW.getColumnType().getTypeName(), oracleRawValueProcessor),
//xml
Map.entry("SYS.XMLTYPE", new OracleXmlValueProcessor())
); );
} }
public static DefaultValueProcessor getValueProcessor(String type) { 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;
} }
} }

View File

@ -1,9 +1,9 @@
package ai.chat2db.plugin.oracle.value.sub; 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.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue; import ai.chat2db.spi.model.SQLDataValue;
import ai.chat2db.spi.sql.Chat2DBContext;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**
@ -15,17 +15,24 @@ public class OracleBlobProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return EasyStringUtils.quoteString(dataValue.getBlobHexString()); return dataValue.getBlobHexString();
} }
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { 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 @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return EasyStringUtils.quoteString(dataValue.getBlobHexString()); return dataValue.getBlobHexString();
} }
} }

View File

@ -13,7 +13,7 @@ public class OracleClobProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return EasyStringUtils.escapeAndQuoteString(dataValue.getValue()); return wrap(dataValue.getValue());
} }
@ -25,6 +25,10 @@ public class OracleClobProcessor extends DefaultValueProcessor {
@Override @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return EasyStringUtils.escapeAndQuoteString(dataValue.getClobString()); return wrap(dataValue.getClobString());
}
private String wrap(String value) {
return EasyStringUtils.escapeAndQuoteString(value);
} }
} }

View File

@ -21,7 +21,7 @@ public class OracleDateProcessor extends DefaultValueProcessor {
*/ */
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { 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 @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { 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);
} }
} }

View File

@ -14,19 +14,22 @@ public class OracleIntervalDSProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return OracleDmlValueTemplate.wrapIntervalDayToSecond(dataValue.getValue(), dataValue.getPrecision(), dataValue.getScale()); return wrap(dataValue.getValue(), dataValue.getPrecision(), dataValue.getScale());
} }
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { public String convertJDBCValueByType(JDBCDataValue dataValue) {
return dataValue.getStringValue(); return super.convertJDBCValueByType(dataValue);
} }
@Override @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { 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);
}
} }

View File

@ -15,18 +15,22 @@ public class OracleIntervalYMProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return OracleDmlValueTemplate.wrapIntervalYearToMonth(dataValue.getValue(), dataValue.getPrecision()); return wrap(dataValue.getValue(), dataValue.getPrecision());
} }
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { public String convertJDBCValueByType(JDBCDataValue dataValue) {
return dataValue.getStringValue(); return super.convertJDBCValueByType(dataValue);
} }
@Override @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { 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);
} }
} }

View File

@ -14,7 +14,7 @@ public class OracleNumberProcessor extends DefaultValueProcessor {
@Override @Override
public String convertSQLValueByType(SQLDataValue dataValue) { public String convertSQLValueByType(SQLDataValue dataValue) {
return dataValue.getValue(); return super.convertSQLValueByType(dataValue);
} }
@ -26,6 +26,6 @@ public class OracleNumberProcessor extends DefaultValueProcessor {
@Override @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return dataValue.getBigDecimalString(); return convertJDBCValueByType(dataValue);
} }
} }

View File

@ -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());
}
}

View File

@ -24,6 +24,7 @@ public class OracleTimeStampProcessor extends DefaultValueProcessor {
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { public String convertJDBCValueByType(JDBCDataValue dataValue) {
// TODO: datagrip对timestampLTZ的处理是不受时区影响的但其实这个字段就是为了可以协同时区问题的有待商讨
Timestamp timestamp = dataValue.getTimestamp(); Timestamp timestamp = dataValue.getTimestamp();
int scale = dataValue.getScale(); int scale = dataValue.getScale();
LocalDateTime localDateTime = timestamp.toLocalDateTime(); LocalDateTime localDateTime = timestamp.toLocalDateTime();
@ -44,8 +45,8 @@ public class OracleTimeStampProcessor extends DefaultValueProcessor {
private String wrap(String value, int scale) { private String wrap(String value, int scale) {
if (scale == 0) { 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);
} }
} }

View File

@ -21,19 +21,21 @@ public class OracleTimeStampTZProcessor extends DefaultValueProcessor {
@Override @Override
public String convertJDBCValueByType(JDBCDataValue dataValue) { 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 @Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return wrap(dataValue.getStringValue(), dataValue.getScale()); return wrap(convertJDBCValueByType(dataValue), dataValue.getScale());
} }
private String wrap(String value, int scale) { private String wrap(String value, int scale) {
if (scale == 0) { 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);
} }
} }

View File

@ -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());
}
}

View File

@ -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_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 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 INTEGER_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 INTEGER_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);
}
} }

View File

@ -4,7 +4,6 @@ import ai.chat2db.server.tools.common.util.EasyStringUtils;
import ai.chat2db.spi.ValueProcessor; import ai.chat2db.spi.ValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue; import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue; import ai.chat2db.spi.model.SQLDataValue;
import ai.chat2db.spi.sql.Chat2DBContext;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.Objects; import java.util.Objects;
@ -28,19 +27,12 @@ public abstract class BaseValueProcessor implements ValueProcessor {
@Override @Override
public String getJdbcValue(JDBCDataValue dataValue) { public String getJdbcValue(JDBCDataValue dataValue) {
Object value = dataValue.getObject(); Object value = dataValue.getObject();
if (Objects.isNull(value)) { if (Objects.isNull(dataValue.getObject())) {
// mysql -> [date]->0000:00:00
if (Chat2DBContext.getDBConfig().getDbType().equalsIgnoreCase("mysql")) {
String stringValue = dataValue.getStringValue();
if (Objects.nonNull(stringValue)) {
return stringValue;
}
}
return null; return null;
} }
if (value instanceof String emptyStr) { if (value instanceof String emptySry) {
if (StringUtils.isBlank(emptyStr)) { if (StringUtils.isBlank(emptySry)) {
return emptyStr; return emptySry;
} }
} }
return convertJDBCValueByType(dataValue); return convertJDBCValueByType(dataValue);
@ -51,13 +43,6 @@ public abstract class BaseValueProcessor implements ValueProcessor {
public String getJdbcValueString(JDBCDataValue dataValue) { public String getJdbcValueString(JDBCDataValue dataValue) {
Object value = dataValue.getObject(); Object value = dataValue.getObject();
if (Objects.isNull(value)) { 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"; return "NULL";
} }
if (value instanceof String stringValue) { if (value instanceof String stringValue) {

View File

@ -7,16 +7,14 @@ import lombok.Data;
import lombok.Getter; import lombok.Getter;
import org.apache.tika.Tika; import org.apache.tika.Tika;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.sql.*; import java.sql.*;
import java.util.Objects; import java.util.Objects;
@ -27,7 +25,6 @@ import java.util.Objects;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
public class JDBCDataValue { public class JDBCDataValue {
private static final Logger log = LoggerFactory.getLogger(JDBCDataValue.class);
private ResultSet resultSet; private ResultSet resultSet;
private ResultSetMetaData metaData; private ResultSetMetaData metaData;
private int columnIndex; private int columnIndex;
@ -37,7 +34,6 @@ public class JDBCDataValue {
try { try {
return resultSet.getObject(columnIndex); return resultSet.getObject(columnIndex);
} catch (Exception e) { } catch (Exception e) {
log.warn("Failed to retrieve object from database", e);
try { try {
return resultSet.getString(columnIndex); return resultSet.getString(columnIndex);
} catch (SQLException ex) { } catch (SQLException ex) {
@ -75,6 +71,7 @@ public class JDBCDataValue {
} }
public int getInt() { public int getInt() {
return ResultSetUtils.getInt(resultSet, columnIndex); return ResultSetUtils.getInt(resultSet, columnIndex);
} }
@ -94,8 +91,123 @@ public class JDBCDataValue {
return ResultSetUtils.getBlob(resultSet, columnIndex); 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() { public String getBlobHexString() {
return BaseEncoding.base16().encode(getBytes()); return "0x" + BaseEncoding.base16().encode(getBytes());
} }
public BigDecimal getBigDecimal() { public BigDecimal getBigDecimal() {
@ -107,189 +219,26 @@ public class JDBCDataValue {
return bigDecimal == null ? new String(getBytes()) : bigDecimal.toPlainString(); return bigDecimal == null ? new String(getBytes()) : bigDecimal.toPlainString();
} }
@Data
public String getBlobString() { @AllArgsConstructor
Blob blob = getBlob(); public static class LOBInfo {
try (InputStream binaryStream = blob.getBinaryStream()) { private String unit;
long length = blob.length(); private int size;
return converterBinaryData(length, binaryStream);
} catch (SQLException | IOException e) {
log.warn("Error while reading binary stream", e);
return getString();
}
} }
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 @Getter
public enum LobUnit { public enum LobUnit {
B("B", 1L), B("B", 1),
K("KB", 1024L), K("KB", 1024),
M("MB", 1024L * 1024L), M("MB", 1024 * 1024),
G("GB", 1024L * 1024L * 1024L); G("GB", 1024 * 1024 * 1024);
private final String unit; 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.unit = unit;
this.size = size; 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 @Getter

View File

@ -25,6 +25,6 @@ public class SQLDataValue {
} }
public String getBlobHexString() { public String getBlobHexString() {
return BaseEncoding.base16().encode(value.getBytes()); return "0x" + BaseEncoding.base16().encode(value.getBytes());
} }
} }

View File

@ -1,5 +1,10 @@
package ai.chat2db.spi.sql; 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.constant.EasyToolsConstant;
import ai.chat2db.server.tools.base.enums.DataSourceTypeEnum; import ai.chat2db.server.tools.base.enums.DataSourceTypeEnum;
import ai.chat2db.server.tools.base.excption.BusinessException; 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.ValueProcessor;
import ai.chat2db.spi.enums.DataTypeEnum; import ai.chat2db.spi.enums.DataTypeEnum;
import ai.chat2db.spi.enums.SqlTypeEnum; import ai.chat2db.spi.enums.SqlTypeEnum;
import ai.chat2db.spi.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.*; import ai.chat2db.spi.model.*;
import ai.chat2db.spi.util.JdbcUtils; import ai.chat2db.spi.util.JdbcUtils;
import ai.chat2db.spi.util.ResultSetUtils; import ai.chat2db.spi.util.ResultSetUtils;
import ai.chat2db.spi.util.SqlUtils; import ai.chat2db.spi.util.SqlUtils;
import cn.hutool.core.date.TimeInterval; import cn.hutool.core.date.TimeInterval;
import com.alibaba.druid.DbType; import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert; 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 * Dbhub unified database connection management
* *
@ -244,7 +248,7 @@ public class SQLExecutor implements CommandExecutor {
continue; continue;
} }
ValueProcessor valueProcessor = Chat2DBContext.getMetaData().getValueProcessor(); 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) { if (count != null && count > 0 && rowCount++ >= count) {
break; break;
@ -382,7 +386,7 @@ public class SQLExecutor implements CommandExecutor {
tableName, tableName,
String columnName) { String columnName) {
try (ResultSet resultSet = connection.getMetaData().getColumns(databaseName, schemaName, tableName, try (ResultSet resultSet = connection.getMetaData().getColumns(databaseName, schemaName, tableName,
columnName)) { columnName)) {
return ResultSetUtils.toObjectList(resultSet, TableColumn.class); return ResultSetUtils.toObjectList(resultSet, TableColumn.class);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -401,8 +405,8 @@ public class SQLExecutor implements CommandExecutor {
public List<TableIndex> indexes(Connection connection, String databaseName, String schemaName, String tableName) { public List<TableIndex> indexes(Connection connection, String databaseName, String schemaName, String tableName) {
List<TableIndex> tableIndices = Lists.newArrayList(); List<TableIndex> tableIndices = Lists.newArrayList();
try (ResultSet resultSet = connection.getMetaData().getIndexInfo(databaseName, schemaName, tableName, try (ResultSet resultSet = connection.getMetaData().getIndexInfo(databaseName, schemaName, tableName,
false, false,
false)) { false)) {
List<TableIndexColumn> tableIndexColumns = ResultSetUtils.toObjectList(resultSet, TableIndexColumn.class); List<TableIndexColumn> tableIndexColumns = ResultSetUtils.toObjectList(resultSet, TableIndexColumn.class);
tableIndexColumns.stream().filter(c -> c.getIndexName() != null).collect( tableIndexColumns.stream().filter(c -> c.getIndexName() != null).collect(
Collectors.groupingBy(TableIndexColumn::getIndexName)).entrySet() Collectors.groupingBy(TableIndexColumn::getIndexName)).entrySet()
@ -578,7 +582,7 @@ public class SQLExecutor implements CommandExecutor {
Header rowNumberHeader = Header.builder() Header rowNumberHeader = Header.builder()
.name(I18nUtils.getMessage("sqlResult.rowNumber")) .name(I18nUtils.getMessage("sqlResult.rowNumber"))
.dataType(DataTypeEnum.CHAT2DB_ROW_NUMBER .dataType(DataTypeEnum.CHAT2DB_ROW_NUMBER
.getCode()).build(); .getCode()).build();
executeResult.setHeaderList(EasyCollectionUtils.union(Arrays.asList(rowNumberHeader), headers)); executeResult.setHeaderList(EasyCollectionUtils.union(Arrays.asList(rowNumberHeader), headers));
// Add row number // Add row number

View File

@ -1,6 +1,8 @@
package ai.chat2db.spi.util; 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.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@ -27,6 +29,7 @@ import java.util.Map;
public class ResultSetUtils { public class ResultSetUtils {
public static List<String> getRsHeader(ResultSet rs) { public static List<String> getRsHeader(ResultSet rs) {
try { try {
ResultSetMetaData resultSetMetaData = rs.getMetaData(); ResultSetMetaData resultSetMetaData = rs.getMetaData();
@ -259,12 +262,4 @@ public class ResultSetUtils {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public static String getStringValue(ResultSet resultSet, int columnIndex) {
try {
return resultSet.getString(columnIndex);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
} }