befly 3.15.4 → 3.15.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/dist/befly.js +58 -8
- package/dist/befly.min.js +11 -11
- package/dist/sync/syncTable.js +63 -8
- package/package.json +2 -2
package/dist/sync/syncTable.js
CHANGED
|
@@ -338,6 +338,12 @@ export class SyncTable {
|
|
|
338
338
|
.replace(/\s*unsigned/gi, "")
|
|
339
339
|
.replace(/\([^)]*\)/g, "")
|
|
340
340
|
.trim();
|
|
341
|
+
// TEXT 家族:允许互相转换(包含收缩),交由数据库自身约束(可能截断/报错)。
|
|
342
|
+
// 目的:兼容历史库里已有的 TEXT / MEDIUMTEXT / LONGTEXT 等差异。
|
|
343
|
+
const textFamily = ["tinytext", "text", "mediumtext", "longtext"];
|
|
344
|
+
if (textFamily.includes(cBase) && textFamily.includes(nBase)) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
341
347
|
const intTypes = ["tinyint", "smallint", "mediumint", "int", "integer", "bigint"];
|
|
342
348
|
const cIntIdx = intTypes.indexOf(cBase);
|
|
343
349
|
const nIntIdx = intTypes.indexOf(nBase);
|
|
@@ -512,7 +518,6 @@ export class SyncTable {
|
|
|
512
518
|
const stmt = SyncTable.buildIndexSQL(tableName, act.indexName, act.fieldName, act.action);
|
|
513
519
|
try {
|
|
514
520
|
await db.unsafe(stmt);
|
|
515
|
-
Logger.debug(`[索引变化] 删除索引 ${tableName}.${act.indexName} (${act.fieldName})`);
|
|
516
521
|
}
|
|
517
522
|
catch (error) {
|
|
518
523
|
Logger.error({ err: error, table: tableName, index: act.indexName, field: act.fieldName, msg: "删除索引失败" });
|
|
@@ -534,7 +539,6 @@ export class SyncTable {
|
|
|
534
539
|
const stmt = SyncTable.buildIndexSQL(tableName, act.indexName, act.fieldName, act.action);
|
|
535
540
|
try {
|
|
536
541
|
await db.unsafe(stmt);
|
|
537
|
-
Logger.debug(`[索引变化] 新建索引 ${tableName}.${act.indexName} (${act.fieldName})`);
|
|
538
542
|
}
|
|
539
543
|
catch (error) {
|
|
540
544
|
Logger.error({ err: error, table: tableName, index: act.indexName, field: act.fieldName, msg: "创建索引失败" });
|
|
@@ -552,6 +556,7 @@ export class SyncTable {
|
|
|
552
556
|
const { ENGINE, CHARSET, COLLATE } = SyncTable.MYSQL_TABLE_CONFIG;
|
|
553
557
|
const createSQL = `CREATE TABLE ${tableQuoted} (\n ${cols}\n ) ENGINE=${ENGINE} DEFAULT CHARSET=${CHARSET} COLLATE=${COLLATE}`;
|
|
554
558
|
await db.unsafe(createSQL);
|
|
559
|
+
Logger.debug(`[表 ${tableName}] + 创建表(系统字段 + 业务字段)`);
|
|
555
560
|
const indexTasks = [];
|
|
556
561
|
const existingIndexes = {};
|
|
557
562
|
for (const sysField of systemIndexFields) {
|
|
@@ -585,15 +590,18 @@ export class SyncTable {
|
|
|
585
590
|
const modifyClauses = [];
|
|
586
591
|
const defaultClauses = [];
|
|
587
592
|
const indexActions = [];
|
|
593
|
+
// 汇总输出(默认仅打印汇总,避免逐条日志刷屏)
|
|
594
|
+
const addedBusinessFields = [];
|
|
595
|
+
const addedSystemFields = [];
|
|
596
|
+
const modifiedFields = [];
|
|
597
|
+
const defaultOnlyChangedFields = [];
|
|
598
|
+
const compatibleTypeChanges = [];
|
|
588
599
|
for (const [fieldKey, fieldDef] of Object.entries(fields)) {
|
|
589
600
|
const dbFieldName = snakeCase(fieldKey);
|
|
590
601
|
if (existingColumns[dbFieldName]) {
|
|
591
602
|
const comparison = SyncTable.compareFieldDefinition(existingColumns[dbFieldName], fieldDef);
|
|
592
603
|
if (comparison.length > 0) {
|
|
593
|
-
|
|
594
|
-
const changeLabel = SyncTable.CHANGE_TYPE_LABELS[c.type] || "未知";
|
|
595
|
-
Logger.debug(` ~ 修改 ${dbFieldName} ${changeLabel}: ${c.current} -> ${c.expected}`);
|
|
596
|
-
}
|
|
604
|
+
modifiedFields.push(dbFieldName);
|
|
597
605
|
const hasTypeChange = comparison.some((c) => c.type === "datatype");
|
|
598
606
|
const onlyDefaultChanged = comparison.every((c) => c.type === "default");
|
|
599
607
|
const defaultChanged = comparison.some((c) => c.type === "default");
|
|
@@ -606,7 +614,7 @@ export class SyncTable {
|
|
|
606
614
|
const errorMsg = [`禁止字段类型变更: ${tableName}.${dbFieldName}`, `当前类型: ${typeChange?.current}`, `目标类型: ${typeChange?.expected}`, "说明: 仅允许宽化型变更(如 INT->BIGINT, VARCHAR->TEXT),其他类型变更需要手动处理"].join("\n");
|
|
607
615
|
throw new Error(errorMsg);
|
|
608
616
|
}
|
|
609
|
-
|
|
617
|
+
compatibleTypeChanges.push(`${dbFieldName}: ${currentType} -> ${expectedType}`);
|
|
610
618
|
}
|
|
611
619
|
if (defaultChanged) {
|
|
612
620
|
const actualDefault = SyncTable.resolveDefaultValue(fieldDef.default ?? null, fieldDef.type);
|
|
@@ -619,6 +627,7 @@ export class SyncTable {
|
|
|
619
627
|
if (fieldDef.type !== "text") {
|
|
620
628
|
const colQuoted = SyncTable.quoteIdentifier(dbFieldName);
|
|
621
629
|
defaultClauses.push(`ALTER COLUMN ${colQuoted} SET DEFAULT ${v}`);
|
|
630
|
+
defaultOnlyChangedFields.push(dbFieldName);
|
|
622
631
|
}
|
|
623
632
|
}
|
|
624
633
|
}
|
|
@@ -629,6 +638,7 @@ export class SyncTable {
|
|
|
629
638
|
}
|
|
630
639
|
}
|
|
631
640
|
else {
|
|
641
|
+
addedBusinessFields.push(dbFieldName);
|
|
632
642
|
addClauses.push(SyncTable.generateDDLClause(fieldKey, fieldDef, true));
|
|
633
643
|
changed = true;
|
|
634
644
|
}
|
|
@@ -638,7 +648,7 @@ export class SyncTable {
|
|
|
638
648
|
if (!existingColumns[sysFieldName]) {
|
|
639
649
|
const colDef = SyncTable.getSystemColumnDef(sysFieldName);
|
|
640
650
|
if (colDef) {
|
|
641
|
-
|
|
651
|
+
addedSystemFields.push(sysFieldName);
|
|
642
652
|
addClauses.push(`ADD COLUMN ${colDef}`);
|
|
643
653
|
changed = true;
|
|
644
654
|
}
|
|
@@ -673,6 +683,51 @@ export class SyncTable {
|
|
|
673
683
|
indexActions: indexActions
|
|
674
684
|
};
|
|
675
685
|
if (plan.changed) {
|
|
686
|
+
// 在执行 DDL 前输出“单条汇总日志”(每张表最多一条),避免刷屏且仍保证表名明确。
|
|
687
|
+
const summaryParts = [];
|
|
688
|
+
summaryParts.push(`[表 ${tableName}] 变更汇总`);
|
|
689
|
+
summaryParts.push(`新增字段=${addedBusinessFields.length}`);
|
|
690
|
+
summaryParts.push(`新增系统字段=${addedSystemFields.length}`);
|
|
691
|
+
summaryParts.push(`修改字段=${modifiedFields.length}`);
|
|
692
|
+
summaryParts.push(`默认值更新=${defaultOnlyChangedFields.length}`);
|
|
693
|
+
summaryParts.push(`索引变更=${indexActions.length}`);
|
|
694
|
+
const detailParts = [];
|
|
695
|
+
if (addedBusinessFields.length > 0) {
|
|
696
|
+
detailParts.push(`新增字段:${addedBusinessFields.join(",")}`);
|
|
697
|
+
}
|
|
698
|
+
if (addedSystemFields.length > 0) {
|
|
699
|
+
detailParts.push(`新增系统字段:${addedSystemFields.join(",")}`);
|
|
700
|
+
}
|
|
701
|
+
if (modifiedFields.length > 0) {
|
|
702
|
+
detailParts.push(`修改字段:${modifiedFields.join(",")}`);
|
|
703
|
+
}
|
|
704
|
+
if (defaultOnlyChangedFields.length > 0) {
|
|
705
|
+
detailParts.push(`默认值更新:${defaultOnlyChangedFields.join(",")}`);
|
|
706
|
+
}
|
|
707
|
+
if (compatibleTypeChanges.length > 0) {
|
|
708
|
+
detailParts.push(`兼容类型变更:${compatibleTypeChanges.join(";")}`);
|
|
709
|
+
}
|
|
710
|
+
if (indexActions.length > 0) {
|
|
711
|
+
const createIndexSummaries = [];
|
|
712
|
+
const dropIndexSummaries = [];
|
|
713
|
+
for (const a of indexActions) {
|
|
714
|
+
const item = `${a.indexName}(${a.fieldName})`;
|
|
715
|
+
if (a.action === "create") {
|
|
716
|
+
createIndexSummaries.push(`+${item}`);
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
dropIndexSummaries.push(`-${item}`);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
const indexPart = [];
|
|
723
|
+
if (dropIndexSummaries.length > 0)
|
|
724
|
+
indexPart.push(dropIndexSummaries.join(","));
|
|
725
|
+
if (createIndexSummaries.length > 0)
|
|
726
|
+
indexPart.push(createIndexSummaries.join(","));
|
|
727
|
+
detailParts.push(`索引:${indexPart.join(",")}`);
|
|
728
|
+
}
|
|
729
|
+
const msg = detailParts.length > 0 ? `${summaryParts.join(",")};${detailParts.join(",")}` : summaryParts.join(",");
|
|
730
|
+
Logger.debug(msg);
|
|
676
731
|
await SyncTable.applyTablePlan(db, tableName, plan);
|
|
677
732
|
}
|
|
678
733
|
return plan;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly",
|
|
3
|
-
"version": "3.15.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "3.15.6",
|
|
4
|
+
"gitHead": "41c6d052c600ae43302d2a97e7a5b597976cdb90",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
|
|
7
7
|
"keywords": [
|