db-migrate 1.0.0-beta.16

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +487 -0
  2. package/LICENSE +22 -0
  3. package/README.md +100 -0
  4. package/api.js +463 -0
  5. package/bin/db-migrate +39 -0
  6. package/connect.js +198 -0
  7. package/get.js +67 -0
  8. package/index.js +85 -0
  9. package/lib/chain.js +157 -0
  10. package/lib/class.js +75 -0
  11. package/lib/commands/check.js +52 -0
  12. package/lib/commands/create-migration.js +252 -0
  13. package/lib/commands/db.js +63 -0
  14. package/lib/commands/down.js +45 -0
  15. package/lib/commands/dump.js +22 -0
  16. package/lib/commands/fn/plugin.js +45 -0
  17. package/lib/commands/generated.js +32 -0
  18. package/lib/commands/helper/assert.js +15 -0
  19. package/lib/commands/helper/load-config.js +26 -0
  20. package/lib/commands/helper/migration-hook.js +4 -0
  21. package/lib/commands/helper/register-events.js +19 -0
  22. package/lib/commands/index.js +9 -0
  23. package/lib/commands/on-complete.js +28 -0
  24. package/lib/commands/run.js +122 -0
  25. package/lib/commands/seed.js +48 -0
  26. package/lib/commands/set-default-argv.js +169 -0
  27. package/lib/commands/sync.js +52 -0
  28. package/lib/commands/undo-seed.js +54 -0
  29. package/lib/commands/up.js +52 -0
  30. package/lib/config.js +207 -0
  31. package/lib/driver/index.js +156 -0
  32. package/lib/driver/shadow.js +74 -0
  33. package/lib/executors/versioned/v1.js +48 -0
  34. package/lib/executors/versioned/v2.js +78 -0
  35. package/lib/file.js +190 -0
  36. package/lib/interface/migratorInterface.js +127 -0
  37. package/lib/interface/seederInterface.js +145 -0
  38. package/lib/learn.js +369 -0
  39. package/lib/methods/v2/conventions.js +47 -0
  40. package/lib/methods/v2/migrate.js +5 -0
  41. package/lib/methods/v2/statetravel.js +86 -0
  42. package/lib/methods/v2/translatestate.js +117 -0
  43. package/lib/relation.js +37 -0
  44. package/lib/state.js +154 -0
  45. package/lib/template.js +312 -0
  46. package/lib/templates/v2.js +12 -0
  47. package/lib/temputils.js +62 -0
  48. package/lib/walker.js +266 -0
  49. package/package.json +87 -0
  50. package/pnpm-lock.yaml +2574 -0
  51. package/te.js +70 -0
