@oliasoft-open-source/node-json-migrator 3.0.0 → 3.1.0-beta-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.mjs CHANGED
@@ -804,10 +804,6 @@ var isArguments = baseIsArguments(/* @__PURE__ */ function() {
804
804
  return isObjectLike(value) && hasOwnProperty$8.call(value, "callee") && !propertyIsEnumerable$1.call(value, "callee");
805
805
  };
806
806
 
807
- function getDefaultExportFromCjs (x) {
808
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
809
- }
810
-
811
807
  function stubFalse() {
812
808
  return false;
813
809
  }
@@ -2324,221 +2320,213 @@ const LoaderModule = { loadModuleFromString };
2324
2320
 
2325
2321
  const hash = (string) => createHash("sha256").update(string).digest("hex");
2326
2322
 
2327
- var balancedMatch;
2328
- var hasRequiredBalancedMatch;
2329
-
2330
- function requireBalancedMatch () {
2331
- if (hasRequiredBalancedMatch) return balancedMatch;
2332
- hasRequiredBalancedMatch = 1;
2333
- balancedMatch = balanced;
2334
- function balanced(a, b, str) {
2335
- if (a instanceof RegExp) a = maybeMatch(a, str);
2336
- if (b instanceof RegExp) b = maybeMatch(b, str);
2337
- var r = range(a, b, str);
2338
- return r && {
2339
- start: r[0],
2340
- end: r[1],
2341
- pre: str.slice(0, r[0]),
2342
- body: str.slice(r[0] + a.length, r[1]),
2343
- post: str.slice(r[1] + b.length)
2344
- };
2345
- }
2346
- function maybeMatch(reg, str) {
2347
- var m = str.match(reg);
2348
- return m ? m[0] : null;
2349
- }
2350
- balanced.range = range;
2351
- function range(a, b, str) {
2352
- var begs, beg, left, right, result;
2353
- var ai = str.indexOf(a);
2354
- var bi = str.indexOf(b, ai + 1);
2355
- var i = ai;
2356
- if (ai >= 0 && bi > 0) {
2357
- if (a === b) {
2358
- return [ai, bi];
2359
- }
2360
- begs = [];
2361
- left = str.length;
2362
- while (i >= 0 && !result) {
2363
- if (i == ai) {
2364
- begs.push(i);
2365
- ai = str.indexOf(a, i + 1);
2366
- } else if (begs.length == 1) {
2367
- result = [begs.pop(), bi];
2368
- } else {
2369
- beg = begs.pop();
2370
- if (beg < left) {
2371
- left = beg;
2372
- right = bi;
2373
- }
2374
- bi = str.indexOf(b, i + 1);
2375
- }
2376
- i = ai < bi && ai >= 0 ? ai : bi;
2377
- }
2378
- if (begs.length) {
2379
- result = [left, right];
2380
- }
2381
- }
2382
- return result;
2383
- }
2384
- return balancedMatch;
2385
- }
2386
-
2387
- var braceExpansion;
2388
- var hasRequiredBraceExpansion;
2389
-
2390
- function requireBraceExpansion () {
2391
- if (hasRequiredBraceExpansion) return braceExpansion;
2392
- hasRequiredBraceExpansion = 1;
2393
- var balanced = requireBalancedMatch();
2394
- braceExpansion = expandTop;
2395
- var escSlash = "\0SLASH" + Math.random() + "\0";
2396
- var escOpen = "\0OPEN" + Math.random() + "\0";
2397
- var escClose = "\0CLOSE" + Math.random() + "\0";
2398
- var escComma = "\0COMMA" + Math.random() + "\0";
2399
- var escPeriod = "\0PERIOD" + Math.random() + "\0";
2400
- function numeric(str) {
2401
- return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
2402
- }
2403
- function escapeBraces(str) {
2404
- return str.split("\\\\").join(escSlash).split("\\{").join(escOpen).split("\\}").join(escClose).split("\\,").join(escComma).split("\\.").join(escPeriod);
2405
- }
2406
- function unescapeBraces(str) {
2407
- return str.split(escSlash).join("\\").split(escOpen).join("{").split(escClose).join("}").split(escComma).join(",").split(escPeriod).join(".");
2408
- }
2409
- function parseCommaParts(str) {
2410
- if (!str)
2411
- return [""];
2412
- var parts = [];
2413
- var m = balanced("{", "}", str);
2414
- if (!m)
2415
- return str.split(",");
2416
- var pre = m.pre;
2417
- var body = m.body;
2418
- var post = m.post;
2419
- var p = pre.split(",");
2420
- p[p.length - 1] += "{" + body + "}";
2421
- var postParts = parseCommaParts(post);
2422
- if (post.length) {
2423
- p[p.length - 1] += postParts.shift();
2424
- p.push.apply(p, postParts);
2425
- }
2426
- parts.push.apply(parts, p);
2427
- return parts;
2428
- }
2429
- function expandTop(str) {
2430
- if (!str)
2431
- return [];
2432
- if (str.substr(0, 2) === "{}") {
2433
- str = "\\{\\}" + str.substr(2);
2434
- }
2435
- return expand(escapeBraces(str), true).map(unescapeBraces);
2436
- }
2437
- function embrace(str) {
2438
- return "{" + str + "}";
2439
- }
2440
- function isPadded(el) {
2441
- return /^-?0\d/.test(el);
2442
- }
2443
- function lte(i, y) {
2444
- return i <= y;
2445
- }
2446
- function gte(i, y) {
2447
- return i >= y;
2448
- }
2449
- function expand(str, isTop) {
2450
- var expansions = [];
2451
- var m = balanced("{", "}", str);
2452
- if (!m) return [str];
2453
- var pre = m.pre;
2454
- var post = m.post.length ? expand(m.post, false) : [""];
2455
- if (/\$$/.test(m.pre)) {
2456
- for (var k = 0; k < post.length; k++) {
2457
- var expansion = pre + "{" + m.body + "}" + post[k];
2458
- expansions.push(expansion);
2459
- }
2460
- } else {
2461
- var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
2462
- var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
2463
- var isSequence = isNumericSequence || isAlphaSequence;
2464
- var isOptions = m.body.indexOf(",") >= 0;
2465
- if (!isSequence && !isOptions) {
2466
- if (m.post.match(/,.*\}/)) {
2467
- str = m.pre + "{" + m.body + escClose + m.post;
2468
- return expand(str);
2469
- }
2470
- return [str];
2471
- }
2472
- var n;
2473
- if (isSequence) {
2474
- n = m.body.split(/\.\./);
2475
- } else {
2476
- n = parseCommaParts(m.body);
2477
- if (n.length === 1) {
2478
- n = expand(n[0], false).map(embrace);
2479
- if (n.length === 1) {
2480
- return post.map(function(p) {
2481
- return m.pre + n[0] + p;
2482
- });
2483
- }
2484
- }
2485
- }
2486
- var N;
2487
- if (isSequence) {
2488
- var x = numeric(n[0]);
2489
- var y = numeric(n[1]);
2490
- var width = Math.max(n[0].length, n[1].length);
2491
- var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
2492
- var test = lte;
2493
- var reverse = y < x;
2494
- if (reverse) {
2495
- incr *= -1;
2496
- test = gte;
2497
- }
2498
- var pad = n.some(isPadded);
2499
- N = [];
2500
- for (var i = x; test(i, y); i += incr) {
2501
- var c;
2502
- if (isAlphaSequence) {
2503
- c = String.fromCharCode(i);
2504
- if (c === "\\")
2505
- c = "";
2506
- } else {
2507
- c = String(i);
2508
- if (pad) {
2509
- var need = width - c.length;
2510
- if (need > 0) {
2511
- var z = new Array(need + 1).join("0");
2512
- if (i < 0)
2513
- c = "-" + z + c.slice(1);
2514
- else
2515
- c = z + c;
2516
- }
2517
- }
2518
- }
2519
- N.push(c);
2520
- }
2521
- } else {
2522
- N = [];
2523
- for (var j = 0; j < n.length; j++) {
2524
- N.push.apply(N, expand(n[j], false));
2525
- }
2526
- }
2527
- for (var j = 0; j < N.length; j++) {
2528
- for (var k = 0; k < post.length; k++) {
2529
- var expansion = pre + N[j] + post[k];
2530
- if (!isTop || isSequence || expansion)
2531
- expansions.push(expansion);
2532
- }
2533
- }
2534
- }
2535
- return expansions;
2536
- }
2537
- return braceExpansion;
2538
- }
2539
-
2540
- var braceExpansionExports = requireBraceExpansion();
2541
- var expand = /*@__PURE__*/getDefaultExportFromCjs(braceExpansionExports);
2323
+ const balanced = (a, b, str) => {
2324
+ const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
2325
+ const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
2326
+ const r = ma !== null && mb != null && range(ma, mb, str);
2327
+ return r && {
2328
+ start: r[0],
2329
+ end: r[1],
2330
+ pre: str.slice(0, r[0]),
2331
+ body: str.slice(r[0] + ma.length, r[1]),
2332
+ post: str.slice(r[1] + mb.length)
2333
+ };
2334
+ };
2335
+ const maybeMatch = (reg, str) => {
2336
+ const m = str.match(reg);
2337
+ return m ? m[0] : null;
2338
+ };
2339
+ const range = (a, b, str) => {
2340
+ let begs, beg, left, right = void 0, result;
2341
+ let ai = str.indexOf(a);
2342
+ let bi = str.indexOf(b, ai + 1);
2343
+ let i = ai;
2344
+ if (ai >= 0 && bi > 0) {
2345
+ if (a === b) {
2346
+ return [ai, bi];
2347
+ }
2348
+ begs = [];
2349
+ left = str.length;
2350
+ while (i >= 0 && !result) {
2351
+ if (i === ai) {
2352
+ begs.push(i);
2353
+ ai = str.indexOf(a, i + 1);
2354
+ } else if (begs.length === 1) {
2355
+ const r = begs.pop();
2356
+ if (r !== void 0)
2357
+ result = [r, bi];
2358
+ } else {
2359
+ beg = begs.pop();
2360
+ if (beg !== void 0 && beg < left) {
2361
+ left = beg;
2362
+ right = bi;
2363
+ }
2364
+ bi = str.indexOf(b, i + 1);
2365
+ }
2366
+ i = ai < bi && ai >= 0 ? ai : bi;
2367
+ }
2368
+ if (begs.length && right !== void 0) {
2369
+ result = [left, right];
2370
+ }
2371
+ }
2372
+ return result;
2373
+ };
2374
+
2375
+ const escSlash = "\0SLASH" + Math.random() + "\0";
2376
+ const escOpen = "\0OPEN" + Math.random() + "\0";
2377
+ const escClose = "\0CLOSE" + Math.random() + "\0";
2378
+ const escComma = "\0COMMA" + Math.random() + "\0";
2379
+ const escPeriod = "\0PERIOD" + Math.random() + "\0";
2380
+ const escSlashPattern = new RegExp(escSlash, "g");
2381
+ const escOpenPattern = new RegExp(escOpen, "g");
2382
+ const escClosePattern = new RegExp(escClose, "g");
2383
+ const escCommaPattern = new RegExp(escComma, "g");
2384
+ const escPeriodPattern = new RegExp(escPeriod, "g");
2385
+ const slashPattern = /\\\\/g;
2386
+ const openPattern = /\\{/g;
2387
+ const closePattern = /\\}/g;
2388
+ const commaPattern = /\\,/g;
2389
+ const periodPattern = /\\./g;
2390
+ function numeric(str) {
2391
+ return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
2392
+ }
2393
+ function escapeBraces(str) {
2394
+ return str.replace(slashPattern, escSlash).replace(openPattern, escOpen).replace(closePattern, escClose).replace(commaPattern, escComma).replace(periodPattern, escPeriod);
2395
+ }
2396
+ function unescapeBraces(str) {
2397
+ return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, ".");
2398
+ }
2399
+ function parseCommaParts(str) {
2400
+ if (!str) {
2401
+ return [""];
2402
+ }
2403
+ const parts = [];
2404
+ const m = balanced("{", "}", str);
2405
+ if (!m) {
2406
+ return str.split(",");
2407
+ }
2408
+ const { pre, body, post } = m;
2409
+ const p = pre.split(",");
2410
+ p[p.length - 1] += "{" + body + "}";
2411
+ const postParts = parseCommaParts(post);
2412
+ if (post.length) {
2413
+ p[p.length - 1] += postParts.shift();
2414
+ p.push.apply(p, postParts);
2415
+ }
2416
+ parts.push.apply(parts, p);
2417
+ return parts;
2418
+ }
2419
+ function expand(str) {
2420
+ if (!str) {
2421
+ return [];
2422
+ }
2423
+ if (str.slice(0, 2) === "{}") {
2424
+ str = "\\{\\}" + str.slice(2);
2425
+ }
2426
+ return expand_(escapeBraces(str), true).map(unescapeBraces);
2427
+ }
2428
+ function embrace(str) {
2429
+ return "{" + str + "}";
2430
+ }
2431
+ function isPadded(el) {
2432
+ return /^-?0\d/.test(el);
2433
+ }
2434
+ function lte(i, y) {
2435
+ return i <= y;
2436
+ }
2437
+ function gte(i, y) {
2438
+ return i >= y;
2439
+ }
2440
+ function expand_(str, isTop) {
2441
+ const expansions = [];
2442
+ const m = balanced("{", "}", str);
2443
+ if (!m)
2444
+ return [str];
2445
+ const pre = m.pre;
2446
+ const post = m.post.length ? expand_(m.post, false) : [""];
2447
+ if (/\$$/.test(m.pre)) {
2448
+ for (let k = 0; k < post.length; k++) {
2449
+ const expansion = pre + "{" + m.body + "}" + post[k];
2450
+ expansions.push(expansion);
2451
+ }
2452
+ } else {
2453
+ const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
2454
+ const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
2455
+ const isSequence = isNumericSequence || isAlphaSequence;
2456
+ const isOptions = m.body.indexOf(",") >= 0;
2457
+ if (!isSequence && !isOptions) {
2458
+ if (m.post.match(/,(?!,).*\}/)) {
2459
+ str = m.pre + "{" + m.body + escClose + m.post;
2460
+ return expand_(str);
2461
+ }
2462
+ return [str];
2463
+ }
2464
+ let n;
2465
+ if (isSequence) {
2466
+ n = m.body.split(/\.\./);
2467
+ } else {
2468
+ n = parseCommaParts(m.body);
2469
+ if (n.length === 1 && n[0] !== void 0) {
2470
+ n = expand_(n[0], false).map(embrace);
2471
+ if (n.length === 1) {
2472
+ return post.map((p) => m.pre + n[0] + p);
2473
+ }
2474
+ }
2475
+ }
2476
+ let N;
2477
+ if (isSequence && n[0] !== void 0 && n[1] !== void 0) {
2478
+ const x = numeric(n[0]);
2479
+ const y = numeric(n[1]);
2480
+ const width = Math.max(n[0].length, n[1].length);
2481
+ let incr = n.length === 3 && n[2] !== void 0 ? Math.abs(numeric(n[2])) : 1;
2482
+ let test = lte;
2483
+ const reverse = y < x;
2484
+ if (reverse) {
2485
+ incr *= -1;
2486
+ test = gte;
2487
+ }
2488
+ const pad = n.some(isPadded);
2489
+ N = [];
2490
+ for (let i = x; test(i, y); i += incr) {
2491
+ let c;
2492
+ if (isAlphaSequence) {
2493
+ c = String.fromCharCode(i);
2494
+ if (c === "\\") {
2495
+ c = "";
2496
+ }
2497
+ } else {
2498
+ c = String(i);
2499
+ if (pad) {
2500
+ const need = width - c.length;
2501
+ if (need > 0) {
2502
+ const z = new Array(need + 1).join("0");
2503
+ if (i < 0) {
2504
+ c = "-" + z + c.slice(1);
2505
+ } else {
2506
+ c = z + c;
2507
+ }
2508
+ }
2509
+ }
2510
+ }
2511
+ N.push(c);
2512
+ }
2513
+ } else {
2514
+ N = [];
2515
+ for (let j = 0; j < n.length; j++) {
2516
+ N.push.apply(N, expand_(n[j], false));
2517
+ }
2518
+ }
2519
+ for (let j = 0; j < N.length; j++) {
2520
+ for (let k = 0; k < post.length; k++) {
2521
+ const expansion = pre + N[j] + post[k];
2522
+ if (!isTop || isSequence || expansion) {
2523
+ expansions.push(expansion);
2524
+ }
2525
+ }
2526
+ }
2527
+ }
2528
+ return expansions;
2529
+ }
2542
2530
 
