refactor(postgresql): Refactoring the PostgreSQL sequence code

This commit is contained in:
Sylphy
2025-04-16 13:24:33 +08:00
parent 8c94329e89
commit fc5c76a8b9
6 changed files with 41 additions and 36 deletions

View File

@ -23,8 +23,6 @@ import java.util.stream.Collectors;
import static ai.chat2db.plugin.postgresql.consts.SequenceCommonConst.*; import static ai.chat2db.plugin.postgresql.consts.SequenceCommonConst.*;
import static ai.chat2db.plugin.postgresql.consts.SQLConst.*; 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.*;
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; import static ai.chat2db.spi.util.SortUtils.sortDatabase;
public class PostgreSQLMetaData extends DefaultMetaService implements MetaData { 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, public String sequenceDDL(Connection connection, @NotEmpty String databaseName, String schemaName,
@NotEmpty String sequenceName) { @NotEmpty String sequenceName) {
DatabaseMetaData metaData = connection.getMetaData(); DatabaseMetaData metaData = connection.getMetaData();
Double databaseProductVersion = Double.valueOf(metaData.getDatabaseProductVersion()); double databaseProductVersion = Double.parseDouble(metaData.getDatabaseProductVersion());
return SQLExecutor.getInstance().preExecute(connection, EXPORT_SEQUENCE_DDL_SQL, resultSet -> { String[] args = new String[]{sequenceName, schemaName};
return SQLExecutor.getInstance().preExecute(connection, EXPORT_SEQUENCE_DDL_SQL, args, resultSet -> {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
if (resultSet.next()) { if (resultSet.next()) {
String nspname = resultSet.getString("nspname"); String nspname = resultSet.getString("nspname");
@ -346,10 +345,10 @@ public class PostgreSQLMetaData extends DefaultMetaService implements MetaData {
default -> typname = "INTEGER"; 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) { 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)); 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); stringBuilder.append(SEMICOLON).append(BLANK_LINE);
Optional.ofNullable(comment).ifPresent(v -> stringBuilder.append(COMMENT_ON_SEQUENCE) Optional.ofNullable(comment).ifPresent(v -> stringBuilder.append(COMMENT_ON_SEQUENCE)
.append(nspname).append(DOT).append(relname) .append(getMetaDataName(nspname, relname))
.append(IS).append(SQUOT).append(comment).append(SQUOT).append(SEMICOLON).append(BLANK_LINE)); .append(IS).append(SQUOT).append(v).append(SQUOT).append(SEMICOLON).append(BLANK_LINE));
Optional.ofNullable(rolname).ifPresent(v -> stringBuilder.append(ALTER_SEQUENCE) Optional.ofNullable(rolname).ifPresent(v -> stringBuilder.append(ALTER_SEQUENCE)
.append(nspname).append(DOT).append(relname) .append(getMetaDataName(nspname, relname))
.append(OWNED_BY).append(v).append(SEMICOLON)); .append(OWNED_BY).append(getMetaDataName(v)).append(SEMICOLON));
} }
return stringBuilder.toString(); return stringBuilder.toString();
}, });
sequenceName, schemaName);
} }
@Override @Override
public List<SimpleSequence> sequences(Connection connection, String databaseName, String schemaName) { public List<SimpleSequence> sequences(Connection connection, String databaseName, String schemaName) {
List<SimpleSequence> simpleSequences = new ArrayList<>(); List<SimpleSequence> 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()) { while (resultSet.next()) {
String relname = resultSet.getString("relname"); String relname = resultSet.getString("relname");
String comment = resultSet.getString("comment"); String comment = resultSet.getString("comment");
@ -396,7 +395,6 @@ public class PostgreSQLMetaData extends DefaultMetaService implements MetaData {
.build()); .build());
} }
return simpleSequences; return simpleSequences;
}, });
schemaName);
} }
} }

View File

