Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ai.chat2db.community.tools.exception.BusinessException;
import ai.chat2db.plugin.mysql.builder.MysqlSqlBuilder;
import ai.chat2db.plugin.mysql.identifier.MysqlIdentifierProcessor;
import ai.chat2db.spi.IDbManager;
import ai.chat2db.spi.DefaultDBManager;
import ai.chat2db.community.domain.api.model.async.AsyncContext;
Expand All @@ -19,10 +20,13 @@
import java.util.Date;

import static cn.hutool.core.date.DatePattern.NORM_DATETIME_PATTERN;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_COPY_TABLE_DATA_TEMPLATE;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_COPY_TABLE_STRUCTURE_TEMPLATE;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_DROP_PROCEDURE_TEMPLATE;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_DROP_TABLE_TEMPLATE;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_DROP_VIEW_TEMPLATE;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_SELECT_DATABASE_TEMPLATE;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_TRUNCATE_TABLE_TEMPLATE;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_SET_FOREIGN_KEY_CHECKS_DISABLED;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_SET_FOREIGN_KEY_CHECKS_ENABLED;
import static ai.chat2db.plugin.mysql.constant.MysqlSqlConstants.SQL_SHOW_CREATE_FUNCTION_TEMPLATE;
Expand Down Expand Up @@ -66,12 +70,12 @@ private void exportFunctions(Connection connection, String databaseName, AsyncCo
}

