mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-08-02 13:34:07 +08:00
MysqlValueProcessor and OracleValueProcessor
This commit is contained in:
@ -2,13 +2,11 @@ package ai.chat2db.plugin.mysql.builder;
|
|||||||
|
|
||||||
import ai.chat2db.plugin.mysql.type.MysqlColumnTypeEnum;
|
import ai.chat2db.plugin.mysql.type.MysqlColumnTypeEnum;
|
||||||
import ai.chat2db.plugin.mysql.type.MysqlIndexTypeEnum;
|
import ai.chat2db.plugin.mysql.type.MysqlIndexTypeEnum;
|
||||||
import ai.chat2db.spi.SqlBuilder;
|
|
||||||
import ai.chat2db.spi.jdbc.DefaultSqlBuilder;
|
import ai.chat2db.spi.jdbc.DefaultSqlBuilder;
|
||||||
import ai.chat2db.spi.model.Database;
|
import ai.chat2db.spi.model.Database;
|
||||||
import ai.chat2db.spi.model.Table;
|
import ai.chat2db.spi.model.Table;
|
||||||
import ai.chat2db.spi.model.TableColumn;
|
import ai.chat2db.spi.model.TableColumn;
|
||||||
import ai.chat2db.spi.model.TableIndex;
|
import ai.chat2db.spi.model.TableIndex;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -288,14 +286,14 @@ public class MysqlSqlBuilder extends DefaultSqlBuilder {
|
|||||||
// 连续数据数量
|
// 连续数据数量
|
||||||
if (from < to) {
|
if (from < to) {
|
||||||
for (int i = to; i < originalArray.length - 1; i++) {
|
for (int i = to; i < originalArray.length - 1; i++) {
|
||||||
if (originalArray[i+1].equals(targetArray[findIndex(targetArray, originalArray[i]) +1])) {
|
if (originalArray[i + 1].equals(targetArray[findIndex(targetArray, originalArray[i]) + 1])) {
|
||||||
continuousDataCount.set(continuousDataCount.incrementAndGet());
|
continuousDataCount.set(continuousDataCount.incrementAndGet());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (continuousDataCount.get() > 0) {
|
if (continuousDataCount.get() > 0) {
|
||||||
System.arraycopy(originalArray, from + 1, newArray, from, to - from +1);
|
System.arraycopy(originalArray, from + 1, newArray, from, to - from + 1);
|
||||||
isContinuousData = true;
|
isContinuousData = true;
|
||||||
} else {
|
} else {
|
||||||
System.arraycopy(originalArray, from + 1, newArray, from, to - from);
|
System.arraycopy(originalArray, from + 1, newArray, from, to - from);
|
||||||
@ -303,12 +301,20 @@ public class MysqlSqlBuilder extends DefaultSqlBuilder {
|
|||||||
} else {
|
} else {
|
||||||
System.arraycopy(originalArray, to, newArray, to + 1, from - to);
|
System.arraycopy(originalArray, to, newArray, to + 1, from - to);
|
||||||
}
|
}
|
||||||
if (isContinuousData){
|
if (isContinuousData) {
|
||||||
newArray[to+continuousDataCount.get()] = temp;
|
newArray[to + continuousDataCount.get()] = temp;
|
||||||
} else {
|
} else {
|
||||||
newArray[to] = temp;
|
newArray[to] = temp;
|
||||||
}
|
}
|
||||||
return newArray;
|
return newArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void buildTableName(String databaseName, String schemaName, String tableName, StringBuilder script) {
|
||||||
|
if (StringUtils.isNotBlank(databaseName)) {
|
||||||
|
script.append("`").append(databaseName).append("`").append('.');
|
||||||
|
}
|
||||||
|
script.append("`").append(tableName).append("`");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,13 @@ public class MysqlValueProcessor extends DefaultValueProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||||
return MysqlValueProcessorFactory.getValueProcessor(dataValue.getType()).convertJDBCValueByType(dataValue);
|
String type = dataValue.getType();
|
||||||
|
return MysqlValueProcessorFactory.getValueProcessor(type).convertJDBCValueByType(dataValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||||
return MysqlValueProcessorFactory.getValueProcessor(dataValue.getType()).convertJDBCValueStrByType(dataValue);
|
String type = dataValue.getType();
|
||||||
|
return MysqlValueProcessorFactory.getValueProcessor(type).convertJDBCValueStrByType(dataValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ public class MysqlValueProcessorFactory {
|
|||||||
Map.entry(MysqlColumnTypeEnum.MULTIPOLYGON.name(), mysqlGeometryProcessor),
|
Map.entry(MysqlColumnTypeEnum.MULTIPOLYGON.name(), mysqlGeometryProcessor),
|
||||||
Map.entry(MysqlColumnTypeEnum.GEOMETRYCOLLECTION.name(), mysqlGeometryProcessor),
|
Map.entry(MysqlColumnTypeEnum.GEOMETRYCOLLECTION.name(), mysqlGeometryProcessor),
|
||||||
// binary
|
// binary
|
||||||
|
Map.entry(MysqlColumnTypeEnum.VARBINARY.name(), mysqlVarBinaryProcessor),
|
||||||
Map.entry(MysqlColumnTypeEnum.BLOB.name(), mysqlVarBinaryProcessor),
|
Map.entry(MysqlColumnTypeEnum.BLOB.name(), mysqlVarBinaryProcessor),
|
||||||
Map.entry(MysqlColumnTypeEnum.LONGBLOB.name(), mysqlVarBinaryProcessor),
|
Map.entry(MysqlColumnTypeEnum.LONGBLOB.name(), mysqlVarBinaryProcessor),
|
||||||
Map.entry(MysqlColumnTypeEnum.TINYBLOB.name(), mysqlVarBinaryProcessor),
|
Map.entry(MysqlColumnTypeEnum.TINYBLOB.name(), mysqlVarBinaryProcessor),
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
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 com.google.common.io.BaseEncoding;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author: zgq
|
* @author: zgq
|
||||||
@ -26,6 +24,6 @@ public class MysqlBinaryProcessor extends DefaultValueProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||||
return convertJDBCValueByType(dataValue);
|
return dataValue.getBlobHexString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,18 @@ public class MysqlBitProcessor extends DefaultValueProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||||
return getString(convertJDBCValueByType(dataValue));
|
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: 2~64
|
||||||
|
return wrap(EasyStringUtils.getBitString(bytes, precision));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(String value) {
|
public String getString(String value) {
|
||||||
|
@ -25,17 +25,17 @@ public class MysqlTextProcessor extends DefaultValueProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||||
return getClobString(dataValue, true, super::convertJDBCValueByType);
|
return getClobString(dataValue, super::convertJDBCValueByType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||||
return wrap(getClobString(dataValue, false, super::convertJDBCValueStrByType));
|
return wrap(getClobString(dataValue, super::convertJDBCValueStrByType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getClobString(JDBCDataValue dataValue, boolean limitSize, Function<JDBCDataValue, String> function) {
|
private String getClobString(JDBCDataValue dataValue, Function<JDBCDataValue, String> function) {
|
||||||
try {
|
try {
|
||||||
return dataValue.getClobString(limitSize);
|
return dataValue.getClobString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("convertJDBCValue error database: {} , error dataType: {} ",
|
log.warn("convertJDBCValue error database: {} , error dataType: {} ",
|
||||||
Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e);
|
Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e);
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package ai.chat2db.plugin.mysql.value.sub;
|
package ai.chat2db.plugin.mysql.value.sub;
|
||||||
|
|
||||||
|
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 ai.chat2db.spi.sql.Chat2DBContext;
|
||||||
|
import ch.qos.logback.core.model.processor.DefaultProcessor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,7 +12,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
* @date: 2024年06月03日 20:48
|
* @date: 2024年06月03日 20:48
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class MysqlVarBinaryProcessor extends MysqlBinaryProcessor {
|
public class MysqlVarBinaryProcessor extends DefaultValueProcessor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||||
@ -22,9 +24,9 @@ public class MysqlVarBinaryProcessor extends MysqlBinaryProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||||
try {
|
try {
|
||||||
return dataValue.getBlobString(true);
|
return dataValue.getBlobString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("convertJDBCValueByType error database: {} , error dataType: {} ",
|
log.warn("convertJDBCValue error database: {} , error dataType: {} ",
|
||||||
Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e);
|
Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e);
|
||||||
return super.convertJDBCValueByType(dataValue);
|
return super.convertJDBCValueByType(dataValue);
|
||||||
}
|
}
|
||||||
@ -33,7 +35,7 @@ public class MysqlVarBinaryProcessor extends MysqlBinaryProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||||
return super.convertJDBCValueStrByType(dataValue);
|
return dataValue.getBlobHexString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ public class OracleBlobProcessor extends DefaultValueProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||||
try {
|
try {
|
||||||
return dataValue.getBlobString(true);
|
return dataValue.getBlobString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("convertJDBCValueByType error database: {} , error dataType: {} ",
|
log.warn("convertJDBCValueByType error database: {} , error dataType: {} ",
|
||||||
Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e);
|
Chat2DBContext.getDBConfig().getDbType(), dataValue.getType(), e);
|
||||||
|
@ -19,13 +19,13 @@ public class OracleClobProcessor extends DefaultValueProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||||
return dataValue.getClobString(true);
|
return dataValue.getClobString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||||
return wrap(dataValue.getClobString(false));
|
return wrap(dataValue.getClobString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String wrap(String value) {
|
private String wrap(String value) {
|
||||||
|
@ -14,7 +14,9 @@ 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author: zgq
|
* @author: zgq
|
||||||
@ -26,6 +28,7 @@ public class JDBCDataValue {
|
|||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private ResultSetMetaData metaData;
|
private ResultSetMetaData metaData;
|
||||||
private int columnIndex;
|
private int columnIndex;
|
||||||
|
private boolean limitSize;
|
||||||
|
|
||||||
public Object getObject() {
|
public Object getObject() {
|
||||||
try {
|
try {
|
||||||
@ -88,34 +91,54 @@ public class JDBCDataValue {
|
|||||||
return ResultSetUtils.getBlob(resultSet, columnIndex);
|
return ResultSetUtils.getBlob(resultSet, columnIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBlobString(boolean limitSize) {
|
public String getBlobString() {
|
||||||
//TODO: Identify more file types
|
|
||||||
Blob blob = getBlob();
|
Blob blob = getBlob();
|
||||||
LOBInfo blobInfo = getBlobInfo(blob);
|
LOBInfo blobInfo = getBlobInfo(blob);
|
||||||
|
String unit = blobInfo.getUnit();
|
||||||
if (blobInfo.getSize() == 0) {
|
if (blobInfo.getSize() == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
InputStream binaryStream = blob.getBinaryStream();
|
try (InputStream binaryStream = blob.getBinaryStream()) {
|
||||||
Tika tika = new Tika();
|
Tika tika = new Tika();
|
||||||
String contentType = tika.detect(binaryStream);
|
String contentType = tika.detect(binaryStream);
|
||||||
if ("image/jpeg".equals(contentType)) {
|
FileTypeEnum fileTypeEnum = FileTypeEnum.fromDescription(contentType);
|
||||||
|
if (Objects.isNull(fileTypeEnum)) {
|
||||||
BufferedImage bufferedImage = ImageIO.read(binaryStream);
|
if (limitSize && isBigSize(unit)) {
|
||||||
return String.format("[%s] %dx%d JPEG image %d %s", getType(), bufferedImage.getWidth(), bufferedImage.getHeight(), blobInfo.getSize(), blobInfo.getUnit());
|
return String.format("[%s] %d %s", getType(), blobInfo.getSize(), unit);
|
||||||
} else if ("text/plain".equals(contentType)) {
|
|
||||||
if (isBigSize(blobInfo.unit) && limitSize) {
|
|
||||||
return String.format("[%s] %d %s", getType(), blobInfo.size, blobInfo.unit);
|
|
||||||
} else {
|
|
||||||
return new String(binaryStream.readAllBytes());
|
|
||||||
}
|
}
|
||||||
|
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) {
|
} catch (SQLException | IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return getString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private LOBInfo getBlobInfo(Blob blob) {
|
private LOBInfo getBlobInfo(Blob blob) {
|
||||||
try {
|
try {
|
||||||
long size = blob.length();
|
long size = blob.length();
|
||||||
@ -125,7 +148,7 @@ public class JDBCDataValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClobString(boolean limitSize) {
|
public String getClobString() {
|
||||||
Clob clob = getClob();
|
Clob clob = getClob();
|
||||||
LOBInfo cLobInfo = getCLobInfo(clob);
|
LOBInfo cLobInfo = getCLobInfo(clob);
|
||||||
int size = cLobInfo.getSize();
|
int size = cLobInfo.getSize();
|
||||||
@ -165,7 +188,7 @@ public class JDBCDataValue {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private LOBInfo getLobInfo(long size) {
|
private LOBInfo getLobInfo(long size) {
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return new LOBInfo(LobUnit.K.unit, 0);
|
return new LOBInfo(LobUnit.B.unit, 0);
|
||||||
}
|
}
|
||||||
return calculateSizeAndUnit(size);
|
return calculateSizeAndUnit(size);
|
||||||
}
|
}
|
||||||
@ -193,7 +216,7 @@ public class JDBCDataValue {
|
|||||||
|
|
||||||
public String getBigDecimalString() {
|
public String getBigDecimalString() {
|
||||||
BigDecimal bigDecimal = getBigDecimal();
|
BigDecimal bigDecimal = getBigDecimal();
|
||||||
return bigDecimal==null?new String(getBytes()):bigDecimal.toPlainString();
|
return bigDecimal == null ? new String(getBytes()) : bigDecimal.toPlainString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ -217,4 +240,25 @@ public class JDBCDataValue {
|
|||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum FileTypeEnum {
|
||||||
|
IMAGE("image/jpeg"),
|
||||||
|
STRING("text/plain"),
|
||||||
|
;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
FileTypeEnum(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FileTypeEnum fromDescription(String description) {
|
||||||
|
for (FileTypeEnum fileType : values()) {
|
||||||
|
if (fileType.description.equals(description)) {
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user