@verdnatura/myt 1.8.6 → 2.0.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 +80 -52
- package/assets/myt.default.yml +7 -0
- package/assets/structure.sql +1 -1
- package/{server/Dockerfile.client → docker/client/Dockerfile} +3 -3
- package/docker/server/Dockerfile +37 -0
- package/docker/server/Dockerfile.base +6 -0
- package/docker/server/Dockerfile.myt +35 -0
- package/docker/server/docker-init.sh +36 -0
- package/{server → docker/server}/docker-start.sh +1 -1
- package/lib/command.js +14 -6
- package/lib/docker.js +60 -34
- package/lib/dumper.js +11 -9
- package/lib/exporter-engine.js +4 -4
- package/lib/server.js +2 -8
- package/myt-apply.js +203 -0
- package/myt-build.js +283 -0
- package/myt-clean.js +15 -11
- package/myt-create.js +19 -11
- package/myt-dump.js +41 -36
- package/myt-fixtures.js +6 -6
- package/myt-init.js +5 -3
- package/myt-pull.js +12 -11
- package/myt-push.js +99 -96
- package/myt-run.js +28 -144
- package/myt-start.js +4 -4
- package/myt-version.js +13 -13
- package/myt.js +285 -149
- package/package.json +4 -3
- package/prebuilts/README.md +15 -0
- package/prebuilts/nodegit-v0.28.0-alpha.36-node-v127-linux-x64.tar.gz +0 -0
- package/template/.dockerignore +5 -0
- package/template/myt.config.yml +1 -4
- package/template/package.json +1 -1
- package/template/realms/.keep +0 -0
- package/template/remotes/docker.ini +1 -1
- package/template/remotes/local.ini +1 -1
- package/template/remotes/socket.ini +3 -0
- package/template/structure/.dump/structure.sql +32 -0
- package/server/Dockerfile.base +0 -1
- package/server/Dockerfile.dump +0 -16
- package/server/Dockerfile.server +0 -16
- package/server/docker-import.sh +0 -10
- package/server/docker-init.sh +0 -24
- /package/{server → docker/client}/docker-dump.sh +0 -0
- /package/{server → docker/client}/docker-fixtures.sh +0 -0
- /package/{server → docker/server}/docker.cnf +0 -0
- /package/template/{dump/Dockerfile.base → docker/Dockerfile} +0 -0
- /package/template/{dump/fixtures.after.sql → fixtures/after.sql} +0 -0
- /package/template/{dump/fixtures.before.sql → fixtures/before.sql} +0 -0
- /package/template/{dump/dump.after.sql → structure/after.sql} +0 -0
- /package/template/{dump/dump.before.sql → structure/before.sql} +0 -0
package/myt-dump.js
CHANGED
|
@@ -8,23 +8,20 @@ class Dump extends Command {
|
|
|
8
8
|
static usage = {
|
|
9
9
|
description: 'Dumps structure and fixtures from remote',
|
|
10
10
|
params: {
|
|
11
|
-
lock: 'Whether to lock tables on dump'
|
|
12
|
-
triggers: 'Whether to include triggers into dump'
|
|
11
|
+
lock: 'Whether to lock tables on dump'
|
|
13
12
|
},
|
|
14
13
|
operand: 'remote'
|
|
15
14
|
};
|
|
16
15
|
|
|
17
|
-
static
|
|
16
|
+
static args = {
|
|
18
17
|
default: {
|
|
19
18
|
remote: 'production'
|
|
20
19
|
},
|
|
21
20
|
alias: {
|
|
22
|
-
lock: 'l'
|
|
23
|
-
triggers: 't'
|
|
21
|
+
lock: 'l'
|
|
24
22
|
},
|
|
25
23
|
boolean: [
|
|
26
|
-
'lock'
|
|
27
|
-
'triggers'
|
|
24
|
+
'lock'
|
|
28
25
|
]
|
|
29
26
|
};
|
|
30
27
|
|
|
@@ -35,21 +32,22 @@ class Dump extends Command {
|
|
|
35
32
|
dumpTriggers: 'Dumping triggers.'
|
|
36
33
|
};
|
|
37
34
|
|
|
38
|
-
async
|
|
35
|
+
async _run(myt, ctx, cfg, opts) {
|
|
36
|
+
const {dumpDir} = ctx;
|
|
37
|
+
|
|
39
38
|
let dumper;
|
|
40
|
-
const dumpDataDir = path.join(opts.dumpDir, '.dump');
|
|
41
39
|
const baseArgs = [
|
|
42
40
|
`--lock-tables=${opts.lock ? 'true' : 'false'}`
|
|
43
41
|
];
|
|
44
42
|
|
|
45
|
-
await fs.remove(
|
|
43
|
+
await fs.remove(dumpDir);
|
|
46
44
|
|
|
47
45
|
// Structure
|
|
48
46
|
|
|
49
47
|
this.emit('dumpStructure');
|
|
50
48
|
|
|
51
|
-
dumper = new Dumper(
|
|
52
|
-
await dumper.init(
|
|
49
|
+
dumper = new Dumper(myt);
|
|
50
|
+
await dumper.init(dumpDir, 'structure');
|
|
53
51
|
let dumpArgs = [
|
|
54
52
|
'--default-character-set=utf8',
|
|
55
53
|
'--no-data',
|
|
@@ -60,7 +58,7 @@ class Dump extends Command {
|
|
|
60
58
|
].concat(baseArgs);
|
|
61
59
|
|
|
62
60
|
dumpArgs.push('--databases');
|
|
63
|
-
dumpArgs = dumpArgs.concat(
|
|
61
|
+
dumpArgs = dumpArgs.concat(cfg.schemas);
|
|
64
62
|
await dumper.runDump('docker-dump.sh', dumpArgs);
|
|
65
63
|
await dumper.end();
|
|
66
64
|
|
|
@@ -68,19 +66,19 @@ class Dump extends Command {
|
|
|
68
66
|
|
|
69
67
|
this.emit('dumpData');
|
|
70
68
|
|
|
71
|
-
dumper = new Dumper(
|
|
72
|
-
await dumper.init(
|
|
73
|
-
await dumper.dumpFixtures(
|
|
69
|
+
dumper = new Dumper(myt);
|
|
70
|
+
await dumper.init(dumpDir, 'data');
|
|
71
|
+
await dumper.dumpFixtures(cfg.fixtures, false, baseArgs);
|
|
74
72
|
await dumper.end();
|
|
75
73
|
|
|
76
74
|
// Privileges
|
|
77
75
|
|
|
78
|
-
const privs =
|
|
76
|
+
const privs = cfg.privileges;
|
|
79
77
|
if (privs) {
|
|
80
78
|
this.emit('dumpPrivileges');
|
|
81
79
|
|
|
82
|
-
dumper = new Dumper(
|
|
83
|
-
await dumper.init(
|
|
80
|
+
dumper = new Dumper(myt);
|
|
81
|
+
await dumper.init(dumpDir, 'privileges');
|
|
84
82
|
|
|
85
83
|
const {tables, userTable, where} = privs;
|
|
86
84
|
|
|
@@ -102,26 +100,33 @@ class Dump extends Command {
|
|
|
102
100
|
|
|
103
101
|
// Triggers
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
this.emit('dumpTriggers');
|
|
103
|
+
this.emit('dumpTriggers');
|
|
107
104
|
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
dumper = new Dumper(myt);
|
|
106
|
+
await dumper.init(dumpDir, 'triggers');
|
|
110
107
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
108
|
+
dumpArgs = [
|
|
109
|
+
'--default-character-set=utf8',
|
|
110
|
+
'--no-create-info',
|
|
111
|
+
'--no-data',
|
|
112
|
+
'--no-create-db',
|
|
113
|
+
'--skip-opt',
|
|
114
|
+
'--comments'
|
|
115
|
+
].concat(baseArgs);
|
|
119
116
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
dumpArgs.push('--databases');
|
|
118
|
+
dumpArgs = dumpArgs.concat(cfg.schemas);
|
|
119
|
+
await dumper.runDump('mysqldump', dumpArgs);
|
|
120
|
+
await dumper.end();
|
|
121
|
+
|
|
122
|
+
// Info
|
|
123
|
+
|
|
124
|
+
await myt.dbConnect();
|
|
125
|
+
const version = await myt.fetchDbVersion();
|
|
126
|
+
await fs.writeFile(
|
|
127
|
+
path.join(dumpDir, 'version.json'),
|
|
128
|
+
JSON.stringify(version, null, 1)
|
|
129
|
+
);
|
|
125
130
|
}
|
|
126
131
|
}
|
|
127
132
|
|
package/myt-fixtures.js
CHANGED
|
@@ -8,16 +8,16 @@ class Fixtures extends Command {
|
|
|
8
8
|
operand: 'remote'
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
static
|
|
11
|
+
static args = {
|
|
12
12
|
default: {
|
|
13
|
-
remote: '
|
|
13
|
+
remote: 'local'
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
async
|
|
18
|
-
const dumper = new Dumper(
|
|
19
|
-
await dumper.init(
|
|
20
|
-
await dumper.dumpFixtures(
|
|
17
|
+
async _run(myt, ctx, cfg, opts) {
|
|
18
|
+
const dumper = new Dumper(myt);
|
|
19
|
+
await dumper.init(ctx.fixturesDir, '.dump');
|
|
20
|
+
await dumper.dumpFixtures(cfg.localFixtures, false);
|
|
21
21
|
await dumper.end();
|
|
22
22
|
}
|
|
23
23
|
}
|
package/myt-init.js
CHANGED
|
@@ -8,14 +8,16 @@ class Init extends Command {
|
|
|
8
8
|
description: 'Initialize an empty workspace'
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
static skipConf = true;
|
|
12
|
+
|
|
13
|
+
async _run(myt, ctx, cfg, opts) {
|
|
14
|
+
const packageFile = path.join(ctx.mytDir, 'package.json');
|
|
13
15
|
const packageExists = await fs.pathExists(packageFile);
|
|
14
16
|
|
|
15
17
|
const templateDir = path.join(__dirname, 'template');
|
|
16
18
|
const templates = await fs.readdir(templateDir);
|
|
17
19
|
for (let template of templates) {
|
|
18
|
-
const dst = path.join(
|
|
20
|
+
const dst = path.join(ctx.mytDir, template);
|
|
19
21
|
if (!await fs.pathExists(dst))
|
|
20
22
|
await fs.copy(path.join(templateDir, template), dst);
|
|
21
23
|
}
|
package/myt-pull.js
CHANGED
|
@@ -3,7 +3,6 @@ const Command = require('./lib/command');
|
|
|
3
3
|
const fs = require('fs-extra');
|
|
4
4
|
const nodegit = require('nodegit');
|
|
5
5
|
const ExporterEngine = require('./lib/exporter-engine');
|
|
6
|
-
const repoExt = require('./lib/repo');
|
|
7
6
|
|
|
8
7
|
class Pull extends Command {
|
|
9
8
|
static usage = {
|
|
@@ -17,7 +16,7 @@ class Pull extends Command {
|
|
|
17
16
|
operand: 'remote'
|
|
18
17
|
};
|
|
19
18
|
|
|
20
|
-
static
|
|
19
|
+
static args = {
|
|
21
20
|
alias: {
|
|
22
21
|
force: 'f',
|
|
23
22
|
checkout: 'c',
|
|
@@ -39,7 +38,7 @@ class Pull extends Command {
|
|
|
39
38
|
routineChanges: 'Incorporating routine changes.'
|
|
40
39
|
};
|
|
41
40
|
|
|
42
|
-
async
|
|
41
|
+
async _run(myt, ctx, cfg, opts) {
|
|
43
42
|
const conn = await myt.dbConnect();
|
|
44
43
|
const repo = await myt.openRepo();
|
|
45
44
|
|
|
@@ -50,13 +49,15 @@ class Pull extends Command {
|
|
|
50
49
|
const match = patch
|
|
51
50
|
.newFile()
|
|
52
51
|
.path()
|
|
53
|
-
.match(
|
|
52
|
+
.match(ctx.routinesRegex);
|
|
54
53
|
if (match) return true;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
return false;
|
|
58
57
|
}
|
|
59
58
|
|
|
59
|
+
const repoExt = require('./lib/repo');
|
|
60
|
+
|
|
60
61
|
// Check for unstaged changes
|
|
61
62
|
|
|
62
63
|
const unstagedDiff = await repoExt.getUnstaged(repo);
|
|
@@ -92,11 +93,11 @@ class Pull extends Command {
|
|
|
92
93
|
|
|
93
94
|
this.emit('routineChanges');
|
|
94
95
|
|
|
95
|
-
const engine = new ExporterEngine(conn,
|
|
96
|
+
const engine = new ExporterEngine(conn, myt);
|
|
96
97
|
await engine.init();
|
|
97
98
|
const shaSums = engine.shaSums;
|
|
98
99
|
|
|
99
|
-
const routinesDir =
|
|
100
|
+
const {routinesDir} = ctx;
|
|
100
101
|
if (!await fs.pathExists(routinesDir))
|
|
101
102
|
await fs.mkdir(routinesDir);
|
|
102
103
|
|
|
@@ -104,7 +105,7 @@ class Pull extends Command {
|
|
|
104
105
|
|
|
105
106
|
const schemas = await fs.readdir(routinesDir);
|
|
106
107
|
for (const schema of schemas) {
|
|
107
|
-
if (
|
|
108
|
+
if (cfg.schemas.indexOf(schema) == -1)
|
|
108
109
|
await fs.remove(`${routinesDir}/${schema}`);
|
|
109
110
|
}
|
|
110
111
|
|
|
@@ -115,7 +116,7 @@ class Pull extends Command {
|
|
|
115
116
|
|
|
116
117
|
// Export objects to SQL files
|
|
117
118
|
|
|
118
|
-
for (const schema of
|
|
119
|
+
for (const schema of cfg.schemas) {
|
|
119
120
|
let schemaDir = `${routinesDir}/${schema}`;
|
|
120
121
|
if (!await fs.pathExists(schemaDir))
|
|
121
122
|
await fs.mkdir(schemaDir);
|
|
@@ -129,14 +130,14 @@ class Pull extends Command {
|
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
async export(conn, engine, exporter, schema) {
|
|
132
|
-
const {opts} = this;
|
|
133
|
+
const {ctx, cfg, opts} = this;
|
|
133
134
|
|
|
134
135
|
const res = await exporter.query(conn, schema);
|
|
135
136
|
if (!res.length) return;
|
|
136
137
|
|
|
137
138
|
const type = exporter.objectType;
|
|
138
139
|
|
|
139
|
-
const routineDir = `${
|
|
140
|
+
const routineDir = `${ctx.routinesDir}/${schema}/${type}s`;
|
|
140
141
|
if (!await fs.pathExists(routineDir))
|
|
141
142
|
await fs.mkdir(routineDir);
|
|
142
143
|
|
|
@@ -162,7 +163,7 @@ class Pull extends Command {
|
|
|
162
163
|
let update = opts.update;
|
|
163
164
|
|
|
164
165
|
const oldSum = engine.getShaSum(type, schema, routineName);
|
|
165
|
-
if (oldSum || opts.sums || (
|
|
166
|
+
if (oldSum || opts.sums || (cfg.sumViews && type === 'view')) {
|
|
166
167
|
const shaSum = engine.shaSum(sql);
|
|
167
168
|
if (oldSum !== shaSum) {
|
|
168
169
|
engine.setShaSum(type, schema, routineName, shaSum);
|
package/myt-push.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
const Myt = require('./myt');
|
|
2
2
|
const Command = require('./lib/command');
|
|
3
3
|
const fs = require('fs-extra');
|
|
4
|
-
const nodegit = require('nodegit');
|
|
5
4
|
const ExporterEngine = require('./lib/exporter-engine');
|
|
6
5
|
const connExt = require('./lib/conn');
|
|
7
|
-
const repoExt = require('./lib/repo');
|
|
8
6
|
const SqlString = require('sqlstring');
|
|
7
|
+
const path = require('path');
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Pushes changes to remote.
|
|
@@ -17,23 +16,31 @@ class Push extends Command {
|
|
|
17
16
|
force: 'Answer yes to all questions',
|
|
18
17
|
commit: 'Whether to save the commit SHA into database',
|
|
19
18
|
sums: 'Save SHA sums of pushed objects',
|
|
20
|
-
triggers: 'Whether to exclude triggers, used to generate local DB'
|
|
19
|
+
triggers: 'Whether to exclude triggers, used to generate local DB',
|
|
20
|
+
docker: 'Whether to load git changes from file',
|
|
21
|
+
load: 'Commit SHA to save'
|
|
21
22
|
},
|
|
22
23
|
operand: 'remote'
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
static
|
|
26
|
+
static args = {
|
|
26
27
|
alias: {
|
|
27
28
|
force: 'f',
|
|
28
29
|
commit: 'c',
|
|
29
30
|
sums: 's',
|
|
30
|
-
triggers: 't'
|
|
31
|
+
triggers: 't',
|
|
32
|
+
docker: 'k',
|
|
33
|
+
load: 'l'
|
|
31
34
|
},
|
|
32
35
|
boolean: [
|
|
33
36
|
'force',
|
|
34
37
|
'commit',
|
|
35
38
|
'sums',
|
|
36
|
-
'triggers'
|
|
39
|
+
'triggers',
|
|
40
|
+
'docker'
|
|
41
|
+
],
|
|
42
|
+
string: [
|
|
43
|
+
'load'
|
|
37
44
|
]
|
|
38
45
|
};
|
|
39
46
|
|
|
@@ -82,8 +89,37 @@ class Push extends Command {
|
|
|
82
89
|
actionMsg = '[+]'.green;
|
|
83
90
|
else
|
|
84
91
|
actionMsg = '[I]'.blue;
|
|
92
|
+
|
|
93
|
+
const msg = ` ${actionMsg.bold} ${script.file}`;
|
|
85
94
|
|
|
86
|
-
|
|
95
|
+
if (script.push)
|
|
96
|
+
process.stdout.write(msg);
|
|
97
|
+
else
|
|
98
|
+
console.log(msg)
|
|
99
|
+
},
|
|
100
|
+
logScriptEnd(script, time) {
|
|
101
|
+
const ms = (time % 1000);
|
|
102
|
+
time = (time - ms) / 1000;
|
|
103
|
+
const s = time % 60;
|
|
104
|
+
time = (time - s) / 60;
|
|
105
|
+
const m = time % 60;
|
|
106
|
+
time = (time - m) / 60;
|
|
107
|
+
const h = time % 60;
|
|
108
|
+
|
|
109
|
+
const parts = [];
|
|
110
|
+
if (h)
|
|
111
|
+
parts.push(`${h}h`);
|
|
112
|
+
if (m)
|
|
113
|
+
parts.push(`${m}m`);
|
|
114
|
+
|
|
115
|
+
if (h || m || s) {
|
|
116
|
+
const msFormat = String(ms).padStart(3, '0');
|
|
117
|
+
parts.push(h || m ? `${s}s` : `${s}.${msFormat}s`);
|
|
118
|
+
} else
|
|
119
|
+
parts.push(`${ms}ms`);
|
|
120
|
+
|
|
121
|
+
const timeMsg = parts.join(' ');
|
|
122
|
+
console.log(` # ${timeMsg}`);
|
|
87
123
|
},
|
|
88
124
|
change(status, ignore, change) {
|
|
89
125
|
let actionMsg;
|
|
@@ -126,11 +162,11 @@ class Push extends Command {
|
|
|
126
162
|
}
|
|
127
163
|
};
|
|
128
164
|
|
|
129
|
-
async
|
|
165
|
+
async _run(myt, ctx, cfg, opts) {
|
|
130
166
|
const conn = await myt.dbConnect();
|
|
131
167
|
this.conn = conn;
|
|
132
168
|
|
|
133
|
-
if (
|
|
169
|
+
if (ctx.isLocalRemote)
|
|
134
170
|
opts.commit = true;
|
|
135
171
|
|
|
136
172
|
// Obtain exclusive lock
|
|
@@ -171,7 +207,7 @@ class Push extends Command {
|
|
|
171
207
|
}
|
|
172
208
|
|
|
173
209
|
try {
|
|
174
|
-
await this.push(
|
|
210
|
+
await this.push(conn);
|
|
175
211
|
} catch(err) {
|
|
176
212
|
try {
|
|
177
213
|
await releaseLock();
|
|
@@ -184,10 +220,10 @@ class Push extends Command {
|
|
|
184
220
|
await releaseLock();
|
|
185
221
|
}
|
|
186
222
|
|
|
187
|
-
async cli(
|
|
188
|
-
|
|
223
|
+
async cli() {
|
|
224
|
+
const {ctx, opts} = this;
|
|
189
225
|
|
|
190
|
-
if (
|
|
226
|
+
if (ctx.isProtectedRemote) {
|
|
191
227
|
console.log(
|
|
192
228
|
'\n ( ( ) ( ( ) ) '
|
|
193
229
|
+ '\n )\\ ))\\ ) ( /( )\\ ) ( ))\\ ) ( /( ( /( '
|
|
@@ -216,10 +252,12 @@ class Push extends Command {
|
|
|
216
252
|
}
|
|
217
253
|
}
|
|
218
254
|
|
|
219
|
-
await super.cli(
|
|
255
|
+
await super.cli();
|
|
220
256
|
}
|
|
221
257
|
|
|
222
|
-
async push(
|
|
258
|
+
async push(conn) {
|
|
259
|
+
const {myt, ctx, cfg, opts} = this;
|
|
260
|
+
|
|
223
261
|
const pushConn = await myt.createConnection();
|
|
224
262
|
|
|
225
263
|
// Get database version
|
|
@@ -228,7 +266,7 @@ class Push extends Command {
|
|
|
228
266
|
this.emit('dbInfo', dbVersion);
|
|
229
267
|
|
|
230
268
|
if (!dbVersion.number)
|
|
231
|
-
dbVersion.number = String('0').padStart(
|
|
269
|
+
dbVersion.number = String('0').padStart(cfg.versionDigits, '0');
|
|
232
270
|
if (!/^[0-9]*$/.test(dbVersion.number))
|
|
233
271
|
throw new Error('Wrong database version');
|
|
234
272
|
|
|
@@ -239,7 +277,7 @@ class Push extends Command {
|
|
|
239
277
|
let nVersions = 0;
|
|
240
278
|
let nChanges = 0;
|
|
241
279
|
let showLog = false;
|
|
242
|
-
const versionsDir =
|
|
280
|
+
const versionsDir = ctx.versionsDir;
|
|
243
281
|
|
|
244
282
|
const skipFiles = new Set([
|
|
245
283
|
'README.md',
|
|
@@ -269,8 +307,9 @@ class Push extends Command {
|
|
|
269
307
|
|
|
270
308
|
for (const script of version.scripts) {
|
|
271
309
|
this.emit('logScript', script);
|
|
272
|
-
if (!script.
|
|
310
|
+
if (!script.push) continue;
|
|
273
311
|
|
|
312
|
+
const ini = performance.now();
|
|
274
313
|
let err;
|
|
275
314
|
try {
|
|
276
315
|
await connExt.queryFromFile(pushConn,
|
|
@@ -278,6 +317,8 @@ class Push extends Command {
|
|
|
278
317
|
} catch (e) {
|
|
279
318
|
err = e;
|
|
280
319
|
}
|
|
320
|
+
const end = performance.now();
|
|
321
|
+
this.emit('logScriptEnd', script, Math.floor(end - ini));
|
|
281
322
|
|
|
282
323
|
await conn.query(
|
|
283
324
|
`INSERT INTO versionLog
|
|
@@ -294,7 +335,7 @@ class Push extends Command {
|
|
|
294
335
|
errorNumber = VALUES(errorNumber),
|
|
295
336
|
errorMessage = VALUES(errorMessage)`,
|
|
296
337
|
[
|
|
297
|
-
|
|
338
|
+
cfg.code,
|
|
298
339
|
version.number,
|
|
299
340
|
script.file,
|
|
300
341
|
err && err.errno,
|
|
@@ -318,7 +359,17 @@ class Push extends Command {
|
|
|
318
359
|
this.emit('applyingRoutines');
|
|
319
360
|
|
|
320
361
|
let nRoutines = 0;
|
|
321
|
-
|
|
362
|
+
|
|
363
|
+
let diff;
|
|
364
|
+
if (opts.docker) {
|
|
365
|
+
const changesFile = path.join(ctx.routinesDir, '.changes.json');
|
|
366
|
+
diff = await fs.exists(changesFile)
|
|
367
|
+
? JSON.parse(await fs.readFile(changesFile, 'utf8'))
|
|
368
|
+
: [];
|
|
369
|
+
} else
|
|
370
|
+
diff = await myt.getChanges(dbVersion.gitCommit);
|
|
371
|
+
|
|
372
|
+
const changes = await this.changedRoutines(diff);
|
|
322
373
|
|
|
323
374
|
const routines = [];
|
|
324
375
|
for (const change of changes)
|
|
@@ -342,7 +393,7 @@ class Push extends Command {
|
|
|
342
393
|
);
|
|
343
394
|
}
|
|
344
395
|
|
|
345
|
-
const engine = new ExporterEngine(conn,
|
|
396
|
+
const engine = new ExporterEngine(conn, myt);
|
|
346
397
|
await engine.init();
|
|
347
398
|
|
|
348
399
|
async function finalize() {
|
|
@@ -354,6 +405,10 @@ class Push extends Command {
|
|
|
354
405
|
}
|
|
355
406
|
}
|
|
356
407
|
|
|
408
|
+
const localRemote = cfg.remote == null || ctx.isLocalRemote;
|
|
409
|
+
let mockFunctions = localRemote && cfg.mockDate && cfg.mockFunctions;
|
|
410
|
+
mockFunctions = new Set(mockFunctions || []);
|
|
411
|
+
|
|
357
412
|
for (const change of changes)
|
|
358
413
|
try {
|
|
359
414
|
if (opts.triggers && change.type.name === 'TRIGGER')
|
|
@@ -362,7 +417,7 @@ class Push extends Command {
|
|
|
362
417
|
const schema = change.schema;
|
|
363
418
|
const name = change.name;
|
|
364
419
|
const type = change.type.name.toLowerCase();
|
|
365
|
-
const fullPath = `${
|
|
420
|
+
const fullPath = `${ctx.routinesDir}/${change.path}.sql`;
|
|
366
421
|
const exists = await fs.pathExists(fullPath);
|
|
367
422
|
|
|
368
423
|
let newSql;
|
|
@@ -371,15 +426,9 @@ class Push extends Command {
|
|
|
371
426
|
const oldSql = await engine.fetchRoutine(type, schema, name);
|
|
372
427
|
const oldSum = engine.getShaSum(type, schema, name);
|
|
373
428
|
|
|
374
|
-
const localRemote = opts.remote == null
|
|
375
|
-
|| opts.localRemotes?.indexOf(opts.remote) !== -1;
|
|
376
|
-
|
|
377
429
|
const isMockFn = type == 'function'
|
|
378
|
-
&& schema ==
|
|
379
|
-
&&
|
|
380
|
-
&& opts.mockDate
|
|
381
|
-
&& opts.mockFunctions
|
|
382
|
-
&& opts.mockFunctions.indexOf(name) !== -1;
|
|
430
|
+
&& schema == cfg.versionSchema
|
|
431
|
+
&& mockFunctions.has(name);
|
|
383
432
|
const ignore = newSql == oldSql || isMockFn;
|
|
384
433
|
|
|
385
434
|
let status;
|
|
@@ -412,7 +461,7 @@ class Push extends Command {
|
|
|
412
461
|
);
|
|
413
462
|
}
|
|
414
463
|
|
|
415
|
-
if (opts.sums || oldSum || (
|
|
464
|
+
if (opts.sums || oldSum || (cfg.sumViews && type === 'view'))
|
|
416
465
|
await engine.fetchShaSum(type, schema, name);
|
|
417
466
|
} else {
|
|
418
467
|
const escapedName =
|
|
@@ -440,13 +489,23 @@ class Push extends Command {
|
|
|
440
489
|
|
|
441
490
|
this.emit('routinesApplied', nRoutines);
|
|
442
491
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
const repo = await nodegit.Repository.open(this.opts.workspace);
|
|
446
|
-
const head = await repo.getHeadCommit();
|
|
492
|
+
if (opts.commit) {
|
|
493
|
+
let commitSha;
|
|
447
494
|
|
|
448
|
-
if (
|
|
449
|
-
|
|
495
|
+
if (opts.docker) {
|
|
496
|
+
commitSha = opts.load;
|
|
497
|
+
} else {
|
|
498
|
+
const gitExists = await fs.pathExists(`${cfg.workspace}/.git`);
|
|
499
|
+
if (gitExists) {
|
|
500
|
+
const nodegit = require('nodegit');
|
|
501
|
+
const repo = await nodegit.Repository.open(cfg.workspace);
|
|
502
|
+
const head = await repo.getHeadCommit();
|
|
503
|
+
commitSha = head?.sha();
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (commitSha && dbVersion.gitCommit !== commitSha)
|
|
508
|
+
await this.updateVersion('gitCommit', commitSha);
|
|
450
509
|
}
|
|
451
510
|
|
|
452
511
|
// End
|
|
@@ -465,71 +524,15 @@ class Push extends Command {
|
|
|
465
524
|
${column} = VALUES(${column}),
|
|
466
525
|
updated = VALUES(updated)`,
|
|
467
526
|
[
|
|
468
|
-
this.
|
|
527
|
+
this.cfg.code,
|
|
469
528
|
value
|
|
470
529
|
]
|
|
471
530
|
);
|
|
472
531
|
}
|
|
473
532
|
|
|
474
|
-
async changedRoutines(
|
|
475
|
-
const repo = await this.myt.openRepo();
|
|
476
|
-
const changes = [];
|
|
477
|
-
const changesMap = new Map();
|
|
478
|
-
|
|
479
|
-
const {opts} = this;
|
|
480
|
-
async function pushChanges(diff) {
|
|
481
|
-
if (!diff) return;
|
|
482
|
-
const patches = await diff.patches();
|
|
483
|
-
|
|
484
|
-
for (const patch of patches) {
|
|
485
|
-
const path = patch.newFile().path();
|
|
486
|
-
const match = path.match(opts.routinesRegex);
|
|
487
|
-
if (!match) continue;
|
|
488
|
-
|
|
489
|
-
let change = changesMap.get(match[1]);
|
|
490
|
-
if (!change) {
|
|
491
|
-
change = {path: match[1]};
|
|
492
|
-
changes.push(change);
|
|
493
|
-
changesMap.set(match[1], change);
|
|
494
|
-
}
|
|
495
|
-
change.mark = patch.isDeleted() ? '-' : '+';
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
const head = await repo.getHeadCommit();
|
|
500
|
-
|
|
501
|
-
if (head && commitSha) {
|
|
502
|
-
let commit;
|
|
503
|
-
let notFound;
|
|
504
|
-
|
|
505
|
-
try {
|
|
506
|
-
commit = await repo.getCommit(commitSha);
|
|
507
|
-
notFound = false;
|
|
508
|
-
} catch (err) {
|
|
509
|
-
if (err.errorFunction == 'Commit.lookup')
|
|
510
|
-
notFound = true;
|
|
511
|
-
else
|
|
512
|
-
throw err;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
if (notFound) {
|
|
516
|
-
console.warn(`Database commit not found, trying git fetch`.yellow);
|
|
517
|
-
await repo.fetchAll();
|
|
518
|
-
commit = await repo.getCommit(commitSha);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
const commitTree = await commit.getTree();
|
|
522
|
-
|
|
523
|
-
const headTree = await head.getTree();
|
|
524
|
-
const diff = await headTree.diff(commitTree);
|
|
525
|
-
await pushChanges(diff);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
await pushChanges(await repoExt.getUnstaged(repo));
|
|
529
|
-
await pushChanges(await repoExt.getStaged(repo));
|
|
530
|
-
|
|
533
|
+
async changedRoutines(diff) {
|
|
531
534
|
const routines = [];
|
|
532
|
-
for (const change of
|
|
535
|
+
for (const change of diff)
|
|
533
536
|
routines.push(new Routine(change));
|
|
534
537
|
|
|
535
538
|
return routines.sort((a, b) => {
|