2543
2531
  const MAX_PATTERN_LENGTH = 1024 * 64;
2544
2532
  const assertValidPattern = (pattern) => {
@@ -3058,7 +3046,7 @@ class AST {
3058
3046
  this.#hasMagic = void 0;
3059
3047
  return [s, unescape(this.toString()), false, false];
3060
3048
  }
3061
- let bodyDotAllowed = !repeated || allowDot || dot || false ? "" : this.#partsToRegExp(true);
3049
+ let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ? "" : this.#partsToRegExp(true);
3062
3050
  if (bodyDotAllowed === body) {
3063
3051
  bodyDotAllowed = "";
3064
3052
  }
@@ -6136,7 +6124,7 @@ const IFREG = 8;
6136
6124
  const IFLNK = 10;
6137
6125
  const IFSOCK = 12;
6138
6126
  const IFMT = 15;
6139
- const IFMT_UNKNOWN = -16;
6127
+ const IFMT_UNKNOWN = ~IFMT;
6140
6128
  const READDIR_CALLED = 16;
6141
6129
  const LSTAT_CALLED = 32;
6142
6130
  const ENOTDIR = 64;
@@ -6398,7 +6386,7 @@ class PathBase {
6398
6386
  }
6399
6387
  const children = Object.assign([], { provisional: 0 });
6400
6388
  this.#children.set(this, children);
6401
- this.#type &= -17;
6389
+ this.#type &= ~READDIR_CALLED;
6402
6390
  return children;
6403
6391
  }
