rake-db 2.10.73 → 2.11.0

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.d.ts CHANGED
@@ -89,8 +89,9 @@ type ConstraintArg = {
89
89
  * @param tx - database adapter that executes inside a transaction
90
90
  * @param up - migrate or rollback
91
91
  * @param config - config of `rakeDb`
92
+ * @param asts - array of migration ASTs to collect changes into
92
93
  */
93
- declare const createMigrationInterface: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(tx: TransactionAdapter, up: boolean, config: RakeDbConfig<CT>) => DbMigration<CT>;
94
+ declare const createMigrationInterface: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(tx: TransactionAdapter, up: boolean, config: RakeDbConfig<CT>, asts: RakeDbAst[]) => DbMigration<CT>;
94
95
  declare class Migration<CT extends ColumnTypesBase> {
95
96
  adapter: TransactionAdapter;
96
97
  log?: QueryLogObject;
@@ -1002,6 +1003,16 @@ type AppCodeUpdater = {
1002
1003
  }): Promise<void>;
1003
1004
  afterAll(params: AppCodeUpdaterParams): Promise<void>;
1004
1005
  };
1006
+ type MigrationItem = {
1007
+ path: string;
1008
+ version: string;
1009
+ /**
1010
+ * Function that loads the migration content,
1011
+ * can store lazy import of a migration file.
1012
+ * Promise can return `{ default: x }` where `x` is a return of `change` or an array of such returns.
1013
+ */
1014
+ load(): Promise<unknown>;
1015
+ };
1005
1016
 
1006
1017
  declare const createDb: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(arg: MaybeArray<AdapterOptions>, config: RakeDbConfig<CT>) => Promise<void>;
1007
1018
  declare const dropDb: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(arg: MaybeArray<AdapterOptions>, config: RakeDbConfig<CT>) => Promise<void>;
@@ -1013,8 +1024,8 @@ declare const makeFileTimeStamp: () => string;
1013
1024
 
1014
1025
  type ChangeCallback<CT extends ColumnTypesBase = ColumnTypesBase> = (db: DbMigration<CT>, up: boolean) => Promise<void>;
1015
1026
 
1016
- declare const migrateOrRollback: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(options: MaybeArray<AdapterOptions>, config: RakeDbConfig<CT>, args: string[], up: boolean) => Promise<void>;
1017
- declare const changeCache: Record<string, ChangeCallback[] | undefined>;
1027
+ declare const RAKE_DB_LOCK_KEY = "8582141715823621641";
1028
+ type MigrateFn = <CT extends ColumnTypesBase>(options: MaybeArray<AdapterOptions>, config: RakeDbConfig<CT>, args?: string[]) => Promise<void>;
1018
1029
  /**
1019
1030
  * Will run all pending yet migrations, sequentially in order,
1020
1031
  * will apply `change` functions top-to-bottom.
@@ -1023,20 +1034,22 @@ declare const changeCache: Record<string, ChangeCallback[] | undefined>;
1023
1034
  * @param config - specifies how to load migrations, may have `appCodeUpdater`, callbacks, and logger.
1024
1035
  * @param args - pass none or `all` to run all migrations, pass int for how many to migrate, `--code` to enable and `--code false` to disable `useCodeUpdater`.
1025
1036
  */
1026
- declare const migrate: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(options: MaybeArray<AdapterOptions>, config: RakeDbConfig<CT>, args?: string[]) => Promise<void>;
1037
+ declare const migrate: MigrateFn;
1027
1038
  /**
1028
1039
  * Will roll back one latest applied migration,
1029
1040
  * will apply `change` functions bottom-to-top.
1030
1041
  *
1031
1042
  * Takes the same options as {@link migrate}.
1032
1043
  */
1033
- declare const rollback: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(options: MaybeArray<AdapterOptions>, config: RakeDbConfig<CT>, args?: string[]) => Promise<void>;
1044
+ declare const rollback: MigrateFn;
1034
1045
  /**
1035
1046
  * Calls {@link rollback} and then {@link migrate}.
1036
1047
  *
1037
1048
  * Takes the same options as {@link migrate}.
1038
1049
  */
