befly 3.15.6 → 3.15.7

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 CHANGED
@@ -10105,17 +10105,18 @@ class SyncTable {
10105
10105
  }
10106
10106
  return "";
10107
10107
  }
10108
- static buildIndexSQL(tableName, indexName, fieldName, action) {
10109
- const tableQuoted = SyncTable.quoteIdentifier(tableName);
10108
+ static buildIndexClause(indexName, fieldName, action) {
10110
10109
  const indexQuoted = SyncTable.quoteIdentifier(indexName);
10111
- const fieldQuoted = SyncTable.quoteIdentifier(fieldName);
10112
- const parts = [];
10113
10110
  if (action === "create") {
10114
- parts.push(`ADD INDEX ${indexQuoted} (${fieldQuoted})`);
10115
- } else {
10116
- parts.push(`DROP INDEX ${indexQuoted}`);
10111
+ const fieldQuoted = SyncTable.quoteIdentifier(fieldName);
10112
+ return `ADD INDEX ${indexQuoted} (${fieldQuoted})`;
10117
10113
  }
10118
- return `ALTER TABLE ${tableQuoted} ALGORITHM=INPLACE, LOCK=NONE, ${parts.join(", ")}`;
10114
+ return `DROP INDEX ${indexQuoted}`;
10115
+ }
10116
+ static buildIndexSQL(tableName, indexName, fieldName, action) {
10117
+ const tableQuoted = SyncTable.quoteIdentifier(tableName);
10118
+ const clause = SyncTable.buildIndexClause(indexName, fieldName, action);
10119
+ return `ALTER TABLE ${tableQuoted} ALGORITHM=INPLACE, LOCK=NONE, ${clause}`;
10119
10120
  }
10120
10121
  static getSystemColumnDef(fieldName) {
10121
10122
  let meta = null;
@@ -10165,23 +10166,49 @@ class SyncTable {
10165
10166
  const nullableSql = normalized.nullable ? " NULL" : " NOT NULL";
10166
10167
  return `${isAdd ? "ADD COLUMN" : "MODIFY COLUMN"} ${colQuoted} ${sqlType}${uniqueSql}${nullableSql}${defaultSql} COMMENT "${escapeComment(normalized.name)}"`;
10167
10168
  }
10169
+ static stripAlgorithmAndLock(stmt) {
10170
+ let sql = String(stmt);
10171
+ sql = sql.replace(/\bALGORITHM\s*=\s*(INPLACE|INSTANT|COPY)\b\s*,?\s*/gi, "").replace(/\bLOCK\s*=\s*(NONE|SHARED|EXCLUSIVE)\b\s*,?\s*/gi, "");
10172
+ sql = sql.replace(/,\s*,/g, ", ").replace(/,\s*$/g, "").replace(/\s{2,}/g, " ").trim();
10173
+ return sql;
10174
+ }
10175
+ static buildDdlFallbackCandidates(stmt) {
10176
+ const original = String(stmt);
10177
+ const attempted = [];
10178
+ if (/\bALGORITHM\s*=\s*INSTANT\b/i.test(original)) {
10179
+ attempted.push({
10180
+ stmt: original.replace(/\bALGORITHM\s*=\s*INSTANT\b/gi, "ALGORITHM=INPLACE"),
10181
+ reason: "ALGORITHM=INSTANT \u2192 INPLACE"
10182
+ });
10183
+ }
10184
+ const stripped = SyncTable.stripAlgorithmAndLock(original);
10185
+ if (stripped !== original) {
10186
+ attempted.push({ stmt: stripped, reason: "\u79FB\u9664 ALGORITHM/LOCK" });
10187
+ }
10188
+ const out = [];
10189
+ for (const item of attempted) {
10190
+ if (!item.stmt || item.stmt.trim() === "")
10191
+ continue;
10192
+ if (item.stmt === original)
10193
+ continue;
10194
+ if (out.some((x) => x.stmt === item.stmt))
10195
+ continue;
10196
+ out.push(item);
10197
+ }
10198
+ return out;
10199
+ }
10168
10200
  static async executeDDLSafely(db, stmt) {
10169
10201
  try {
10170
10202
  await db.unsafe(stmt);
10171
10203
  return true;
10172
10204
  } catch (error) {
10173
- if (stmt.includes("ALGORITHM=INSTANT")) {
10174
- const inplaceSql = stmt.replace(/ALGORITHM=INSTANT/g, "ALGORITHM=INPLACE");
10205
+ const candidates = SyncTable.buildDdlFallbackCandidates(stmt);
10206
+ for (const candidate of candidates) {
10175
10207
  try {
10176
- await db.unsafe(inplaceSql);
10177
- return true;
10178
- } catch {
10179
- let traditionSql = stmt;
10180
- traditionSql = traditionSql.replace(/\bALGORITHM\s*=\s*(INPLACE|INSTANT)\b\s*,?\s*/g, "").replace(/\bLOCK\s*=\s*(NONE|SHARED|EXCLUSIVE)\b\s*,?\s*/g, "");
10181
- traditionSql = traditionSql.replace(/,\s*,/g, ", ").replace(/,\s*$/g, "").replace(/\s{2,}/g, " ").trim();
10182
- await db.unsafe(traditionSql);
10208
+ await db.unsafe(candidate.stmt);
10209
+ Logger.debug(`[DDL\u964D\u7EA7] ${candidate.reason}\uFF08\u5DF2\u6210\u529F\uFF09`);
10183
10210
  return true;
10184
- }
10211
+ } catch {}
10185
10212
  }
10186
10213
  throw error;
10187
10214
  }
@@ -10335,12 +10362,17 @@ class SyncTable {
10335
10362
  return;
10336
10363
  const dropIndexActions = plan.indexActions.filter((a) => a.action === "drop");
10337
10364
  const createIndexActions = plan.indexActions.filter((a) => a.action === "create");
10338
- for (const act of dropIndexActions) {
10339
- const stmt = SyncTable.buildIndexSQL(tableName, act.indexName, act.fieldName, act.action);
10365
+ if (dropIndexActions.length > 0) {
10366
+ const dropClauses = [];
10367
+ for (const act of dropIndexActions) {
10368
+ dropClauses.push(SyncTable.buildIndexClause(act.indexName, act.fieldName, "drop"));
10369
+ }
10370
+ const tableQuoted = SyncTable.quoteIdentifier(tableName);
10371
+ const stmt = `ALTER TABLE ${tableQuoted} ALGORITHM=INPLACE, LOCK=NONE, ${dropClauses.join(", ")}`;
10340
10372
  try {
10341
- await db.unsafe(stmt);
10373
+ await SyncTable.executeDDLSafely(db, stmt);
10342
10374
  } catch (error) {
10343
- Logger.error({ err: error, table: tableName, index: act.indexName, field: act.fieldName, msg: "\u5220\u9664\u7D22\u5F15\u5931\u8D25" });
10375
+ Logger.error({ err: error, table: tableName, msg: "\u6279\u91CF\u5220\u9664\u7D22\u5F15\u5931\u8D25" });
10344
10376
  throw error;
10345
10377
  }
10346
10378
  }
@@ -10355,12 +10387,17 @@ class SyncTable {
10355
10387
  const stmt = `ALTER TABLE ${tableQuoted} ALGORITHM=INSTANT, LOCK=NONE, ${plan.defaultClauses.join(", ")}`;
10356
10388
  await SyncTable.executeDDLSafely(db, stmt);
10357
10389
  }
10358
- for (const act of createIndexActions) {
10359
- const stmt = SyncTable.buildIndexSQL(tableName, act.indexName, act.fieldName, act.action);
10390
+ if (createIndexActions.length > 0) {
10391
+ const createClauses = [];
10392
+ for (const act of createIndexActions) {
10393
+ createClauses.push(SyncTable.buildIndexClause(act.indexName, act.fieldName, "create"));
10394
+ }
10395
+ const tableQuoted = SyncTable.quoteIdentifier(tableName);
10396
+ const stmt = `ALTER TABLE ${tableQuoted} ALGORITHM=INPLACE, LOCK=NONE, ${createClauses.join(", ")}`;
10360
10397
  try {
10361
- await db.unsafe(stmt);
10398
+ await SyncTable.executeDDLSafely(db, stmt);
10362
10399
  } catch (error) {
10363
- Logger.error({ err: error, table: tableName, index: act.indexName, field: act.fieldName, msg: "\u521B\u5EFA\u7D22\u5F15\u5931\u8D25" });
10400
+ Logger.error({ err: error, table: tableName, msg: "\u6279\u91CF\u521B\u5EFA\u7D22\u5F15\u5931\u8D25" });
10364
10401
  throw error;
10365
10402
  }
10366
10403
  }
@@ -10376,29 +10413,21 @@ class SyncTable {
10376
10413
  ) ENGINE=${ENGINE} DEFAULT CHARSET=${CHARSET} COLLATE=${COLLATE}`;
10377
10414
  await db.unsafe(createSQL);
10378
10415
  Logger.debug(`[\u8868 ${tableName}] + \u521B\u5EFA\u8868\uFF08\u7CFB\u7EDF\u5B57\u6BB5 + \u4E1A\u52A1\u5B57\u6BB5\uFF09`);
10379
- const indexTasks = [];
10380
- const existingIndexes = {};
10416
+ const indexClauses = [];
10381
10417
  for (const sysField of systemIndexFields) {
10382
10418
  const indexName = `idx_${sysField}`;
10383
- if (existingIndexes[indexName]) {
10384
- continue;
10385
- }
10386
- const stmt = SyncTable.buildIndexSQL(tableName, indexName, sysField, "create");
10387
- indexTasks.push(db.unsafe(stmt));
10419
+ indexClauses.push(SyncTable.buildIndexClause(indexName, sysField, "create"));
10388
10420
  }
10389
10421
  for (const [fieldKey, fieldDef] of Object.entries(fields)) {
10390
10422
  const dbFieldName = snakeCase(fieldKey);
10391
10423
  if (fieldDef.index === true && fieldDef.unique !== true) {
10392
10424
  const indexName = `idx_${dbFieldName}`;
10393
- if (existingIndexes[indexName]) {
10394
- continue;
10395
- }
10396
- const stmt = SyncTable.buildIndexSQL(tableName, indexName, dbFieldName, "create");
10397
- indexTasks.push(db.unsafe(stmt));
10425
+ indexClauses.push(SyncTable.buildIndexClause(indexName, dbFieldName, "create"));
10398
10426
  }
10399
10427
  }
10400
- if (indexTasks.length > 0) {
10401
- await Promise.all(indexTasks);
10428
+ if (indexClauses.length > 0) {
10429
+ const stmt = `ALTER TABLE ${tableQuoted} ALGORITHM=INPLACE, LOCK=NONE, ${indexClauses.join(", ")}`;
10430
+ await SyncTable.executeDDLSafely(db, stmt);
10402
10431
  }
10403
10432
  }
10404
10433
  static async modifyTable(db, dbName, tableName, fields) {