package/get.js ADDED
@@ -0,0 +1,67 @@
1
+ exports.migrate = async (db, opt) => {
2
+ await db.get('test', {
3
+ columns: ['column1']
4
+ });
5
+
6
+ /**
7
+ * columns can be aliased
8
+ */
9
+ await db.get('test', {
10
+ columns: {
11
+ column1: 'maxima'
12
+ }
13
+ });
14
+
15
+ /**
16
+ * We avoid tapping into complicated languages to define
17
+ * the where clause. Instead you just use SQL or mongo schema
18
+ * depending on the db you use. If you want to provide genericity we will
19
+ * suggest using helper libraries like sql2mongo or vice versa. This allows
20
+ * flexibility and avoids also the need to learn to many new things and
21
+ * reinventing the weel just for a translation layer in this case.
22
+ */
23
+ await db.get('test', {
24
+ columns: {
25
+ column1: 'maxima',
26
+ column2: 'something'
27
+ },
28
+ search: 'maxima >= 12'
29
+ });
30
+
31
+ /**
32
+ * However, the most simple operation we will support upfront. Everything
33
+ * else can use tooling. We will provide a plugin hook so this can be in
34
+ * doubt tightly integrated into the migrations.
35
+ */
36
+ await db.get('test', {
37
+ columns: {
38
+ column1: 'maxima',
39
+ column2: 'something'
40
+ },
41
+ search: {
42
+ maxima: 15
43
+ }
44
+ });
45
+
46
+ /**
47
+ * when doing more then searching, you want to access it in query mode.
48
+ * You will have to write the whole definition by hand. This guarantees
49
+ * that we still understand what is happening (type of operation), but
50
+ * gives ultimate flexibility.
51
+ *
52
+ * The table param is optional, when using for example SQL it will not be
53
+ * needed, databases like mongodb will need it however, so it might be
54
+ * recommended as a best practice to not omit it, depending on how ultimate
55
+ * the decision of the db is yet.
56
+ *
57
+ * Adding LIMITS yourself is possible, but leave this to db-migrate in doubt.
58
+ */
59
+ await db.get('test', {
60
+ query: 'DISTINCT value1 FROM test' // select will be forcefully prepended so we always know this will only get data
61
+ });
62
+ };
63
+
64
+ exports._meta = {
65
+ version: 2,
66
+ DML: true
67
+ };
package/index.js ADDED
@@ -0,0 +1,85 @@
1
+ module.exports.version = require('./package.json').version;
2
+
3
+ var fs = require('fs');
4
+ var path = require('path');
5
+ var log = require('db-migrate-shared').log;
6
+
7
+ exports.dataType = require('db-migrate-shared').dataType;
8
+
9
+ function loadPluginList (options) {
10
+ try {
11
+ fs.accessSync(path.join(options.cwd, 'package.json'), fs.constants.R_OK);
12
+ } catch (err) {
13
+ throw new Error(
14
+ 'There was no package.json found in the current working dir!',
15
+ options.cwd
16
+ );
17
+ }
18
+
19
+ try {
20
+ var plugins = JSON.parse(
21
+ fs.readFileSync(path.join(options.cwd, 'package.json'), 'utf-8')
22
+ );
23
+ } catch (err) {
24
+ throw new Error('Error parsing package.json', err);
25
+ }
26
+
27
+ var targets = [];
28
+
29
+ plugins = Object.assign(
30
+ plugins.dependencies || {},
31
+ plugins.devDependencies || {}
32
+ );
33
+
34
+ for (var plugin in plugins) {
35
+ if (plugin.startsWith('db-migrate-plugin')) targets.push(plugin);
36
+ }
37
+
38
+ return targets;
39
+ }
40
+
41
+ function loadPlugins (options) {
42
+ var plugins = loadPluginList(options);
43
+ var i = 0;
44
+ var length = plugins.length;
45
+ var hooks = {};
46
+
47
+ for (; i < length; ++i) {
48
+ var plugin = require(path.join(options.cwd, 'node_modules', plugins[i]));
49
+
50
+ if (!plugin.hooks || !plugin.loadPlugin) {
51
+ continue;
52
+ }
53
+
54
+ // name is now derived from package name
55
+ plugin.name = plugins[i];
56
+
57
+ plugin.hooks.forEach(function (hook) {
58
+ hooks[hook] = hooks[hook] || [];
59
+ hooks[hook].push(plugin);
60
+ });
61
+ }
62
+
63
+ return hooks;
64
+ }
65
+
66
+ module.exports.getInstance = function (isModule, options = {}, callback) {
67
+ delete require.cache[require.resolve('./api.js')];
68
+ delete require.cache[require.resolve('yargs')];
69
+ var Mod = require('./api.js');
70
+ var plugins = {};
71
+ options.cwd = options.cwd || process.cwd();
72
+
73
+ try {
74
+ if (!options || !options.noPlugins) plugins = loadPlugins(options);
75
+ } catch (ex) {
76
+ log.verbose('No plugin could be loaded!');
77
+ log.verbose(ex);
78
+ }
79
+
80
+ if (options && options.plugins) {
81
+ plugins = Object.assign(plugins, options.plugins);
82
+ }
83
+
84
+ return new Mod(plugins, isModule, options, callback);
85
+ };
package/lib/chain.js ADDED
@@ -0,0 +1,157 @@
1
+ const DEFAULT = [
2
+ 'renameCollection',
3
+ 'dropCollection',
4
+ 'createCollection',
5
+ 'createTable',
6
+ 'dropTable',
7
+ 'renameTable',
8
+ 'addColumn',
9
+ 'removeColumn',
10
+ 'renameColumn',
11
+ 'changeColumn',
12
+ 'addIndex',
13
+ 'removeIndex',
14
+ 'addForeignKey',
15
+ 'removeForeignKey'
16
+ ];
17
+
18
+ let rollbackCounter = 0;
19
+ let rollbackSignal = null;
20
+ let signal = null;
21
+ let counter = 0;
22
+
23
+ const dbmControl = {
24
+ inc: () => {
25
+ ++counter;
26
+ },
27
+
28
+ signal: () => {
29
+ signal = true;
30
+ },
31
+
32
+ hasSignaled: () => {
33
+ return signal;
34
+ },
35
+
36
+ previousSignal: () => {
37
+ const r = rollbackSignal;
38
+ // we reset on retrieval and mark as retrieved
39
+ rollbackSignal = rollbackSignal === null ? null : false;
40
+ return r;
41
+ },
42
+
43
+ get: () => {
44
+ return counter;
45
+ },
46
+
47
+ getPrevious: () => {
48
+ const r = rollbackCounter;
49
+
50
+ // we reset on retrieval and mark as retrieved
51
+ rollbackCounter = rollbackCounter > 0 ? false : 0;
52
+
53
+ return r;
54
+ }
55
+ };
56
+
57
+ class Chain {
58
+ constructor (context, file, driver, internals) {
59
+ this.file = file;
60
+ this.context = context;
61
+ this.driver = context;
62
+ this.udriver = driver;
63
+ if (this.udriver._dbmControl !== true) {
64
+ this.udriver._counter = dbmControl;
65
+ this.udriver._dbmControl = true;
66
+ const runSql = this.udriver.runSql;
67
+ this.udriver._dbmControlRSQL = runSql;
68
+
69
+ // couple runSql
70
+ this.udriver.runSql = function (...args) {
71
+ return runSql.apply(this, args).then(x => {
72
+ ++counter;
73
+ return x;
74
+ });
75
+ };
76
+ }
77
+ this.internals = internals;
78
+ this.chains = [];
79
+ this.interfaces = [];
80
+ this.it = 0;
81
+ this._step = null;
82
+ this._interface = null;
83
+
84
+ DEFAULT.concat(Object.keys(this.context.learnable || [])).forEach(
85
+ method => {
86
+ this[method] = function (...args) {
87
+ // we don't handle any callbacks here, v2 ultimately deprecates them
88
+
89
+ this.transferInt();
90
+
91
+ return this.exec.apply(this, [method].concat(args));
92
+ };
93
+ }
94
+ );
95
+ }
96
+
97
+ transferInt () {
98
+ rollbackCounter = counter;
99
+ counter = 0;
100
+ rollbackSignal = signal;
101
+ signal = null;
102
+ }
103
+
104
+ addChain (chain) {
105
+ this.chains.push(chain);
106
+ }
107
+
108
+ step () {
109
+ this._step = this.chains[this.it];
110
+ if (!this._step) return null;
111
+ if (!this.interfaces[this.it]) {
112
+ this.interfaces[this.it] = this._step.getInterface(
113
+ this.context,
114
+ this.file,
115
+ this.udriver,
116
+ this.internals
117
+ );
118
+ }
119
+
120
+ this._interface = this.interfaces[this.it++];
121
+ return this._step;
122
+ }
123
+
124
+ reset () {
125
+ this.it = 0;
126
+ }
127
+
128
+ async exec (m, ...args) {
129
+ let ret;
130
+ const stat = [];
131
+ while (this.step()) {
132
+ ret = await this._interface[m].apply(this._interface, args);
133
+ stat.push(ret);
134
+
135
+ if (this._step.hasStateUsage) {
136
+ this._step.useState(ret);
137
+ }
138
+
139
+ if (this._step.hasModification) {
140
+ const ret = this._step.modify(
141
+ this.context,
142
+ this.udriver,
143
+ this.internals
144
+ );
145
+
146
+ if (ret.driver) {
147
+ this.udriver = ret.driver;
148
+ }
149
+ }
150
+ }
151
+
152
+ this.reset();
153
+ return ret;
154
+ }
155
+ }
156
+
157
+ module.exports = Chain;
package/lib/class.js ADDED
@@ -0,0 +1,75 @@
1
+ /* Simple JavaScript Inheritance
2
+ * By John Resig http://ejohn.org/
3
+ * MIT Licensed.
4
+ */
5
+ // Inspired by base2 and Prototype
6
+ var initializing = false;
7
+
8
+ /*eslint-disable */
9
+ var fnTest = /xyz/.test(function() {
10
+ xyz; // lgtm [js/useless-expression]
11
+ })
12
+ ? /\b_super\b/
13
+ : /.*/;
14
+ /* eslint-enable */
15
+
16
+ // The base Class implementation (does nothing)
17
+ var Class = function () {};
18
+
19
+ // Create a new Class that inherits from this class
20
+ Class.extend = function ext (prop) {
21
+ var _super = this.prototype;
22
+
23
+ // Instantiate a base class (but only create the instance,
24
+ // don't run the init constructor)
25
+ initializing = true;
26
+ var prototype = new this();
27
+ initializing = false;
28
+
29
+ // Copy the properties over onto the new prototype
30
+ for (var name in prop) {
31
+ // Check if we're overwriting an existing function
32
+ prototype[name] =
33
+ typeof prop[name] === 'function' &&
34
+ typeof _super[name] === 'function' &&
35
+ fnTest.test(prop[name])
36
+ ? (function (name, fn) {
37
+ return function () {
38
+ var tmp = this._super;
39
+
40
+ // Add a new ._super() method that is the same method
41
+ // but on the super-class
42
+ this._super = _super[name];
43
+
44
+ // The method only need to be bound temporarily, so we
45
+ // remove it when we're done executing
46
+ var ret = fn.apply(this, arguments);
47
+ this._super = tmp;
48
+
49
+ return ret;
50
+ };
51
+ })(name, prop[name])
52
+ : prop[name];
53
+ }
54
+
55
+ // The dummy class constructor
56
+ function Class () {
57
+ // All construction is actually done in the init method
58
+ if (!initializing && this.init) {
59
+ this.init.apply(this, arguments);
60
+ }
61
+ }
62
+
63
+ // Populate our constructed prototype object
64
+ Class.prototype = prototype;
65
+
66
+ // Enforce the constructor to be what we expect
67
+ Class.prototype.constructor = Class;
68
+
69
+ // And make this class extendable
70
+ Class.extend = ext;
71
+
72
+ return Class;
73
+ };
74
+
75
+ module.exports = Class;
@@ -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.migrationsDir = path.resolve(
25
+ internals.argv['migrations-dir'],
26
+ internals.locTitle
27
+ );
28
+ } else {
29
+ migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']);
30
+ }
31
+
32
+ internals.migrationsDir = migrator.migrationsDir;
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.check(internals.argv);
48
+ return internals.onComplete(migrator, internals, null, res);
49
+ } catch (err) {
50
+ return internals.onComplete(migrator, internals, err);
51
+ }
52
+ };
@@ -0,0 +1,252 @@
1
+ 'use strict';
2
+
3
+ const Promise = require('bluebird');
4
+ const log = require('db-migrate-shared').log;
5
+ const mkdirp = Promise.promisify(require('mkdirp'));
6
+ const fs = require('fs');
7
+ const stat = Promise.promisify(fs.stat);
8
+ const writeFile = Promise.promisify(fs.writeFile);
9
+ const yargs = require('yargs');
10
+ const util = require('util');
11
+ const path = require('path');
12
+
13
+ async function createMigrationDir (dir) {
14
+ const res = await stat(dir).catch(_ => {
15
+ return { err: true };
16
+ });
17
+ if (res && res.err === true) {
18
+ await mkdirp(dir);
19
+ }
20
+
21
+ // Create migrations/package.json to ensure migration files are
22
+ // executed as CJS and not ESM
23
+ // https://github.com/db-migrate/node-db-migrate/issues/721
24
+ const packageJsonPath = path.resolve(dir, 'package.json');
25
+
26
+ await stat(packageJsonPath).then(
27
+ async () => {
28
+ const packageJson = require(packageJsonPath);
29
+ packageJson.type = 'commonjs';
30
+ const packageJsonStr = JSON.stringify(packageJson, null, 2);
31
+ await writeFile(packageJsonPath, packageJsonStr, 'utf-8');
32
+ },
33
+ async (err) => {
34
+ const packageJson = JSON.stringify({
35
+ type: 'commonjs'
36
+ }, null, 2)
37
+ await writeFile(packageJsonPath, packageJson, 'utf-8');
38
+ }
39
+ )
40
+ }
41
+
42
+ async function executeCreateMigration (internals, config) {
43
+ let migrationsDir = internals.argv['migrations-dir'];
44
+ let path;
45
+ let hooks = false;
46
+ let pluginTemplate = false;
47
+ let customWrite = false;
48
+ const { plugins } = internals;
49
+
50
+ internals.runTimestamp = new Date();
51
+
52
+ if (internals.migrationMode && internals.migrationMode !== 'all') {
53
+ migrationsDir =
54
+ internals.argv['migrations-dir'] + '/' + internals.migrationMode;
55
+ }
56
+
57
+ if (internals.argv._.length === 0) {
58
+ log.error("'migrationName' is required.");
59
+ if (!internals.isModule) {
60
+ yargs.showHelp();
61
+ }
62
+
63
+ throw new Error("'migrationName' is required.");
64
+ }
65
+
66
+ const Migration = require('../template.js');
67
+
68
+ internals.argv.title = internals.argv._.shift();
69
+ const folder = internals.argv.title.toString().split('/');
70
+
71
+ internals.argv.title = folder[folder.length - 1] || folder[0];
72
+ path = migrationsDir;
73
+
74
+ if (folder.length > 1) {
75
+ path += '/';
76
+
77
+ for (let i = 0; i < folder.length - 1; ++i) {
78
+ path += folder[i] + '/';
79
+ }
80
+ }
81
+ internals.argv['migrations-dir'] = path;
82
+
83
+ try {
84
+ await createMigrationDir(path);
85
+ } catch (err) {
86
+ log.error('Failed to create migration directory at ', migrationsDir, err);
87
+ throw new Error('Failed to create migration directory.');
88
+ }
89
+
90
+ let templateType = Migration.TemplateType.DEFAULT_JS;
91
+ if (
92
+ shouldCreateSqlFiles(internals, config) &&
93
+ shouldCreateCoffeeFile(internals, config)
94
+ ) {
95
+ templateType = Migration.TemplateType.COFFEE_SQL_FILE_LOADER;
96
+ } else if (
97
+ shouldCreateSqlFiles(internals, config) &&
98
+ shouldIgnoreOnInitFiles(internals, config)
99
+ ) {
100
+ templateType = Migration.TemplateType.SQL_FILE_LOADER_IGNORE_ON_INIT;
101
+ } else if (shouldCreateSqlFiles(internals, config)) {
102
+ templateType = Migration.TemplateType.SQL_FILE_LOADER;
103
+ } else if (shouldCreateCoffeeFile(internals, config)) {
104
+ templateType = Migration.TemplateType.DEFAULT_COFFEE;
105
+ } else if (shouldCreateV2File(internals, config)) {
106
+ templateType = Migration.TemplateType.V2_DEFAULT;
107
+ }
108
+ if (plugins) {
109
+ hooks = plugins.hook('create:template') || [];
110
+ }
111
+
112
+ if (hooks !== false) {
113
+ for (const plugin of hooks) {
114
+ const template = plugin['init:template']();
115
+
116
+ if (internals.argv[template.option] || config[template.option]) {
117
+ pluginTemplate = plugin;
118
+ customWrite = plugin['create:template:custom:write'] === true;
119
+
120
+ if (customWrite) {
121
+ templateType = `${plugin.name}${templateType}`;
122
+ } else {
123
+ templateType = template.type;
124
+ }
125
+
126
+ // no reason to continue processing here
127
+ break;
128
+ }
129
+ }
130
+ }
131
+
132
+ if (!pluginTemplate && !customWrite) {
133
+ const migration = new Migration(
134
+ internals.argv.title +
135
+ (shouldCreateCoffeeFile(internals, config) ? '.coffee' : '.js'),
136
+ path,
137
+ internals.runTimestamp,
138
+ templateType,
139
+ internals.plugins
140
+ );
141
+
142
+ await migration.write();
143
+ log.info(util.format('Created migration at %s', migration.file.path));
144
+ if (shouldCreateSqlFiles(internals, config)) {
145
+ return createSqlFiles(internals, config);
146
+ }
147
+ } else {
148
+ const plugin = pluginTemplate;
149
+
150
+ if (typeof plugin['write:template'] !== 'function') {
151
+ log.error(`Plugin ${plugin.name} does not have function write:template`);
152
+ throw new Error(`write:template not existent!`);
153
+ }
154
+
155
+ await plugin['write:template'](
156
+ { argv: { ...internals.argv }, config: { ...config } },
157
+ async opts => {
158
+ let title = internals.argv.title;
159
+ let _path = path;
160
+ const extension = opts.extension || '.js';
161
+
162
+ if (opts.suffix) {
163
+ title += opts.suffix;
164
+ }
165
+
166
+ if (opts.pathExtension) {
167
+ _path += opts.pathExtension;
168
+ }
169
+
170
+ const migration = new Migration(
171
+ title + extension,
172
+ _path,
173
+ internals.runTimestamp,
174
+ opts.type,
175
+ internals.plugins
176
+ );
177
+ await migration.write();
178
+ }
179
+ );
180
+ }
181
+
182
+ return Promise.resolve();
183
+ }
184
+
185
+ function shouldCreateSqlFiles (internals, config) {
186
+ return internals.argv['sql-file'] || config['sql-file'];
187
+ }
188
+
189
+ function shouldIgnoreOnInitFiles (internals, config) {
190
+ return internals.argv['ignore-on-init'] || config['ignore-on-init'];
191
+ }
192
+
193
+ function shouldCreateCoffeeFile (internals, config) {
194
+ return internals.argv['coffee-file'] || config['coffee-file'];
195
+ }
196
+
197
+ function shouldCreateV2File (internals, config) {
198
+ return internals.argv['v2-file'] || config['v2-file'];
199
+ }
200
+
201
+ async function createSqlFiles (internals, config) {
202
+ let migrationsDir = internals.argv['migrations-dir'];
203
+
204
+ if (internals.migrationMode && internals.migrationMode !== 'all') {
205
+ migrationsDir =
206
+ internals.argv['migrations-dir'] + '/' + internals.migrationMode;
207
+ }
208
+
209
+ const sqlDir = migrationsDir + '/sqls';
210
+ try {
211
+ await createMigrationDir(sqlDir);
212
+ } catch (err) {
213
+ log.error('Failed to create migration directory at ', sqlDir, err);
214
+
215
+ throw err;
216
+ }
217
+
218
+ const Migration = require('../template.js');
219
+
220
+ const templateTypeDefaultSQL = Migration.TemplateType.DEFAULT_SQL;
221
+ const migrationUpSQL = new Migration(
222
+ internals.argv.title + '-up.sql',
223
+ sqlDir,
224
+ internals.runTimestamp,
225
+ templateTypeDefaultSQL,
226
+ internals.plugins
227
+ );
228
+ await migrationUpSQL.write();
229
+
230
+ log.info(
231
+ util.format('Created migration up sql file at %s', migrationUpSQL.file.path)
232
+ );
233
+
234
+ const migrationDownSQL = new Migration(
235
+ internals.argv.title + '-down.sql',
236
+ sqlDir,
237
+ internals.runTimestamp,
238
+ templateTypeDefaultSQL,
239
+ internals.plugins
240
+ );
241
+ migrationDownSQL.write();
242
+ log.info(
243
+ util.format(
244
+ 'Created migration down sql file at %s',
245
+ migrationDownSQL.file.path
246
+ )
247
+ );
248
+
249
+ return Promise.resolve();
250
+ }
251
+
252
+ module.exports = executeCreateMigration;