db-migrate 1.0.0-beta.22 → 1.0.0-beta.23

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/api.js CHANGED
@@ -245,6 +245,31 @@ dbmigrate.prototype = {
245
245
  );
246
246
  },
247
247
 
248
+ fix: function (specification, opts, callback) {
249
+ var executeFix = load('fix');
250
+
251
+ if (arguments.length > 0) {
252
+ if (typeof specification === 'string') {
253
+ this.internals.argv.destination = specification;
254
+ } else if (typeof specification === 'number') {
255
+ this.internals.argv.count = specification;
256
+ } else if (typeof specification === 'function') {
257
+ callback = specification;
258
+ }
259
+
260
+ if (typeof opts === 'string') {
261
+ this.internals.migrationMode = opts;
262
+ this.internals.matching = opts;
263
+ } else if (typeof opts === 'function') {
264
+ callback = opts;
265
+ }
266
+ }
267
+
268
+ return Promise.resolve(executeFix(this.internals, this.config)).nodeify(
269
+ callback
270
+ );
271
+ },
272
+
248
273
  check: function (specification, opts, callback) {
249
274
  var executeCheck = load('check');
250
275
 
@@ -0,0 +1,52 @@
1
+ var path = require('path');
2
+ var log = require('db-migrate-shared').log;
3
+ var migrationHook = require('./helper/migration-hook.js');
4
+
5
+ async function prepare (internals, config) {
6
+ try {
7
+ await migrationHook(internals);
8
+ var Migrator = require('../walker.js');
9
+ var index = require('../../connect');
10
+
11
+ if (!internals.argv.count) {
12
+ internals.argv.count = Number.MAX_VALUE;
13
+ }
14
+ const migrator = await index.connect(
15
+ {
16
+ config: config.getCurrent().settings,
17
+ internals: internals,
18
+ prefix: 'migration'
19
+ },
20
+ Migrator
21
+ );
22
+
23
+ if (internals.locTitle) {
24
+ migrator.directory = path.resolve(
25
+ internals.argv['migrations-dir'],
26
+ internals.locTitle
27
+ );
28
+ } else {
29
+ migrator.directory = path.resolve(internals.argv['migrations-dir']);
30
+ }
31
+
32
+ internals.migrationsDir = migrator.directory;
33
+
34
+ await migrator.createMigrationsTable();
35
+ log.verbose('migration table created');
36
+
37
+ return migrator;
38
+ } catch (err) {
39
+ throw err;
40
+ }
41
+ }
42
+
43
+ module.exports = async function (internals, config) {
44
+ const migrator = await prepare(internals, config);
45
+
46
+ try {
47
+ const res = await migrator.fix(internals.argv);
48
+ return internals.onComplete(migrator, internals, null, res);
49
+ } catch (err) {
50
+ return internals.onComplete(migrator, internals, err);
51
+ }
52
+ };
@@ -9,6 +9,7 @@ const files = {
9
9
  "db": require('./db.js'),
10
10
  "down": require('./down.js'),
11
11
  "dump": require('./dump.js'),
12
+ "fix": require('./fix.js'),
12
13
  "fn/plugin": require('./fn/plugin.js'),
13
14
  "generated": require('./generated.js'),
14
15
  "helper/assert": require('./helper/assert.js'),
@@ -36,6 +36,7 @@ function run (internals, config) {
36
36
 
37
37
  executeSync(internals, config);
38
38
  break;
39
+ case 'fix':
39
40
  case 'up':
40
41
  case 'down':
41
42
  case 'reset':
@@ -58,6 +59,9 @@ function run (internals, config) {
58
59
  if (action === 'up') {
59
60
  var executeUp = load('up');
60
61
  executeUp(internals, config);
62
+ } else if (action === 'fix') {
63
+ var executeFix = load('fix');
64
+ executeFix(internals, config);
61
65
  } else {
62
66
  var executeDown = load('down');
63
67
  executeDown(internals, config);
@@ -9,6 +9,7 @@ const StateTravel = require('../../methods/v2/statetravel');
9
9
  const Migrate = require('../../methods/v2/migrate');
10
10
  const TranslateState = require('../../methods/v2/translatestate');
11
11
  const AddConventions = require('../../methods/v2/conventions');
12
+ const util = require('util');
12
13
 
13
14
  const execUnit = {
14
15
  _extend: (context, type) => {
@@ -65,6 +66,45 @@ const execUnit = {
65
66
  // end migration, same as start migration
66
67
  },
67
68
 
69
+ fix: async function (context, driver, file) {
70
+ const _file = file.get();
71
+ const chain = new Chain(context._driver, file, driver, context.internals);
72
+ if (!_file._meta.noDefaultColumn) {
73
+ chain.addChain(AddConventions);
74
+ }
75
+ chain.addChain(Learn);
76
+ // chain.addChain(StateTravel);
77
+
78
+ await State.startMigration(context._driver, file, context.internals);
79
+ // startMigration - needs secondary instance since we can not afford to
80
+ // loose state and the transaction start will include these for roll back
81
+ // we will disable them probably at all from DDL when the driver does not
82
+ // explicitly signal DDL transaction support (like crdb)
83
+ try {
84
+ await _file.migrate(chain, {
85
+ options: context.internals.safeOptions,
86
+ seedLink: context.seedLink,
87
+ dbm: context.internals.safeOptions.dbmigrate
88
+ });
89
+ } catch (err) {
90
+ context.internals.rollback = true;
91
+
92
+ // transfer last state
93
+ chain.transferInt();
94
+
95
+ log.error(
96
+ 'An error occured. No alternative failure strategy defined. Rolling back!',
97
+ err
98
+ );
99
+ await execUnit.down(context, driver, file);
100
+ throw err;
101
+ }
102
+ await Promise.promisify(context.writeMigrationRecord.bind(context))(file);
103
+ await State.endMigration(context._driver, file, context.internals);
104
+ log.verbose(`[fix] current schema`, util.inspect(context.internals.schema, false, null, true));
105
+ // end migration, same as start migration
106
+ },
107
+
68
108
  down: async function (context, driver, file) {
69
109
  // start migration, see up comments
70
110
  await State.startMigration(context._driver, file, context.internals);
package/lib/walker.js CHANGED
@@ -239,6 +239,65 @@ Walker.prototype = {
239
239
  .nodeify(callback);
240
240
  },
241
241
 
242
+ fix: function (options, callback) {
243
+ const partialName = options.destination;
244
+ const count = options.count;
245
+ const sortFn = function (a, b) {
246
+ a = a.name.slice(0, a.name.indexOf('-'));
247
+ b = b.name.slice(0, b.name.indexOf('-'));
248
+
249
+ if (!isNaN(a)) {
250
+ return a - b;
251
+ }
252
+
253
+ return a.localeCompare(b);
254
+ };
255
+
256
+ const files = File.loadFromDatabase(
257
+ this.directory,
258
+ this.prefix,
259
+ this._driver,
260
+ this.internals
261
+ ).then(completedFiles => {
262
+ const toRun = dbmUtil.filterDown(completedFiles, partialName, count).sort(sortFn);
263
+
264
+ if (toRun.length === 0) {
265
+ log.info(this.title + 'Nothing to run');
266
+ }
267
+
268
+ if (this.internals.check) {
269
+ const toRunNames = toRun.map(migration => migration.name);
270
+ log.info(this.title + 'run:', toRunNames);
271
+ return toRunNames;
272
+ }
273
+
274
+ return toRun;
275
+ });
276
+
277
+ if (this.internals.check) {
278
+ return files.nodeify(callback);
279
+ }
280
+
281
+ return files
282
+ .each(file => {
283
+ log.verbose(this.title + 'preparing to run fix:', file.name);
284
+ const _meta = file.get()._meta || {};
285
+ const version = _meta.version || 1;
286
+ if (version < 2) {
287
+ log.warn(`${this.title} skipping "${file.name}" as v1 migrations do not maintain a schema`);
288
+ return Promise.resolve();
289
+ }
290
+
291
+ this.internals.modSchema = { i: {}, c: {}, f: {}, s: [] };
292
+ return require(`./executors/versioned/v${version}`).fix(
293
+ this,
294
+ this.driver,
295
+ file
296
+ );
297
+ })
298
+ .nodeify(callback);
299
+ },
300
+
242
301
  check: function (options, callback) {
243
302
  return Promise.all([
244
303
  File.loadFromDatabase(
package/package.json CHANGED
@@ -31,7 +31,7 @@
31
31
  "programable",
32
32
  "api"
33
33
  ],
34
- "version": "1.0.0-beta.22",
34
+ "version": "1.0.0-beta.23",
35
35
  "engines": {
36
36
  "node": ">=8.0.0"
37
37
  },