@dudousxd/nestjs-durable-store-mikro-orm 0.33.1 → 0.33.2
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/index.cjs +91 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -2
- package/dist/index.d.ts +35 -2
- package/dist/index.js +88 -8
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,8 @@ __export(index_exports, {
|
|
|
25
25
|
BufferedEventRepository: () => BufferedEventRepository,
|
|
26
26
|
BufferedSignalEntity: () => BufferedSignalEntity,
|
|
27
27
|
BufferedSignalRepository: () => BufferedSignalRepository,
|
|
28
|
+
DATETIME_PRECISION: () => DATETIME_PRECISION,
|
|
29
|
+
DEFAULT_BLOCKING_ALTER_ROW_LIMIT: () => DEFAULT_BLOCKING_ALTER_ROW_LIMIT,
|
|
28
30
|
ENTITIES: () => ENTITIES,
|
|
29
31
|
MikroOrmStateStore: () => MikroOrmStateStore,
|
|
30
32
|
RunAttributeEntity: () => RunAttributeEntity,
|
|
@@ -40,6 +42,7 @@ __export(index_exports, {
|
|
|
40
42
|
durableEntities: () => durableEntities,
|
|
41
43
|
durableManagedTables: () => durableManagedTables,
|
|
42
44
|
ensureMikroOrmDurableSchema: () => ensureMikroOrmDurableSchema,
|
|
45
|
+
mikroOrmDeferredAlterWarning: () => mikroOrmDeferredAlterWarning,
|
|
43
46
|
mikroOrmSchemaRepairWarning: () => mikroOrmSchemaRepairWarning
|
|
44
47
|
});
|
|
45
48
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -90,6 +93,7 @@ function snakeCase(property) {
|
|
|
90
93
|
return property.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
91
94
|
}
|
|
92
95
|
__name(snakeCase, "snakeCase");
|
|
96
|
+
var DATETIME_PRECISION = 6;
|
|
93
97
|
function columnNamer(naming) {
|
|
94
98
|
if (naming === "snake_case") return snakeCase;
|
|
95
99
|
if (naming === "preserve") return (property) => property;
|
|
@@ -296,6 +300,7 @@ function durableEntities(options = {}) {
|
|
|
296
300
|
},
|
|
297
301
|
wakeAt: {
|
|
298
302
|
type: "Date",
|
|
303
|
+
length: DATETIME_PRECISION,
|
|
299
304
|
nullable: true,
|
|
300
305
|
fieldName: col("wakeAt")
|
|
301
306
|
},
|
|
@@ -306,6 +311,7 @@ function durableEntities(options = {}) {
|
|
|
306
311
|
},
|
|
307
312
|
lockedUntil: {
|
|
308
313
|
type: "Date",
|
|
314
|
+
length: DATETIME_PRECISION,
|
|
309
315
|
nullable: true,
|
|
310
316
|
fieldName: col("lockedUntil")
|
|
311
317
|
},
|
|
@@ -368,10 +374,12 @@ function durableEntities(options = {}) {
|
|
|
368
374
|
},
|
|
369
375
|
createdAt: {
|
|
370
376
|
type: "Date",
|
|
377
|
+
length: DATETIME_PRECISION,
|
|
371
378
|
fieldName: col("createdAt")
|
|
372
379
|
},
|
|
373
380
|
updatedAt: {
|
|
374
381
|
type: "Date",
|
|
382
|
+
length: DATETIME_PRECISION,
|
|
375
383
|
fieldName: col("updatedAt")
|
|
376
384
|
}
|
|
377
385
|
}
|
|
@@ -460,20 +468,24 @@ function durableEntities(options = {}) {
|
|
|
460
468
|
},
|
|
461
469
|
wakeAt: {
|
|
462
470
|
type: "Date",
|
|
471
|
+
length: DATETIME_PRECISION,
|
|
463
472
|
nullable: true,
|
|
464
473
|
fieldName: col("wakeAt")
|
|
465
474
|
},
|
|
466
475
|
enqueuedAt: {
|
|
467
476
|
type: "Date",
|
|
477
|
+
length: DATETIME_PRECISION,
|
|
468
478
|
nullable: true,
|
|
469
479
|
fieldName: col("enqueuedAt")
|
|
470
480
|
},
|
|
471
481
|
startedAt: {
|
|
472
482
|
type: "Date",
|
|
483
|
+
length: DATETIME_PRECISION,
|
|
473
484
|
fieldName: col("startedAt")
|
|
474
485
|
},
|
|
475
486
|
finishedAt: {
|
|
476
487
|
type: "Date",
|
|
488
|
+
length: DATETIME_PRECISION,
|
|
477
489
|
fieldName: col("finishedAt")
|
|
478
490
|
}
|
|
479
491
|
}
|
|
@@ -618,6 +630,7 @@ function durableEntities(options = {}) {
|
|
|
618
630
|
},
|
|
619
631
|
publishedAt: {
|
|
620
632
|
type: "Date",
|
|
633
|
+
length: DATETIME_PRECISION,
|
|
621
634
|
fieldName: col("publishedAt")
|
|
622
635
|
}
|
|
623
636
|
}
|
|
@@ -676,10 +689,12 @@ function durableEntities(options = {}) {
|
|
|
676
689
|
},
|
|
677
690
|
createdAt: {
|
|
678
691
|
type: "Date",
|
|
692
|
+
length: DATETIME_PRECISION,
|
|
679
693
|
fieldName: col("createdAt")
|
|
680
694
|
},
|
|
681
695
|
updatedAt: {
|
|
682
696
|
type: "Date",
|
|
697
|
+
length: DATETIME_PRECISION,
|
|
683
698
|
fieldName: col("updatedAt")
|
|
684
699
|
}
|
|
685
700
|
}
|
|
@@ -722,6 +737,21 @@ var MARKER_TABLE = "durable_schema_meta";
|
|
|
722
737
|
var MARKER_ROW_ID = "durable";
|
|
723
738
|
var SCHEMA_LOCK_NAME = "durable_schema";
|
|
724
739
|
var SCHEMA_REVISION = 1;
|
|
740
|
+
var DEFAULT_BLOCKING_ALTER_ROW_LIMIT = 1e5;
|
|
741
|
+
function deferredAlterWarning(store, deferred, limit) {
|
|
742
|
+
return [
|
|
743
|
+
`[nestjs-durable] ${store} did NOT apply ${deferred.length} durable-schema column type change(s) at boot.`,
|
|
744
|
+
`MySQL rebuilds a table to change a column type and blocks writes to it until the copy ends, and these tables hold more than blockingAlterRowLimit (${limit}) rows:`,
|
|
745
|
+
...deferred.map((d) => ` -- ${d.table}, ~${d.rows} rows
|
|
746
|
+
${d.statement};`),
|
|
747
|
+
"Run them in a maintenance window or with an online schema change tool (gh-ost, pt-online-schema-change), or raise blockingAlterRowLimit to let a boot run them. Until then the store keeps working on the old column types, and this warning repeats on every boot."
|
|
748
|
+
].join("\n");
|
|
749
|
+
}
|
|
750
|
+
__name(deferredAlterWarning, "deferredAlterWarning");
|
|
751
|
+
function mikroOrmDeferredAlterWarning(deferred, limit) {
|
|
752
|
+
return deferredAlterWarning("store-mikro-orm", deferred, limit);
|
|
753
|
+
}
|
|
754
|
+
__name(mikroOrmDeferredAlterWarning, "mikroOrmDeferredAlterWarning");
|
|
725
755
|
function mikroOrmSchemaRepairWarning(repairs) {
|
|
726
756
|
return [
|
|
727
757
|
`[nestjs-durable] store-mikro-orm repaired the durable schema at boot: ${repairs.join("; ")}.`,
|
|
@@ -926,29 +956,43 @@ async function ensureMikroOrmDurableSchema(orm, options = {}) {
|
|
|
926
956
|
if (await readStoredFingerprint(orm) === expected) {
|
|
927
957
|
return;
|
|
928
958
|
}
|
|
929
|
-
const
|
|
930
|
-
await
|
|
959
|
+
const limit = options.blockingAlterRowLimit ?? DEFAULT_BLOCKING_ALTER_ROW_LIMIT;
|
|
960
|
+
const { repairs, freshInstall, deferred } = await healDurableSchema(orm, dialect, limit);
|
|
961
|
+
if (deferred.length === 0) await writeFingerprint(orm, dialect, expected);
|
|
931
962
|
if (repairs.length > 0 && !freshInstall) logger.warn(mikroOrmSchemaRepairWarning(repairs));
|
|
963
|
+
if (deferred.length > 0) logger.warn(mikroOrmDeferredAlterWarning(deferred, limit));
|
|
932
964
|
} finally {
|
|
933
965
|
await releaseSchemaLock(orm, dialect);
|
|
934
966
|
}
|
|
935
967
|
}
|
|
936
968
|
__name(ensureMikroOrmDurableSchema, "ensureMikroOrmDurableSchema");
|
|
937
|
-
async function healDurableSchema(orm) {
|
|
969
|
+
async function healDurableSchema(orm, dialect, blockingAlterRowLimit) {
|
|
938
970
|
const sql = await orm.schema.getUpdateSchemaSQL({
|
|
939
971
|
safe: true
|
|
940
972
|
});
|
|
941
|
-
const ours = sql.split(";").map((statement) => statement.trim()).filter((statement) => {
|
|
973
|
+
const ours = mergeColumnTypeChanges(sql.split(";").map((statement) => statement.trim()).filter((statement) => {
|
|
942
974
|
const table = targetTable(statement);
|
|
943
975
|
return table !== void 0 && DURABLE_TABLE_NAMES.has(table);
|
|
944
|
-
});
|
|
976
|
+
}));
|
|
945
977
|
const connection = orm.em.getConnection();
|
|
946
978
|
const created = new Set(ours.filter((statement) => /^create\s+table\b/i.test(statement)).map((statement) => targetTable(statement)));
|
|
947
979
|
const repairs = [];
|
|
980
|
+
const deferred = [];
|
|
948
981
|
for (const statement of ours) {
|
|
982
|
+
const table = targetTable(statement);
|
|
983
|
+
if (dialect === "mysql" && !created.has(table) && isColumnTypeChange(statement)) {
|
|
984
|
+
const rows = await estimatedRowCount(orm, table);
|
|
985
|
+
if (rows > blockingAlterRowLimit) {
|
|
986
|
+
deferred.push({
|
|
987
|
+
table,
|
|
988
|
+
rows,
|
|
989
|
+
statement
|
|
990
|
+
});
|
|
991
|
+
continue;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
949
994
|
try {
|
|
950
995
|
await connection.execute(statement);
|
|
951
|
-
const table = targetTable(statement);
|
|
952
996
|
const isCreateTable = /^create\s+table\b/i.test(statement);
|
|
953
997
|
if (isCreateTable || !created.has(table)) repairs.push(...describeDurableStatement(statement));
|
|
954
998
|
} catch (err) {
|
|
@@ -968,10 +1012,45 @@ async function healDurableSchema(orm) {
|
|
|
968
1012
|
].every((table) => created.has(table));
|
|
969
1013
|
return {
|
|
970
1014
|
repairs,
|
|
971
|
-
freshInstall
|
|
1015
|
+
freshInstall,
|
|
1016
|
+
deferred
|
|
972
1017
|
};
|
|
973
1018
|
}
|
|
974
1019
|
__name(healDurableSchema, "healDurableSchema");
|
|
1020
|
+
function mergeColumnTypeChanges(statements) {
|
|
1021
|
+
const merged = [];
|
|
1022
|
+
const at = /* @__PURE__ */ new Map();
|
|
1023
|
+
for (const statement of statements) {
|
|
1024
|
+
const table = targetTable(statement);
|
|
1025
|
+
if (!table || !isColumnTypeChange(statement)) {
|
|
1026
|
+
merged.push(statement);
|
|
1027
|
+
continue;
|
|
1028
|
+
}
|
|
1029
|
+
const actions = statement.replace(/^alter\s+table\s+[`"']?[\w$]+[`"']?\s*/i, "");
|
|
1030
|
+
const index = at.get(table);
|
|
1031
|
+
if (index === void 0) {
|
|
1032
|
+
at.set(table, merged.length);
|
|
1033
|
+
merged.push(statement);
|
|
1034
|
+
} else {
|
|
1035
|
+
merged[index] = `${merged[index]}, ${actions}`;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
return merged;
|
|
1039
|
+
}
|
|
1040
|
+
__name(mergeColumnTypeChanges, "mergeColumnTypeChanges");
|
|
1041
|
+
function isColumnTypeChange(statement) {
|
|
1042
|
+
if (!/^alter\s+table\b/i.test(statement)) return false;
|
|
1043
|
+
const actions = splitTopLevel(statement.replace(/^alter\s+table\s+[`"']?[\w$]+[`"']?\s*/i, ""));
|
|
1044
|
+
return actions.length > 0 && actions.every((action) => /^modify\b/i.test(action));
|
|
1045
|
+
}
|
|
1046
|
+
__name(isColumnTypeChange, "isColumnTypeChange");
|
|
1047
|
+
async function estimatedRowCount(orm, table) {
|
|
1048
|
+
const rows = await orm.em.getConnection().execute("select table_rows as table_rows from information_schema.tables where table_schema = database() and table_name = ? limit 1", [
|
|
1049
|
+
table
|
|
1050
|
+
]);
|
|
1051
|
+
return Number(rows[0]?.table_rows ?? 0);
|
|
1052
|
+
}
|
|
1053
|
+
__name(estimatedRowCount, "estimatedRowCount");
|
|
975
1054
|
function isSafeSqlIdentifier(value) {
|
|
976
1055
|
return /^[A-Za-z0-9_]+$/.test(value);
|
|
977
1056
|
}
|
|
@@ -1055,7 +1134,8 @@ var MikroOrmStateStore = class _MikroOrmStateStore {
|
|
|
1055
1134
|
}
|
|
1056
1135
|
async ensureSchema() {
|
|
1057
1136
|
await ensureMikroOrmDurableSchema(this.orm, {
|
|
1058
|
-
logger: this.opts.schemaLogger
|
|
1137
|
+
logger: this.opts.schemaLogger,
|
|
1138
|
+
blockingAlterRowLimit: this.opts.schemaBlockingAlterRowLimit
|
|
1059
1139
|
});
|
|
1060
1140
|
}
|
|
1061
1141
|
async tryAdmitSingleton(runId, tag, workflow, limit, retryWakeAt) {
|
|
@@ -2286,6 +2366,8 @@ __name(fromScheduleEntity, "fromScheduleEntity");
|
|
|
2286
2366
|
BufferedEventRepository,
|
|
2287
2367
|
BufferedSignalEntity,
|
|
2288
2368
|
BufferedSignalRepository,
|
|
2369
|
+
DATETIME_PRECISION,
|
|
2370
|
+
DEFAULT_BLOCKING_ALTER_ROW_LIMIT,
|
|
2289
2371
|
ENTITIES,
|
|
2290
2372
|
MikroOrmStateStore,
|
|
2291
2373
|
RunAttributeEntity,
|
|
@@ -2301,6 +2383,7 @@ __name(fromScheduleEntity, "fromScheduleEntity");
|
|
|
2301
2383
|
durableEntities,
|
|
2302
2384
|
durableManagedTables,
|
|
2303
2385
|
ensureMikroOrmDurableSchema,
|
|
2386
|
+
mikroOrmDeferredAlterWarning,
|
|
2304
2387
|
mikroOrmSchemaRepairWarning
|
|
2305
2388
|
});
|
|
2306
2389
|
//# sourceMappingURL=index.cjs.map
|