6404
6392
  /**
@@ -8920,14 +8908,15 @@ const migrationTablesExist = (db, entity) => {
8920
8908
  SELECT EXISTS (
8921
8909
  SELECT FROM information_schema.tables
8922
8910
  WHERE table_schema = 'public'
8923
- AND table_name = '${entity}_migrations'
8911
+ AND table_name = $(tableName)
8924
8912
  )
8925
8913
  `;
8926
- return db.any(query);
8914
+ const params = { tableName: `${entity}_migrations` };
8915
+ return db.one(query, params);
8927
8916
  };
8928
8917
  const createMigrationsTables = (db, entity) => {
8929
8918
  const query = `
8930
- CREATE TABLE IF NOT EXISTS ${entity}_migrations (
8919
+ CREATE TABLE IF NOT EXISTS $(migrationsTable:name) (
8931
8920
  file_hash TEXT NOT NULL PRIMARY KEY,
8932
8921
  file_name TEXT NOT NULL,
8933
8922
  sequence TEXT NOT NULL,
@@ -8935,20 +8924,26 @@ const createMigrationsTables = (db, entity) => {
8935
8924
  UNIQUE (file_name),
8936
8925
  UNIQUE (sequence)
8937
8926
  );
8938
- CREATE TABLE IF NOT EXISTS ${entity}_versions (
8927
+ CREATE TABLE IF NOT EXISTS $(versionsTable:name) (
8939
8928
  version TEXT NOT NULL PRIMARY KEY,
8940
8929
  plan TEXT NOT NULL,
8941
8930
  created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
8942
8931
  );
8943
8932
  `;
8944
- return db.any(query);
8933
+ const params = {
8934
+ migrationsTable: `${entity}_migrations`,
8935
+ versionsTable: `${entity}_versions`
8936
+ };
8937
+ return db.none(query, params);
8945
8938
  };
8946
8939
  const getMigrationRecords = (db, entity) => {
8947
8940
  const query = `
8948
- SELECT file_hash, file_name, sequence FROM ${entity}_migrations
8941
+ SELECT file_hash, file_name, sequence
8942
+ FROM $(migrationsTable:name)
8949
8943
  ORDER BY sequence
8950
8944
  `;
8951
- return db.manyOrNone(query).then(
8945
+ const params = { migrationsTable: `${entity}_migrations` };
8946
+ return db.manyOrNone(query, params).then(
8952
8947
  (data) => data.map((r) => ({
8953
8948
  fileHash: r.file_hash,
8954
8949
  fileName: r.file_name,
@@ -8966,7 +8961,7 @@ const insertMigrationsRecords = (db, pgpHelpers, entity, migrations) => {
8966
8961
  const cs = new pgpHelpers.ColumnSet(
8967
8962
  ["file_name", "file_hash", "sequence"],
8968
8963
  {
8969
- table: `${entity}_migrations`
8964
+ table: new pgpHelpers.TableName({ table: `${entity}_migrations` })
8970
8965
  }
8971
8966
  );
8972
8967
  const onConflict = " ON CONFLICT(file_name) DO NOTHING";
@@ -8975,13 +8970,14 @@ const insertMigrationsRecords = (db, pgpHelpers, entity, migrations) => {
8975
8970
  }
8976
8971
  };
8977
8972
  const replaceMigrationsRecords = async (db, pgpHelpers, entity, migrations) => {
8978
- const truncate = `DELETE FROM ${entity}_migrations`;
8979
- await db.none(truncate);
8973
+ const query = `DELETE FROM $(migrationsTableName:name)`;
8974
+ const params = { migrationsTableName: `${entity}_migrations` };
8975
+ await db.none(query, params);
8980
8976
  await insertMigrationsRecords(db, pgpHelpers, entity, migrations);
8981
8977
  };
8982
8978
  const insertVersions = (db, pgpHelpers, entity, records) => {
8983
8979
  const cs = new pgpHelpers.ColumnSet(["version", "plan"], {
8984
- table: `${entity}_versions`
8980
+ table: new pgpHelpers.TableName({ table: `${entity}_versions` })
8985
8981
  });
8986
8982
  const onConflict = " ON CONFLICT(version) DO NOTHING";
8987
8983
  const query = pgpHelpers.insert(records, cs) + onConflict;
@@ -8989,19 +8985,97 @@ const insertVersions = (db, pgpHelpers, entity, records) => {
8989
8985
  };
8990
8986
  const getPlanFromVersion = (db, entity, version) => {
8991
8987
  const query = `
8992
- SELECT plan FROM ${entity}_versions
8993
- WHERE version=$1;
8988
+ SELECT plan FROM $(versionsTable:name)
8989
+ WHERE version=$(version);
8994
8990
  `;
8995
- return db.oneOrNone(query, [version], (r) => r?.plan || null);
8991
+ const params = {
8992
+ version,
8993
+ versionsTable: `${entity}_versions`
8994
+ };
8995
+ return db.oneOrNone(query, params, (r) => r?.plan || null);
8996
8996
  };
8997
8997
  const getVersions = async (db, entity) => {
8998
8998
  const query = `
8999
8999
  SELECT
9000
9000
  version,
9001
9001
  plan
9002
- FROM ${entity}_versions ORDER BY created_on DESC
9002
+ FROM $(versionsTable:name) ORDER BY created_on DESC
9003
+ `;
9004
+ const params = {
9005
+ versionsTable: `${entity}_versions`
9006
+ };
9007
+ return db.any(query, params);
9008
+ };
9009
+ const getRecordList = async (db, entity, entityColumnNames, latestVersion, latestVersionPlanLength) => {
9010
+ const query = `
9011
+ SELECT
9012
+ $(entityIdColumn:name) AS id,
9013
+ name,
9014
+ $(entityCreatedColumn:name) AS created,
9015
+ version
9016
+ FROM $(entityTable:name)
9017
+ WHERE (
9018
+ version IS NULL
9019
+ OR (
9020
+ version <> $(latestVersion)
9021
+ AND (
9022
+ SELECT
9023
+ CASE
9024
+ WHEN IS_JSON(plan) THEN JSON_ARRAY_LENGTH(plan::json)
9025
+ ELSE 0
9026
+ END AS length
9027
+ FROM $(entityVersionsTable:name)
9028
+ WHERE $(entityVersionsTable:name).version = version
9029
+ LIMIT 1
9030
+ )::integer <= $(latestVersionPlanLength)
9031
+ )
9032
+ )
9033
+ `;
9034
+ const params = {
9035
+ entityTable: entity,
9036
+ entityVersionsTable: `${entity}_versions`,
9037
+ entityIdColumn: entityColumnNames.id,
9038
+ entityCreatedColumn: entityColumnNames.created,
9039
+ latestVersion,
9040
+ latestVersionPlanLength
9041
+ };
9042
+ return db.any(query, params);
9043
+ };
9044
+ const getRecord = async (t, entity, entityColumnNames, entityId) => {
9045
+ const query = `
9046
+ SELECT *
9047
+ FROM $(entityTable:name)
9048
+ WHERE $(entityIdColumn:name) = $(entityId)
9049
+ `;
9050
+ const params = {
9051
+ entityTable: entity,
9052
+ entityId,
9053
+ entityIdColumn: entityColumnNames.id
9054
+ };
9055
+ return t.one(query, params);
9056
+ };
9057
+ const updateRecord = async (t, entity, entityColumnNames, entityId, currentVersion, nextData, nextVersion, etag) => {
9058
+ const useEtag = typeof etag === "number";
9059
+ const query = `
9060
+ UPDATE $(entityTable:name)
9061
+ SET data = $(nextData),
9062
+ version = $(nextVersion)
9063
+ ${useEtag ? ", etag = etag + 1" : ""}
9064
+ WHERE $(entityIdColumn:name) = $(entityId)
9065
+ AND version = $(currentVersion)
9066
+ ${useEtag ? "AND etag = $(etag)" : ""}
9067
+ RETURNING *
9003
9068
  `;
9004
- return db.any(query);
9069
+ const params = {
9070
+ entityTable: entity,
9071
+ entityId,
9072
+ entityIdColumn: entityColumnNames.id,
9073
+ currentVersion,
9074
+ nextData,
9075
+ nextVersion,
9076
+ etag
9077
+ };
9078
+ return t.oneOrNone(query, params);
9005
9079
  };
9006
9080
 
9007
9081
  let cachedPlannedVersion = null;
@@ -9565,6 +9639,145 @@ const migrate = async ({
9565
9639
  };
9566
9640
  };
9567
9641
 
9642
+ const migrateRecord = async ({
9643
+ record,
9644
+ config,
9645
+ beforeMigrateRecord,
9646
+ afterMigrateRecord
9647
+ }) => {
9648
+ const { dry } = config;
9649
+ console.log(chalk.gray(` ${record.name}`));
9650
+ try {
9651
+ await config.database.tx(async (transaction) => {
9652
+ const currentRecord = await getRecord(
9653
+ transaction,
9654
+ config.entity,
9655
+ config.entityColumnNames,
9656
+ record.id
9657
+ );
9658
+ const { data, etag, version: currentVersion } = currentRecord;
9659
+ await beforeMigrateRecord({
9660
+ currentRecord,
9661
+ dry
9662
+ });
9663
+ const { nextPayload: nextData, nextVersion } = await migrate({
9664
+ payload: data,
9665
+ config: {
9666
+ ...config,
9667
+ version: currentVersion,
9668
+ printPendingFileNames: true
9669
+ }
9670
+ });
9671
+ if (!dry) {
9672
+ const nextRecord = await updateRecord(
9673
+ transaction,
9674
+ config?.entity,
9675
+ config.entityColumnNames,
9676
+ record.id,
9677
+ currentVersion,
9678
+ nextData,
9679
+ nextVersion,
9680
+ etag
9681
+ );
9682
+ if (!nextRecord) {
9683
+ throw new Error(
9684
+ "Failed to patch record with newest migration - The record was probably updated while migrating..."
9685
+ );
9686
+ }
9687
+ await afterMigrateRecord({
9688
+ currentRecord,
9689
+ nextRecord,
9690
+ transaction,
9691
+ dry
9692
+ });
9693
+ }
9694
+ });
9695
+ return null;
9696
+ } catch (error) {
9697
+ const migrationErrorPayload = {
9698
+ id: record.id,
9699
+ name: record.name,
9700
+ created: record.created,
9701
+ error,
9702
+ stackTrace: error.stack
9703
+ };
9704
+ console.log(
9705
+ chalk.red(
9706
+ ` Dataset migration with id ${record.id} failed:
9707
+ ${error.stack}`
9708
+ )
9709
+ );
9710
+ return migrationErrorPayload;
9711
+ }
9712
+ };
9713
+ const migrateRecords = async ({
9714
+ recordList,
9715
+ config,
9716
+ beforeMigrateRecord,
9717
+ afterMigrateRecord,
9718
+ onMigrationErrors
9719
+ }) => {
9720
+ const { dry } = config;
9721
+ const migrationErrors = [];
9722
+ if (recordList.length) {
9723
+ console.log(chalk.gray("Executing record migration scripts..."));
9724
+ for await (const record of recordList) {
9725
+ const migrationErrorPayload = await migrateRecord({
9726
+ record,
9727
+ config,
9728
+ beforeMigrateRecord,
9729
+ afterMigrateRecord
9730
+ });
9731
+ if (migrationErrorPayload) {
9732
+ migrationErrors.push(migrationErrorPayload);
9733
+ }
9734
+ }
9735
+ }
9736
+ if (migrationErrors.length) {
9737
+ console.log(
9738
+ chalk.yellow(
9739
+ `Completed ${config?.entity ?? "entity"} migrations (some failed)${config?.dry ? " [dry-run, no output written]" : ""} \u2713`
9740
+ )
9741
+ );
9742
+ await onMigrationErrors({
9743
+ migrationErrors,
9744
+ dry
9745
+ });
9746
+ } else {
9747
+ console.log(
9748
+ chalk.green(
9749
+ `Completed ${config?.entity ?? "entity"} migrations (success)${config?.dry ? " [dry-run, no output written]" : ""} \u2713`
9750
+ )
9751
+ );
9752
+ }
9753
+ };
9754
+ const migrateAll = async ({
9755
+ config,
9756
+ beforeMigrateRecord,
9757
+ afterMigrateRecord,
9758
+ onMigrationErrors
9759
+ }) => {
9760
+ const plan = await getPlannedMigrations({
9761
+ config
9762
+ });
9763
+ const latestVersion = plan.nextVersion;
9764
+ const latestVersionPlanLength = plan.plannedMigrations.length;
9765
+ const recordList = await getRecordList(
9766
+ config?.database,
9767
+ config?.entity,
9768
+ config?.entityColumnNames,
9769
+ latestVersion,
9770
+ latestVersionPlanLength
9771
+ );
9772
+ await migrateRecords({
9773
+ config,
9774
+ recordList,
9775
+ beforeMigrateRecord,
9776
+ afterMigrateRecord,
9777
+ onMigrationErrors
9778
+ });
9779
+ };
9780
+
9568
9781
  const parsePlan = (plan) => {
9569
9782
  return (() => {
9570
9783
  try {
@@ -9613,4 +9826,4 @@ const printVersionHistory = async ({ config }) => {
9613
9826
  }
9614
9827
  };
9615
9828
 
9616
- export { createMigration, getPlannedMigrations, getPlannedVersion, getVersions, migrate, pipe, printVersionHistory };
9829
+ export { createMigration, getPlannedMigrations, getPlannedVersion, getVersions, migrate, migrateAll, pipe, printVersionHistory };