befly 3.76.4 → 3.76.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/syncDb/report.js +36 -5
package/package.json
CHANGED
package/scripts/syncDb/report.js
CHANGED
|
@@ -39,14 +39,39 @@ function colorText(text, color, enabled) {
|
|
|
39
39
|
return ansi ? `${ansi}${text}\x1b[0m` : text;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
const fieldTypeProperties = new Set(["fieldType", "maxValue", "precision", "scale"]);
|
|
43
|
+
|
|
42
44
|
function targetFieldTypeText(field) {
|
|
43
45
|
if (!field || typeof field !== "object") return "-";
|
|
44
46
|
return field.fieldType === "integer" ? "BIGINT" : field.fieldType === "number" ? `DECIMAL(${field.precision},${field.scale})` : field.fieldType === "varchar" ? `VARCHAR(${field.maxValue})` : field.fieldType === "text" ? "MEDIUMTEXT" : "-";
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
function actualFieldTypeText(field) {
|
|
50
|
+
if (!field || typeof field !== "object") return "-";
|
|
51
|
+
const dbType = String(field.dbType || "").toLowerCase();
|
|
52
|
+
if (["tinyint", "smallint", "mediumint", "int", "bigint"].includes(dbType)) return dbType.toUpperCase();
|
|
53
|
+
if (["decimal", "numeric"].includes(dbType)) return `${dbType.toUpperCase()}(${field.precision},${field.scale})`;
|
|
54
|
+
if (["varchar", "char"].includes(dbType)) return `${dbType.toUpperCase()}(${field.maxValue})`;
|
|
55
|
+
if (dbType) return dbType.toUpperCase();
|
|
56
|
+
return targetFieldTypeText(field);
|
|
57
|
+
}
|
|
58
|
+
|
|
47
59
|
function fieldTypeText(operation) {
|
|
48
60
|
if (!["addColumn", "alterColumn"].includes(operation.kind)) return "-";
|
|
49
|
-
|
|
61
|
+
const after = targetFieldTypeText(operation.after);
|
|
62
|
+
if (operation.kind === "addColumn" || !operation.before) return after;
|
|
63
|
+
const before = actualFieldTypeText(operation.before);
|
|
64
|
+
return before === "-" || before === after ? after : `${before} -> ${after}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function blockedFieldTypeText(blocked) {
|
|
68
|
+
const target = blocked.target;
|
|
69
|
+
if (target && typeof target === "object" && target.fieldType && typeof blocked.before === "string") {
|
|
70
|
+
const before = blocked.before.toUpperCase();
|
|
71
|
+
const after = targetFieldTypeText(target);
|
|
72
|
+
return before === after ? after : `${before} -> ${after}`;
|
|
73
|
+
}
|
|
74
|
+
return targetFieldTypeText(target || blocked.after);
|
|
50
75
|
}
|
|
51
76
|
|
|
52
77
|
function preflightResult(operation, colors) {
|
|
@@ -70,13 +95,14 @@ function buildSyncRows(plan, colors) {
|
|
|
70
95
|
}));
|
|
71
96
|
for (const notice of plan.notices.filter((item) => !createdTables.has(item.table))) rows.push({ 类型: colorText("保留", "deepskyblue", colors), 风险: "-", 表: notice.table, 对象: notice.object || "-", 字段类型: "-", 变更: notice.message, 预检结果: "-" });
|
|
72
97
|
for (const blocked of plan.blocked.filter((item) => !createdTables.has(item.table))) {
|
|
73
|
-
const
|
|
98
|
+
const hasBooleanCompare = typeof blocked.before === "boolean" || typeof blocked.after === "boolean";
|
|
99
|
+
const change = blocked.kind === "preflight" || hasBooleanCompare ? blocked.reason : blocked.before !== undefined || blocked.after !== undefined ? `${formatValue(blocked.before)} -> ${formatValue(blocked.after)}` : blocked.reason;
|
|
74
100
|
rows.push({
|
|
75
101
|
类型: colorText("禁止同步", "orangered", colors),
|
|
76
102
|
风险: colorText("阻塞", "orangered", colors),
|
|
77
103
|
表: blocked.table,
|
|
78
104
|
对象: blocked.object || "-",
|
|
79
|
-
字段类型:
|
|
105
|
+
字段类型: blockedFieldTypeText(blocked),
|
|
80
106
|
变更: change,
|
|
81
107
|
预检结果: blocked.kind === "preflight" ? colorText("否", "red", colors) : "-"
|
|
82
108
|
});
|
|
@@ -139,11 +165,16 @@ function escapeTableValue(value) {
|
|
|
139
165
|
|
|
140
166
|
function archiveChangeText(operation) {
|
|
141
167
|
if (operation.kind === "createTable") return "创建全新表";
|
|
142
|
-
if (operation.kind === "addColumn") return
|
|
168
|
+
if (operation.kind === "addColumn") return `NULL=${operation.after.nullable ? "是" : "否"},默认值=${formatValue(operation.after.default)}`;
|
|
143
169
|
if (operation.kind === "addIndex") return `新增${operation.after.type === "unique" ? "唯一" : "普通"}索引:${operation.after.fields.join(", ")}`;
|
|
144
170
|
if (operation.kind === "replaceIndex") return `${formatValue(operation.before)} -> ${formatValue(operation.after)}`;
|
|
145
171
|
if (operation.kind === "dropIndex") return `删除未在 Tables 中声明的索引:${operation.object}`;
|
|
146
|
-
return
|
|
172
|
+
return (
|
|
173
|
+
operation.changes
|
|
174
|
+
.filter((change) => !fieldTypeProperties.has(change.property))
|
|
175
|
+
.map((change) => `${change.property}: ${formatValue(change.before)} -> ${formatValue(change.after)}`)
|
|
176
|
+
.join(";") || "-"
|
|
177
|
+
);
|
|
147
178
|
}
|
|
148
179
|
|
|
149
180
|
function renderArchive(context) {
|