@prairielearn/migrations 1.0.0 → 1.2.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/CHANGELOG.md +24 -0
- package/README.md +145 -0
- package/dist/batched-migrations/batched-migration-job.d.ts +42 -0
- package/dist/batched-migrations/batched-migration-job.js +25 -0
- package/dist/batched-migrations/batched-migration-job.js.map +1 -0
- package/dist/batched-migrations/batched-migration-job.sql +12 -0
- package/dist/batched-migrations/batched-migration-runner.d.ts +28 -0
- package/dist/batched-migrations/batched-migration-runner.js +136 -0
- package/dist/batched-migrations/batched-migration-runner.js.map +1 -0
- package/dist/batched-migrations/batched-migration-runner.sql +93 -0
- package/dist/batched-migrations/batched-migration-runner.test.js +185 -0
- package/dist/batched-migrations/batched-migration-runner.test.js.map +1 -0
- package/dist/batched-migrations/batched-migration.d.ts +79 -0
- package/dist/batched-migrations/batched-migration.js +73 -0
- package/dist/batched-migrations/batched-migration.js.map +1 -0
- package/dist/batched-migrations/batched-migration.sql +95 -0
- package/dist/batched-migrations/batched-migrations-runner.d.ts +63 -0
- package/dist/batched-migrations/batched-migrations-runner.js +273 -0
- package/dist/batched-migrations/batched-migrations-runner.js.map +1 -0
- package/dist/batched-migrations/batched-migrations-runner.sql +35 -0
- package/dist/batched-migrations/batched-migrations-runner.test.d.ts +1 -0
- package/dist/batched-migrations/batched-migrations-runner.test.js +116 -0
- package/dist/batched-migrations/batched-migrations-runner.test.js.map +1 -0
- package/dist/batched-migrations/fixtures/20230406184103_successful_migration.d.ts +9 -0
- package/dist/batched-migrations/fixtures/20230406184103_successful_migration.js +14 -0
- package/dist/batched-migrations/fixtures/20230406184103_successful_migration.js.map +1 -0
- package/dist/batched-migrations/fixtures/20230407230446_no_rows_migration.d.ts +8 -0
- package/dist/batched-migrations/fixtures/20230407230446_no_rows_migration.js +16 -0
- package/dist/batched-migrations/fixtures/20230407230446_no_rows_migration.js.map +1 -0
- package/dist/batched-migrations/index.d.ts +3 -0
- package/dist/batched-migrations/index.js +18 -0
- package/dist/batched-migrations/index.js.map +1 -0
- package/dist/index.d.ts +3 -11
- package/dist/index.js +15 -167
- package/dist/index.js.map +1 -1
- package/dist/load-migrations.d.ts +8 -0
- package/dist/load-migrations.js +60 -0
- package/dist/load-migrations.js.map +1 -0
- package/dist/load-migrations.test.d.ts +1 -0
- package/dist/{index.test.js → load-migrations.test.js} +12 -44
- package/dist/load-migrations.test.js.map +1 -0
- package/dist/migrations/fixtures/20230407210409_create_users.sql +2 -0
- package/dist/migrations/fixtures/20230407210430_insert_user.d.ts +1 -0
- package/dist/migrations/fixtures/20230407210430_insert_user.js +7 -0
- package/dist/migrations/fixtures/20230407210430_insert_user.js.map +1 -0
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.js +6 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/migrations.d.ts +6 -0
- package/dist/migrations/migrations.js +159 -0
- package/dist/migrations/migrations.js.map +1 -0
- package/dist/migrations/migrations.test.d.ts +1 -0
- package/dist/migrations/migrations.test.js +78 -0
- package/dist/migrations/migrations.test.js.map +1 -0
- package/package.json +16 -8
- package/schema-migrations/20230303193423_batched_migrations__create.sql +49 -0
- package/src/batched-migrations/batched-migration-job.sql +12 -0
- package/src/batched-migrations/batched-migration-job.ts +34 -0
- package/src/batched-migrations/batched-migration-runner.sql +93 -0
- package/src/batched-migrations/batched-migration-runner.test.ts +208 -0
- package/src/batched-migrations/batched-migration-runner.ts +215 -0
- package/src/batched-migrations/batched-migration.sql +95 -0
- package/src/batched-migrations/batched-migration.ts +129 -0
- package/src/batched-migrations/batched-migrations-runner.sql +35 -0
- package/src/batched-migrations/batched-migrations-runner.test.ts +111 -0
- package/src/batched-migrations/batched-migrations-runner.ts +327 -0
- package/src/batched-migrations/fixtures/20230406184103_successful_migration.ts +13 -0
- package/src/batched-migrations/fixtures/20230406184107_failing_migration.js +16 -0
- package/src/batched-migrations/fixtures/20230407230446_no_rows_migration.ts +15 -0
- package/src/batched-migrations/index.ts +21 -0
- package/src/index.ts +20 -173
- package/src/{index.test.ts → load-migrations.test.ts} +10 -48
- package/src/load-migrations.ts +76 -0
- package/src/migrations/fixtures/20230407210409_create_users.sql +2 -0
- package/src/migrations/fixtures/20230407210430_insert_user.ts +5 -0
- package/src/migrations/index.ts +1 -0
- package/src/migrations/migrations.test.ts +80 -0
- package/src/migrations/migrations.ts +149 -0
- package/dist/index.test.js.map +0 -1
- /package/dist/{index.test.d.ts → batched-migrations/batched-migration-runner.test.d.ts} +0 -0
- /package/dist/{index.sql → migrations/migrations.sql} +0 -0
- /package/src/{index.sql → migrations/migrations.sql} +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.finalizeBatchedMigration = exports.enqueueBatchedMigration = exports.stopBatchedMigrations = exports.startBatchedMigrations = exports.initBatchedMigrations = exports.BatchedMigrationsRunner = void 0;
|
|
30
|
+
const node_events_1 = __importDefault(require("node:events"));
|
|
31
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
32
|
+
const promises_1 = require("node:timers/promises");
|
|
33
|
+
const postgres_1 = require("@prairielearn/postgres");
|
|
34
|
+
const named_locks_1 = require("@prairielearn/named-locks");
|
|
35
|
+
const load_migrations_1 = require("../load-migrations");
|
|
36
|
+
const batched_migration_1 = require("./batched-migration");
|
|
37
|
+
const batched_migration_runner_1 = require("./batched-migration-runner");
|
|
38
|
+
const sql = (0, postgres_1.loadSqlEquiv)(__filename);
|
|
39
|
+
const DEFAULT_MIN_VALUE = 1n;
|
|
40
|
+
const DEFAULT_BATCH_SIZE = 1000;
|
|
41
|
+
const DEFAULT_WORK_DURATION_MS = 60000;
|
|
42
|
+
const DEFAULT_SLEEP_DURATION_MS = 30000;
|
|
43
|
+
const EXTENSIONS = ['.js', '.ts', '.mjs', '.mts'];
|
|
44
|
+
class BatchedMigrationsRunner extends node_events_1.default {
|
|
45
|
+
constructor(options) {
|
|
46
|
+
super();
|
|
47
|
+
this.running = false;
|
|
48
|
+
this.migrationFiles = null;
|
|
49
|
+
this.abortController = new AbortController();
|
|
50
|
+
this.getMigrationFiles = async () => {
|
|
51
|
+
if (!this.migrationFiles) {
|
|
52
|
+
this.migrationFiles = await (0, load_migrations_1.readAndValidateMigrationsFromDirectories)(this.options.directories, EXTENSIONS);
|
|
53
|
+
}
|
|
54
|
+
return this.migrationFiles;
|
|
55
|
+
};
|
|
56
|
+
this.options = options;
|
|
57
|
+
this.lockName = `batched-migrations:${this.options.project}`;
|
|
58
|
+
}
|
|
59
|
+
lockNameForTimestamp(timestamp) {
|
|
60
|
+
return `${this.lockName}:${timestamp}`;
|
|
61
|
+
}
|
|
62
|
+
async getMigrationForIdentifier(identifier) {
|
|
63
|
+
const timestamp = identifier.split('_')[0];
|
|
64
|
+
const migrationFiles = await this.getMigrationFiles();
|
|
65
|
+
const migrationFile = migrationFiles.find((m) => m.timestamp === timestamp);
|
|
66
|
+
return migrationFile ?? null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Loads the implementation for the migration with the given identifier. The identifier
|
|
70
|
+
* must start with a 14-character timestamp. It may optionally be followed by
|
|
71
|
+
* an underscore with additional characters, which are ignored. These should
|
|
72
|
+
* typically be used to provide a human-readable name for the migration.
|
|
73
|
+
*/
|
|
74
|
+
async loadMigrationImplementation(migrationFile) {
|
|
75
|
+
var _a;
|
|
76
|
+
// We use dynamic imports to handle both CJS and ESM modules.
|
|
77
|
+
const migrationModulePath = node_path_1.default.join(migrationFile.directory, migrationFile.filename);
|
|
78
|
+
const migrationModule = await (_a = migrationModulePath, Promise.resolve().then(() => __importStar(require(_a))));
|
|
79
|
+
const migrationImplementation = migrationModule.default;
|
|
80
|
+
(0, batched_migration_1.validateBatchedMigrationImplementation)(migrationImplementation);
|
|
81
|
+
return migrationImplementation;
|
|
82
|
+
}
|
|
83
|
+
async enqueueBatchedMigration(identifier) {
|
|
84
|
+
const migrationFile = await this.getMigrationForIdentifier(identifier);
|
|
85
|
+
if (!migrationFile) {
|
|
86
|
+
throw new Error(`No migration found for identifier ${identifier}`);
|
|
87
|
+
}
|
|
88
|
+
const migrationImplementation = await this.loadMigrationImplementation(migrationFile);
|
|
89
|
+
const migrationParameters = await migrationImplementation.getParameters();
|
|
90
|
+
// If `max` is null, that implies that there are no rows to process, so
|
|
91
|
+
// we can immediately mark the migration as finished.
|
|
92
|
+
const status = migrationParameters.max === null ? 'succeeded' : 'pending';
|
|
93
|
+
const minValue = BigInt(migrationParameters.min ?? DEFAULT_MIN_VALUE);
|
|
94
|
+
const maxValue = BigInt(migrationParameters.max ?? minValue);
|
|
95
|
+
const batchSize = migrationParameters.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
96
|
+
await (0, batched_migration_1.insertBatchedMigration)({
|
|
97
|
+
project: this.options.project,
|
|
98
|
+
filename: migrationFile.filename,
|
|
99
|
+
timestamp: migrationFile.timestamp,
|
|
100
|
+
batch_size: batchSize,
|
|
101
|
+
min_value: minValue,
|
|
102
|
+
max_value: maxValue,
|
|
103
|
+
status,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async finalizeBatchedMigration(identifier, options) {
|
|
107
|
+
const timestamp = identifier.split('_')[0];
|
|
108
|
+
let migration = await (0, batched_migration_1.selectBatchedMigrationForTimestamp)(this.options.project, timestamp);
|
|
109
|
+
if (migration.status === 'succeeded')
|
|
110
|
+
return;
|
|
111
|
+
// If the migration isn't already in the finalizing state, mark it as such.
|
|
112
|
+
if (migration.status !== 'finalizing') {
|
|
113
|
+
migration = await (0, batched_migration_1.updateBatchedMigrationStatus)(migration.id, 'finalizing');
|
|
114
|
+
}
|
|
115
|
+
await (0, named_locks_1.doWithLock)(this.lockNameForTimestamp(timestamp), { autoRenew: true }, async () => {
|
|
116
|
+
const migrationFile = await this.getMigrationForIdentifier(identifier);
|
|
117
|
+
if (!migrationFile) {
|
|
118
|
+
throw new Error(`No migration found for identifier ${identifier}`);
|
|
119
|
+
}
|
|
120
|
+
const migrationImplementation = await this.loadMigrationImplementation(migrationFile);
|
|
121
|
+
const runner = new batched_migration_runner_1.BatchedMigrationRunner(migration, migrationImplementation, {
|
|
122
|
+
// Always log progress unless explicitly disabled.
|
|
123
|
+
logProgress: options?.logProgress ?? true,
|
|
124
|
+
});
|
|
125
|
+
// Because we don't give any arguments to `run()`, it will run until it
|
|
126
|
+
// has attempted every job.
|
|
127
|
+
await runner.run();
|
|
128
|
+
});
|
|
129
|
+
migration = await (0, batched_migration_1.selectBatchedMigrationForTimestamp)(this.options.project, timestamp);
|
|
130
|
+
if (migration.status === 'succeeded')
|
|
131
|
+
return;
|
|
132
|
+
throw new Error(`Expected batched migration with identifier ${identifier} to be marked as 'succeeded', but it is '${migration.status}'.`);
|
|
133
|
+
}
|
|
134
|
+
start(options = {}) {
|
|
135
|
+
if (this.running) {
|
|
136
|
+
throw new Error('BatchedMigrationsRunner is already running');
|
|
137
|
+
}
|
|
138
|
+
this.loop(options);
|
|
139
|
+
}
|
|
140
|
+
async loop({ workDurationMs, sleepDurationMs }) {
|
|
141
|
+
workDurationMs ?? (workDurationMs = DEFAULT_WORK_DURATION_MS);
|
|
142
|
+
sleepDurationMs ?? (sleepDurationMs = DEFAULT_SLEEP_DURATION_MS);
|
|
143
|
+
this.running = true;
|
|
144
|
+
while (this.running) {
|
|
145
|
+
if (this.abortController.signal.aborted) {
|
|
146
|
+
// We assign this here so that `stop()` can tell when this loop is done
|
|
147
|
+
// processing jobs.
|
|
148
|
+
this.running = false;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
let didWork = false;
|
|
152
|
+
try {
|
|
153
|
+
didWork = await this.maybePerformWork(workDurationMs);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
this.emit('error', err);
|
|
157
|
+
}
|
|
158
|
+
// If we did work, we'll immediately try again since there's probably more
|
|
159
|
+
// work to be done. If not, we'll sleep for a while - maybe some more work
|
|
160
|
+
// will become available!
|
|
161
|
+
if (!didWork) {
|
|
162
|
+
// We provide the signal here so that we can more quickly stop things
|
|
163
|
+
// when we're shutting down.
|
|
164
|
+
try {
|
|
165
|
+
await (0, promises_1.setTimeout)(sleepDurationMs, null, { ref: false, signal: this.abortController.signal });
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
// We don't care about errors here, they should only ever occur when
|
|
169
|
+
// the AbortController is aborted. Continue to the next iteration of
|
|
170
|
+
// the loop so we can shut down.
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async getOrStartMigration() {
|
|
177
|
+
return (0, named_locks_1.doWithLock)(this.lockName, {}, async () => {
|
|
178
|
+
let migration = await (0, postgres_1.queryValidatedZeroOrOneRow)(sql.select_running_migration, { project: this.options.project }, batched_migration_1.BatchedMigrationRowSchema);
|
|
179
|
+
if (!migration) {
|
|
180
|
+
migration = await (0, postgres_1.queryValidatedZeroOrOneRow)(sql.start_next_pending_migration, { project: this.options.project }, batched_migration_1.BatchedMigrationRowSchema);
|
|
181
|
+
}
|
|
182
|
+
return migration;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
async maybePerformWork(durationMs) {
|
|
186
|
+
const migration = await this.getOrStartMigration();
|
|
187
|
+
if (!migration) {
|
|
188
|
+
// No work to do. Handle this case.
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
// This server may not yet know about the current running migration. If
|
|
192
|
+
// that's the case, we'll just skip it for now.
|
|
193
|
+
const migrationFile = await this.getMigrationForIdentifier(migration.timestamp);
|
|
194
|
+
if (!migrationFile) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
let didWork = false;
|
|
198
|
+
await (0, named_locks_1.tryWithLock)(this.lockNameForTimestamp(migrationFile.timestamp), { autoRenew: true }, async () => {
|
|
199
|
+
didWork = true;
|
|
200
|
+
const migrationImplementation = await this.loadMigrationImplementation(migrationFile);
|
|
201
|
+
const runner = new batched_migration_runner_1.BatchedMigrationRunner(migration, migrationImplementation);
|
|
202
|
+
try {
|
|
203
|
+
await runner.run({ signal: this.abortController.signal, durationMs });
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
this.emit('error', err);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
return didWork;
|
|
210
|
+
}
|
|
211
|
+
async stop() {
|
|
212
|
+
this.abortController.abort();
|
|
213
|
+
// Spin until we're no longer running.
|
|
214
|
+
while (this.running) {
|
|
215
|
+
await (0, promises_1.setTimeout)(1000);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.BatchedMigrationsRunner = BatchedMigrationsRunner;
|
|
220
|
+
let runner = null;
|
|
221
|
+
function assertRunner(runner) {
|
|
222
|
+
if (!runner)
|
|
223
|
+
throw new Error('Batched migrations not initialized');
|
|
224
|
+
}
|
|
225
|
+
function initBatchedMigrations(options) {
|
|
226
|
+
if (runner)
|
|
227
|
+
throw new Error('Batched migrations already initialized');
|
|
228
|
+
runner = new BatchedMigrationsRunner(options);
|
|
229
|
+
return runner;
|
|
230
|
+
}
|
|
231
|
+
exports.initBatchedMigrations = initBatchedMigrations;
|
|
232
|
+
function startBatchedMigrations(options = {}) {
|
|
233
|
+
assertRunner(runner);
|
|
234
|
+
runner.start(options);
|
|
235
|
+
return runner;
|
|
236
|
+
}
|
|
237
|
+
exports.startBatchedMigrations = startBatchedMigrations;
|
|
238
|
+
async function stopBatchedMigrations() {
|
|
239
|
+
assertRunner(runner);
|
|
240
|
+
await runner.stop();
|
|
241
|
+
runner = null;
|
|
242
|
+
}
|
|
243
|
+
exports.stopBatchedMigrations = stopBatchedMigrations;
|
|
244
|
+
/**
|
|
245
|
+
* Given a batched migration identifier like `20230406184103_migration`,
|
|
246
|
+
* enqueues it for execution by creating a row in the `batched_migrations`
|
|
247
|
+
* table.
|
|
248
|
+
*
|
|
249
|
+
* Despite taking a full identifier, only the timestamp is used to uniquely
|
|
250
|
+
* identify the batched migration. The remaining part is just used to make
|
|
251
|
+
* calls more human-readable.
|
|
252
|
+
*
|
|
253
|
+
* @param identifier The identifier of the batched migration to enqueue.
|
|
254
|
+
*/
|
|
255
|
+
async function enqueueBatchedMigration(identifier) {
|
|
256
|
+
assertRunner(runner);
|
|
257
|
+
await runner.enqueueBatchedMigration(identifier);
|
|
258
|
+
}
|
|
259
|
+
exports.enqueueBatchedMigration = enqueueBatchedMigration;
|
|
260
|
+
/**
|
|
261
|
+
* Given a batched migration identifier like `20230406184103_migration`,
|
|
262
|
+
* synchronously runs it to completion. An error will be thrown if the final
|
|
263
|
+
* status of the migration is not `succeeded`.
|
|
264
|
+
*
|
|
265
|
+
* @param identifier The identifier of the batched migration to finalize.
|
|
266
|
+
* @param options Options for finalizing the batched migration.
|
|
267
|
+
*/
|
|
268
|
+
async function finalizeBatchedMigration(identifier, options) {
|
|
269
|
+
assertRunner(runner);
|
|
270
|
+
await runner.finalizeBatchedMigration(identifier, options);
|
|
271
|
+
}
|
|
272
|
+
exports.finalizeBatchedMigration = finalizeBatchedMigration;
|
|
273
|
+
//# sourceMappingURL=batched-migrations-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batched-migrations-runner.js","sourceRoot":"","sources":["../../src/batched-migrations/batched-migrations-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
-- BLOCK select_running_migration
|
|
2
|
+
SELECT
|
|
3
|
+
*
|
|
4
|
+
FROM
|
|
5
|
+
batched_migrations
|
|
6
|
+
WHERE
|
|
7
|
+
status = 'running'
|
|
8
|
+
AND project = $project
|
|
9
|
+
ORDER BY
|
|
10
|
+
id ASC
|
|
11
|
+
LIMIT
|
|
12
|
+
1;
|
|
13
|
+
|
|
14
|
+
-- BLOCK start_next_pending_migration
|
|
15
|
+
UPDATE batched_migrations
|
|
16
|
+
SET
|
|
17
|
+
status = 'running',
|
|
18
|
+
started_at = CURRENT_TIMESTAMP,
|
|
19
|
+
updated_at = CURRENT_TIMESTAMP
|
|
20
|
+
WHERE
|
|
21
|
+
id = (
|
|
22
|
+
SELECT
|
|
23
|
+
id
|
|
24
|
+
FROM
|
|
25
|
+
batched_migrations
|
|
26
|
+
WHERE
|
|
27
|
+
status = 'pending'
|
|
28
|
+
AND project = $project
|
|
29
|
+
ORDER BY
|
|
30
|
+
id ASC
|
|
31
|
+
LIMIT
|
|
32
|
+
1
|
|
33
|
+
)
|
|
34
|
+
RETURNING
|
|
35
|
+
*;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const chai_1 = __importStar(require("chai"));
|
|
30
|
+
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
|
|
31
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
32
|
+
const postgres_1 = require("@prairielearn/postgres");
|
|
33
|
+
const namedLocks = __importStar(require("@prairielearn/named-locks"));
|
|
34
|
+
const index_1 = require("../index");
|
|
35
|
+
const batched_migrations_runner_1 = require("./batched-migrations-runner");
|
|
36
|
+
const batched_migration_1 = require("./batched-migration");
|
|
37
|
+
chai_1.default.use(chai_as_promised_1.default);
|
|
38
|
+
const postgresTestUtils = (0, postgres_1.makePostgresTestUtils)({
|
|
39
|
+
database: 'prairielearn_migrations',
|
|
40
|
+
});
|
|
41
|
+
describe('BatchedMigrationsRunner', () => {
|
|
42
|
+
before(async () => {
|
|
43
|
+
await postgresTestUtils.createDatabase();
|
|
44
|
+
await namedLocks.init(postgresTestUtils.getPoolConfig(), (err) => {
|
|
45
|
+
throw err;
|
|
46
|
+
});
|
|
47
|
+
await (0, index_1.init)([index_1.SCHEMA_MIGRATIONS_PATH], 'prairielearn_migrations');
|
|
48
|
+
});
|
|
49
|
+
afterEach(async () => {
|
|
50
|
+
await postgresTestUtils.resetDatabase();
|
|
51
|
+
});
|
|
52
|
+
after(async () => {
|
|
53
|
+
await namedLocks.close();
|
|
54
|
+
await postgresTestUtils.dropDatabase();
|
|
55
|
+
});
|
|
56
|
+
it('enqueues migrations', async () => {
|
|
57
|
+
const runner = new batched_migrations_runner_1.BatchedMigrationsRunner({
|
|
58
|
+
project: 'test',
|
|
59
|
+
directories: [node_path_1.default.join(__dirname, 'fixtures')],
|
|
60
|
+
});
|
|
61
|
+
await runner.enqueueBatchedMigration('20230406184103_successful_migration');
|
|
62
|
+
await runner.enqueueBatchedMigration('20230406184107_failing_migration');
|
|
63
|
+
await runner.enqueueBatchedMigration('20230407230446_no_rows_migration');
|
|
64
|
+
const migrations = await (0, batched_migration_1.selectAllBatchedMigrations)('test');
|
|
65
|
+
chai_1.assert.lengthOf(migrations, 3);
|
|
66
|
+
chai_1.assert.equal(migrations[0].timestamp, '20230406184103');
|
|
67
|
+
chai_1.assert.equal(migrations[0].filename, '20230406184103_successful_migration.ts');
|
|
68
|
+
chai_1.assert.equal(migrations[0].status, 'pending');
|
|
69
|
+
chai_1.assert.equal(migrations[1].timestamp, '20230406184107');
|
|
70
|
+
chai_1.assert.equal(migrations[1].filename, '20230406184107_failing_migration.js');
|
|
71
|
+
chai_1.assert.equal(migrations[1].status, 'pending');
|
|
72
|
+
chai_1.assert.equal(migrations[2].timestamp, '20230407230446');
|
|
73
|
+
chai_1.assert.equal(migrations[2].filename, '20230407230446_no_rows_migration.ts');
|
|
74
|
+
chai_1.assert.equal(migrations[2].status, 'succeeded');
|
|
75
|
+
});
|
|
76
|
+
it('safely enqueues migrations multiple times', async () => {
|
|
77
|
+
const runner = new batched_migrations_runner_1.BatchedMigrationsRunner({
|
|
78
|
+
project: 'test',
|
|
79
|
+
directories: [node_path_1.default.join(__dirname, 'fixtures')],
|
|
80
|
+
});
|
|
81
|
+
await runner.enqueueBatchedMigration('20230406184103_successful_migration');
|
|
82
|
+
await runner.enqueueBatchedMigration('20230406184103_successful_migration');
|
|
83
|
+
await runner.enqueueBatchedMigration('20230406184103_successful_migration');
|
|
84
|
+
const migrations = await (0, batched_migration_1.selectAllBatchedMigrations)('test');
|
|
85
|
+
chai_1.assert.lengthOf(migrations, 1);
|
|
86
|
+
});
|
|
87
|
+
it('finalizes a successful migration', async () => {
|
|
88
|
+
const runner = new batched_migrations_runner_1.BatchedMigrationsRunner({
|
|
89
|
+
project: 'test',
|
|
90
|
+
directories: [node_path_1.default.join(__dirname, 'fixtures')],
|
|
91
|
+
});
|
|
92
|
+
await runner.enqueueBatchedMigration('20230406184103_successful_migration');
|
|
93
|
+
await runner.finalizeBatchedMigration('20230406184103_successful_migration', {
|
|
94
|
+
logProgress: false,
|
|
95
|
+
});
|
|
96
|
+
const migrations = await (0, batched_migration_1.selectAllBatchedMigrations)('test');
|
|
97
|
+
chai_1.assert.lengthOf(migrations, 1);
|
|
98
|
+
chai_1.assert.equal(migrations[0].timestamp, '20230406184103');
|
|
99
|
+
chai_1.assert.equal(migrations[0].status, 'succeeded');
|
|
100
|
+
});
|
|
101
|
+
it('finalizes a failing migration', async () => {
|
|
102
|
+
const runner = new batched_migrations_runner_1.BatchedMigrationsRunner({
|
|
103
|
+
project: 'test',
|
|
104
|
+
directories: [node_path_1.default.join(__dirname, 'fixtures')],
|
|
105
|
+
});
|
|
106
|
+
await runner.enqueueBatchedMigration('20230406184107_failing_migration');
|
|
107
|
+
await chai_1.assert.isRejected(runner.finalizeBatchedMigration('20230406184107_failing_migration', {
|
|
108
|
+
logProgress: false,
|
|
109
|
+
}), "but it is 'failed'");
|
|
110
|
+
const migrations = await (0, batched_migration_1.selectAllBatchedMigrations)('test');
|
|
111
|
+
chai_1.assert.lengthOf(migrations, 1);
|
|
112
|
+
chai_1.assert.equal(migrations[0].timestamp, '20230406184107');
|
|
113
|
+
chai_1.assert.equal(migrations[0].status, 'failed');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=batched-migrations-runner.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batched-migrations-runner.test.js","sourceRoot":"","sources":["../../src/batched-migrations/batched-migrations-runner.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const batched_migration_1 = require("../batched-migration");
|
|
4
|
+
exports.default = (0, batched_migration_1.makeBatchedMigration)({
|
|
5
|
+
async getParameters() {
|
|
6
|
+
return {
|
|
7
|
+
min: 1n,
|
|
8
|
+
max: 100n,
|
|
9
|
+
batchSize: 10,
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
async execute(_min, _max) { },
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=20230406184103_successful_migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20230406184103_successful_migration.js","sourceRoot":"","sources":["../../../src/batched-migrations/fixtures/20230406184103_successful_migration.ts"],"names":[],"mappings":";;AAAA,4DAA4D;AAE5D,kBAAe,IAAA,wCAAoB,EAAC;IAClC,KAAK,CAAC,aAAa;QACjB,OAAO;YACL,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,IAAI;YACT,SAAS,EAAE,EAAE;SACd,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,IAAY,IAAG,CAAC;CAC7C,CAAC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const batched_migration_1 = require("../batched-migration");
|
|
4
|
+
exports.default = (0, batched_migration_1.makeBatchedMigration)({
|
|
5
|
+
async getParameters() {
|
|
6
|
+
return {
|
|
7
|
+
// Simulates the case where there are no rows to process. A null
|
|
8
|
+
// max value is what we would get for some query like
|
|
9
|
+
// `SELECT MAX(id) FROM table;`.
|
|
10
|
+
max: null,
|
|
11
|
+
batchSize: 10,
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
async execute(_min, _max) { },
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=20230407230446_no_rows_migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20230407230446_no_rows_migration.js","sourceRoot":"","sources":["../../../src/batched-migrations/fixtures/20230407230446_no_rows_migration.ts"],"names":[],"mappings":";;AAAA,4DAA4D;AAE5D,kBAAe,IAAA,wCAAoB,EAAC;IAClC,KAAK,CAAC,aAAa;QACjB,OAAO;YACL,gEAAgE;YAChE,qDAAqD;YACrD,gCAAgC;YAChC,GAAG,EAAE,IAAI;YACT,SAAS,EAAE,EAAE;SACd,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,IAAY,IAAG,CAAC;CAC7C,CAAC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { BatchedMigrationRow, BatchedMigrationStatus, makeBatchedMigration, selectAllBatchedMigrations, selectBatchedMigration, selectBatchedMigrationForTimestamp, retryFailedBatchedMigrationJobs, } from './batched-migration';
|
|
2
|
+
export { BatchedMigrationJobRow, BatchedMigrationJobStatus, selectRecentJobsWithStatus, } from './batched-migration-job';
|
|
3
|
+
export { initBatchedMigrations, startBatchedMigrations, stopBatchedMigrations, enqueueBatchedMigration, finalizeBatchedMigration, } from './batched-migrations-runner';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.finalizeBatchedMigration = exports.enqueueBatchedMigration = exports.stopBatchedMigrations = exports.startBatchedMigrations = exports.initBatchedMigrations = exports.selectRecentJobsWithStatus = exports.retryFailedBatchedMigrationJobs = exports.selectBatchedMigrationForTimestamp = exports.selectBatchedMigration = exports.selectAllBatchedMigrations = exports.makeBatchedMigration = void 0;
|
|
4
|
+
var batched_migration_1 = require("./batched-migration");
|
|
5
|
+
Object.defineProperty(exports, "makeBatchedMigration", { enumerable: true, get: function () { return batched_migration_1.makeBatchedMigration; } });
|
|
6
|
+
Object.defineProperty(exports, "selectAllBatchedMigrations", { enumerable: true, get: function () { return batched_migration_1.selectAllBatchedMigrations; } });
|
|
7
|
+
Object.defineProperty(exports, "selectBatchedMigration", { enumerable: true, get: function () { return batched_migration_1.selectBatchedMigration; } });
|
|
8
|
+
Object.defineProperty(exports, "selectBatchedMigrationForTimestamp", { enumerable: true, get: function () { return batched_migration_1.selectBatchedMigrationForTimestamp; } });
|
|
9
|
+
Object.defineProperty(exports, "retryFailedBatchedMigrationJobs", { enumerable: true, get: function () { return batched_migration_1.retryFailedBatchedMigrationJobs; } });
|
|
10
|
+
var batched_migration_job_1 = require("./batched-migration-job");
|
|
11
|
+
Object.defineProperty(exports, "selectRecentJobsWithStatus", { enumerable: true, get: function () { return batched_migration_job_1.selectRecentJobsWithStatus; } });
|
|
12
|
+
var batched_migrations_runner_1 = require("./batched-migrations-runner");
|
|
13
|
+
Object.defineProperty(exports, "initBatchedMigrations", { enumerable: true, get: function () { return batched_migrations_runner_1.initBatchedMigrations; } });
|
|
14
|
+
Object.defineProperty(exports, "startBatchedMigrations", { enumerable: true, get: function () { return batched_migrations_runner_1.startBatchedMigrations; } });
|
|
15
|
+
Object.defineProperty(exports, "stopBatchedMigrations", { enumerable: true, get: function () { return batched_migrations_runner_1.stopBatchedMigrations; } });
|
|
16
|
+
Object.defineProperty(exports, "enqueueBatchedMigration", { enumerable: true, get: function () { return batched_migrations_runner_1.enqueueBatchedMigration; } });
|
|
17
|
+
Object.defineProperty(exports, "finalizeBatchedMigration", { enumerable: true, get: function () { return batched_migrations_runner_1.finalizeBatchedMigration; } });
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/batched-migrations/index.ts"],"names":[],"mappings":";;;AAAA,yDAQ6B;AAL3B,yHAAA,oBAAoB,OAAA;AACpB,+HAAA,0BAA0B,OAAA;AAC1B,2HAAA,sBAAsB,OAAA;AACtB,uIAAA,kCAAkC,OAAA;AAClC,oIAAA,+BAA+B,OAAA;AAEjC,iEAIiC;AAD/B,mIAAA,0BAA0B,OAAA;AAE5B,yEAMqC;AALnC,kIAAA,qBAAqB,OAAA;AACrB,mIAAA,sBAAsB,OAAA;AACtB,kIAAA,qBAAqB,OAAA;AACrB,oIAAA,uBAAuB,OAAA;AACvB,qIAAA,wBAAwB,OAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
timestamp: string;
|
|
5
|
-
}
|
|
6
|
-
export declare function readAndValidateMigrationsFromDirectory(dir: string): Promise<MigrationFile[]>;
|
|
7
|
-
export declare function sortMigrationFiles(migrationFiles: MigrationFile[]): MigrationFile[];
|
|
8
|
-
export declare function getMigrationsToExecute(migrationFiles: MigrationFile[], executedMigrations: {
|
|
9
|
-
timestamp: string | null;
|
|
10
|
-
}[]): MigrationFile[];
|
|
11
|
-
export {};
|
|
1
|
+
export { init } from './migrations';
|
|
2
|
+
export { BatchedMigrationRow, BatchedMigrationStatus, BatchedMigrationJobRow, BatchedMigrationJobStatus, makeBatchedMigration, initBatchedMigrations, startBatchedMigrations, stopBatchedMigrations, enqueueBatchedMigration, finalizeBatchedMigration, selectAllBatchedMigrations, selectBatchedMigration, selectBatchedMigrationForTimestamp, selectRecentJobsWithStatus, } from './batched-migrations';
|
|
3
|
+
export declare const SCHEMA_MIGRATIONS_PATH: string;
|