-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(chat2db-mysql): optimize valueProcessor
- Loading branch information
Showing
12 changed files
with
465 additions
and
14 deletions.
There are no files selected for viewing
6 changes: 6 additions & 0 deletions
6
...t2db-plugins/chat2db-mariadb/src/main/java/ai/chat2db/plugin/mariadb/MariaDBMetaData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,15 @@ | ||
package ai.chat2db.plugin.mariadb; | ||
|
||
|
||
import ai.chat2db.plugin.mariadb.value.MariaDBValueProcessor; | ||
import ai.chat2db.plugin.mysql.MysqlMetaData; | ||
import ai.chat2db.spi.MetaData; | ||
import ai.chat2db.spi.ValueProcessor; | ||
|
||
public class MariaDBMetaData extends MysqlMetaData implements MetaData { | ||
|
||
@Override | ||
public ValueProcessor getValueProcessor() { | ||
return new MariaDBValueProcessor(); | ||
} | ||
} |
109 changes: 109 additions & 0 deletions
109
.../chat2db-mariadb/src/main/java/ai/chat2db/plugin/mariadb/value/MariaDBValueProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package ai.chat2db.plugin.mariadb.value; | ||
|
||
import ai.chat2db.plugin.mariadb.value.factory.MariaDBValueProcessorFactory; | ||
import ai.chat2db.plugin.mysql.value.MysqlValueProcessor; | ||
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 org.apache.commons.lang3.StringUtils; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.Objects; | ||
|
||
/** | ||
* @author: zgq | ||
* @date: 2024年05月24日 21:02 | ||
* <br> | ||
* TODO: | ||
* attribute: [zerofill] example tinyint[5] zerofill 34->00034 | ||
*/ | ||
public class MariaDBValueProcessor extends MysqlValueProcessor { | ||
|
||
|
||
private static final Logger log = LoggerFactory.getLogger(MariaDBValueProcessor.class); | ||
|
||
@Override | ||
public String getJdbcValue(JDBCDataValue dataValue) { | ||
Object value = dataValue.getObject(); | ||
if (Objects.isNull(value)) { | ||
// example: [date]->0000-00-00 | ||
String stringValue = dataValue.getStringValue(); | ||
if (Objects.nonNull(stringValue)) { | ||
return stringValue; | ||
} | ||
return null; | ||
} | ||
if (value instanceof String emptyStr) { | ||
if (StringUtils.isBlank(emptyStr)) { | ||
return emptyStr; | ||
} | ||
} | ||
return convertJDBCValueByType(dataValue); | ||
} | ||
|
||
|
||
@Override | ||
public String getJdbcSqlValueString(JDBCDataValue dataValue) { | ||
Object value = dataValue.getObject(); | ||
if (Objects.isNull(value)) { | ||
// example: [date]->0000-00-00 | ||
String stringValue = dataValue.getStringValue(); | ||
if (Objects.nonNull(stringValue)) { | ||
return EasyStringUtils.escapeAndQuoteString(stringValue); | ||
} | ||
return "NULL"; | ||
} | ||
if (value instanceof String stringValue) { | ||
if (StringUtils.isBlank(stringValue)) { | ||
return EasyStringUtils.quoteString(stringValue); | ||
} | ||
} | ||
return convertJDBCValueStrByType(dataValue); | ||
} | ||
|
||
@Override | ||
public String convertSQLValueByType(SQLDataValue dataValue) { | ||
try { | ||
DefaultValueProcessor valueProcessor = MariaDBValueProcessorFactory.getValueProcessor(dataValue.getDateTypeName()); | ||
if (Objects.isNull(valueProcessor)) { | ||
return super.convertSQLValueByType(dataValue); | ||
} | ||
return valueProcessor.convertSQLValueByType(dataValue); | ||
} catch (Exception e) { | ||
log.warn("convertSQLValueByType error", e); | ||
return super.convertSQLValueByType(dataValue); | ||
} | ||
} | ||
|
||
@Override | ||
public String convertJDBCValueByType(JDBCDataValue dataValue) { | ||
String type = dataValue.getType(); | ||
try { | ||
DefaultValueProcessor valueProcessor = MariaDBValueProcessorFactory.getValueProcessor(type); | ||
if (Objects.isNull(valueProcessor)) { | ||
return super.convertJDBCValueByType(dataValue); | ||
} | ||
return valueProcessor.convertJDBCValueByType(dataValue); | ||
} catch (Exception e) { | ||
log.warn("convertJDBCValueByType error", e); | ||
return super.convertJDBCValueByType(dataValue); | ||
} | ||
} | ||
|
||
@Override | ||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { | ||
String type = dataValue.getType(); | ||
try { | ||
DefaultValueProcessor valueProcessor = MariaDBValueProcessorFactory.getValueProcessor(type); | ||
if (Objects.isNull(valueProcessor)) { | ||
return super.convertJDBCValueByType(dataValue); | ||
} | ||
return valueProcessor.convertJDBCValueStrByType(dataValue); | ||
} catch (Exception e) { | ||
log.warn("convertJDBCValueStrByType error", e); | ||
return super.convertJDBCValueStrByType(dataValue); | ||
} | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
...b/src/main/java/ai/chat2db/plugin/mariadb/value/factory/MariaDBValueProcessorFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package ai.chat2db.plugin.mariadb.value.factory; | ||
|
||
import ai.chat2db.plugin.mariadb.value.sub.MariaDBBitProcessor; | ||
import ai.chat2db.plugin.mariadb.value.sub.MariaDBGeometryProcessor; | ||
import ai.chat2db.plugin.mariadb.value.sub.MariaDBTimestampProcessor; | ||
import ai.chat2db.plugin.mariadb.value.sub.MariaDBYearProcessor; | ||
import ai.chat2db.plugin.mysql.type.MysqlColumnTypeEnum; | ||
import ai.chat2db.plugin.mysql.value.sub.*; | ||
import ai.chat2db.spi.jdbc.DefaultValueProcessor; | ||
|
||
import java.util.Map; | ||
|
||
/** | ||
* @author: zgq | ||
* @date: 2024年06月03日 23:16 | ||
*/ | ||
public class MariaDBValueProcessorFactory { | ||
|
||
private static final Map<String, DefaultValueProcessor> PROCESSOR_MAP; | ||
|
||
static { | ||
MariaDBGeometryProcessor mariaDBGeometryProcessor = new MariaDBGeometryProcessor(); | ||
MysqlVarBinaryProcessor mysqlVarBinaryProcessor = new MysqlVarBinaryProcessor(); | ||
MariaDBTimestampProcessor mariaDBTimestampProcessor = new MariaDBTimestampProcessor(); | ||
MysqlTextProcessor mysqlTextProcessor = new MysqlTextProcessor(); | ||
PROCESSOR_MAP = Map.ofEntries( | ||
//text | ||
Map.entry(MysqlColumnTypeEnum.TEXT.name(), mysqlTextProcessor), | ||
Map.entry(MysqlColumnTypeEnum.TINYTEXT.name(), mysqlTextProcessor), | ||
Map.entry(MysqlColumnTypeEnum.MEDIUMTEXT.name(), mysqlTextProcessor), | ||
Map.entry(MysqlColumnTypeEnum.LONGTEXT.name(), mysqlTextProcessor), | ||
// geometry | ||
Map.entry(MysqlColumnTypeEnum.GEOMETRY.name(), mariaDBGeometryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.POINT.name(), mariaDBGeometryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.LINESTRING.name(), mariaDBGeometryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.POLYGON.name(), mariaDBGeometryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.MULTIPOINT.name(), mariaDBGeometryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.MULTILINESTRING.name(), mariaDBGeometryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.MULTIPOLYGON.name(), mariaDBGeometryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.GEOMETRYCOLLECTION.name(), mariaDBGeometryProcessor), | ||
// binary | ||
Map.entry(MysqlColumnTypeEnum.VARBINARY.name(), mysqlVarBinaryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.BLOB.name(), mysqlVarBinaryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.LONGBLOB.name(), mysqlVarBinaryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.TINYBLOB.name(), mysqlVarBinaryProcessor), | ||
Map.entry(MysqlColumnTypeEnum.MEDIUMBLOB.name(), mysqlVarBinaryProcessor), | ||
// timestamp | ||
Map.entry(MysqlColumnTypeEnum.TIMESTAMP.name(), mariaDBTimestampProcessor), | ||
Map.entry(MysqlColumnTypeEnum.DATETIME.name(), mariaDBTimestampProcessor), | ||
//others | ||
Map.entry(MysqlColumnTypeEnum.YEAR.name(), new MariaDBYearProcessor()), | ||
Map.entry(MysqlColumnTypeEnum.BIT.name(), new MariaDBBitProcessor()), | ||
Map.entry(MysqlColumnTypeEnum.DECIMAL.name(), new MysqlDecimalProcessor()), | ||
Map.entry(MysqlColumnTypeEnum.BINARY.name(), new MysqlBinaryProcessor()) | ||
); | ||
} | ||
|
||
public static DefaultValueProcessor getValueProcessor(String type) { | ||
return PROCESSOR_MAP.get(type); | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
...hat2db-mariadb/src/main/java/ai/chat2db/plugin/mariadb/value/sub/MariaDBBitProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package ai.chat2db.plugin.mariadb.value.sub; | ||
|
||
import ai.chat2db.plugin.mysql.value.template.MysqlDmlValueTemplate; | ||
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 org.apache.commons.lang3.StringUtils; | ||
|
||
import java.sql.SQLException; | ||
import java.util.Objects; | ||
import java.util.function.Function; | ||
|
||
/** | ||
* @author: zgq | ||
* @date: 2024年06月01日 13:08 | ||
*/ | ||
public class MariaDBBitProcessor extends DefaultValueProcessor { | ||
|
||
@Override | ||
public String convertSQLValueByType(SQLDataValue dataValue) { | ||
return getString(dataValue.getValue()); | ||
} | ||
|
||
|
||
@Override | ||
public String convertJDBCValueByType(JDBCDataValue dataValue) { | ||
return getValue(dataValue, s -> s); | ||
} | ||
|
||
|
||
@Override | ||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { | ||
return getValue(dataValue, this::wrap); | ||
} | ||
|
||
private String getValue(JDBCDataValue dataValue, Function<String, String> function) { | ||
try { | ||
//mariadb tinyint(1) | ||
if ((dataValue.getMetaData().getColumnType(dataValue.getColumnIndex()) == -7)) { | ||
return String.valueOf(dataValue.getInt()); | ||
} | ||
} catch (SQLException e) { | ||
super.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()); | ||
} | ||
} | ||
//bit(m) m: 2~64 | ||
return function.apply(EasyStringUtils.getBitString(bytes, precision)); | ||
} | ||
|
||
public String getString(String value) { | ||
|
||
if (Objects.equals("true", value.toLowerCase())) { | ||
return "1"; | ||
} | ||
if (Objects.equals("false", value.toLowerCase())) { | ||
return "0"; | ||
} | ||
if (StringUtils.isBlank(value)) { | ||
return "NULL"; | ||
} | ||
return MysqlDmlValueTemplate.wrapBit(value); | ||
} | ||
|
||
private String wrap(String value) { | ||
return MysqlDmlValueTemplate.wrapBit(value); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
...b-mariadb/src/main/java/ai/chat2db/plugin/mariadb/value/sub/MariaDBGeometryProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package ai.chat2db.plugin.mariadb.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 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; | ||
|
||
/** | ||
* @author: zgq | ||
* @date: 2024年06月01日 12:42 | ||
*/ | ||
public class MariaDBGeometryProcessor extends DefaultValueProcessor { | ||
|
||
|
||
private static final Logger log = LoggerFactory.getLogger(MariaDBGeometryProcessor.class); | ||
|
||
@Override | ||
public String convertSQLValueByType(SQLDataValue dataValue) { | ||
return MysqlDmlValueTemplate.wrapGeometry(dataValue.getValue()); | ||
} | ||
|
||
@Override | ||
public String convertJDBCValueByType(JDBCDataValue dataValue) { | ||
try { | ||
Geometry dbGeometry = null; | ||
byte[] geometryAsBytes = dataValue.getBytes(); | ||
if (geometryAsBytes != null) { | ||
if (geometryAsBytes.length < 5) { | ||
throw new Exception("Invalid geometry inputStream - less than five bytes"); | ||
} | ||
|
||
//first four bytes of the geometry are the SRID, | ||
//followed by the actual WKB. Determine the SRID | ||
//here | ||
byte[] sridBytes = new byte[4]; | ||
System.arraycopy(geometryAsBytes, 0, sridBytes, 0, 4); | ||
boolean bigEndian = (geometryAsBytes[4] == 0x00); | ||
|
||
int srid = 0; | ||
if (bigEndian) { | ||
for (int i = 0; i < sridBytes.length; i++) { | ||
srid = (srid << 8) + (sridBytes[i] & 0xff); | ||
} | ||
} else { | ||
for (int i = 0; i < sridBytes.length; i++) { | ||
srid += (sridBytes[i] & 0xff) << (8 * i); | ||
} | ||
} | ||
|
||
//use the JTS WKBReader for WKB parsing | ||
WKBReader wkbReader = new WKBReader(); | ||
|
||
//copy the byte array, removing the first four | ||
//SRID bytes | ||
byte[] wkb = new byte[geometryAsBytes.length - 4]; | ||
System.arraycopy(geometryAsBytes, 4, wkb, 0, wkb.length); | ||
dbGeometry = wkbReader.read(wkb); | ||
dbGeometry.setSRID(srid); | ||
} | ||
return dbGeometry != null ? dbGeometry.toString() : null; | ||
} catch (Exception e) { | ||
log.warn("Error converting database geometry", e); | ||
return dataValue.getStringValue(); | ||
} | ||
} | ||
|
||
|
||
@Override | ||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { | ||
return MysqlDmlValueTemplate.wrapGeometry(convertJDBCValueByType(dataValue)); | ||
} | ||
|
||
} |
30 changes: 30 additions & 0 deletions
30
...-mariadb/src/main/java/ai/chat2db/plugin/mariadb/value/sub/MariaDBTimestampProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package ai.chat2db.plugin.mariadb.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月01日 18:26 | ||
*/ | ||
public class MariaDBTimestampProcessor extends DefaultValueProcessor { | ||
|
||
@Override | ||
public String convertSQLValueByType(SQLDataValue dataValue) { | ||
return EasyStringUtils.quoteString(dataValue.getValue()); | ||
} | ||
|
||
|
||
@Override | ||
public String convertJDBCValueByType(JDBCDataValue dataValue) { | ||
return dataValue.getStringValue(); | ||
} | ||
|
||
|
||
@Override | ||
public String convertJDBCValueStrByType(JDBCDataValue dataValue) { | ||
return EasyStringUtils.quoteString(dataValue.getStringValue()); | ||
} | ||
} |
Oops, something went wrong.