From fc5c76a8b91a07cdca8a31e94b807600050d1c53 Mon Sep 17 00:00:00 2001 From: Sylphy Date: Wed, 16 Apr 2025 13:24:33 +0800 Subject: [PATCH] refactor(postgresql): Refactoring the PostgreSQL sequence code --- .../plugin/postgresql/PostgreSQLMetaData.java | 28 +++++++------- .../builder/PostgreSQLSqlBuilder.java | 37 ++++++++++--------- .../plugin/postgresql/consts/SQLConst.java | 2 +- .../tools/base/constant/SymbolConstant.java | 4 ++ .../java/ai/chat2db/spi/model/Sequence.java | 3 +- .../java/ai/chat2db/spi/sql/SQLExecutor.java | 3 +- 6 files changed, 41 insertions(+), 36 deletions(-) diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java index 79feb7e8..33506b10 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java @@ -23,8 +23,6 @@ import java.util.stream.Collectors; import static ai.chat2db.plugin.postgresql.consts.SequenceCommonConst.*; import static ai.chat2db.plugin.postgresql.consts.SQLConst.*; import static ai.chat2db.server.tools.base.constant.SymbolConstant.*; -import static ai.chat2db.server.tools.base.constant.SymbolConstant.DOT; -import static ai.chat2db.server.tools.base.constant.SymbolConstant.SEMICOLON; import static ai.chat2db.spi.util.SortUtils.sortDatabase; public class PostgreSQLMetaData extends DefaultMetaService implements MetaData { @@ -324,8 +322,9 @@ public class PostgreSQLMetaData extends DefaultMetaService implements MetaData { public String sequenceDDL(Connection connection, @NotEmpty String databaseName, String schemaName, @NotEmpty String sequenceName) { DatabaseMetaData metaData = connection.getMetaData(); - Double databaseProductVersion = Double.valueOf(metaData.getDatabaseProductVersion()); - return SQLExecutor.getInstance().preExecute(connection, EXPORT_SEQUENCE_DDL_SQL, resultSet -> { + double databaseProductVersion = Double.parseDouble(metaData.getDatabaseProductVersion()); + String[] args = new String[]{sequenceName, schemaName}; + return SQLExecutor.getInstance().preExecute(connection, EXPORT_SEQUENCE_DDL_SQL, args, resultSet -> { StringBuilder stringBuilder = new StringBuilder(); if (resultSet.next()) { String nspname = resultSet.getString("nspname"); @@ -346,10 +345,10 @@ public class PostgreSQLMetaData extends DefaultMetaService implements MetaData { default -> typname = "INTEGER"; } - stringBuilder.append(CREATE_SEQUENCE).append(nspname).append(DOT).append(relname).append(NEW_LINE); + stringBuilder.append(CREATE_SEQUENCE).append(getMetaDataName(nspname, relname)).append(NEW_LINE); if (databaseProductVersion >= 10.0) { - stringBuilder.append(AS).append(typname).append(NEW_LINE); + stringBuilder.append(AS).append(getMetaDataName(typname)).append(NEW_LINE); } Optional.ofNullable(seqstart).ifPresent(v -> stringBuilder.append(START_WITH).append(v).append(NEW_LINE)); @@ -371,22 +370,22 @@ public class PostgreSQLMetaData extends DefaultMetaService implements MetaData { stringBuilder.append(SEMICOLON).append(BLANK_LINE); Optional.ofNullable(comment).ifPresent(v -> stringBuilder.append(COMMENT_ON_SEQUENCE) - .append(nspname).append(DOT).append(relname) - .append(IS).append(SQUOT).append(comment).append(SQUOT).append(SEMICOLON).append(BLANK_LINE)); + .append(getMetaDataName(nspname, relname)) + .append(IS).append(SQUOT).append(v).append(SQUOT).append(SEMICOLON).append(BLANK_LINE)); Optional.ofNullable(rolname).ifPresent(v -> stringBuilder.append(ALTER_SEQUENCE) - .append(nspname).append(DOT).append(relname) - .append(OWNED_BY).append(v).append(SEMICOLON)); + .append(getMetaDataName(nspname, relname)) + .append(OWNED_BY).append(getMetaDataName(v)).append(SEMICOLON)); } return stringBuilder.toString(); - }, - sequenceName, schemaName); + }); } @Override public List sequences(Connection connection, String databaseName, String schemaName) { List simpleSequences = new ArrayList<>(); - return SQLExecutor.getInstance().preExecute(connection, EXPORT_SEQUENCES_SQL, resultSet -> { + String[] args = new String[]{schemaName}; + return SQLExecutor.getInstance().preExecute(connection, EXPORT_SEQUENCES_SQL, args, resultSet -> { while (resultSet.next()) { String relname = resultSet.getString("relname"); String comment = resultSet.getString("comment"); @@ -396,7 +395,6 @@ public class PostgreSQLMetaData extends DefaultMetaService implements MetaData { .build()); } return simpleSequences; - }, - schemaName); + }); } } diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/builder/PostgreSQLSqlBuilder.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/builder/PostgreSQLSqlBuilder.java index 257b56a7..3c181350 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/builder/PostgreSQLSqlBuilder.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/builder/PostgreSQLSqlBuilder.java @@ -11,16 +11,14 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import static ai.chat2db.plugin.postgresql.consts.SequenceCommonConst.*; -import static ai.chat2db.server.tools.base.constant.SymbolConstant.BLANK_LINE; -import static ai.chat2db.server.tools.base.constant.SymbolConstant.SQUOT; -import static ai.chat2db.server.tools.base.constant.SymbolConstant.DOT; -import static ai.chat2db.server.tools.base.constant.SymbolConstant.SEMICOLON; +import static ai.chat2db.server.tools.base.constant.SymbolConstant.*; public class PostgreSQLSqlBuilder extends DefaultSqlBuilder { @@ -247,7 +245,7 @@ public class PostgreSQLSqlBuilder extends DefaultSqlBuilder { Double databaseProductVersion = Double.valueOf(Chat2DBContext.getConnection().getMetaData().getDatabaseProductVersion()); StringBuilder sqlBuilder = new StringBuilder(); - sqlBuilder.append(CREATE_SEQUENCE).append(sequence.getNspname()).append(DOT).append(sequence.getRelname()).append("\n "); + sqlBuilder.append(CREATE_SEQUENCE).append(getMetaDataName(sequence.getNspname(), sequence.getRelname())).append("\n "); if (databaseProductVersion >= 10.0) { sqlBuilder.append(AS).append(sequence.getTypname()).append("\n "); } @@ -270,12 +268,12 @@ public class PostgreSQLSqlBuilder extends DefaultSqlBuilder { sqlBuilder.append(SEMICOLON).append("\n ").append("\n "); Optional.ofNullable(sequence.getComment()).ifPresent(v -> sqlBuilder.append(COMMENT_ON_SEQUENCE) - .append(sequence.getNspname()).append(DOT).append(sequence.getRelname()) - .append(IS).append(sequence.getComment()).append(SEMICOLON).append("\n ").append("\n ")); + .append(getMetaDataName(sequence.getNspname(), sequence.getRelname())) + .append(IS).append(SQUOT).append(v).append(SQUOT).append(SEMICOLON).append("\n ").append("\n ")); Optional.ofNullable(sequence.getRolname()).ifPresent(v -> sqlBuilder.append(ALTER_SEQUENCE) - .append(sequence.getNspname()).append(DOT).append(sequence.getRelname()) - .append(OWNED_BY).append(v).append(SEMICOLON)); + .append(getMetaDataName(sequence.getNspname(), sequence.getRelname())) + .append(OWNED_BY).append(getMetaDataName(v)).append(SEMICOLON)); return sqlBuilder.toString(); } @@ -283,19 +281,19 @@ public class PostgreSQLSqlBuilder extends DefaultSqlBuilder { public String buildModifySequenceSql(Sequence oldSequence, Sequence newSequence) { StringBuilder sqlBuilder = new StringBuilder(); if (!StringUtils.equalsIgnoreCase(oldSequence.getRelname(), newSequence.getRelname())) { - sqlBuilder.append(ALTER_SEQUENCE).append(oldSequence.getNspname()).append(DOT).append(oldSequence.getRelname()).append(RENAME_TO).append(newSequence.getRelname()).append(SEMICOLON).append(BLANK_LINE); + sqlBuilder.append(ALTER_SEQUENCE).append(getMetaDataName(oldSequence.getNspname(), oldSequence.getRelname())).append(RENAME_TO).append(getMetaDataName(newSequence.getRelname())).append(SEMICOLON).append(BLANK_LINE); } if (!StringUtils.equals(oldSequence.getComment(), newSequence.getComment())) { - sqlBuilder.append(COMMENT_ON_SEQUENCE).append(newSequence.getNspname()).append(DOT).append(newSequence.getRelname()).append(IS).append(SQUOT).append(newSequence.getComment()).append(SQUOT).append(SEMICOLON).append(BLANK_LINE); + sqlBuilder.append(COMMENT_ON_SEQUENCE).append(getMetaDataName(newSequence.getNspname(), newSequence.getRelname())).append(IS).append(SQUOT).append(newSequence.getComment()).append(SQUOT).append(SEMICOLON).append(BLANK_LINE); } if (!StringUtils.equals(oldSequence.getSeqcache(), newSequence.getSeqcache())) { - sqlBuilder.append(ALTER_SEQUENCE).append(newSequence.getNspname()).append(DOT).append(newSequence.getRelname()).append(CACHE).append(newSequence.getSeqcache()).append(SEMICOLON).append(BLANK_LINE); + sqlBuilder.append(ALTER_SEQUENCE).append(getMetaDataName(newSequence.getNspname(), newSequence.getRelname())).append(CACHE).append(getMetaDataName(newSequence.getSeqcache())).append(SEMICOLON).append(BLANK_LINE); } if (BooleanUtil.xor(oldSequence.getSeqcycle(), newSequence.getSeqcycle())) { if (Boolean.TRUE.equals(newSequence.getSeqcycle())) { - sqlBuilder.append(ALTER_SEQUENCE).append(newSequence.getNspname()).append(DOT).append(newSequence.getRelname()).append(CYCLE).append(BLANK_LINE); + sqlBuilder.append(ALTER_SEQUENCE).append(getMetaDataName(newSequence.getNspname(), newSequence.getRelname())).append(CYCLE).append(BLANK_LINE); } else { - sqlBuilder.append(ALTER_SEQUENCE).append(newSequence.getNspname()).append(DOT).append(newSequence.getRelname()).append(NO_CYCLE).append(BLANK_LINE); + sqlBuilder.append(ALTER_SEQUENCE).append(getMetaDataName(newSequence.getNspname(), newSequence.getRelname())).append(NO_CYCLE).append(BLANK_LINE); } } @@ -305,7 +303,7 @@ public class PostgreSQLSqlBuilder extends DefaultSqlBuilder { !StringUtils.equals(oldSequence.getSeqmin(), newSequence.getSeqmin())) { sqlBuilder.append(ALTER_SEQUENCE); if (!StringUtils.equals(oldSequence.getSeqstart(), newSequence.getSeqstart())) { - sqlBuilder.append(newSequence.getNspname()).append(DOT).append(newSequence.getRelname()).append(RESTART_WITH).append(newSequence.getSeqstart()); + sqlBuilder.append(getMetaDataName(newSequence.getNspname(), newSequence.getRelname())).append(RESTART_WITH).append(newSequence.getSeqstart()); } if (!StringUtils.equals(oldSequence.getSeqincrement(), newSequence.getSeqincrement())) { sqlBuilder.append(INCREMENT_BY).append(newSequence.getSeqincrement()); @@ -320,11 +318,16 @@ public class PostgreSQLSqlBuilder extends DefaultSqlBuilder { } if (!StringUtils.equals(oldSequence.getTypname(), newSequence.getTypname())) { - sqlBuilder.append(ALTER_SEQUENCE).append(newSequence.getNspname()).append(DOT).append(newSequence.getRelname()).append(AS).append(newSequence.getTypname()).append(SEMICOLON).append(BLANK_LINE); + sqlBuilder.append(ALTER_SEQUENCE).append(getMetaDataName(newSequence.getNspname(), newSequence.getRelname())).append(AS).append(newSequence.getTypname()).append(SEMICOLON).append(BLANK_LINE); } if (!StringUtils.equals(oldSequence.getRolname(), newSequence.getRolname())) { - sqlBuilder.append(ALTER_SEQUENCE).append(newSequence.getNspname()).append(DOT).append(newSequence.getRelname()).append(OWNER_TO).append(newSequence.getRolname()).append(SEMICOLON).append(BLANK_LINE); + sqlBuilder.append(ALTER_SEQUENCE).append(getMetaDataName(newSequence.getNspname(), newSequence.getRelname())).append(OWNER_TO).append(getMetaDataName(newSequence.getRolname())).append(SEMICOLON).append(BLANK_LINE); } return sqlBuilder.toString(); } + + private String getMetaDataName(String... names) { + return Arrays.stream(names).filter(StringUtils::isNotBlank).map(name -> DOUBLE_SQUOT + name + DOUBLE_SQUOT).collect(Collectors.joining(DOT)); + } + } diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/consts/SQLConst.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/consts/SQLConst.java index b49ed538..20d0afa1 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/consts/SQLConst.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/consts/SQLConst.java @@ -659,7 +659,7 @@ public class SQLConst { JOIN pg_namespace n ON n.oid = c.relnamespace JOIN - pg_authid a ON a.oid = c.relowner + pg_roles a ON a.oid = c.relowner JOIN pg_type t ON s.seqtypid = t.oid WHERE c.relname = ? diff --git a/chat2db-server/chat2db-server-tools/chat2db-server-tools-base/src/main/java/ai/chat2db/server/tools/base/constant/SymbolConstant.java b/chat2db-server/chat2db-server-tools/chat2db-server-tools-base/src/main/java/ai/chat2db/server/tools/base/constant/SymbolConstant.java index a2c4617e..60349175 100644 --- a/chat2db-server/chat2db-server-tools/chat2db-server-tools-base/src/main/java/ai/chat2db/server/tools/base/constant/SymbolConstant.java +++ b/chat2db-server/chat2db-server-tools/chat2db-server-tools-base/src/main/java/ai/chat2db/server/tools/base/constant/SymbolConstant.java @@ -26,6 +26,10 @@ public class SymbolConstant { * apostrophe"'" */ public static final String SQUOT = "'"; + /** + * apostrophe""" + */ + public static final String DOUBLE_SQUOT = "\""; /** * empty string "" */ diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/Sequence.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/Sequence.java index ff1f1ca4..570e378e 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/Sequence.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/Sequence.java @@ -16,8 +16,7 @@ import java.io.Serializable; @SuperBuilder @NoArgsConstructor @AllArgsConstructor -public class Sequence implements Serializable { - private static final long serialVersionUID = 1L; +public class Sequence { /** * Schema name */ diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java index 58782041..40408fb1 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java @@ -124,7 +124,8 @@ public class SQLExecutor implements CommandExecutor { } } - public R preExecute(Connection connection, String sql, ResultSetFunction function, String... args) { + public R preExecute(Connection connection, String sql, String[] args, ResultSetFunction function) { + log.info("execute:{}", sql); try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]);