befly 3.76.5 → 3.76.6
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/index.js +1 -1
- package/scripts/syncDb/model.js +1 -1
- package/scripts/syncDb/plan.js +17 -11
- package/scripts/syncDb/report.js +28 -4
package/package.json
CHANGED
package/scripts/syncDb/index.js
CHANGED
|
@@ -30,7 +30,7 @@ async function buildPlan(mysql, targetTables, tableNames) {
|
|
|
30
30
|
export async function syncDb(mysqlConfig, options = {}) {
|
|
31
31
|
const apply = options.apply === true;
|
|
32
32
|
const list = options.list === true;
|
|
33
|
-
const tableNames = Array.isArray(options.tableNames) ? options.tableNames
|
|
33
|
+
const tableNames = [...new Set((Array.isArray(options.tableNames) ? options.tableNames : options.tableName ? [options.tableName] : []).filter(Boolean))];
|
|
34
34
|
const tableScope = tableNames.length > 0 ? tableNames.join(", ") : "";
|
|
35
35
|
const startedAt = nowText();
|
|
36
36
|
let client;
|
package/scripts/syncDb/model.js
CHANGED
|
@@ -33,7 +33,7 @@ export function selectTables(tables, tableNames = []) {
|
|
|
33
33
|
|
|
34
34
|
const selectedNameSet = new Set(selectedNames);
|
|
35
35
|
const selectedTables = Object.fromEntries(Object.entries(tables).filter(([key, table]) => selectedNameSet.has(key) || selectedNameSet.has(table.codeName) || selectedNameSet.has(table.fileName)));
|
|
36
|
-
const matchedNames = new Set(Object.
|
|
36
|
+
const matchedNames = new Set(Object.entries(selectedTables).flatMap(([key, table]) => [key, table.codeName, table.fileName]));
|
|
37
37
|
const missingName = selectedNames.find((name) => !matchedNames.has(name));
|
|
38
38
|
if (missingName) throw new TypeError(`找不到 Table 定义:${missingName}`);
|
|
39
39
|
return selectedTables;
|
package/scripts/syncDb/plan.js
CHANGED
|
@@ -15,21 +15,28 @@ function targetDbType(fieldType) {
|
|
|
15
15
|
return { integer: "bigint", number: "decimal", varchar: "varchar", text: "mediumtext" }[fieldType];
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
const compatibleFieldTypeSources = {
|
|
19
|
+
integer: new Set(["integer", "tinyint", "smallint", "mediumint", "int"]),
|
|
20
|
+
number: new Set(["number"]),
|
|
21
|
+
varchar: new Set(["varchar", "char"]),
|
|
22
|
+
text: new Set(["text", "tinytext", "longtext", "json", "varchar", "char"])
|
|
23
|
+
};
|
|
24
|
+
|
|
18
25
|
function compatibleFieldType(target, actual) {
|
|
19
|
-
|
|
20
|
-
integer: new Set(["integer", "tinyint", "smallint", "mediumint", "int"]),
|
|
21
|
-
number: new Set(["number"]),
|
|
22
|
-
varchar: new Set(["varchar", "char"]),
|
|
23
|
-
text: new Set(["text", "tinytext", "longtext", "json", "varchar", "char"])
|
|
24
|
-
};
|
|
25
|
-
return sources[target]?.has(actual) === true;
|
|
26
|
+
return compatibleFieldTypeSources[target]?.has(actual) === true;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
function columnChanges(target, actual) {
|
|
29
30
|
const changes = [];
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
if (target.fieldType !== actual.fieldType) changes.push({ property: "fieldType", before: actual.fieldType, after: target.fieldType });
|
|
32
|
+
if (target.fieldType === "varchar" && target.maxValue !== actual.maxValue) changes.push({ property: "maxValue", before: actual.maxValue, after: target.maxValue });
|
|
33
|
+
if (target.fieldType === "number") {
|
|
34
|
+
if (target.precision !== actual.precision) changes.push({ property: "precision", before: actual.precision, after: target.precision });
|
|
35
|
+
if (target.scale !== actual.scale) changes.push({ property: "scale", before: actual.scale, after: target.scale });
|
|
32
36
|
}
|
|
37
|
+
if (target.nullable !== actual.nullable) changes.push({ property: "nullable", before: actual.nullable, after: target.nullable });
|
|
38
|
+
if (target.name !== actual.name) changes.push({ property: "name", before: actual.name, after: target.name });
|
|
39
|
+
if (target.unsigned !== actual.unsigned) changes.push({ property: "unsigned", before: actual.unsigned, after: target.unsigned });
|
|
33
40
|
if (!sameDefault(target.default, actual.default)) changes.push({ property: "default", before: actual.default, after: target.default });
|
|
34
41
|
return changes;
|
|
35
42
|
}
|
|
@@ -68,8 +75,7 @@ export function updatePlanHash(plan) {
|
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
export function buildSchemaPlan(targetTables, actualTables, { tableNames = [], singleTable = false } = {}) {
|
|
71
|
-
const
|
|
72
|
-
const restrictUnmanagedTables = selectedTableNames.length > 0 || singleTable;
|
|
78
|
+
const restrictUnmanagedTables = singleTable || (Array.isArray(tableNames) ? tableNames.length > 0 : Boolean(tableNames));
|
|
73
79
|
const plan = { operations: [], notices: [], blocked: [], counts: {} };
|
|
74
80
|
|
|
75
81
|
for (const target of Object.values(targetTables)) {
|
package/scripts/syncDb/report.js
CHANGED
|
@@ -2,6 +2,8 @@ import { mkdir } from "node:fs/promises";
|
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
|
|
4
4
|
function formatValue(value) {
|
|
5
|
+
if (value === true) return "是";
|
|
6
|
+
if (value === false) return "否";
|
|
5
7
|
if (value === "") return '""';
|
|
6
8
|
if (value === null || value === undefined) return "无";
|
|
7
9
|
if (value && typeof value === "object") {
|
|
@@ -41,6 +43,17 @@ function colorText(text, color, enabled) {
|
|
|
41
43
|
|
|
42
44
|
const fieldTypeProperties = new Set(["fieldType", "maxValue", "precision", "scale"]);
|
|
43
45
|
|
|
46
|
+
const propertyNames = {
|
|
47
|
+
nullable: "是否可空",
|
|
48
|
+
name: "注释",
|
|
49
|
+
default: "默认值",
|
|
50
|
+
unsigned: "无符号",
|
|
51
|
+
type: "索引类型",
|
|
52
|
+
fields: "索引字段"
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const indexTypeNames = { index: "普通", unique: "唯一" };
|
|
56
|
+
|
|
44
57
|
function targetFieldTypeText(field) {
|
|
45
58
|
if (!field || typeof field !== "object") return "-";
|
|
46
59
|
return field.fieldType === "integer" ? "BIGINT" : field.fieldType === "number" ? `DECIMAL(${field.precision},${field.scale})` : field.fieldType === "varchar" ? `VARCHAR(${field.maxValue})` : field.fieldType === "text" ? "MEDIUMTEXT" : "-";
|
|
@@ -75,7 +88,8 @@ function blockedFieldTypeText(blocked) {
|
|
|
75
88
|
}
|
|
76
89
|
|
|
77
90
|
function preflightResult(operation, colors) {
|
|
78
|
-
|
|
91
|
+
if (!operation.preflight) return "-";
|
|
92
|
+
return colorText(operation.preflight.blocked ? "否" : "是", operation.preflight.blocked ? "red" : "limegreen", colors);
|
|
79
93
|
}
|
|
80
94
|
|
|
81
95
|
function buildSyncRows(plan, colors) {
|
|
@@ -165,14 +179,24 @@ function escapeTableValue(value) {
|
|
|
165
179
|
|
|
166
180
|
function archiveChangeText(operation) {
|
|
167
181
|
if (operation.kind === "createTable") return "创建全新表";
|
|
168
|
-
if (operation.kind === "addColumn") return
|
|
182
|
+
if (operation.kind === "addColumn") return `是否可空=${operation.after.nullable ? "是" : "否"},默认值=${formatValue(operation.after.default)}`;
|
|
169
183
|
if (operation.kind === "addIndex") return `新增${operation.after.type === "unique" ? "唯一" : "普通"}索引:${operation.after.fields.join(", ")}`;
|
|
170
|
-
if (operation.kind === "replaceIndex")
|
|
184
|
+
if (operation.kind === "replaceIndex") {
|
|
185
|
+
return operation.changes
|
|
186
|
+
.map((change) => {
|
|
187
|
+
const label = propertyNames[change.property] || change.property;
|
|
188
|
+
if (change.property === "type") return `${label}: ${indexTypeNames[change.before] || change.before} -> ${indexTypeNames[change.after] || change.after}`;
|
|
189
|
+
const before = Array.isArray(change.before) ? change.before.join(", ") : formatValue(change.before);
|
|
190
|
+
const after = Array.isArray(change.after) ? change.after.join(", ") : formatValue(change.after);
|
|
191
|
+
return `${label}: ${before} -> ${after}`;
|
|
192
|
+
})
|
|
193
|
+
.join(";");
|
|
194
|
+
}
|
|
171
195
|
if (operation.kind === "dropIndex") return `删除未在 Tables 中声明的索引:${operation.object}`;
|
|
172
196
|
return (
|
|
173
197
|
operation.changes
|
|
174
198
|
.filter((change) => !fieldTypeProperties.has(change.property))
|
|
175
|
-
.map((change) => `${change.property}: ${formatValue(change.before)} -> ${formatValue(change.after)}`)
|
|
199
|
+
.map((change) => `${propertyNames[change.property] || change.property}: ${formatValue(change.before)} -> ${formatValue(change.after)}`)
|
|
176
200
|
.join(";") || "-"
|
|
177
201
|
);
|
|
178
202
|
}
|