fix(sequence): 发号器自动建表兼容 PostgreSQL 等非 MySQL 方言

Table.from 推导的列缺少 originType,DDL 阶段无法按目标库转换类型,
PostgreSQL 下 DATETIME 原样输出导致建表失败(type "datetime" does not exist)。
补全 originType 使 anyline 方言别名转换(DATETIME -> TIMESTAMP)生效。

同时显式命名主键约束:anyline 随机生成的约束名约 16% 概率以数字开头,
未加引号时为 SQL 语法错误。

MySQL 差分验证建表行为不变;本地 PostgreSQL 实测建表成功。
This commit is contained in:
PIGCLOUD committed 2026-08-01 11:59:35 +08:00
1 parent 2ab4d66f28
commit fb5e1bdf6e
2 files changed
+77 -11

No files matched your search

@@ -23,6 +23,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.anyline.metadata.Column;
import org.anyline.metadata.Index;
import org.anyline.metadata.PrimaryKey;
import org.anyline.metadata.Table;
import org.anyline.proxy.ServiceProxy;
import org.anyline.service.AnylineService;
@@ -55,20 +56,39 @@ public class SequenceAutoConfiguration {
AnylineService service = ServiceProxy.service();
Table tableMetadata = service.metadata().table(sequenceDbProperties.getDb().getTableName(), false);
if (Objects.isNull(tableMetadata)) {
Table table = Table.from(SequenceTable.class);
table.setName(sequenceDbProperties.getDb().getTableName());
table.setComment("序列号区间管理表");
table.setPrimaryKey(SequenceTable.Fields.id);
LinkedHashMap<String, Index> indexLinkedHashMap = new LinkedHashMap<>();
Index nameUnique = new Index(SequenceTable.Fields.name);
nameUnique.setUnique(true);
nameUnique.addColumn(new Column(SequenceTable.Fields.name));
indexLinkedHashMap.put(SequenceTable.Fields.name, nameUnique);
table.setIndexes(indexLinkedHashMap);
Table table = buildSequenceTable(sequenceDbProperties.getDb().getTableName());
service.ddl().create(table);
log.debug("发号器自动创建表成功:{} ", table);
}
}
/**
* 构建发号器表结构
* @param tableName 表名
* @return 表定义
*/
static Table buildSequenceTable(String tableName) {
Table table = Table.from(SequenceTable.class);
table.setName(tableName);
table.setComment("序列号区间管理表");
// Table.from 不会填充 originType,缺失时 DDL 阶段无法按目标库转换类型
// (如 PostgreSQL 下 DATETIME 需转为 TIMESTAMP),会原样输出导致建表失败
for (Object o : table.getColumns().values()) {
Column column = (Column) o;
column.setOriginType(column.getTypeName());
}
// 显式主键约束名:anyline 随机生成的约束名可能以数字开头,属 SQL 语法错误
PrimaryKey primaryKey = new PrimaryKey();
primaryKey.setName("pk_" + tableName);
primaryKey.addColumn(new Column(SequenceTable.Fields.id));
table.setPrimaryKey(primaryKey);
LinkedHashMap<String, Index> indexLinkedHashMap = new LinkedHashMap<>();
Index nameUnique = new Index(SequenceTable.Fields.name);
nameUnique.setUnique(true);
nameUnique.addColumn(new Column(SequenceTable.Fields.name));
indexLinkedHashMap.put(SequenceTable.Fields.name, nameUnique);
table.setIndexes(indexLinkedHashMap);
return table;
}
}
@@ -0,0 +1,46 @@
package com.pig4cloud.pigx.common.sequence;
import org.anyline.adapter.init.DefaultEnvironmentWorker;
import org.anyline.metadata.Column;
import org.anyline.metadata.Table;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class SequenceAutoConfigurationTests {
@BeforeAll
static void initAnylineEnvironment() {
DefaultEnvironmentWorker.start();
}
/**
* Table.from 不会填充 originType,缺失时 DDL 阶段按目标库的类型转换(如
* PostgreSQL 下 DATETIME -> TIMESTAMP)会被跳过,直接输出 DATETIME 导致建表失败。
*/
@Test
void everyColumnCarriesOriginTypeForDialectConversion() {
Table table = SequenceAutoConfiguration.buildSequenceTable("pigx_sequence");
for (Object o : table.getColumns().values()) {
Column column = (Column) o;
assertThat(column.getOriginType()).as("column %s originType", column.getName())
.isEqualTo(column.getTypeName());
}
}
/**
* anyline 随机生成的主键约束名可能以数字开头,未加引号时在 PostgreSQL / MySQL
* 下都是语法错误,必须显式命名。
*/
@Test
void primaryKeyHasExplicitName() {
Table table = SequenceAutoConfiguration.buildSequenceTable("pigx_sequence");
assertThat(table.getPrimaryKey()).isNotNull();
assertThat(table.getPrimaryKey().getName()).isEqualTo("pk_pigx_sequence");
assertThat(table.getPrimaryKey().getColumns()).containsKey("ID");
}
}