mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-09-22 04:27:30 +08:00
OracleValueProcessor
This commit is contained in:
@ -11,8 +11,10 @@ import ai.chat2db.plugin.oracle.builder.OracleSqlBuilder;
|
||||
import ai.chat2db.plugin.oracle.type.OracleColumnTypeEnum;
|
||||
import ai.chat2db.plugin.oracle.type.OracleDefaultValueEnum;
|
||||
import ai.chat2db.plugin.oracle.type.OracleIndexTypeEnum;
|
||||
import ai.chat2db.plugin.oracle.value.OracleValueProcessor;
|
||||
import ai.chat2db.spi.MetaData;
|
||||
import ai.chat2db.spi.SqlBuilder;
|
||||
import ai.chat2db.spi.ValueProcessor;
|
||||
import ai.chat2db.spi.jdbc.DefaultMetaService;
|
||||
import ai.chat2db.spi.model.*;
|
||||
import ai.chat2db.spi.sql.SQLExecutor;
|
||||
@ -340,4 +342,12 @@ public class OracleMetaData extends DefaultMetaService implements MetaData {
|
||||
public List<String> getSystemSchemas() {
|
||||
return systemSchemas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ValueProcessor getValueProcessor() {
|
||||
return new OracleValueProcessor();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ai.chat2db.plugin.oracle.value;
|
||||
|
||||
import ai.chat2db.plugin.oracle.value.factory.OracleValueProcessorFactory;
|
||||
import ai.chat2db.spi.jdbc.DefaultValueProcessor;
|
||||
import ai.chat2db.spi.model.JDBCDataValue;
|
||||
import ai.chat2db.spi.model.SQLDataValue;
|
||||
@ -13,18 +14,19 @@ public class OracleValueProcessor extends DefaultValueProcessor {
|
||||
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return super.convertSQLValueByType(dataValue);
|
||||
return OracleValueProcessorFactory.getValueProcessor(dataValue.getDateTypeName()).convertSQLValueByType(dataValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
return super.convertJDBCValueByType(dataValue);
|
||||
String type = dataValue.getType();
|
||||
return OracleValueProcessorFactory.getValueProcessor(dataValue.getType()).convertJDBCValueByType(dataValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||
return super.convertJDBCValueStrByType(dataValue);
|
||||
return OracleValueProcessorFactory.getValueProcessor(dataValue.getType()).convertJDBCValueStrByType(dataValue);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,47 @@
|
||||
package ai.chat2db.plugin.oracle.value.factory;
|
||||
|
||||
import ai.chat2db.plugin.oracle.type.OracleColumnTypeEnum;
|
||||
import ai.chat2db.plugin.oracle.value.sub.*;
|
||||
import ai.chat2db.spi.jdbc.DefaultValueProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author: zgq
|
||||
* @date: 2024年06月03日 23:21
|
||||
*/
|
||||
*/ // TODO: 1.空间数据类型 2.XML数据类型 3.动态类型数据 4.ANSI、DB2 和 SQL/DS 数据
|
||||
public class OracleValueProcessorFactory {
|
||||
|
||||
private static final Map<String, DefaultValueProcessor> PROCESSOR_MAP;
|
||||
|
||||
static {
|
||||
OracleClobProcessor oracleClobProcessor = new OracleClobProcessor();
|
||||
OracleTimeStampProcessor oracleTimeStampProcessor = new OracleTimeStampProcessor();
|
||||
PROCESSOR_MAP = Map.ofEntries(
|
||||
//clob
|
||||
Map.entry(OracleColumnTypeEnum.CLOB.name(), oracleClobProcessor),
|
||||
Map.entry(OracleColumnTypeEnum.NCLOB.name(), oracleClobProcessor),
|
||||
Map.entry(OracleColumnTypeEnum.LONG.name(), oracleClobProcessor),
|
||||
//date
|
||||
Map.entry(OracleColumnTypeEnum.DATE.name(), new OracleDateProcessor()),
|
||||
//timestamp
|
||||
Map.entry(OracleColumnTypeEnum.TIMESTAMP.name(), oracleTimeStampProcessor),
|
||||
Map.entry(OracleColumnTypeEnum.TIMESTAMP_WITH_LOCAL_TIME_ZONE.getColumnType().getTypeName(), oracleTimeStampProcessor),
|
||||
Map.entry(OracleColumnTypeEnum.TIMESTAMP_WITH_TIME_ZONE.getColumnType().getTypeName(), new OracleTimeStampTZProcessor()),
|
||||
//INTERVAL
|
||||
Map.entry("INTERVALDS", new OracleIntervalDSProcessor()),
|
||||
Map.entry("INTERVALYM", new OracleIntervalYMProcessor()),
|
||||
//number
|
||||
Map.entry(OracleColumnTypeEnum.NUMBER.name(), new OracleNumberProcessor()),
|
||||
//blob
|
||||
Map.entry(OracleColumnTypeEnum.BLOB.name(), new OracleBlobProcessor())
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public static DefaultValueProcessor getValueProcessor(String type) {
|
||||
DefaultValueProcessor processor = PROCESSOR_MAP.get(type);
|
||||
return processor == null ? new DefaultValueProcessor() : processor;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package ai.chat2db.plugin.oracle.value.sub;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author: zgq
|
||||
* @date: 2024年06月05日 20:06
|
||||
*/
|
||||
@Slf4j
|
||||
public class OracleBlobProcessor extends DefaultValueProcessor {
|
||||
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return dataValue.getBlobHexString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
try {
|
||||
return dataValue.getBlobString(true);
|
||||
} 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 dataValue.getBlobHexString();
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
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月04日 17:06
|
||||
*/
|
||||
public class OracleClobProcessor extends DefaultValueProcessor {
|
||||
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return wrap(dataValue.getValue());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
return dataValue.getClobString(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||
return wrap(dataValue.getClobString(false));
|
||||
}
|
||||
|
||||
private String wrap(String value) {
|
||||
return EasyStringUtils.escapeAndQuoteString(value);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
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;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* @author: zgq
|
||||
* @date: 2024年06月04日 16:33
|
||||
*/
|
||||
public class OracleDateProcessor extends DefaultValueProcessor {
|
||||
|
||||
/**
|
||||
* @param dataValue
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return wrap(dataValue.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataValue
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
Timestamp timestamp = dataValue.getTimestamp();
|
||||
LocalDateTime localDateTime = timestamp.toLocalDateTime();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
String formattedDateTime = localDateTime.format(formatter);
|
||||
if (formattedDateTime.endsWith("00:00:00")) {
|
||||
formattedDateTime = formattedDateTime.substring(0, formattedDateTime.length() - 9);
|
||||
}
|
||||
return formattedDateTime;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataValue
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||
return wrap(convertJDBCValueByType(dataValue));
|
||||
}
|
||||
|
||||
private String wrap(String value) {
|
||||
return String.format(OracleDmlValueTemplate.DATE_TEMPLATE, value);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
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月05日 18:56
|
||||
*/
|
||||
public class OracleIntervalDSProcessor extends DefaultValueProcessor {
|
||||
|
||||
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return wrap(dataValue.getValue(), dataValue.getPrecision(), dataValue.getScale());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
return super.convertJDBCValueByType(dataValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
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月05日 18:58
|
||||
*/
|
||||
public class OracleIntervalYMProcessor extends DefaultValueProcessor {
|
||||
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return wrap(dataValue.getValue(), dataValue.getPrecision());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
return super.convertJDBCValueByType(dataValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||
return wrap(convertJDBCValueByType(dataValue), dataValue.getPrecision());
|
||||
}
|
||||
|
||||
public String wrap(String value, int precision) {
|
||||
return String.format(OracleDmlValueTemplate.INTEGER_YEAR_TO_MONTH_TEMPLATE, value, precision);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package ai.chat2db.plugin.oracle.value.sub;
|
||||
|
||||
import ai.chat2db.spi.jdbc.DefaultValueProcessor;
|
||||
import ai.chat2db.spi.model.JDBCDataValue;
|
||||
import ai.chat2db.spi.model.SQLDataValue;
|
||||
|
||||
/**
|
||||
* 功能描述
|
||||
*
|
||||
* @author: zgq
|
||||
* @date: 2024年06月05日 20:00
|
||||
*/
|
||||
public class OracleNumberProcessor extends DefaultValueProcessor {
|
||||
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return super.convertSQLValueByType(dataValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
return dataValue.getBigDecimalString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||
return convertJDBCValueByType(dataValue);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
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;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* @author: zgq
|
||||
* @date: 2024年06月05日 16:20
|
||||
*/
|
||||
public class OracleTimeStampProcessor extends DefaultValueProcessor {
|
||||
|
||||
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return wrap(dataValue.getValue(), dataValue.getScale());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
// TODO: datagrip对timestampLTZ的处理是不受时区影响的,但其实这个字段就是为了可以协同时区问题的,有待商讨
|
||||
Timestamp timestamp = dataValue.getTimestamp();
|
||||
int scale = dataValue.getScale();
|
||||
LocalDateTime localDateTime = timestamp.toLocalDateTime();
|
||||
StringBuilder templateBuilder = new StringBuilder("yyyy-MM-dd HH:mm:ss");
|
||||
if (scale != 0) {
|
||||
templateBuilder.append(".");
|
||||
templateBuilder.append("S".repeat(scale));
|
||||
}
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(templateBuilder.toString());
|
||||
return localDateTime.format(formatter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
|
||||
return wrap(convertJDBCValueByType(dataValue), dataValue.getScale());
|
||||
}
|
||||
|
||||
private String wrap(String value, int scale) {
|
||||
if (scale == 0) {
|
||||
return String.format(OracleDmlValueTemplate.DATE_TEMPLATE, value);
|
||||
}
|
||||
return String.format(OracleDmlValueTemplate.TIMESTAMP_TEMPLATE, value, scale);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
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月05日 17:32
|
||||
*/
|
||||
public class OracleTimeStampTZProcessor extends DefaultValueProcessor {
|
||||
|
||||
@Override
|
||||
public String convertSQLValueByType(SQLDataValue dataValue) {
|
||||
return wrap(dataValue.getValue(), dataValue.getScale());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String convertJDBCValueByType(JDBCDataValue dataValue) {
|
||||
// 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(convertJDBCValueByType(dataValue), dataValue.getScale());
|
||||
}
|
||||
|
||||
private String wrap(String value, int scale) {
|
||||
if (scale == 0) {
|
||||
return String.format(OracleDmlValueTemplate.TIMESTAMP_TZ_WITHOUT_NANOS_TEMPLATE, value);
|
||||
}
|
||||
return String.format(OracleDmlValueTemplate.TIMESTAMP_TZ_TEMPLATE, value, scale);
|
||||
}
|
||||
}
|
@ -6,5 +6,13 @@ package ai.chat2db.plugin.oracle.value.template;
|
||||
*/
|
||||
public class OracleDmlValueTemplate {
|
||||
|
||||
public static final String DATE_TEMPLATE = "TO_DATE('%s', 'SYYYY-MM-DD HH24:MI:SS')";
|
||||
public static final String DATE_TEMPLATE = "TO_DATE('%s', 'YYYY-MM-DD HH24:MI:SS')";
|
||||
|
||||
public static final String TIMESTAMP_TEMPLATE = "TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS.FF%d')";
|
||||
|
||||
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 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)";
|
||||
}
|
||||
|
Reference in New Issue
Block a user