1039
- declare const redo: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(options: MaybeArray<AdapterOptions>, config: RakeDbConfig<CT>, args?: string[]) => Promise<void>;
1050
+ declare const redo: MigrateFn;
1051
+ declare const migrateOrRollback: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(trx: TransactionAdapter, config: RakeDbConfig<CT>, files: MigrationItem[], count: number, asts: RakeDbAst[], up: boolean) => Promise<void>;
1052
+ declare const changeCache: Record<string, ChangeCallback[] | undefined>;
1040
1053
 
1041
1054
  /**
1042
1055
  * Type of {@link rakeDb} function
@@ -1078,6 +1091,6 @@ declare const rakeDb: RakeDbFn;
1078
1091
 
1079
1092
  declare const saveMigratedVersion: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(db: SilentQueries, version: string, config: RakeDbConfig<CT>) => Promise<void>;
1080
1093
  declare const removeMigratedVersion: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(db: SilentQueries, version: string, config: RakeDbConfig<CT>) => Promise<void>;
1081
- declare const getMigratedVersionsMap: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(db: Adapter, config: RakeDbConfig<CT>) => Promise<Record<string, boolean>>;
1094
+ declare const getMigratedVersionsMap: <CT extends Record<string, orchid_core.AnyColumnTypeCreator>>(db: TransactionAdapter, config: RakeDbConfig<CT>) => Promise<Record<string, boolean>>;
1082
1095
 
1083
- export { AppCodeUpdater, AppCodeUpdaterParams, ChangeTableCallback, ChangeTableOptions, ColumnComment, ColumnsShapeCallback, DbMigration, DropMode, Migration, MigrationColumnTypes, RakeDbAst, RakeDbConfig, SilentQueries, TableOptions, changeCache, createDb, createMigrationInterface, dropDb, generate, getMigratedVersionsMap, makeFileTimeStamp, migrate, migrateOrRollback, rakeDb, redo, removeMigratedVersion, resetDb, rollback, saveMigratedVersion, writeMigrationFile };
1096
+ export { AppCodeUpdater, AppCodeUpdaterParams, ChangeTableCallback, ChangeTableOptions, ColumnComment, ColumnsShapeCallback, DbMigration, DropMode, Migration, MigrationColumnTypes, RAKE_DB_LOCK_KEY, RakeDbAst, RakeDbConfig, SilentQueries, TableOptions, changeCache, createDb, createMigrationInterface, dropDb, generate, getMigratedVersionsMap, makeFileTimeStamp, migrate, migrateOrRollback, rakeDb, redo, removeMigratedVersion, resetDb, rollback, saveMigratedVersion, writeMigrationFile };
package/dist/index.js CHANGED
@@ -1396,7 +1396,7 @@ var __spreadValues$3 = (a, b) => {
1396
1396
  return a;
1397
1397
  };
1398
1398
  var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
1399
- const createMigrationInterface = (tx, up, config) => {
1399
+ const createMigrationInterface = (tx, up, config, asts) => {
1400
1400
  const adapter = new pqb.TransactionAdapter(tx, tx.client, tx.types);
1401
1401
  const { query, arrays } = adapter;
1402
1402
  const log = pqb.logParamToLogObject(config.logger || console, config.log);
@@ -1415,7 +1415,7 @@ const createMigrationInterface = (tx, up, config) => {
1415
1415
  for (const key of Object.getOwnPropertyNames(proto)) {
1416
1416
  db[key] = proto[key];
1417
1417
  }
1418
- db.migratedAsts = [];
1418
+ db.migratedAsts = asts;
1419
1419
  return Object.assign(db, {
1420
1420
  adapter,
1421
1421
  log,
@@ -2200,8 +2200,7 @@ const removeMigratedVersion = async (db, version, config) => {
2200
2200
  const getMigratedVersionsMap = async (db, config) => {
2201
2201
  try {
2202
2202
  const result = await db.arrays(
2203
- `SELECT *
2204
- FROM ${quoteWithSchema({ name: config.migrationsTable })}`
2203
+ `SELECT * FROM ${quoteWithSchema({ name: config.migrationsTable })}`
2205
2204
  );
2206
2205
  return Object.fromEntries(result.rows.map((row) => [row[0], true]));
2207
2206
  } catch (err) {
@@ -2229,128 +2228,156 @@ var __spreadValues$2 = (a, b) => {
2229
2228
  }
2230
2229
  return a;
2231
2230
  };
2231
+ const RAKE_DB_LOCK_KEY = "8582141715823621641";
2232
+ function makeMigrateFn(defaultCount, up, fn) {
2233
+ return async (options, config, args = []) => {
2234
+ const files = await getMigrations(config, up);
2235
+ const count = getCount(args);
2236
+ const conf = prepareConfig(config, args, count);
2237
+ const asts = [];
2238
+ const appCodeUpdaterCache = {};
2239
+ const { appCodeUpdater } = conf;
2240
+ const arrOptions = orchidCore.toArray(options);
2241
+ let localAsts = asts;
2242
+ for (const opts of arrOptions) {
2243
+ const adapter = new pqb.Adapter(opts);
2244
+ try {
2245
+ await adapter.transaction(begin, async (trx) => {
2246
+ await trx.query(
2247
+ `SELECT pg_advisory_xact_lock('${RAKE_DB_LOCK_KEY}')`
2248
+ );
2249
+ await fn(
2250
+ trx,
2251
+ conf,
2252
+ files,
2253
+ count != null ? count : defaultCount,
2254
+ localAsts
2255
+ );
2256
+ });
2257
+ } finally {
2258
+ await adapter.close();
2259
+ }
2260
+ localAsts = [];
2261
+ }
2262
+ await runCodeUpdaterAfterAll(
2263
+ arrOptions[0],
2264
+ config,
2265
+ appCodeUpdater,
2266
+ asts,
2267
+ appCodeUpdaterCache
2268
+ );
2269
+ };
2270
+ }
2271
+ const migrate = makeMigrateFn(
2272
+ Infinity,
2273
+ true,
2274
+ (trx, configs, files, count, asts) => migrateOrRollback(trx, configs, files, count, asts, true)
2275
+ );
2276
+ const rollback = makeMigrateFn(
2277
+ 1,
2278
+ false,
2279
+ (trx, config, files, count, asts) => migrateOrRollback(trx, config, files, count, asts, false)
2280
+ );
2281
+ const redo = makeMigrateFn(
2282
+ 1,
2283
+ false,
2284
+ async (trx, config, files, count, asts) => {
2285
+ await migrateOrRollback(trx, config, files, count, asts, false);
2286
+ files.reverse();
2287
+ await migrateOrRollback(trx, config, files, count, asts, true);
2288
+ files.reverse();
2289
+ }
2290
+ );
2232
2291
  const getDb = (adapter) => pqb.createDb({ adapter });
2233
- const migrateOrRollback = async (options, config, args, up) => {
2234
- var _a, _b, _c, _d, _e, _f;
2235
- config = __spreadValues$2({}, config);
2236
- const files = await getMigrations(config, up);
2237
- let count = up ? Infinity : 1;
2238
- let argI = 0;
2292
+ const getCount = (args) => {
2239
2293
  const num = args[0] === "all" ? Infinity : parseInt(args[0]);
2240
- if (!isNaN(num)) {
2241
- argI++;
2242
- count = num;
2243
- }
2244
- const arg = args[argI];
2294
+ return isNaN(num) ? void 0 : num;
2295
+ };
2296
+ function prepareConfig(config, args, count) {
2297
+ config = __spreadValues$2({}, config);
2298
+ const i = count === void 0 ? 0 : 1;
2299
+ const arg = args[i];
2245
2300
  if (arg === "--code") {
2246
- config.useCodeUpdater = args[argI + 1] !== "false";
2301
+ config.useCodeUpdater = args[i + 1] !== "false";
2247
2302
  }
2248
2303
  if (!config.useCodeUpdater)
2249
2304
  delete config.appCodeUpdater;
2250
- const appCodeUpdaterCache = {};
2251
- for (const opts of orchidCore.toArray(options)) {
2252
- const adapter = new pqb.Adapter(opts);
2253
- let db;
2254
- if (up) {
2255
- await ((_a = config.beforeMigrate) == null ? void 0 : _a.call(config, db != null ? db : db = getDb(adapter)));
2256
- } else {
2257
- await ((_b = config.beforeRollback) == null ? void 0 : _b.call(config, db != null ? db : db = getDb(adapter)));
2258
- }
2259
- const migratedVersions = await getMigratedVersionsMap(adapter, config);
2260
- try {
2261
- for (const file of files) {
2262
- if (up && migratedVersions[file.version] || !up && !migratedVersions[file.version]) {
2263
- continue;
2264
- }
2265
- if (count-- <= 0)
2266
- break;
2267
- await processMigration(
2268
- adapter,
2269
- up,
2270
- file,
2271
- config,
2272
- opts,
2273
- appCodeUpdaterCache
2274
- );
2275
- (_c = config.logger) == null ? void 0 : _c.log(
2276
- `${up ? "Migrated" : "Rolled back"} ${orchidCore.pathToLog(file.path)}`
2277
- );
2278
- }
2279
- if (up) {
2280
- await ((_d = config.afterMigrate) == null ? void 0 : _d.call(config, db != null ? db : db = getDb(adapter)));
2281
- } else {
2282
- await ((_e = config.afterRollback) == null ? void 0 : _e.call(config, db != null ? db : db = getDb(adapter)));
2283
- }
2284
- } finally {
2285
- await ((_f = config.appCodeUpdater) == null ? void 0 : _f.afterAll({
2286
- options: opts,
2287
- basePath: config.basePath,
2288
- cache: appCodeUpdaterCache,
2289
- logger: config.logger,
2290
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
2291
- baseTable: config.baseTable,
2292
- import: config.import
2293
- }));
2294
- await adapter.close();
2305
+ return config;
2306
+ }
2307
+ const migrateOrRollback = async (trx, config, files, count, asts, up) => {
2308
+ var _a, _b, _c;
2309
+ let db;
2310
+ await ((_a = config[up ? "beforeMigrate" : "beforeRollback"]) == null ? void 0 : _a.call(config, db != null ? db : db = getDb(trx)));
2311
+ const migratedVersions = await getMigratedVersionsMap(trx, config);
2312
+ for (const file of files) {
2313
+ if (up && migratedVersions[file.version] || !up && !migratedVersions[file.version]) {
2314
+ continue;
2295
2315
  }
2296
- delete config.appCodeUpdater;
2316
+ if (count-- <= 0)
2317
+ break;
2318
+ await runMigration(trx, up, file, config, asts);
2319
+ (_b = config.logger) == null ? void 0 : _b.log(
2320
+ `${up ? "Migrated" : "Rolled back"} ${orchidCore.pathToLog(file.path)}`
2321
+ );
2297
2322
  }
2323
+ await ((_c = config[up ? "afterMigrate" : "afterRollback"]) == null ? void 0 : _c.call(config, db != null ? db : db = getDb(trx)));
2298
2324
  };
2299
- const changeCache = {};
2300
- const begin = {
2301
- text: "BEGIN",
2302
- values: orchidCore.emptyArray
2303
- };
2304
- const processMigration = async (db, up, file, config, options, appCodeUpdaterCache) => {
2305
- var _a;
2306
- const asts = await db.transaction(begin, async (tx) => {
2307
- clearChanges();
2308
- let changes = changeCache[file.path];
2309
- if (!changes) {
2310
- const module = await file.load();
2311
- const exported = (module == null ? void 0 : module.default) && orchidCore.toArray(module.default);
2312
- if (config.forceDefaultExports && !exported) {
2313
- throw new RakeDbError(
2314
- `Missing a default export in ${file.path} migration`
2315
- );
2316
- }
2317
- changes = exported || getCurrentChanges();
2318
- changeCache[file.path] = changes;
2319
- }
2320
- const db2 = createMigrationInterface(tx, up, config);
2321
- if (changes.length) {
2322
- const from = up ? 0 : changes.length - 1;
2323
- const to = up ? changes.length : -1;
2324
- const step = up ? 1 : -1;
2325
- for (let i = from; i !== to; i += step) {
2326
- await changes[i](db2, up);
2327
- }
2328
- }
2329
- await (up ? saveMigratedVersion : removeMigratedVersion)(
2330
- db2.adapter,
2331
- file.version,
2332
- config
2333
- );
2334
- return db2.migratedAsts;
2335
- });
2325
+ async function runCodeUpdaterAfterAll(options, config, appCodeUpdater, asts, cache) {
2336
2326
  for (const ast of asts) {
2337
- await ((_a = config.appCodeUpdater) == null ? void 0 : _a.process({
2327
+ await (appCodeUpdater == null ? void 0 : appCodeUpdater.process({
2338
2328
  ast,
2339
2329
  options,
2340
2330
  basePath: config.basePath,
2341
- cache: appCodeUpdaterCache,
2331
+ cache,
2342
2332
  logger: config.logger,
2343
2333
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
2344
2334
  baseTable: config.baseTable,
2345
2335
  import: config.import
2346
2336
  }));
2347
2337
  }
2338
+ await (appCodeUpdater == null ? void 0 : appCodeUpdater.afterAll({
2339
+ options,
2340
+ basePath: config.basePath,
2341
+ cache,
2342
+ logger: config.logger,
2343
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
2344
+ baseTable: config.baseTable,
2345
+ import: config.import
2346
+ }));
2347
+ }
2348
+ const changeCache = {};
2349
+ const begin = {
2350
+ text: "BEGIN",
2351
+ values: orchidCore.emptyArray
2348
2352
  };
2349
- const migrate = (options, config, args = []) => migrateOrRollback(options, config, args, true);
2350
- const rollback = (options, config, args = []) => migrateOrRollback(options, config, args, false);
2351
- const redo = async (options, config, args = []) => {
2352
- await migrateOrRollback(options, config, args, false);
2353
- await migrateOrRollback(options, config, args, true);
2353
+ const runMigration = async (trx, up, file, config, asts) => {
2354
+ clearChanges();
2355
+ let changes = changeCache[file.path];
2356
+ if (!changes) {
2357
+ const module = await file.load();
2358
+ const exported = (module == null ? void 0 : module.default) && orchidCore.toArray(module.default);
2359
+ if (config.forceDefaultExports && !exported) {
2360
+ throw new RakeDbError(
2361
+ `Missing a default export in ${file.path} migration`
2362
+ );
2363
+ }
2364
+ changes = exported || getCurrentChanges();
2365
+ changeCache[file.path] = changes;
2366
+ }
2367
+ const db = createMigrationInterface(trx, up, config, asts);
2368
+ if (changes.length) {
2369
+ const from = up ? 0 : changes.length - 1;
2370
+ const to = up ? changes.length : -1;
2371
+ const step = up ? 1 : -1;
2372
+ for (let i = from; i !== to; i += step) {
2373
+ await changes[i](db, up);
2374
+ }
2375
+ }
2376
+ await (up ? saveMigratedVersion : removeMigratedVersion)(
2377
+ db.adapter,
2378
+ file.version,
2379
+ config
2380
+ );
2354
2381
  };
2355
2382
 
2356
2383
  const execute = async (options, sql) => {
@@ -3860,6 +3887,7 @@ Migrate and rollback common arguments:
3860
3887
  `;
3861
3888
 
3862
3889
  exports.Migration = Migration;
3890
+ exports.RAKE_DB_LOCK_KEY = RAKE_DB_LOCK_KEY;
3863
3891
  exports.changeCache = changeCache;
3864
3892
  exports.createDb = createDb;
3865
3893
  exports.createMigrationInterface = createMigrationInterface;