db-migrate 1.0.0-beta.27 → 1.0.0-beta.28
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/connect.js +21 -4
- package/lib/chain.js +5 -2
- package/lib/executors/versioned/v2.js +9 -9
- package/lib/methods/v2/statetravel.js +6 -5
- package/lib/methods/v2/translatestate.js +7 -6
- package/lib/state.js +73 -9
- package/lib/walker.js +4 -2
- package/package.json +2 -2
- package/tttt.js +2 -0
package/connect.js
CHANGED
|
@@ -9,7 +9,9 @@ var path = require('path');
|
|
|
9
9
|
var log = require('db-migrate-shared').log;
|
|
10
10
|
const Promise = require('bluebird');
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Promise.promisifyAll(driver);
|
|
13
|
+
|
|
14
|
+
exports.connect = async function (config, PassedClass) {
|
|
13
15
|
var internals = {};
|
|
14
16
|
var prefix = 'migration';
|
|
15
17
|
if (config.config) {
|
|
@@ -18,6 +20,8 @@ exports.connect = function (config, PassedClass) {
|
|
|
18
20
|
config = config.config;
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
const db2 = await driver.connectAsync(config, internals);
|
|
24
|
+
|
|
21
25
|
return Promise.fromCallback(callback => {
|
|
22
26
|
driver.connect(config, internals, function (err, db) {
|
|
23
27
|
if (err) {
|
|
@@ -25,6 +29,14 @@ exports.connect = function (config, PassedClass) {
|
|
|
25
29
|
return;
|
|
26
30
|
}
|
|
27
31
|
|
|
32
|
+
const realClose = db.close;
|
|
33
|
+
// close both lines with one disconnect action
|
|
34
|
+
db.close = function (cb) {
|
|
35
|
+
db2.close(function () {});
|
|
36
|
+
db.close = realClose;
|
|
37
|
+
db.close(cb);
|
|
38
|
+
};
|
|
39
|
+
|
|
28
40
|
var dirPath = path.resolve(
|
|
29
41
|
internals.argv['migrations-dir'] || 'migrations'
|
|
30
42
|
);
|
|
@@ -59,7 +71,8 @@ exports.connect = function (config, PassedClass) {
|
|
|
59
71
|
dirPath,
|
|
60
72
|
internals.mode !== 'static',
|
|
61
73
|
internals,
|
|
62
|
-
prefix
|
|
74
|
+
prefix,
|
|
75
|
+
{ db2 }
|
|
63
76
|
)
|
|
64
77
|
);
|
|
65
78
|
});
|
|
@@ -100,6 +113,7 @@ exports.connect = function (config, PassedClass) {
|
|
|
100
113
|
db,
|
|
101
114
|
oldClose,
|
|
102
115
|
prefix,
|
|
116
|
+
db2,
|
|
103
117
|
cb
|
|
104
118
|
);
|
|
105
119
|
};
|
|
@@ -115,7 +129,8 @@ exports.connect = function (config, PassedClass) {
|
|
|
115
129
|
dirPath,
|
|
116
130
|
internals.mode !== 'static',
|
|
117
131
|
internals,
|
|
118
|
-
prefix
|
|
132
|
+
prefix,
|
|
133
|
+
{ db2 }
|
|
119
134
|
)
|
|
120
135
|
);
|
|
121
136
|
}
|
|
@@ -142,6 +157,7 @@ function migrationFiles (
|
|
|
142
157
|
db,
|
|
143
158
|
close,
|
|
144
159
|
prefix,
|
|
160
|
+
db2,
|
|
145
161
|
cb
|
|
146
162
|
) {
|
|
147
163
|
var file;
|
|
@@ -187,7 +203,8 @@ function migrationFiles (
|
|
|
187
203
|
internals.argv['migrations-dir'],
|
|
188
204
|
internals.mode !== 'static',
|
|
189
205
|
internals,
|
|
190
|
-
prefix
|
|
206
|
+
prefix,
|
|
207
|
+
{ db2 }
|
|
191
208
|
)
|
|
192
209
|
);
|
|
193
210
|
|
package/lib/chain.js
CHANGED
|
@@ -55,10 +55,11 @@ const dbmControl = {
|
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
class Chain {
|
|
58
|
-
constructor (context, file, driver, internals) {
|
|
58
|
+
constructor (context, file, driver, internals, pdriver) {
|
|
59
59
|
this.file = file;
|
|
60
60
|
this.context = context;
|
|
61
61
|
this.driver = context;
|
|
62
|
+
this.pdriver = pdriver;
|
|
62
63
|
this.udriver = driver;
|
|
63
64
|
if (this.udriver._dbmControl !== true) {
|
|
64
65
|
this.udriver._counter = dbmControl;
|
|
@@ -113,7 +114,8 @@ class Chain {
|
|
|
113
114
|
this.context,
|
|
114
115
|
this.file,
|
|
115
116
|
this.udriver,
|
|
116
|
-
this.internals
|
|
117
|
+
this.internals,
|
|
118
|
+
this.pdriver
|
|
117
119
|
);
|
|
118
120
|
}
|
|
119
121
|
|
|
@@ -136,6 +138,7 @@ class Chain {
|
|
|
136
138
|
this._step.useState(ret);
|
|
137
139
|
}
|
|
138
140
|
|
|
141
|
+
// need to check if we still want this
|
|
139
142
|
if (this._step.hasModification) {
|
|
140
143
|
const ret = this._step.modify(
|
|
141
144
|
this.context,
|
|
@@ -29,7 +29,7 @@ const execUnit = {
|
|
|
29
29
|
|
|
30
30
|
up: async function (context, driver, file) {
|
|
31
31
|
const _file = file.get();
|
|
32
|
-
const chain = new Chain(context._driver, file, driver, context.internals);
|
|
32
|
+
const chain = new Chain(context._driver, file, driver, context.internals, context._pdriver);
|
|
33
33
|
if (!_file._meta.noDefaultColumn) {
|
|
34
34
|
chain.addChain(AddConventions);
|
|
35
35
|
}
|
|
@@ -37,7 +37,7 @@ const execUnit = {
|
|
|
37
37
|
chain.addChain(StateTravel);
|
|
38
38
|
chain.addChain(Migrate);
|
|
39
39
|
|
|
40
|
-
await State.startMigration(context.
|
|
40
|
+
await State.startMigration(context._pdriver, file, context.internals);
|
|
41
41
|
// startMigration - needs secondary instance since we can not afford to
|
|
42
42
|
// loose state and the transaction start will include these for roll back
|
|
43
43
|
// we will disable them probably at all from DDL when the driver does not
|
|
@@ -62,20 +62,20 @@ const execUnit = {
|
|
|
62
62
|
throw err;
|
|
63
63
|
}
|
|
64
64
|
await Promise.promisify(context.writeMigrationRecord.bind(context))(file);
|
|
65
|
-
return State.endMigration(context.
|
|
65
|
+
return State.endMigration(context._pdriver, file, context.internals);
|
|
66
66
|
// end migration, same as start migration
|
|
67
67
|
},
|
|
68
68
|
|
|
69
69
|
fix: async function (context, driver, file) {
|
|
70
70
|
const _file = file.get();
|
|
71
|
-
const chain = new Chain(context._driver, file, driver, context.internals);
|
|
71
|
+
const chain = new Chain(context._driver, file, driver, context.internals, context._pdriver);
|
|
72
72
|
if (!_file._meta.noDefaultColumn) {
|
|
73
73
|
chain.addChain(AddConventions);
|
|
74
74
|
}
|
|
75
75
|
chain.addChain(Learn);
|
|
76
76
|
chain.addChain(StateTravel);
|
|
77
77
|
|
|
78
|
-
await State.startMigration(context.
|
|
78
|
+
await State.startMigration(context._pdriver, file, context.internals);
|
|
79
79
|
// startMigration - needs secondary instance since we can not afford to
|
|
80
80
|
// loose state and the transaction start will include these for roll back
|
|
81
81
|
// we will disable them probably at all from DDL when the driver does not
|
|
@@ -99,16 +99,16 @@ const execUnit = {
|
|
|
99
99
|
await execUnit.down(context, driver, file);
|
|
100
100
|
throw err;
|
|
101
101
|
}
|
|
102
|
-
await State.endMigration(context.
|
|
102
|
+
await State.endMigration(context._pdriver, file, context.internals);
|
|
103
103
|
log.verbose(`[fix] current schema`, util.inspect(context.internals.schema, false, null, true));
|
|
104
104
|
// end migration, same as start migration
|
|
105
105
|
},
|
|
106
106
|
|
|
107
107
|
down: async function (context, driver, file) {
|
|
108
108
|
// start migration, see up comments
|
|
109
|
-
await State.startMigration(context.
|
|
110
|
-
await TranslateState(context._driver, file, driver, context.internals);
|
|
111
|
-
await State.endMigration(context.
|
|
109
|
+
await State.startMigration(context._pdriver, file, context.internals);
|
|
110
|
+
await TranslateState(context._driver, file, driver, context.internals, context._pdriver);
|
|
111
|
+
await State.endMigration(context._pdriver, file, context.internals);
|
|
112
112
|
return Promise.promisify(context.deleteMigrationRecord.bind(context))(file);
|
|
113
113
|
// end migration, see up comments
|
|
114
114
|
}
|
|
@@ -18,16 +18,17 @@ const DEFAULT = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
class StateTravel {
|
|
21
|
-
constructor (internals, file, driver) {
|
|
21
|
+
constructor (internals, file, driver, pdriver) {
|
|
22
22
|
this.file = file;
|
|
23
23
|
this.internals = internals;
|
|
24
24
|
this.driver = driver;
|
|
25
|
+
this.pdriver = pdriver;
|
|
25
26
|
this._counter = 0;
|
|
26
27
|
this._default = async function _default () {
|
|
27
|
-
await State.step(this.
|
|
28
|
+
await State.step(this.pdriver, ++this._counter, this.internals);
|
|
28
29
|
|
|
29
30
|
return State.update(
|
|
30
|
-
this.
|
|
31
|
+
this.pdriver,
|
|
31
32
|
this.file,
|
|
32
33
|
this.internals.modSchema,
|
|
33
34
|
this.internals
|
|
@@ -49,9 +50,9 @@ const noTravelError = prop => {
|
|
|
49
50
|
};
|
|
50
51
|
|
|
51
52
|
module.exports = {
|
|
52
|
-
getInterface: (context, file, driver, internals) => {
|
|
53
|
+
getInterface: (context, file, driver, internals, pdriver) => {
|
|
53
54
|
if (context.learnable) {
|
|
54
|
-
const st = new StateTravel(internals, file, context);
|
|
55
|
+
const st = new StateTravel(internals, file, context, pdriver);
|
|
55
56
|
return Shadow.overshadow(
|
|
56
57
|
driver,
|
|
57
58
|
Object.assign(st, context.statechanger),
|
|
@@ -72,6 +72,7 @@ async function processEntry (
|
|
|
72
72
|
file,
|
|
73
73
|
driver,
|
|
74
74
|
internals,
|
|
75
|
+
pdriver,
|
|
75
76
|
{ t: type, a: action, c: args }
|
|
76
77
|
) {
|
|
77
78
|
let skip = false;
|
|
@@ -79,7 +80,7 @@ async function processEntry (
|
|
|
79
80
|
if (
|
|
80
81
|
internals.rollback === true &&
|
|
81
82
|
internals.rollbackContinue !== true &&
|
|
82
|
-
driver.udriver._meta
|
|
83
|
+
driver.udriver._meta?.signalColumns?.indexOf(action) !== -1
|
|
83
84
|
) {
|
|
84
85
|
internals.rollbackContinue = true;
|
|
85
86
|
skip = driver.udriver._counter.previousSignal() === null;
|
|
@@ -101,20 +102,20 @@ async function processEntry (
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
internals.modSchema.s.shift();
|
|
104
|
-
await State.update(
|
|
105
|
+
await State.update(pdriver, file, internals.modSchema, internals);
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
module.exports = async (context, file, driver, internals) => {
|
|
108
|
+
module.exports = async (context, file, driver, internals, pdriver) => {
|
|
108
109
|
const mod = internals.modSchema;
|
|
109
110
|
|
|
110
|
-
const chain = new Chain(context, file, driver, internals);
|
|
111
|
+
const chain = new Chain(context, file, driver, internals, pdriver);
|
|
111
112
|
internals.unlearn = true;
|
|
112
113
|
|
|
113
114
|
chain.addChain(Learn);
|
|
114
115
|
chain.addChain(Migrate);
|
|
115
116
|
await Promise.resolve(mod.s.reverse()).each(args =>
|
|
116
|
-
processEntry(context, file, chain, internals, args)
|
|
117
|
+
processEntry(context, file, chain, internals, pdriver, args)
|
|
117
118
|
);
|
|
118
119
|
|
|
119
|
-
await State.deleteState(
|
|
120
|
+
await State.deleteState(pdriver, file, internals);
|
|
120
121
|
};
|
package/lib/state.js
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
const MSTATE = '__dbmigrate_state__';
|
|
2
2
|
const SSTATE = '__dbmigrate_schema__';
|
|
3
|
+
const RUNON = 'run_on';
|
|
4
|
+
|
|
3
5
|
const log = require('db-migrate-shared').log;
|
|
4
6
|
const fs = require('fs').promises;
|
|
5
7
|
const path = require('path');
|
|
8
|
+
const crypto = require('crypto');
|
|
9
|
+
|
|
10
|
+
const ID = crypto.randomBytes(32).toString('base64');
|
|
11
|
+
let owner = false;
|
|
6
12
|
|
|
7
13
|
module.exports = {
|
|
14
|
+
/**
|
|
15
|
+
* Lock state will add the basic state controller an ID
|
|
16
|
+
* and a process controlled date.
|
|
17
|
+
* It is important that all systems are in sync. We will use the
|
|
18
|
+
* database clock instead if possible.
|
|
19
|
+
*/
|
|
8
20
|
lockState: async function (driver, state, internals) {
|
|
9
21
|
if (!state) {
|
|
22
|
+
owner = true;
|
|
10
23
|
return driver._insertKV(
|
|
11
24
|
internals.migrationState,
|
|
12
25
|
MSTATE,
|
|
@@ -14,23 +27,48 @@ module.exports = {
|
|
|
14
27
|
s: {
|
|
15
28
|
step: 0,
|
|
16
29
|
fin: 0,
|
|
30
|
+
ID,
|
|
17
31
|
date: new Date()
|
|
18
32
|
}
|
|
19
33
|
})
|
|
20
34
|
);
|
|
21
35
|
} else {
|
|
36
|
+
let runOn = state.run_on;
|
|
22
37
|
state = state.value;
|
|
23
38
|
state = JSON.parse(state);
|
|
24
|
-
|
|
25
|
-
|
|
39
|
+
|
|
40
|
+
if (!state.s.ID || state.s.ID !== ID) {
|
|
41
|
+
owner = true;
|
|
42
|
+
state.s.ID = ID;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const d = new Date();
|
|
46
|
+
|
|
47
|
+
state.s.date = d;
|
|
48
|
+
await driver._updateKVC(
|
|
26
49
|
internals.migrationState,
|
|
27
50
|
MSTATE,
|
|
28
|
-
|
|
29
|
-
|
|
51
|
+
JSON.stringify(state),
|
|
52
|
+
RUNON,
|
|
53
|
+
runOn
|
|
30
54
|
);
|
|
55
|
+
|
|
56
|
+
state = await driver._getKV(internals.migrationState, MSTATE);
|
|
57
|
+
|
|
58
|
+
runOn = state.run_on;
|
|
59
|
+
state = state.value;
|
|
60
|
+
state = JSON.parse(state);
|
|
61
|
+
|
|
62
|
+
if (state.s.ID !== ID) {
|
|
63
|
+
owner = false;
|
|
64
|
+
}
|
|
31
65
|
}
|
|
32
66
|
},
|
|
33
67
|
|
|
68
|
+
isOwner: function () {
|
|
69
|
+
return owner;
|
|
70
|
+
},
|
|
71
|
+
|
|
34
72
|
init: async function (driver, internals, { emptyState, backupState }) {
|
|
35
73
|
await driver._createKV(internals.migrationState);
|
|
36
74
|
const _schema = await driver._getKV(internals.migrationState, SSTATE);
|
|
@@ -97,7 +135,7 @@ module.exports = {
|
|
|
97
135
|
return Promise.resolve();
|
|
98
136
|
}
|
|
99
137
|
|
|
100
|
-
await driver._updateKV(internals.migrationState, SSTATE, internals.schema);
|
|
138
|
+
await driver._updateKV(internals.migrationState, SSTATE, JSON.stringify(internals.schema));
|
|
101
139
|
|
|
102
140
|
return driver._updateKV(
|
|
103
141
|
internals.migrationState,
|
|
@@ -115,17 +153,40 @@ module.exports = {
|
|
|
115
153
|
return Promise.resolve();
|
|
116
154
|
}
|
|
117
155
|
|
|
118
|
-
let
|
|
156
|
+
let state = await driver._getKV(
|
|
119
157
|
internals.migrationState,
|
|
120
158
|
MSTATE
|
|
121
159
|
);
|
|
160
|
+
|
|
161
|
+
let runOn = state.run_on;
|
|
162
|
+
state = state.value;
|
|
122
163
|
state = JSON.parse(state);
|
|
123
|
-
|
|
124
|
-
|
|
164
|
+
|
|
165
|
+
if (!state.s.ID || state.s.ID !== ID) {
|
|
166
|
+
owner = true;
|
|
167
|
+
state.s.ID = ID;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const d = new Date();
|
|
171
|
+
|
|
172
|
+
state.s.date = d;
|
|
173
|
+
await driver._updateKVC(
|
|
125
174
|
internals.migrationState,
|
|
126
175
|
MSTATE,
|
|
127
|
-
JSON.stringify(state)
|
|
176
|
+
JSON.stringify(state),
|
|
177
|
+
RUNON,
|
|
178
|
+
runOn
|
|
128
179
|
);
|
|
180
|
+
|
|
181
|
+
state = await driver._getKV(internals.migrationState, MSTATE);
|
|
182
|
+
|
|
183
|
+
runOn = state.run_on;
|
|
184
|
+
state = state.value;
|
|
185
|
+
state = JSON.parse(state);
|
|
186
|
+
|
|
187
|
+
if (state.s.ID !== ID) {
|
|
188
|
+
owner = false;
|
|
189
|
+
}
|
|
129
190
|
},
|
|
130
191
|
|
|
131
192
|
step: async function (driver, step, internals) {
|
|
@@ -165,6 +226,9 @@ module.exports = {
|
|
|
165
226
|
state.s.date = new Date();
|
|
166
227
|
state.s.fin = 1;
|
|
167
228
|
|
|
229
|
+
// unlock from current process
|
|
230
|
+
state.s.ID = 0;
|
|
231
|
+
|
|
168
232
|
return driver._updateKV(
|
|
169
233
|
internals.migrationState,
|
|
170
234
|
MSTATE,
|
package/lib/walker.js
CHANGED
|
@@ -24,10 +24,12 @@ const INTERFACES = {
|
|
|
24
24
|
'static-seed': require('./interface/seederInterface.js')
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const Walker = function (driver, directory, mode, intern, prefix) {
|
|
27
|
+
const Walker = function (driver, directory, mode, intern, prefix, opts = {}) {
|
|
28
28
|
this.driver = dbmUtil.reduceToInterface(driver, INTERFACES[prefix]);
|
|
29
29
|
this._driver = driver;
|
|
30
|
+
this._pdriver = opts.db2;
|
|
30
31
|
Promise.promisifyAll(this._driver);
|
|
32
|
+
Promise.promisifyAll(this._pdriver);
|
|
31
33
|
this.directory = directory;
|
|
32
34
|
this.internals = intern;
|
|
33
35
|
/**
|
|
@@ -60,7 +62,7 @@ const Walker = function (driver, directory, mode, intern, prefix) {
|
|
|
60
62
|
|
|
61
63
|
Walker.prototype = {
|
|
62
64
|
createTables: async function (options) {
|
|
63
|
-
await State.init(this.
|
|
65
|
+
await State.init(this._pdriver, this.internals, options);
|
|
64
66
|
return this._driver._createList(this.internals.migrationTable);
|
|
65
67
|
},
|
|
66
68
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "db-migrate",
|
|
3
3
|
"description": "Database migration framework for node.js",
|
|
4
|
-
"author": "Tobias
|
|
4
|
+
"author": "Tobias Gurtzick",
|
|
5
5
|
"bin": "./bin/db-migrate",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"database",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"programable",
|
|
32
32
|
"api"
|
|
33
33
|
],
|
|
34
|
-
"version": "1.0.0-beta.
|
|
34
|
+
"version": "1.0.0-beta.28",
|
|
35
35
|
"engines": {
|
|
36
36
|
"node": ">=8.0.0"
|
|
37
37
|
},
|
package/tttt.js
ADDED