knex-migrator 4.0.4 → 4.1.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/README.md +12 -12
- package/lib/index.js +182 -208
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -6,14 +6,14 @@ A database migration tool for [knex.js](https://github.com/tgriesser/knex), whic
|
|
|
6
6
|
|
|
7
7
|
- [x] JS API
|
|
8
8
|
- [x] CLI Tool
|
|
9
|
-
- [x] Differentiation between database
|
|
9
|
+
- [x] Differentiation between database initialization and migration (Support for a database schema, [like we use in Ghost](https://github.com/TryGhost/Ghost/blob/1.16.2/core/server/data/schema/schema.js))
|
|
10
10
|
- [x] Support for database creation
|
|
11
11
|
- [x] Hooks
|
|
12
12
|
- [x] Rollback to latest version
|
|
13
13
|
- [x] Auto-Rollback on error
|
|
14
14
|
- [x] Database health check
|
|
15
15
|
- [x] Supports transactions
|
|
16
|
-
- [x] Full atomic, support for separate DML/DDL scripts (no autocommit)
|
|
16
|
+
- [x] Full atomic, support for separate DML/DDL scripts (no autocommit)
|
|
17
17
|
- [x] Migration lock
|
|
18
18
|
- [x] Full debug & pretty log support
|
|
19
19
|
- [x] Custom migration folder structure
|
|
@@ -36,8 +36,8 @@ Add me to your globals:
|
|
|
36
36
|
|
|
37
37
|
- Replicas are unsupported, because Knex.js [doesn't support them](https://github.com/tgriesser/knex/issues/2253).
|
|
38
38
|
- Sqlite does **not** support read locks by default. Read [here](https://github.com/TryGhost/knex-migrator/issues/87) why.
|
|
39
|
-
- [
|
|
40
|
-
- Don't mix DDL/DML statements in a migration script. In MySQL DDL statements use implicit commits.
|
|
39
|
+
- [Comparison](https://github.com/TryGhost/knex-migrator/issues/119) with other available migration tools.
|
|
40
|
+
- Don't mix DDL/DML statements in a migration script. In MySQL DDL statements use implicit commits.
|
|
41
41
|
- It's highly recommended to write both the `up` and the `down` function to ensure a full rollback.
|
|
42
42
|
- If your process dies while migrations are running, knex-migrator won't be able to release the migration lock.
|
|
43
43
|
To release to lock you can run `knex-migrator rollback`. **But** it's recommended to check your database first to see in which state it is.
|
|
@@ -73,7 +73,7 @@ Please take a look at [this real example](https://github.com/TryGhost/Ghost/blob
|
|
|
73
73
|
|
|
74
74
|
```
|
|
75
75
|
project/
|
|
76
|
-
migrations/
|
|
76
|
+
migrations/
|
|
77
77
|
hooks/
|
|
78
78
|
init/
|
|
79
79
|
index.js
|
|
@@ -88,9 +88,9 @@ project/
|
|
|
88
88
|
versions/
|
|
89
89
|
1.0/
|
|
90
90
|
1-add-events-table.js
|
|
91
|
-
2-normalise-settings.js
|
|
91
|
+
2-normalise-settings.js
|
|
92
92
|
2.0/
|
|
93
|
-
1-add-timestamps-columns.js
|
|
93
|
+
1-add-timestamps-columns.js
|
|
94
94
|
2.1/
|
|
95
95
|
1-remove-empty-strings.js
|
|
96
96
|
2-add-webhooks-table.js
|
|
@@ -199,7 +199,7 @@ Commands:
|
|
|
199
199
|
|
|
200
200
|
#### knex-migrator init
|
|
201
201
|
|
|
202
|
-
-
|
|
202
|
+
- Initializes your database based on your init scripts
|
|
203
203
|
- Creates the database if it was not created yet
|
|
204
204
|
|
|
205
205
|
##### Options
|
|
@@ -223,10 +223,10 @@ Commands:
|
|
|
223
223
|
##### Options
|
|
224
224
|
|
|
225
225
|
```bash
|
|
226
|
-
# The
|
|
226
|
+
# The version you would like to migrate to
|
|
227
227
|
--v
|
|
228
228
|
|
|
229
|
-
# Combo Feature to check whether the database was already
|
|
229
|
+
# Combo Feature to check whether the database was already initialized
|
|
230
230
|
--init
|
|
231
231
|
|
|
232
232
|
# Force the execution no matter which current version you are on
|
|
@@ -312,13 +312,13 @@ knexMigrator.reset
|
|
|
312
312
|
knexMigrator.isDatabaseOK()
|
|
313
313
|
.then(function() {
|
|
314
314
|
// database is OK
|
|
315
|
-
//
|
|
315
|
+
// initialization & migrations are not missing
|
|
316
316
|
})
|
|
317
317
|
.catch(function(err) {
|
|
318
318
|
if (err.code === 'DB_NOT_INITIALISED') {
|
|
319
319
|
return knexMigrator.init();
|
|
320
320
|
}
|
|
321
|
-
|
|
321
|
+
|
|
322
322
|
if (err.code === 'DB_NEEDS_MIGRATION') {
|
|
323
323
|
return knexMigrator.migrate();
|
|
324
324
|
}
|
package/lib/index.js
CHANGED
|
@@ -155,30 +155,28 @@ KnexMigrator.prototype.init = function init(options) {
|
|
|
155
155
|
throw err;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
return database.createTransaction(self.connection, function (transacting) {
|
|
158
|
+
return database.createTransaction(self.connection, async function (transacting) {
|
|
159
|
+
const existingMigrations = await transacting('migrations').select('name');
|
|
160
|
+
const existingMigrationsNames = existingMigrations.map(m => m.name);
|
|
161
|
+
|
|
159
162
|
// CASE: Run over all migration scripts and add the file name to the database.
|
|
160
|
-
|
|
163
|
+
for (const versionToMigrateTo of versionsToMigrateTo) {
|
|
161
164
|
let versionPath = path.join(self.migrationPath, self.subfolder, versionToMigrateTo);
|
|
162
165
|
let filesToMigrateTo = utils.listFiles(versionPath) || [];
|
|
163
166
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
currentVersion: self.currentVersion
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
});
|
|
167
|
+
// CASE: check if migration exists, do not insert twice
|
|
168
|
+
for (const name of filesToMigrateTo) {
|
|
169
|
+
if (existingMigrationsNames.includes(name)) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
await transacting('migrations').insert({
|
|
174
|
+
name,
|
|
175
|
+
version: versionToMigrateTo,
|
|
176
|
+
currentVersion: self.currentVersion
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
182
180
|
});
|
|
183
181
|
})
|
|
184
182
|
.then(function () {
|
|
@@ -286,11 +284,10 @@ KnexMigrator.prototype.init = function init(options) {
|
|
|
286
284
|
* @param {Object} options - Custom options you can pass in (version, force, init, only, skip)
|
|
287
285
|
* @returns {Bluebird<any>}
|
|
288
286
|
*/
|
|
289
|
-
KnexMigrator.prototype.migrate = function migrate(options) {
|
|
287
|
+
KnexMigrator.prototype.migrate = async function migrate(options) {
|
|
290
288
|
options = options || {};
|
|
291
289
|
|
|
292
|
-
let
|
|
293
|
-
onlyVersion = options.version,
|
|
290
|
+
let onlyVersion = options.version,
|
|
294
291
|
force = options.force,
|
|
295
292
|
init = options.init,
|
|
296
293
|
onlyFile = options.only,
|
|
@@ -308,14 +305,11 @@ KnexMigrator.prototype.migrate = function migrate(options) {
|
|
|
308
305
|
|
|
309
306
|
// CASE: `--init` flag is passed. Combo feature.
|
|
310
307
|
if (init) {
|
|
311
|
-
|
|
312
|
-
.then(function () {
|
|
313
|
-
return self.migrate(_.omit(options, 'init'));
|
|
314
|
-
});
|
|
308
|
+
await this.init();
|
|
315
309
|
}
|
|
316
310
|
|
|
317
311
|
try {
|
|
318
|
-
hooks = require(path.join(
|
|
312
|
+
hooks = require(path.join(this.migrationPath, '/hooks/migrate'));
|
|
319
313
|
} catch (err) {
|
|
320
314
|
debug('Hook Error: ' + err.message);
|
|
321
315
|
debug('No hooks found, no problem.');
|
|
@@ -323,152 +317,130 @@ KnexMigrator.prototype.migrate = function migrate(options) {
|
|
|
323
317
|
|
|
324
318
|
this.connection = database.connect(this.dbConfig);
|
|
325
319
|
|
|
326
|
-
|
|
327
|
-
.
|
|
328
|
-
return migrations.run(self.connection);
|
|
329
|
-
})
|
|
330
|
-
.then(function () {
|
|
331
|
-
return locking.lock(self.connection);
|
|
332
|
-
})
|
|
333
|
-
.then(function () {
|
|
334
|
-
return self._integrityCheck({
|
|
335
|
-
force: force
|
|
336
|
-
});
|
|
337
|
-
})
|
|
338
|
-
.then(function (result) {
|
|
339
|
-
_.each(result, function (value, version) {
|
|
340
|
-
// CASE: Log which versions won't be executed based on the "only" flag
|
|
341
|
-
if (onlyVersion && version !== onlyVersion) {
|
|
342
|
-
debug('Do not execute: ' + version);
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
});
|
|
320
|
+
try {
|
|
321
|
+
await database.ensureConnectionWorks(this.connection);
|
|
346
322
|
|
|
347
|
-
|
|
348
|
-
// CASE: filter out versions which should not run
|
|
349
|
-
let containsVersion = _.find(result, function (obj, key) {
|
|
350
|
-
return key === onlyVersion;
|
|
351
|
-
});
|
|
323
|
+
await migrations.run(this.connection);
|
|
352
324
|
|
|
353
|
-
|
|
354
|
-
logging.warn('Cannot find requested version: ' + onlyVersion);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
325
|
+
await locking.lock(this.connection);
|
|
357
326
|
|
|
358
|
-
|
|
359
|
-
// CASE: compare files on disk with files in database
|
|
360
|
-
if (value.expected !== value.actual) {
|
|
361
|
-
debug('Need to execute migrations for: ' + version);
|
|
362
|
-
versionsToMigrate.push(version);
|
|
363
|
-
}
|
|
364
|
-
});
|
|
365
|
-
})
|
|
366
|
-
.then(function executeBeforeHook() {
|
|
367
|
-
if (!versionsToMigrate.length) {
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
327
|
+
const result = await this._integrityCheck({force});
|
|
370
328
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
})
|
|
378
|
-
.then(function executeMigrations() {
|
|
379
|
-
if (!versionsToMigrate.length) {
|
|
329
|
+
_.each(result, function (_value, version) {
|
|
330
|
+
// CASE: Log which versions won't be executed based on the "only" flag
|
|
331
|
+
if (onlyVersion && version !== onlyVersion) {
|
|
332
|
+
debug('Do not execute: ' + version);
|
|
380
333
|
return;
|
|
381
334
|
}
|
|
335
|
+
});
|
|
382
336
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
hooks: hooks
|
|
388
|
-
});
|
|
337
|
+
if (onlyVersion) {
|
|
338
|
+
// CASE: filter out versions which should not run
|
|
339
|
+
let containsVersion = _.find(result, function (_obj, key) {
|
|
340
|
+
return key === onlyVersion;
|
|
389
341
|
});
|
|
390
|
-
})
|
|
391
|
-
.then(function executeAfterHook() {
|
|
392
|
-
if (!versionsToMigrate.length) {
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
342
|
|
|
396
|
-
if (
|
|
397
|
-
|
|
398
|
-
return hooks.after({
|
|
399
|
-
connection: self.connection
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
})
|
|
403
|
-
.then(function () {
|
|
404
|
-
return locking.unlock(self.connection);
|
|
405
|
-
})
|
|
406
|
-
.catch(function (err) {
|
|
407
|
-
// CASE: Do not rollback if migrations are locked
|
|
408
|
-
if (err instanceof errors.MigrationsAreLockedError) {
|
|
409
|
-
throw err;
|
|
343
|
+
if (!containsVersion) {
|
|
344
|
+
logging.warn('Cannot find requested version: ' + onlyVersion);
|
|
410
345
|
}
|
|
346
|
+
}
|
|
411
347
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
348
|
+
_.each(result, function (value, version) {
|
|
349
|
+
// CASE: compare files on disk with files in database
|
|
350
|
+
if (value.expected !== value.actual) {
|
|
351
|
+
debug('Need to execute migrations for: ' + version);
|
|
352
|
+
versionsToMigrate.push(version);
|
|
415
353
|
}
|
|
354
|
+
});
|
|
416
355
|
|
|
417
|
-
|
|
418
|
-
if (
|
|
419
|
-
|
|
356
|
+
if (versionsToMigrate.length) {
|
|
357
|
+
if (hooks.before) {
|
|
358
|
+
debug('Before hook');
|
|
359
|
+
await hooks.before({
|
|
360
|
+
connection: this.connection
|
|
361
|
+
});
|
|
420
362
|
}
|
|
421
363
|
|
|
422
|
-
|
|
423
|
-
debug(`Task failed: ${err.context.name}`);
|
|
424
|
-
}
|
|
364
|
+
logging.info('Running migrations.');
|
|
425
365
|
|
|
426
|
-
|
|
366
|
+
for (const versionToMigrate of versionsToMigrate) {
|
|
367
|
+
try {
|
|
368
|
+
await this._migrateTo({
|
|
369
|
+
version: versionToMigrate,
|
|
370
|
+
only: onlyFile,
|
|
371
|
+
hooks: hooks
|
|
372
|
+
});
|
|
373
|
+
} catch (err) {
|
|
374
|
+
// CASE: Do not rollback if migrations are locked
|
|
375
|
+
if (err instanceof errors.MigrationsAreLockedError) {
|
|
376
|
+
throw err;
|
|
377
|
+
}
|
|
427
378
|
|
|
428
|
-
|
|
379
|
+
// CASE: Do not rollback migration scripts, if lock error
|
|
380
|
+
if (err instanceof errors.LockError) {
|
|
381
|
+
throw err;
|
|
382
|
+
}
|
|
429
383
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
throw err;
|
|
435
|
-
}).catch(function (innerErr) {
|
|
436
|
-
if (errors.utils.isIgnitionError(innerErr)) {
|
|
437
|
-
throw err;
|
|
438
|
-
}
|
|
384
|
+
// CASE: ETIMEDOUT, ENOTFOUND
|
|
385
|
+
if (err instanceof errors.DatabaseError) {
|
|
386
|
+
throw err;
|
|
387
|
+
}
|
|
439
388
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
context: `OuterError: ${err.message}`
|
|
444
|
-
});
|
|
445
|
-
}).finally(function () {
|
|
446
|
-
return locking.unlock(self.connection);
|
|
447
|
-
});
|
|
448
|
-
}).finally(function () {
|
|
449
|
-
let ops = [];
|
|
389
|
+
if (err.context && err.context.name) {
|
|
390
|
+
debug(`Task failed: ${err.context.name}`);
|
|
391
|
+
}
|
|
450
392
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
393
|
+
logging.info(`Rolling back: ${err.message}.`);
|
|
394
|
+
|
|
395
|
+
const versionsMigrated = versionsToMigrate.slice(
|
|
396
|
+
0,
|
|
397
|
+
versionsToMigrate.indexOf(versionToMigrate) + 1
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
versionsMigrated.reverse();
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
for (const versionMigrated of versionsMigrated) {
|
|
404
|
+
await this._rollback({version: versionMigrated, task: err.context});
|
|
405
|
+
}
|
|
406
|
+
logging.info(`Rollback was successful.`);
|
|
407
|
+
throw err;
|
|
408
|
+
} catch (innerErr) {
|
|
409
|
+
if (errors.utils.isIgnitionError(innerErr)) {
|
|
410
|
+
throw err;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
throw new errors.RollbackError({
|
|
414
|
+
message: innerErr.message,
|
|
415
|
+
err: innerErr,
|
|
416
|
+
context: `OuterError: ${err.message}`
|
|
417
|
+
});
|
|
418
|
+
} finally {
|
|
419
|
+
await locking.unlock(this.connection);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
458
422
|
}
|
|
459
423
|
|
|
460
|
-
|
|
461
|
-
debug('
|
|
462
|
-
|
|
463
|
-
.
|
|
464
|
-
|
|
465
|
-
|
|
424
|
+
if (hooks.after) {
|
|
425
|
+
debug('After hook');
|
|
426
|
+
await hooks.after({
|
|
427
|
+
connection: this.connection
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
await locking.unlock(this.connection);
|
|
432
|
+
} finally {
|
|
433
|
+
if (hooks.shutdown) {
|
|
434
|
+
debug('Shutdown hook');
|
|
435
|
+
await hooks.shutdown({
|
|
436
|
+
executedFromShell: this.executedFromShell
|
|
466
437
|
});
|
|
438
|
+
}
|
|
467
439
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
440
|
+
debug('Destroy connection');
|
|
441
|
+
await this.connection.destroy();
|
|
442
|
+
debug('Destroyed connection');
|
|
443
|
+
}
|
|
472
444
|
};
|
|
473
445
|
|
|
474
446
|
/**
|
|
@@ -1132,7 +1104,6 @@ KnexMigrator.prototype._integrityCheck = function _integrityCheck(options) {
|
|
|
1132
1104
|
subfolder = this.subfolder,
|
|
1133
1105
|
force = options.force,
|
|
1134
1106
|
folders = [],
|
|
1135
|
-
operations = {},
|
|
1136
1107
|
toReturn = {},
|
|
1137
1108
|
futureVersions = [];
|
|
1138
1109
|
|
|
@@ -1148,29 +1119,69 @@ KnexMigrator.prototype._integrityCheck = function _integrityCheck(options) {
|
|
|
1148
1119
|
// ignore
|
|
1149
1120
|
}
|
|
1150
1121
|
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1122
|
+
return this
|
|
1123
|
+
.connection('migrations')
|
|
1124
|
+
.select('version')
|
|
1125
|
+
.count('version', {as: 'c'})
|
|
1126
|
+
.groupBy('version')
|
|
1127
|
+
.then((dbMigrations) => {
|
|
1128
|
+
_.each(folders, function (folder) {
|
|
1129
|
+
// CASE: versions/1.1-members or versions/2.0-payments
|
|
1130
|
+
if (folder !== 'init') {
|
|
1131
|
+
try {
|
|
1132
|
+
folder = folder.match(/([\d._]+)/)[0];
|
|
1133
|
+
} catch (err) {
|
|
1134
|
+
logging.warn('Cannot parse folder name.');
|
|
1135
|
+
logging.warn('Ignore Folder: ' + folder);
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1162
1139
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1140
|
+
// CASE:
|
|
1141
|
+
// if your current version is 1.0 and you add migration scripts for the next version 1.1
|
|
1142
|
+
// we won't execute them until your current version changes to 1.1 or until you force KM to migrate to it
|
|
1143
|
+
if (self.currentVersion && !force) {
|
|
1144
|
+
if (utils.isGreaterThanVersion({smallerVersion: self.currentVersion, greaterVersion: folder})) {
|
|
1145
|
+
futureVersions.push(folder);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
let actual = 0;
|
|
1150
|
+
let expected;
|
|
1151
|
+
|
|
1152
|
+
const migrationCount = dbMigrations.find(m => m.version === folder);
|
|
1153
|
+
if (migrationCount) {
|
|
1154
|
+
actual = migrationCount.c;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
if (folder !== 'init') {
|
|
1158
|
+
expected = utils.listFiles(path.join(self.migrationPath, subfolder, folder)).length;
|
|
1159
|
+
} else {
|
|
1160
|
+
expected = utils.listFiles(path.join(self.migrationPath, folder)).length;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
debug('Version ' + folder + ' expected: ' + expected);
|
|
1164
|
+
debug('Version ' + folder + ' actual: ' + actual);
|
|
1165
|
+
|
|
1166
|
+
toReturn[folder] = {
|
|
1167
|
+
expected: expected,
|
|
1168
|
+
actual: actual
|
|
1169
|
+
};
|
|
1170
|
+
});
|
|
1171
|
+
|
|
1172
|
+
// CASE: ensure that either you have to run `migrate --force` or they ran already
|
|
1173
|
+
if (futureVersions.length) {
|
|
1174
|
+
_.each(futureVersions, function (futureVersion) {
|
|
1175
|
+
if (toReturn[futureVersion].actual !== toReturn[futureVersion].expected) {
|
|
1176
|
+
logging.warn('knex-migrator is skipping ' + futureVersion);
|
|
1177
|
+
logging.warn('Current version in MigratorConfig.js is smaller then requested version, use --force to proceed!');
|
|
1178
|
+
logging.warn('Please run `knex-migrator migrate --v ' + futureVersion + ' --force` to proceed!');
|
|
1179
|
+
delete toReturn[futureVersion];
|
|
1180
|
+
}
|
|
1181
|
+
});
|
|
1169
1182
|
}
|
|
1170
|
-
}
|
|
1171
1183
|
|
|
1172
|
-
|
|
1173
|
-
version: folder
|
|
1184
|
+
return toReturn;
|
|
1174
1185
|
}).catch(function onMigrationsLookupError(err) {
|
|
1175
1186
|
// CASE: no database selected (database.connection.database="")
|
|
1176
1187
|
if (err.errno === 1046) {
|
|
@@ -1199,43 +1210,6 @@ KnexMigrator.prototype._integrityCheck = function _integrityCheck(options) {
|
|
|
1199
1210
|
|
|
1200
1211
|
throw err;
|
|
1201
1212
|
});
|
|
1202
|
-
});
|
|
1203
|
-
|
|
1204
|
-
return Promise.props(operations)
|
|
1205
|
-
.then(function (result) {
|
|
1206
|
-
_.each(result, function (value, version) {
|
|
1207
|
-
let actual = value.length,
|
|
1208
|
-
expected = actual;
|
|
1209
|
-
|
|
1210
|
-
if (version !== 'init') {
|
|
1211
|
-
expected = utils.listFiles(path.join(self.migrationPath, subfolder, version)).length;
|
|
1212
|
-
} else {
|
|
1213
|
-
expected = utils.listFiles(path.join(self.migrationPath, version)).length;
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
debug('Version ' + version + ' expected: ' + expected);
|
|
1217
|
-
debug('Version ' + version + ' actual: ' + actual);
|
|
1218
|
-
|
|
1219
|
-
toReturn[version] = {
|
|
1220
|
-
expected: expected,
|
|
1221
|
-
actual: actual
|
|
1222
|
-
};
|
|
1223
|
-
});
|
|
1224
|
-
|
|
1225
|
-
// CASE: ensure that either you have to run `migrate --force` or they ran already
|
|
1226
|
-
if (futureVersions.length) {
|
|
1227
|
-
_.each(futureVersions, function (futureVersion) {
|
|
1228
|
-
if (toReturn[futureVersion].actual !== toReturn[futureVersion].expected) {
|
|
1229
|
-
logging.warn('knex-migrator is skipping ' + futureVersion);
|
|
1230
|
-
logging.warn('Current version in MigratorConfig.js is smaller then requested version, use --force to proceed!');
|
|
1231
|
-
logging.warn('Please run `knex-migrator migrate --v ' + futureVersion + ' --force` to proceed!');
|
|
1232
|
-
delete toReturn[futureVersion];
|
|
1233
|
-
}
|
|
1234
|
-
});
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
return toReturn;
|
|
1238
|
-
});
|
|
1239
1213
|
};
|
|
1240
1214
|
|
|
1241
1215
|
module.exports = KnexMigrator;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knex-migrator",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.2",
|
|
4
4
|
"description": "Database migrations with knex.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ghost",
|
|
@@ -44,18 +44,18 @@
|
|
|
44
44
|
"knex-migrator-rollback": "./bin/knex-migrator-rollback"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
|
-
"node": "^
|
|
47
|
+
"node": "^12.22.1 || ^14.17.0 || ^16.13.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"bluebird": "3.7.2",
|
|
51
51
|
"commander": "5.1.0",
|
|
52
52
|
"compare-ver": "2.0.2",
|
|
53
|
-
"debug": "4.3.
|
|
54
|
-
"ghost-ignition": "4.6.
|
|
53
|
+
"debug": "4.3.2",
|
|
54
|
+
"ghost-ignition": "4.6.3",
|
|
55
55
|
"knex": "0.21.19",
|
|
56
56
|
"lodash": "4.17.21",
|
|
57
57
|
"moment": "2.24.0",
|
|
58
|
-
"nconf": "0.11.
|
|
58
|
+
"nconf": "0.11.3",
|
|
59
59
|
"resolve": "1.20.0"
|
|
60
60
|
},
|
|
61
61
|
"files": [
|