@ -11,16 +11,14 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static ai.chat2db.plugin.postgresql.consts.SequenceCommonConst.*; 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.*;
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;
public class PostgreSQLSqlBuilder extends DefaultSqlBuilder { public class PostgreSQLSqlBuilder extends DefaultSqlBuilder {
@ -247,7 +245,7 @@ public class PostgreSQLSqlBuilder extends DefaultSqlBuilder {
Double databaseProductVersion = Double.valueOf(Chat2DBContext.getConnection().getMetaData().getDatabaseProductVersion()); Double databaseProductVersion = Double.valueOf(Chat2DBContext.getConnection().getMetaData().getDatabaseProductVersion());
StringBuilder sqlBuilder = new StringBuilder(); 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) { if (databaseProductVersion >= 10.0) {
sqlBuilder.append(AS).append(sequence.getTypname()).append("\n "); sqlBuilder.append(AS).append(sequence.getTypname()).append("\n ");
} }
@ -270,12 +268,12 @@ public class PostgreSQLSqlBuilder extends DefaultSqlBuilder {
sqlBuilder.append(SEMICOLON).append("\n ").append("\n "); sqlBuilder.append(SEMICOLON).append("\n ").append("\n ");
Optional.ofNullable(sequence.getComment()).ifPresent(v -> sqlBuilder.append(COMMENT_ON_SEQUENCE) Optional.ofNullable(sequence.getComment()).ifPresent(v -> sqlBuilder.append(COMMENT_ON_SEQUENCE)
.append(sequence.getNspname()).append(DOT).append(sequence.getRelname()) .append(getMetaDataName(sequence.getNspname(), sequence.getRelname()))
.append(IS).append(sequence.getComment()).append(SEMICOLON).append("\n ").append("\n ")); .append(IS).append(SQUOT).append(v).append(SQUOT).append(SEMICOLON).append("\n ").append("\n "));
Optional.ofNullable(sequence.getRolname()).ifPresent(v -> sqlBuilder.append(ALTER_SEQUENCE) Optional.ofNullable(sequence.getRolname()).ifPresent(v -> sqlBuilder.append(ALTER_SEQUENCE)
.append(sequence.getNspname()).append(DOT).append(sequence.getRelname()) .append(getMetaDataName(sequence.getNspname(), sequence.getRelname()))
.append(OWNED_BY).append(v).append(SEMICOLON)); .append(OWNED_BY).append(getMetaDataName(v)).append(SEMICOLON));
return sqlBuilder.toString(); return sqlBuilder.toString();
} }
@ -283,19 +281,19 @@ public class PostgreSQLSqlBuilder extends DefaultSqlBuilder {
public String buildModifySequenceSql(Sequence oldSequence, Sequence newSequence) { public String buildModifySequenceSql(Sequence oldSequence, Sequence newSequence) {
StringBuilder sqlBuilder = new StringBuilder(); StringBuilder sqlBuilder = new StringBuilder();
if (!StringUtils.equalsIgnoreCase(oldSequence.getRelname(), newSequence.getRelname())) { 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())) { 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())) { 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 (BooleanUtil.xor(oldSequence.getSeqcycle(), newSequence.getSeqcycle())) {
if (Boolean.TRUE.equals(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 { } 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())) { !StringUtils.equals(oldSequence.getSeqmin(), newSequence.getSeqmin())) {
sqlBuilder.append(ALTER_SEQUENCE); sqlBuilder.append(ALTER_SEQUENCE);
if (!StringUtils.equals(oldSequence.getSeqstart(), newSequence.getSeqstart())) { 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())) { if (!StringUtils.equals(oldSequence.getSeqincrement(), newSequence.getSeqincrement())) {
sqlBuilder.append(INCREMENT_BY).append(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())) { 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())) { 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(); 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));
}
} }

View File

@ -659,7 +659,7 @@ public class SQLConst {
JOIN JOIN
pg_namespace n ON n.oid = c.relnamespace pg_namespace n ON n.oid = c.relnamespace
JOIN JOIN
pg_authid a ON a.oid = c.relowner pg_roles a ON a.oid = c.relowner
JOIN JOIN
pg_type t ON s.seqtypid = t.oid pg_type t ON s.seqtypid = t.oid
WHERE c.relname = ? WHERE c.relname = ?

View File

@ -26,6 +26,10 @@ public class SymbolConstant {
* apostrophe"'" * apostrophe"'"
*/ */
public static final String SQUOT = "'"; public static final String SQUOT = "'";
/**
* apostrophe"""
*/
public static final String DOUBLE_SQUOT = "\"";
/** /**
* empty string "" * empty string ""
*/ */

View File

@ -16,8 +16,7 @@ import java.io.Serializable;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class Sequence implements Serializable { public class Sequence {
private static final long serialVersionUID = 1L;
/** /**
* Schema name * Schema name
*/ */

View File

@ -124,7 +124,8 @@ public class SQLExecutor implements CommandExecutor {
} }
} }
public <R> R preExecute(Connection connection, String sql, ResultSetFunction<R> function, String... args) { public <R> R preExecute(Connection connection, String sql, String[] args, ResultSetFunction<R> function) {
log.info("execute:{}", sql);
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i + 1, args[i]); preparedStatement.setObject(i + 1, args[i]);