db-migrate 1.0.0-beta.2 → 1.0.0-beta.20
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/LICENSE +26 -0
- package/README.md +1 -15
- package/api.js +22 -15
- package/connect.js +6 -6
- package/index.js +10 -13
- package/lib/chain.js +66 -11
- package/lib/commands/check.js +3 -3
- package/lib/commands/create-migration.js +121 -28
- package/lib/commands/db.js +2 -0
- package/lib/commands/down.js +1 -1
- package/lib/commands/dump.js +22 -0
- package/lib/commands/generated.js +32 -0
- package/lib/commands/helper/register-events.js +2 -0
- package/lib/commands/run.js +4 -9
- package/lib/commands/set-default-argv.js +13 -15
- package/lib/commands/sync.js +3 -3
- package/lib/commands/up.js +3 -3
- package/lib/config.js +2 -2
- package/lib/driver/index.js +37 -11
- package/lib/executors/versioned/v2.js +13 -3
- package/lib/file.js +2 -4
- package/lib/learn.js +64 -31
- package/lib/methods/v2/conventions.js +47 -0
- package/lib/methods/v2/statetravel.js +11 -9
- package/lib/methods/v2/translatestate.js +45 -12
- package/lib/state.js +5 -5
- package/lib/template.js +34 -4
- package/lib/templates/v2.js +12 -0
- package/lib/temputils.js +8 -0
- package/lib/walker.js +17 -2
- package/package.json +26 -23
- package/.eslintrc +0 -8
- package/.jscsrc +0 -0
- package/.jshintignore +0 -2
- package/.jshintrc +0 -14
- package/.prettierrc +0 -3
- package/.tern-project +0 -7
- package/.travis.yml +0 -47
- package/CHANGELOG.md +0 -474
- package/CODE_OF_CONDUCT.md +0 -46
- package/CONTRIBUTING.md +0 -81
- package/Makefile +0 -8
- package/commitlint.config.js +0 -1
- package/lib/commands/transition.js +0 -5
- package/lib/transitions/1.js +0 -30
- package/lib/transitions/ask.js +0 -22
- package/lib/transitions/snippets/setup.sjs +0 -8
- package/lib/transitions/transitioner.js +0 -78
- package/lib/transitions/try-require.js +0 -113
- package/lib/transitions/update-version.js +0 -48
package/lib/commands/run.js
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var log = require('db-migrate-shared').log;
|
|
4
|
-
var
|
|
5
|
-
var load = require('./');
|
|
6
|
-
var transition = load('transition');
|
|
4
|
+
var yargs = require('yargs');
|
|
7
5
|
|
|
8
6
|
function run (internals, config) {
|
|
7
|
+
const { load } = internals;
|
|
9
8
|
var action = internals.argv._.shift();
|
|
10
9
|
var folder = action.split(':');
|
|
11
10
|
|
|
12
11
|
action = folder[0];
|
|
13
12
|
|
|
14
13
|
switch (action) {
|
|
15
|
-
case 'transition':
|
|
16
|
-
transition(internals);
|
|
17
|
-
break;
|
|
18
14
|
case 'create':
|
|
19
15
|
if (folder[1]) {
|
|
20
16
|
internals.matching = folder[1];
|
|
@@ -114,10 +110,9 @@ function run (internals, config) {
|
|
|
114
110
|
);
|
|
115
111
|
} else {
|
|
116
112
|
log.error(
|
|
117
|
-
'Invalid Action: Must be [up|down|check|create|reset|sync|'
|
|
118
|
-
'db|transition].'
|
|
113
|
+
'Invalid Action: Must be [up|down|check|create|reset|sync|db].'
|
|
119
114
|
);
|
|
120
|
-
|
|
115
|
+
yargs.showHelp();
|
|
121
116
|
process.exit(1);
|
|
122
117
|
}
|
|
123
118
|
break;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var yargs = require('yargs');
|
|
2
2
|
var log = require('db-migrate-shared').log;
|
|
3
3
|
|
|
4
4
|
module.exports = function (internals, isModule) {
|
|
@@ -20,10 +20,10 @@ module.exports = function (internals, isModule) {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
if (!isModule) {
|
|
23
|
-
internals.argv =
|
|
23
|
+
internals.argv = yargs
|
|
24
24
|
.default(defaultConfig)
|
|
25
25
|
.usage(
|
|
26
|
-
'Usage: db-migrate [up|down|check|reset|sync|create|db
|
|
26
|
+
'Usage: db-migrate [up|down|check|reset|sync|create|db] ' +
|
|
27
27
|
'[[dbname/]migrationName|all] [options]'
|
|
28
28
|
)
|
|
29
29
|
.describe(
|
|
@@ -64,6 +64,8 @@ module.exports = function (internals, isModule) {
|
|
|
64
64
|
.boolean('version')
|
|
65
65
|
.describe('config', 'Location of the database.json file.')
|
|
66
66
|
.string('config')
|
|
67
|
+
.describe('v2-file', 'Create v2 schema migration')
|
|
68
|
+
.boolean('v2-file')
|
|
67
69
|
.describe(
|
|
68
70
|
'sql-file',
|
|
69
71
|
'Automatically create two sql files for up and down statements in ' +
|
|
@@ -110,29 +112,25 @@ module.exports = function (internals, isModule) {
|
|
|
110
112
|
.describe('ignore-completed-migrations', 'Start at the first migration')
|
|
111
113
|
.boolean('ignore-completed-migrations')
|
|
112
114
|
.describe('log-level', 'Set the log-level, for example sql|warn')
|
|
113
|
-
.string('log-level')
|
|
115
|
+
.string('log-level')
|
|
116
|
+
.parse();
|
|
114
117
|
} else {
|
|
115
|
-
|
|
116
|
-
internals.argv = {
|
|
117
|
-
get argv () {
|
|
118
|
-
return _internalsArgv;
|
|
119
|
-
}
|
|
120
|
-
};
|
|
118
|
+
internals.argv = Object.assign(defaultConfig, internals.cmdOptions);
|
|
121
119
|
}
|
|
122
120
|
|
|
123
121
|
var plugins = internals.plugins;
|
|
124
122
|
var plugin = plugins.hook('init:cli:config:hook');
|
|
125
|
-
var _config = internals.argv.
|
|
123
|
+
var _config = internals.argv.config;
|
|
126
124
|
|
|
127
125
|
if (plugin) {
|
|
128
126
|
plugin.forEach(function (plugin) {
|
|
129
127
|
// var configs = plugin['init:cli:config:hook']();
|
|
130
128
|
// if (!configs) return;
|
|
131
|
-
// hook not yet used, we look into migrating away from
|
|
129
|
+
// hook not yet used, we look into migrating away from yargs first
|
|
132
130
|
});
|
|
133
131
|
}
|
|
134
132
|
|
|
135
|
-
internals.argv = deepExtend(internals.argv
|
|
133
|
+
internals.argv = deepExtend(internals.argv, rc('db-migrate', {}));
|
|
136
134
|
internals.argv.rcconfig = internals.argv.config;
|
|
137
135
|
internals.argv.config = internals.argv.configFile || _config;
|
|
138
136
|
|
|
@@ -142,7 +140,7 @@ module.exports = function (internals, isModule) {
|
|
|
142
140
|
}
|
|
143
141
|
|
|
144
142
|
if (!isModule && (internals.argv.help || internals.argv._.length === 0)) {
|
|
145
|
-
|
|
143
|
+
yargs.showHelp();
|
|
146
144
|
process.exit(1);
|
|
147
145
|
}
|
|
148
146
|
|
|
@@ -160,7 +158,7 @@ module.exports = function (internals, isModule) {
|
|
|
160
158
|
internals.notransactions = internals.argv['non-transactional'];
|
|
161
159
|
internals.dryRun = internals.argv['dry-run'];
|
|
162
160
|
global.dryRun = internals.dryRun;
|
|
163
|
-
internals.check = internals.argv
|
|
161
|
+
internals.check = internals.argv.check;
|
|
164
162
|
|
|
165
163
|
if (internals.dryRun) {
|
|
166
164
|
log.info('dry run');
|
package/lib/commands/sync.js
CHANGED
|
@@ -21,15 +21,15 @@ async function prepare (internals, config) {
|
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
if (internals.locTitle) {
|
|
24
|
-
migrator.
|
|
24
|
+
migrator.directory = path.resolve(
|
|
25
25
|
internals.argv['migrations-dir'],
|
|
26
26
|
internals.locTitle
|
|
27
27
|
);
|
|
28
28
|
} else {
|
|
29
|
-
migrator.
|
|
29
|
+
migrator.directory = path.resolve(internals.argv['migrations-dir']);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
internals.migrationsDir = migrator.
|
|
32
|
+
internals.migrationsDir = migrator.directory;
|
|
33
33
|
|
|
34
34
|
await migrator.createMigrationsTable();
|
|
35
35
|
log.verbose('migration table created');
|
package/lib/commands/up.js
CHANGED
|
@@ -21,15 +21,15 @@ async function prepare (internals, config) {
|
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
if (internals.locTitle) {
|
|
24
|
-
migrator.
|
|
24
|
+
migrator.directory = path.resolve(
|
|
25
25
|
internals.argv['migrations-dir'],
|
|
26
26
|
internals.locTitle
|
|
27
27
|
);
|
|
28
28
|
} else {
|
|
29
|
-
migrator.
|
|
29
|
+
migrator.directory = path.resolve(internals.argv['migrations-dir']);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
internals.migrationsDir = migrator.
|
|
32
|
+
internals.migrationsDir = migrator.directory;
|
|
33
33
|
|
|
34
34
|
await migrator.createMigrationsTable();
|
|
35
35
|
log.verbose('migration table created');
|
package/lib/config.js
CHANGED
|
@@ -176,8 +176,8 @@ exports.loadObject = function (_config, currentEnv) {
|
|
|
176
176
|
|
|
177
177
|
if (currentEnv) {
|
|
178
178
|
out.setCurrent(currentEnv);
|
|
179
|
-
} else if (config
|
|
180
|
-
out.setCurrent(config
|
|
179
|
+
} else if (config.default) {
|
|
180
|
+
out.setCurrent(config.default);
|
|
181
181
|
} else if (config.defaultEnv) {
|
|
182
182
|
if (config.defaultEnv.ENV) {
|
|
183
183
|
out.setCurrent(process.env[config.defaultEnv.ENV]);
|
package/lib/driver/index.js
CHANGED
|
@@ -18,6 +18,8 @@ var ShadowProto = {
|
|
|
18
18
|
|
|
19
19
|
exports.connect = function (config, intern, callback) {
|
|
20
20
|
var driver, req;
|
|
21
|
+
let plugin = false;
|
|
22
|
+
const { plugins } = intern;
|
|
21
23
|
|
|
22
24
|
var mod = internals.mod;
|
|
23
25
|
internals = intern;
|
|
@@ -90,27 +92,51 @@ exports.connect = function (config, intern, callback) {
|
|
|
90
92
|
log.verbose('connecting');
|
|
91
93
|
|
|
92
94
|
var connect = function (config) {
|
|
93
|
-
driver.connect(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
driver.connect(
|
|
96
|
+
// safe disconnect of our config object into userspace
|
|
97
|
+
JSON.parse(JSON.stringify(config)),
|
|
98
|
+
intern,
|
|
99
|
+
function (err, db) {
|
|
100
|
+
if (err) {
|
|
101
|
+
callback(err);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
log.verbose('connected');
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
if (!global.immunity) {
|
|
107
|
+
db = Shadow.infect(db, internals, ShadowProto);
|
|
108
|
+
}
|
|
103
109
|
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
callback(null, db);
|
|
111
|
+
}
|
|
112
|
+
);
|
|
106
113
|
};
|
|
107
114
|
|
|
108
115
|
if (config.tunnel) {
|
|
109
116
|
var tunnel = require('tunnel-ssh');
|
|
110
117
|
var tunnelConfig = JSON.parse(JSON.stringify(config.tunnel));
|
|
118
|
+
const { tunnelType } = tunnelConfig;
|
|
119
|
+
|
|
120
|
+
if (plugins) {
|
|
121
|
+
plugin = plugins.overwrite(
|
|
122
|
+
`connection:tunnel:${
|
|
123
|
+
tunnelType && tunnelType !== 'ssh' ? tunnelType : 'ssh'
|
|
124
|
+
}`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
111
128
|
tunnelConfig.dstHost = config.host;
|
|
112
129
|
tunnelConfig.dstPort = config.port;
|
|
113
130
|
|
|
131
|
+
if (plugin) {
|
|
132
|
+
tunnel =
|
|
133
|
+
plugin[
|
|
134
|
+
`connection:tunnel:${
|
|
135
|
+
tunnelType && tunnelType !== 'ssh' ? tunnelType : 'ssh'
|
|
136
|
+
}`
|
|
137
|
+
](tunnelConfig);
|
|
138
|
+
}
|
|
139
|
+
|
|
114
140
|
if (tunnelConfig.privateKeyPath) {
|
|
115
141
|
tunnelConfig.privateKey = require('fs').readFileSync(
|
|
116
142
|
tunnelConfig.privateKeyPath
|
|
@@ -8,13 +8,14 @@ const Chain = require('../../chain');
|
|
|
8
8
|
const StateTravel = require('../../methods/v2/statetravel');
|
|
9
9
|
const Migrate = require('../../methods/v2/migrate');
|
|
10
10
|
const TranslateState = require('../../methods/v2/translatestate');
|
|
11
|
+
const AddConventions = require('../../methods/v2/conventions');
|
|
11
12
|
|
|
12
13
|
const execUnit = {
|
|
13
14
|
_extend: (context, type) => {
|
|
14
15
|
return {
|
|
15
16
|
atomic: function (actions) {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
const action = actions[type];
|
|
18
|
+
const reverse = actions[type === 'up' ? 'up' : 'down'];
|
|
18
19
|
|
|
19
20
|
if (!action || !reverse) {
|
|
20
21
|
return Promise.reject(new Error('invalid operation'));
|
|
@@ -28,6 +29,9 @@ const execUnit = {
|
|
|
28
29
|
up: async function (context, driver, file) {
|
|
29
30
|
const _file = file.get();
|
|
30
31
|
const chain = new Chain(context._driver, file, driver, context.internals);
|
|
32
|
+
if (!_file._meta.noDefaultColumn) {
|
|
33
|
+
chain.addChain(AddConventions);
|
|
34
|
+
}
|
|
31
35
|
chain.addChain(Learn);
|
|
32
36
|
chain.addChain(StateTravel);
|
|
33
37
|
chain.addChain(Migrate);
|
|
@@ -44,6 +48,11 @@ const execUnit = {
|
|
|
44
48
|
dbm: context.internals.safeOptions.dbmigrate
|
|
45
49
|
});
|
|
46
50
|
} catch (err) {
|
|
51
|
+
context.internals.rollback = true;
|
|
52
|
+
|
|
53
|
+
// transfer last state
|
|
54
|
+
chain.transferInt();
|
|
55
|
+
|
|
47
56
|
log.error(
|
|
48
57
|
'An error occured. No alternative failure strategy defined. Rolling back!',
|
|
49
58
|
err
|
|
@@ -51,7 +60,8 @@ const execUnit = {
|
|
|
51
60
|
await execUnit.down(context, driver, file);
|
|
52
61
|
throw err;
|
|
53
62
|
}
|
|
54
|
-
|
|
63
|
+
await Promise.promisify(context.writeMigrationRecord.bind(context))(file);
|
|
64
|
+
return State.endMigration(context._driver, file, context.internals);
|
|
55
65
|
// end migration, same as start migration
|
|
56
66
|
},
|
|
57
67
|
|
package/lib/file.js
CHANGED
|
@@ -38,7 +38,7 @@ function formatTitle (title) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function parseDate (name) {
|
|
41
|
-
|
|
41
|
+
const date = new Date();
|
|
42
42
|
const match = name.match(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})-[^.]+/);
|
|
43
43
|
date.setUTCFullYear(match[1]);
|
|
44
44
|
date.setUTCDate(match[3]);
|
|
@@ -125,9 +125,7 @@ File.registerHook = function (Plugin, internals) {
|
|
|
125
125
|
|
|
126
126
|
if (plugin.maintainer && plugin.maintainer.repository) {
|
|
127
127
|
log.verbose(
|
|
128
|
-
`The repo of the ${plugin.name} plugin is ${
|
|
129
|
-
plugin.maintainer.repository
|
|
130
|
-
}!`
|
|
128
|
+
`The repo of the ${plugin.name} plugin is ${plugin.maintainer.repository}!`
|
|
131
129
|
);
|
|
132
130
|
}
|
|
133
131
|
return plugin['migrator:migration:hook:require']();
|
package/lib/learn.js
CHANGED
|
@@ -8,7 +8,7 @@ class STD {
|
|
|
8
8
|
throw new Error(`There is no ${t} table in schema!`);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
if (!this.schema[t][c]) {
|
|
11
|
+
if (!this.schema[t][c] && !this.schema[t].columns[c]) {
|
|
12
12
|
throw new Error(`There is no ${c} column in schema!`);
|
|
13
13
|
}
|
|
14
14
|
};
|
|
@@ -17,6 +17,10 @@ class STD {
|
|
|
17
17
|
this.indizies = schema.i;
|
|
18
18
|
this.schema = schema.c;
|
|
19
19
|
this.foreign = schema.f;
|
|
20
|
+
if (!schema.e) {
|
|
21
|
+
schema.e = {};
|
|
22
|
+
}
|
|
23
|
+
this.extra = schema.e;
|
|
20
24
|
this.modS = mod.c;
|
|
21
25
|
this.modI = mod.i;
|
|
22
26
|
this.modF = mod.f;
|
|
@@ -87,6 +91,16 @@ class STD {
|
|
|
87
91
|
delete this.schema[t];
|
|
88
92
|
}
|
|
89
93
|
|
|
94
|
+
if (this.foreign[t]) {
|
|
95
|
+
this.modF[n] = this.foreign[n];
|
|
96
|
+
delete this.foreign[t];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (this.indizies[t]) {
|
|
100
|
+
this.modI[n] = this.indizies[t];
|
|
101
|
+
delete this.indizies[t];
|
|
102
|
+
}
|
|
103
|
+
|
|
90
104
|
this.modC.push({ t: 0, a: 'renameTable', c: [n, t] });
|
|
91
105
|
|
|
92
106
|
return Promise.resolve();
|
|
@@ -104,11 +118,13 @@ class STD {
|
|
|
104
118
|
return this.createTable.apply(this, args);
|
|
105
119
|
}
|
|
106
120
|
|
|
107
|
-
removeColumn (t, c, o) {
|
|
108
|
-
|
|
121
|
+
removeColumn (t, c, o = {}) {
|
|
122
|
+
const alter = {};
|
|
109
123
|
this.checkColumn(t, c);
|
|
124
|
+
const hasColumns = this.schema[t].columns !== undefined;
|
|
125
|
+
const columns = hasColumns ? this.schema[t].columns : this.schema[t];
|
|
110
126
|
|
|
111
|
-
if (
|
|
127
|
+
if (columns[c].notNull === true) {
|
|
112
128
|
if (this.validations.columnStrategies !== true) {
|
|
113
129
|
if (
|
|
114
130
|
this.driver._meta &&
|
|
@@ -134,9 +150,7 @@ class STD {
|
|
|
134
150
|
);
|
|
135
151
|
}
|
|
136
152
|
throw new Error(
|
|
137
|
-
`There is no such column recreation strategy "${
|
|
138
|
-
o.columnStrategy
|
|
139
|
-
}!"`
|
|
153
|
+
`There is no such column recreation strategy "${o.columnStrategy}!"`
|
|
140
154
|
);
|
|
141
155
|
}
|
|
142
156
|
} else {
|
|
@@ -158,30 +172,41 @@ class STD {
|
|
|
158
172
|
|
|
159
173
|
this.modS[t] = {};
|
|
160
174
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
o.passthrough.column
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
if (columns[c].notNull === true) {
|
|
176
|
+
switch (o.columnStrategy) {
|
|
177
|
+
case 'delay':
|
|
178
|
+
this.modS[t][c] = columns[c];
|
|
179
|
+
|
|
180
|
+
o.passthrough = o.passthrough || {};
|
|
181
|
+
o.passthrough.column =
|
|
182
|
+
o.passthrough.column ||
|
|
183
|
+
`__dbmrn_${c}_${new Date().toISOString()}__`;
|
|
184
|
+
|
|
185
|
+
this.modC.push({
|
|
186
|
+
t: 0,
|
|
187
|
+
a: 'renameColumn',
|
|
188
|
+
c: [t, o.passthrough.column, c]
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
break;
|
|
192
|
+
case 'defaultValue':
|
|
193
|
+
this.modS[t][c] = columns[c];
|
|
194
|
+
this.modS[t][c].defaultValue = o.passthrough.defaultValue;
|
|
195
|
+
|
|
196
|
+
this.modC.push({ t: 1, a: 'addColumn', c: [t, c, o] });
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
this.modS[t][c] = columns[c];
|
|
179
201
|
|
|
180
|
-
|
|
181
|
-
break;
|
|
202
|
+
this.modC.push({ t: 1, a: 'addColumn', c: [t, c, o] });
|
|
182
203
|
}
|
|
183
204
|
|
|
184
|
-
|
|
205
|
+
if (hasColumns) {
|
|
206
|
+
delete this.schema[t].columns[c];
|
|
207
|
+
} else {
|
|
208
|
+
delete this.schema[t][c];
|
|
209
|
+
}
|
|
185
210
|
|
|
186
211
|
return Promise.resolve(alter);
|
|
187
212
|
}
|
|
@@ -202,7 +227,10 @@ class STD {
|
|
|
202
227
|
throw new Error(`There is no ${t} table in schema!`);
|
|
203
228
|
}
|
|
204
229
|
this.schema[t] = this.schema[t] || {};
|
|
205
|
-
this.schema[t]
|
|
230
|
+
const hasColumns = this.schema[t].columns !== undefined;
|
|
231
|
+
const columns = hasColumns ? this.schema[t].columns : this.schema[t];
|
|
232
|
+
|
|
233
|
+
columns[c] = s;
|
|
206
234
|
|
|
207
235
|
this.modC.push({ t: 0, a: 'removeColumn', c: [t, c] });
|
|
208
236
|
|
|
@@ -212,8 +240,13 @@ class STD {
|
|
|
212
240
|
changeColumn (t, c, s) {
|
|
213
241
|
this.checkColumn(t, c);
|
|
214
242
|
|
|
215
|
-
this.modS[t]
|
|
216
|
-
|
|
243
|
+
if (!this.modS[t]) this.modS[t] = {};
|
|
244
|
+
|
|
245
|
+
const hasColumns = this.schema[t].columns !== undefined;
|
|
246
|
+
const columns = hasColumns ? this.schema[t].columns : this.schema[t];
|
|
247
|
+
|
|
248
|
+
this.modS[t][c] = columns[c];
|
|
249
|
+
columns[c] = Object.assign(columns[c], s);
|
|
217
250
|
|
|
218
251
|
this.modC.push({ t: 1, a: 'changeColumn', c: [t, c] });
|
|
219
252
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const Shadow = require('../../driver/shadow');
|
|
2
|
+
|
|
3
|
+
class AddConventions {
|
|
4
|
+
constructor (internals, file, driver) {
|
|
5
|
+
this.file = file;
|
|
6
|
+
this.internals = internals;
|
|
7
|
+
this.driver = driver;
|
|
8
|
+
this._counter = 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
createTable (t, d) {
|
|
12
|
+
d.__dbmigrate__flag = {
|
|
13
|
+
type: 'string'
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return Promise.resolve();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
createCollection (...args) {
|
|
20
|
+
return this.createTable.apply(this, args);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const noAction = prop => {
|
|
25
|
+
return function () {
|
|
26
|
+
return Promise.resolve();
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
getInterface: (context, file, driver, internals) => {
|
|
32
|
+
if (context.conventions) {
|
|
33
|
+
const st = new AddConventions(internals, file, context);
|
|
34
|
+
return Shadow.overshadow(
|
|
35
|
+
driver,
|
|
36
|
+
Object.assign(st, context.conventions),
|
|
37
|
+
noAction
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return Shadow.overshadow(
|
|
42
|
+
driver,
|
|
43
|
+
new AddConventions(internals, file, context),
|
|
44
|
+
noAction
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -23,20 +23,22 @@ class StateTravel {
|
|
|
23
23
|
this.internals = internals;
|
|
24
24
|
this.driver = driver;
|
|
25
25
|
this._counter = 0;
|
|
26
|
+
this._default = async function _default () {
|
|
27
|
+
await State.step(this.driver, ++this._counter, this.internals);
|
|
28
|
+
|
|
29
|
+
return State.update(
|
|
30
|
+
this.driver,
|
|
31
|
+
this.file,
|
|
32
|
+
this.internals.modSchema,
|
|
33
|
+
this.internals
|
|
34
|
+
);
|
|
35
|
+
};
|
|
26
36
|
}
|
|
27
37
|
}
|
|
28
38
|
|
|
29
39
|
Object.keys(DEFAULT).forEach(m => {
|
|
30
40
|
StateTravel.prototype[m] = async function (...args) {
|
|
31
|
-
|
|
32
|
-
const res = await State.update(
|
|
33
|
-
this.driver,
|
|
34
|
-
this.file,
|
|
35
|
-
this.internals.modSchema,
|
|
36
|
-
this.internals
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
return res;
|
|
41
|
+
return this._default();
|
|
40
42
|
};
|
|
41
43
|
});
|
|
42
44
|
|
|
@@ -2,7 +2,7 @@ const Promise = require('bluebird');
|
|
|
2
2
|
const State = require('../../state');
|
|
3
3
|
const Chain = require('../../chain');
|
|
4
4
|
const Migrate = require('./migrate');
|
|
5
|
-
const
|
|
5
|
+
const log = require('db-migrate-shared').log;
|
|
6
6
|
|
|
7
7
|
const methods = {
|
|
8
8
|
createTable: async (driver, [t], internals) => {
|
|
@@ -43,6 +43,26 @@ const methods = {
|
|
|
43
43
|
|
|
44
44
|
changeColumn: async (driver, [t, c], internals) => {
|
|
45
45
|
return driver.changeColumn(t, c, internals.modSchema.c[t][c]);
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
addIndex: async (driver, [t, i], internals) => {
|
|
49
|
+
if (!internals.modSchema.i[t][i]) {
|
|
50
|
+
log.warn(
|
|
51
|
+
`There was an attempt to create the index "${i}" in the table "${t}".`
|
|
52
|
+
);
|
|
53
|
+
log.warn(
|
|
54
|
+
`This index did not exist at the time of deleting it. ` +
|
|
55
|
+
`This can happen if an index was created by hand and then deleted ` +
|
|
56
|
+
`by db-migrate. Make sure to recreate it by hand to avoid any problems.`
|
|
57
|
+
);
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
}
|
|
60
|
+
return driver.addIndex(
|
|
61
|
+
t,
|
|
62
|
+
i,
|
|
63
|
+
internals.modSchema.i[t][i].c,
|
|
64
|
+
internals.modSchema.i[t][i].u ? true : undefined
|
|
65
|
+
);
|
|
46
66
|
}
|
|
47
67
|
};
|
|
48
68
|
|
|
@@ -53,17 +73,30 @@ async function processEntry (
|
|
|
53
73
|
internals,
|
|
54
74
|
{ t: type, a: action, c: args }
|
|
55
75
|
) {
|
|
56
|
-
|
|
57
|
-
switch (type) {
|
|
58
|
-
case 0:
|
|
59
|
-
await driver[action].apply(driver, args);
|
|
60
|
-
break;
|
|
61
|
-
case 1:
|
|
62
|
-
await f[action](driver, args, internals);
|
|
63
|
-
break;
|
|
76
|
+
let skip = false;
|
|
64
77
|
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
if (
|
|
79
|
+
internals.rollback === true &&
|
|
80
|
+
internals.rollbackContinue !== true &&
|
|
81
|
+
driver.udriver._meta.signalColumns.indexOf(action) !== -1
|
|
82
|
+
) {
|
|
83
|
+
internals.rollbackContinue = true;
|
|
84
|
+
skip = driver.udriver._counter.previousSignal() === null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!skip) {
|
|
88
|
+
const f = Object.assign(methods, context.reverse);
|
|
89
|
+
switch (type) {
|
|
90
|
+
case 0:
|
|
91
|
+
await driver[action].apply(driver, args);
|
|
92
|
+
break;
|
|
93
|
+
case 1:
|
|
94
|
+
await f[action](driver, args, internals);
|
|
95
|
+
break;
|
|
96
|
+
|
|
97
|
+
default:
|
|
98
|
+
throw new Error(`Invalid state record, of type ${type}`);
|
|
99
|
+
}
|
|
67
100
|
}
|
|
68
101
|
|
|
69
102
|
internals.modSchema.s.shift();
|
|
@@ -74,7 +107,7 @@ module.exports = async (context, file, driver, internals) => {
|
|
|
74
107
|
const mod = internals.modSchema;
|
|
75
108
|
|
|
76
109
|
const chain = new Chain(context, file, driver, internals);
|
|
77
|
-
chain.addChain(Learn);
|
|
110
|
+
// chain.addChain(Learn);
|
|
78
111
|
chain.addChain(Migrate);
|
|
79
112
|
await Promise.resolve(mod.s.reverse()).each(args =>
|
|
80
113
|
processEntry(context, file, chain, internals, args)
|
package/lib/state.js
CHANGED
|
@@ -31,7 +31,7 @@ module.exports = {
|
|
|
31
31
|
|
|
32
32
|
init: async function (driver, internals) {
|
|
33
33
|
await driver._createKV(internals.migrationState);
|
|
34
|
-
|
|
34
|
+
const schema = await driver._getKV(internals.migrationState, SSTATE);
|
|
35
35
|
if (schema) {
|
|
36
36
|
internals.schema = JSON.parse(schema.value);
|
|
37
37
|
} else {
|
|
@@ -39,7 +39,7 @@ module.exports = {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (!internals.dryRun) {
|
|
42
|
-
|
|
42
|
+
const state = await driver._getKV(internals.migrationState, MSTATE);
|
|
43
43
|
return module.exports.lockState(driver, state, internals);
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -47,10 +47,10 @@ module.exports = {
|
|
|
47
47
|
},
|
|
48
48
|
|
|
49
49
|
startMigration: async function (driver, file, internals) {
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
const state = await driver._getKV(internals.migrationState, MSTATE);
|
|
51
|
+
const mig = await driver._getKV(internals.migrationState, file.name);
|
|
52
52
|
|
|
53
|
-
if (mig) {
|
|
53
|
+
if (mig && mig.value !== '{}') {
|
|
54
54
|
internals.modSchema = JSON.parse(mig.value);
|
|
55
55
|
}
|
|
56
56
|
|