private void exportFunction(Connection connection, String functionName, AsyncContext asyncContext) throws SQLException {
String sql = String.format(SQL_SHOW_CREATE_FUNCTION_TEMPLATE, functionName);
String sql = String.format(SQL_SHOW_CREATE_FUNCTION_TEMPLATE, format(functionName));
try (PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
asyncContext.write(String.format(FUNCTION_TITLE, functionName));
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append(SQLConstants.DROP_FUNCTION_IF_EXISTS_SQL_PREFIX).append(functionName).append(SQLConstants.SEMICOLON).append(SQLConstants.LINE_SEPARATOR);
sqlBuilder.append(SQLConstants.DROP_FUNCTION_IF_EXISTS_SQL_PREFIX).append(format(functionName)).append(SQLConstants.SEMICOLON).append(SQLConstants.LINE_SEPARATOR);

sqlBuilder.append(DELIMITER_BLOCK_START).append(SQLConstants.LINE_SEPARATOR).append(resultSet.getString(CREATE_FUNCTION_COLUMN))
.append(ROUTINE_DELIMITER)
Expand All @@ -95,7 +99,7 @@ private void exportTables(Connection connection, String databaseName, String sch


public void exportTable(Connection connection, String databaseName, String schemaName, String tableName, AsyncContext asyncContext) throws SQLException {
String sql = String.format(SQL_SHOW_CREATE_TABLE_TEMPLATE, tableName);
String sql = String.format(SQL_SHOW_CREATE_TABLE_TEMPLATE, format(tableName));
asyncContext.info(DateUtil.formatDateTime(new Date()) + EXPORTING_TABLE_MESSAGE + tableName);
try (PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
Expand Down Expand Up @@ -130,7 +134,7 @@ private void exportViews(Connection connection, String databaseName, AsyncContex
}

private void exportView(Connection connection, String viewName, AsyncContext asyncContext) throws SQLException {
String sql = String.format(SQL_SHOW_CREATE_VIEW_TEMPLATE, viewName);
String sql = String.format(SQL_SHOW_CREATE_VIEW_TEMPLATE, format(viewName));
try (PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
asyncContext.write(String.format(VIEW_TITLE, viewName));
Expand All @@ -152,7 +156,7 @@ private void exportProcedures(Connection connection, AsyncContext asyncContext)
}

private void exportProcedure(Connection connection, String procedureName, AsyncContext asyncContext) throws SQLException {
String sql = String.format(SQL_SHOW_CREATE_PROCEDURE_TEMPLATE, procedureName);
String sql = String.format(SQL_SHOW_CREATE_PROCEDURE_TEMPLATE, format(procedureName));
try (PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
asyncContext.write(String.format(PROCEDURE_TITLE, procedureName));
Expand All @@ -177,7 +181,7 @@ private void exportTriggers(Connection connection, AsyncContext asyncContext) th
}

private void exportTrigger(Connection connection, String triggerName, AsyncContext asyncContext) throws SQLException {
String sql = String.format(SQL_SHOW_CREATE_TRIGGER_TEMPLATE, triggerName);
String sql = String.format(SQL_SHOW_CREATE_TRIGGER_TEMPLATE, format(triggerName));
try (PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
asyncContext.write(String.format(TRIGGER_TITLE, triggerName));
Expand Down Expand Up @@ -240,8 +244,23 @@ public String dropTable(Connection connection, String databaseName, String schem
return String.format(SQL_DROP_TABLE_TEMPLATE, format(tableName));
}

@Override
public String truncateTable(Connection connection, String databaseName, String schemaName, String tableName) {
return String.format(SQL_TRUNCATE_TABLE_TEMPLATE, format(tableName));
}

@Override
public void copyTable(Connection connection, String databaseName, String schemaName, String tableName, String newTableName, boolean copyData) {
DefaultSQLExecutor.getInstance().execute(connection, buildCopyTableSql(tableName, newTableName, copyData), resultSet -> null);
}

static String buildCopyTableSql(String tableName, String newTableName, boolean copyData) {
String template = copyData ? SQL_COPY_TABLE_DATA_TEMPLATE : SQL_COPY_TABLE_STRUCTURE_TEMPLATE;
return String.format(template, format(newTableName), format(tableName));
}

public static String format(String tableName) {
return SQLConstants.BACK_QUOTE + tableName + SQLConstants.BACK_QUOTE;
return MysqlIdentifierProcessor.INSTANCE.quoteIdentifierAlways(tableName);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
@Slf4j
public class MysqlMetaData extends DefaultMetaService implements IDbMetaData {

public static final ISQLIdentifierProcessor MYSQL_IDENTIFIER_PROCESSOR = new MysqlIdentifierProcessor();
public static final ISQLIdentifierProcessor MYSQL_IDENTIFIER_PROCESSOR = MysqlIdentifierProcessor.INSTANCE;

@Override
public List<Database> databases(Connection connection) {
Expand All @@ -63,9 +63,9 @@ public List<Database> databases(Connection connection) {

@Override
public List<Table> tables(Connection connection, @NotEmpty String databaseName, String schemaName, String tableName) {
String sql = String.format(TABLES_SQL, databaseName);
String sql = String.format(TABLES_SQL, getSQLIdentifierProcessor().escapeString(databaseName));
if (StringUtils.isNotBlank(tableName)) {
sql += SQL_TABLE_NAME_EQUALS_FILTER + tableName + SQL_SINGLE_QUOTE;
sql += SQL_TABLE_NAME_EQUALS_FILTER + getSQLIdentifierProcessor().escapeString(tableName) + SQL_SINGLE_QUOTE;
}
Map<String, String> collationMap = getCollationMap(connection);
return DefaultSQLExecutor.getInstance().execute(connection, sql, resultSet -> {
Expand Down Expand Up @@ -131,14 +131,14 @@ public String tableDDL(Connection connection, @NotEmpty String databaseName, Str
}

public static String format(String tableName) {
return SQL_METADATA_QUOTE + tableName + SQL_METADATA_QUOTE;
return MysqlIdentifierProcessor.INSTANCE.quoteIdentifierAlways(tableName);
}

@Override
public Function function(Connection connection, @NotEmpty String databaseName, String schemaName,
String functionName) {

String functionInfoSql = String.format(ROUTINES_SQL, FUNCTION, databaseName, functionName);
String functionInfoSql = String.format(ROUTINES_SQL, FUNCTION, getSQLIdentifierProcessor().escapeString(databaseName), getSQLIdentifierProcessor().escapeString(functionName));
Function function = DefaultSQLExecutor.getInstance().execute(connection, functionInfoSql, resultSet -> {
Function f = new Function();
f.setDatabaseName(databaseName);
Expand All @@ -162,7 +162,7 @@ public Function function(Connection connection, @NotEmpty String databaseName, S
@Override
public List<Trigger> triggers(Connection connection, String databaseName, String schemaName) {
List<Trigger> triggers = new ArrayList<>();
String sql = String.format(TRIGGER_SQL_LIST, databaseName);
String sql = String.format(TRIGGER_SQL_LIST, getSQLIdentifierProcessor().escapeString(databaseName));
return DefaultSQLExecutor.getInstance().execute(connection, sql, resultSet -> {
while (resultSet.next()) {
Trigger trigger = new Trigger();
Expand Down Expand Up @@ -208,7 +208,7 @@ public List<Procedure> procedures(Connection connection, String databaseName, St
@Override
public Procedure procedure(Connection connection, @NotEmpty String databaseName, String schemaName,
String procedureName) {
String routinesSql = String.format(ROUTINES_SQL, PROCEDURE, databaseName, procedureName);
String routinesSql = String.format(ROUTINES_SQL, PROCEDURE, getSQLIdentifierProcessor().escapeString(databaseName), getSQLIdentifierProcessor().escapeString(procedureName));
String showCreateProcedureSql = SQL_SHOW_CREATE_PROCEDURE + mysqlQualifiedName(databaseName, procedureName);
Procedure procedure = DefaultSQLExecutor.getInstance().execute(connection, routinesSql, resultSet -> {
Procedure p = new Procedure();
Expand All @@ -230,7 +230,7 @@ public Procedure procedure(Connection connection, @NotEmpty String databaseName,
}
@Override
public List<TableColumn> columns(Connection connection, String databaseName, String schemaName, String tableName) {
String sql = String.format(SELECT_TABLE_COLUMNS, databaseName, tableName);
String sql = String.format(SELECT_TABLE_COLUMNS, getSQLIdentifierProcessor().escapeString(databaseName), getSQLIdentifierProcessor().escapeString(tableName));
List<TableColumn> tableColumns = new ArrayList<>();
return DefaultSQLExecutor.getInstance().execute(connection, sql, resultSet -> {
while (resultSet.next()) {
Expand Down Expand Up @@ -285,7 +285,7 @@ private void setColumnSize(TableColumn column, String columnType) {

@Override
public Table view(Connection connection, String databaseName, String schemaName, String viewName) {
String quoteViewName = MYSQL_IDENTIFIER_PROCESSOR.quoteIdentifier(viewName);
String quoteViewName = MysqlIdentifierProcessor.INSTANCE.quoteIdentifierAlways(viewName);
String sql = String.format(VIEW_DDL_SQL, quoteViewName);
return DefaultSQLExecutor.getInstance().execute(connection, sql, resultSet -> {
Table table = new Table();
Expand All @@ -303,9 +303,9 @@ public Table view(Connection connection, String databaseName, String schemaName,
@Override
public List<TableIndex> indexes(Connection connection, String databaseName, String schemaName, String tableName) {
StringBuilder queryBuf = new StringBuilder(SQL_SHOW_INDEX_FROM);
queryBuf.append(SQL_METADATA_QUOTE).append(tableName).append(SQL_METADATA_QUOTE);
queryBuf.append(MysqlIdentifierProcessor.INSTANCE.quoteIdentifierAlways(tableName));
queryBuf.append(SQL_FROM);
queryBuf.append(SQL_METADATA_QUOTE).append(databaseName).append(SQL_METADATA_QUOTE);
queryBuf.append(MysqlIdentifierProcessor.INSTANCE.quoteIdentifierAlways(databaseName));
return DefaultSQLExecutor.getInstance().execute(connection, queryBuf.toString(), resultSet -> {
LinkedHashMap<String, TableIndex> map = new LinkedHashMap();
while (resultSet.next()) {
Expand Down Expand Up @@ -461,7 +461,7 @@ private <T> List<T> queryTableMetaOptions(String sql, IResultSetFunction<List<T>
@Override
public String getMetaDataName(String... names) {
return Arrays.stream(names).filter(StringUtils::isNotBlank)
.map(name -> SQL_METADATA_QUOTE + name + SQL_METADATA_QUOTE)
.map(MysqlIdentifierProcessor.INSTANCE::quoteIdentifierAlways)
.collect(Collectors.joining(SQL_DOT));
}

Expand Down Expand Up @@ -496,7 +496,7 @@ public ModifyViewConfiguration viewMeta(String databaseName, String schemaName)
StringBuilder sqlBuilder = new StringBuilder(100);
sqlBuilder.append(SQL_CREATE).append(SQL_VIEW_KEYWORD);
if (StringUtils.isNotBlank(databaseName)) {
sqlBuilder.append(SQL_METADATA_QUOTE).append(databaseName).append(SQL_METADATA_QUOTE).append(SQL_DOT);
sqlBuilder.append(MysqlIdentifierProcessor.INSTANCE.quoteIdentifierAlways(databaseName)).append(SQL_DOT);
}
sqlBuilder.append(SQL_METADATA_QUOTE).append(SQL_UNDEFINED).append(SQL_METADATA_QUOTE);
sqlBuilder.append(SQL_AS).append(sql).append(SQL_SEMICOLON);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ai.chat2db.plugin.mysql;

import ai.chat2db.plugin.mysql.converter.MysqlRoutineConverter;
import ai.chat2db.plugin.mysql.identifier.MysqlIdentifierProcessor;
import ai.chat2db.plugin.mysql.model.RoutineParameter;
import ai.chat2db.community.tools.exception.BusinessException;
import ai.chat2db.community.tools.util.I18nUtils;
Expand Down Expand Up @@ -362,11 +363,7 @@ private String mysqlQualifiedName(String databaseName, String routineName) {
}

private String quoteMysqlIdentifier(String name) {
String trimmed = StringUtils.trimToEmpty(name);
if (trimmed.matches("^`(?:``|[^`])+`$")) {
return trimmed;
}
return "`" + trimmed.replace("`", "``") + "`";
return MysqlIdentifierProcessor.INSTANCE.quoteIdentifierAlways(name);
}

private String routineInvocationName(String name) {
Expand Down
Loading
Loading