@verdnatura/myt 1.5.18 → 1.5.19
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/.dockerignore +2 -2
- package/LICENSE +17 -17
- package/README.md +278 -278
- package/assets/db.ini +5 -5
- package/assets/myt.default.yml +11 -11
- package/assets/structure.sql +24 -24
- package/cli.js +4 -4
- package/exporters/event.ejs +18 -18
- package/exporters/event.js +31 -31
- package/exporters/event.sql +19 -19
- package/exporters/function.ejs +17 -17
- package/exporters/function.js +27 -27
- package/exporters/function.sql +16 -16
- package/exporters/procedure.ejs +11 -11
- package/exporters/procedure.js +23 -23
- package/exporters/procedure.sql +14 -14
- package/exporters/trigger.ejs +4 -4
- package/exporters/trigger.js +10 -10
- package/exporters/trigger.sql +13 -13
- package/exporters/view.ejs +7 -7
- package/exporters/view.js +29 -29
- package/exporters/view.sql +12 -12
- package/lib/command.js +13 -13
- package/lib/conn.js +141 -141
- package/lib/docker.js +133 -133
- package/lib/dumper.js +83 -83
- package/lib/exporter-engine.js +112 -112
- package/lib/exporter.js +86 -86
- package/lib/repo.js +29 -29
- package/lib/server.js +71 -71
- package/lib/util.js +7 -7
- package/myt-clean.js +58 -58
- package/myt-create.js +74 -74
- package/myt-dump.js +75 -75
- package/myt-fixtures.js +29 -29
- package/myt-init.js +36 -36
- package/myt-pull.js +183 -183
- package/myt-push.js +568 -568
- package/myt-run.js +177 -177
- package/myt-start.js +54 -54
- package/myt-version.js +218 -218
- package/myt.js +361 -361
- package/package.json +41 -41
- package/server/Dockerfile.base +1 -1
- package/server/Dockerfile.client +14 -14
- package/server/Dockerfile.dump +16 -16
- package/server/Dockerfile.server +25 -25
- package/server/docker-dump.sh +4 -4
- package/server/docker-fixtures.sh +4 -4
- package/server/docker-import.sh +6 -6
- package/server/docker-init.sh +20 -20
- package/server/docker-start.sh +10 -10
- package/server/docker.cnf +9 -9
- package/template/dump/Dockerfile.base +1 -1
- package/template/dump/afterDump.sql +1 -1
- package/template/dump/beforeDump.sql +1 -1
- package/template/dump/fixtures.sql +1 -1
- package/template/myt.config.yml +11 -11
- package/template/package.json +13 -13
- package/template/remotes/docker.ini +4 -4
- package/template/remotes/local.ini +5 -5
- package/template/routines/README.md +1 -1
- package/template/versions/00001-firstVersion/00-firstScript.sql +1 -1
- package/template/versions/README.md +1 -1
package/lib/dumper.js
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
const docker = require('./docker');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const SqlString = require('sqlstring');
|
|
5
|
-
|
|
6
|
-
module.exports = class Dumper {
|
|
7
|
-
constructor(opts) {
|
|
8
|
-
this.opts = opts;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async init(dumpFile) {
|
|
12
|
-
const dumpDir = this.opts.dumpDir;
|
|
13
|
-
if (!await fs.pathExists(dumpDir))
|
|
14
|
-
await fs.mkdir(dumpDir);
|
|
15
|
-
|
|
16
|
-
const dumpPath = path.join(dumpDir, dumpFile);
|
|
17
|
-
|
|
18
|
-
// FIXME: If it's called after docker.build() statement it creates an
|
|
19
|
-
// "invalid" WriteStream
|
|
20
|
-
const dumpStream = await fs.createWriteStream(dumpPath);
|
|
21
|
-
|
|
22
|
-
const buidDir = path.join(__dirname, '..',)
|
|
23
|
-
await docker.build(buidDir, {
|
|
24
|
-
tag: 'myt/client',
|
|
25
|
-
file: path.join(buidDir, 'server', 'Dockerfile.client')
|
|
26
|
-
}, this.opts.debug);
|
|
27
|
-
|
|
28
|
-
this.dumpStream = dumpStream;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async use(schema) {
|
|
32
|
-
await this.dumpStream.write(
|
|
33
|
-
`USE ${SqlString.escapeId(schema, true)};\n`,
|
|
34
|
-
'utf8'
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async dumpFixtures(tables, replace, args) {
|
|
39
|
-
const fixturesArgs = [
|
|
40
|
-
'--no-create-info',
|
|
41
|
-
'--skip-triggers',
|
|
42
|
-
'--skip-extended-insert',
|
|
43
|
-
'--skip-disable-keys',
|
|
44
|
-
'--skip-add-locks',
|
|
45
|
-
'--skip-set-charset',
|
|
46
|
-
'--skip-comments',
|
|
47
|
-
'--skip-tz-utc'
|
|
48
|
-
].concat(args);
|
|
49
|
-
|
|
50
|
-
if (replace)
|
|
51
|
-
fixturesArgs.push('--replace');
|
|
52
|
-
|
|
53
|
-
for (const schema in tables) {
|
|
54
|
-
await this.use(schema);
|
|
55
|
-
const args = fixturesArgs.concat([schema], tables[schema]);
|
|
56
|
-
await this.runDump('mysqldump', args, this.dumpStream);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async runDump(command, args) {
|
|
61
|
-
const iniPath = path.join(this.opts.subdir || '', 'remotes', this.opts.iniFile);
|
|
62
|
-
const myArgs = [
|
|
63
|
-
`--defaults-file=${iniPath}`
|
|
64
|
-
];
|
|
65
|
-
const execOptions = {
|
|
66
|
-
stdio: [
|
|
67
|
-
process.stdin,
|
|
68
|
-
this.dumpStream,
|
|
69
|
-
process.stderr
|
|
70
|
-
]
|
|
71
|
-
};
|
|
72
|
-
const commandArgs = [command].concat(myArgs, args);
|
|
73
|
-
await docker.run('myt/client', commandArgs, {
|
|
74
|
-
addHost: 'host.docker.internal:host-gateway',
|
|
75
|
-
volume: `${this.opts.mytDir}:/workspace`,
|
|
76
|
-
rm: true
|
|
77
|
-
}, execOptions);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async end() {
|
|
81
|
-
await this.dumpStream.end();
|
|
82
|
-
}
|
|
83
|
-
}
|
|
1
|
+
const docker = require('./docker');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const SqlString = require('sqlstring');
|
|
5
|
+
|
|
6
|
+
module.exports = class Dumper {
|
|
7
|
+
constructor(opts) {
|
|
8
|
+
this.opts = opts;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async init(dumpFile) {
|
|
12
|
+
const dumpDir = this.opts.dumpDir;
|
|
13
|
+
if (!await fs.pathExists(dumpDir))
|
|
14
|
+
await fs.mkdir(dumpDir);
|
|
15
|
+
|
|
16
|
+
const dumpPath = path.join(dumpDir, dumpFile);
|
|
17
|
+
|
|
18
|
+
// FIXME: If it's called after docker.build() statement it creates an
|
|
19
|
+
// "invalid" WriteStream
|
|
20
|
+
const dumpStream = await fs.createWriteStream(dumpPath);
|
|
21
|
+
|
|
22
|
+
const buidDir = path.join(__dirname, '..',)
|
|
23
|
+
await docker.build(buidDir, {
|
|
24
|
+
tag: 'myt/client',
|
|
25
|
+
file: path.join(buidDir, 'server', 'Dockerfile.client')
|
|
26
|
+
}, this.opts.debug);
|
|
27
|
+
|
|
28
|
+
this.dumpStream = dumpStream;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async use(schema) {
|
|
32
|
+
await this.dumpStream.write(
|
|
33
|
+
`USE ${SqlString.escapeId(schema, true)};\n`,
|
|
34
|
+
'utf8'
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async dumpFixtures(tables, replace, args) {
|
|
39
|
+
const fixturesArgs = [
|
|
40
|
+
'--no-create-info',
|
|
41
|
+
'--skip-triggers',
|
|
42
|
+
'--skip-extended-insert',
|
|
43
|
+
'--skip-disable-keys',
|
|
44
|
+
'--skip-add-locks',
|
|
45
|
+
'--skip-set-charset',
|
|
46
|
+
'--skip-comments',
|
|
47
|
+
'--skip-tz-utc'
|
|
48
|
+
].concat(args);
|
|
49
|
+
|
|
50
|
+
if (replace)
|
|
51
|
+
fixturesArgs.push('--replace');
|
|
52
|
+
|
|
53
|
+
for (const schema in tables) {
|
|
54
|
+
await this.use(schema);
|
|
55
|
+
const args = fixturesArgs.concat([schema], tables[schema]);
|
|
56
|
+
await this.runDump('mysqldump', args, this.dumpStream);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async runDump(command, args) {
|
|
61
|
+
const iniPath = path.join(this.opts.subdir || '', 'remotes', this.opts.iniFile);
|
|
62
|
+
const myArgs = [
|
|
63
|
+
`--defaults-file=${iniPath}`
|
|
64
|
+
];
|
|
65
|
+
const execOptions = {
|
|
66
|
+
stdio: [
|
|
67
|
+
process.stdin,
|
|
68
|
+
this.dumpStream,
|
|
69
|
+
process.stderr
|
|
70
|
+
]
|
|
71
|
+
};
|
|
72
|
+
const commandArgs = [command].concat(myArgs, args);
|
|
73
|
+
await docker.run('myt/client', commandArgs, {
|
|
74
|
+
addHost: 'host.docker.internal:host-gateway',
|
|
75
|
+
volume: `${this.opts.mytDir}:/workspace`,
|
|
76
|
+
rm: true
|
|
77
|
+
}, execOptions);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async end() {
|
|
81
|
+
await this.dumpStream.end();
|
|
82
|
+
}
|
|
83
|
+
}
|
package/lib/exporter-engine.js
CHANGED
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
const shajs = require('sha.js');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const Exporter = require('./exporter');
|
|
4
|
-
|
|
5
|
-
module.exports = class ExporterEngine {
|
|
6
|
-
constructor(conn, opts) {
|
|
7
|
-
this.conn = conn;
|
|
8
|
-
this.opts = opts;
|
|
9
|
-
this.pullFile = `${opts.mytDir}/.pullinfo.json`;
|
|
10
|
-
this.exporters = [];
|
|
11
|
-
this.exporterMap = {};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async init () {
|
|
15
|
-
if (await fs.pathExists(this.pullFile)) {
|
|
16
|
-
this.pullInfo = JSON.parse(await fs.readFile(this.pullFile, 'utf8'));
|
|
17
|
-
const lastPull = this.pullInfo.lastPull;
|
|
18
|
-
if (lastPull)
|
|
19
|
-
this.pullInfo.lastPull = new Date(lastPull);
|
|
20
|
-
} else
|
|
21
|
-
this.pullInfo = {
|
|
22
|
-
lastPull: null,
|
|
23
|
-
shaSums: {}
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
this.shaSums = this.pullInfo.shaSums;
|
|
27
|
-
this.lastPull = this.pullInfo.lastPull;
|
|
28
|
-
this.infoChanged = false;
|
|
29
|
-
|
|
30
|
-
const types = [
|
|
31
|
-
'function',
|
|
32
|
-
'procedure',
|
|
33
|
-
'view',
|
|
34
|
-
'trigger',
|
|
35
|
-
'event'
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
for (const type of types) {
|
|
39
|
-
const exporter = new Exporter(type, this.opts.replace);
|
|
40
|
-
await exporter.init();
|
|
41
|
-
|
|
42
|
-
this.exporters.push(exporter);
|
|
43
|
-
this.exporterMap[type] = exporter;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async fetchRoutine(type, schema, name) {
|
|
48
|
-
const exporter = this.exporterMap[type];
|
|
49
|
-
const [row] = await exporter.query(this.conn, schema, name);
|
|
50
|
-
return row && exporter.format(row);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async fetchShaSum(type, schema, name) {
|
|
54
|
-
const sql = await this.fetchRoutine(type, schema, name);
|
|
55
|
-
this.setShaSum(type, schema, name, this.shaSum(sql));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
shaSum(sql) {
|
|
59
|
-
if (!sql) return null;
|
|
60
|
-
return shajs('sha256')
|
|
61
|
-
.update(JSON.stringify(sql))
|
|
62
|
-
.digest('hex');
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
getShaSum(type, schema, name) {
|
|
66
|
-
try {
|
|
67
|
-
return this.shaSums[schema][type][name];
|
|
68
|
-
} catch (e) {};
|
|
69
|
-
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
setShaSum(type, schema, name, shaSum) {
|
|
74
|
-
if (!shaSum) {
|
|
75
|
-
this.deleteShaSum(type, schema, name);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const shaSums = this.shaSums;
|
|
80
|
-
if (!shaSums[schema])
|
|
81
|
-
shaSums[schema] = {};
|
|
82
|
-
if (!shaSums[schema][type])
|
|
83
|
-
shaSums[schema][type] = {};
|
|
84
|
-
shaSums[schema][type][name] = shaSum;
|
|
85
|
-
this.infoChanged = true;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
deleteShaSum(type, schema, name) {
|
|
89
|
-
try {
|
|
90
|
-
delete this.shaSums[schema][type][name];
|
|
91
|
-
this.infoChanged = true;
|
|
92
|
-
} catch (e) {};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
deleteSchemaSums(schema) {
|
|
96
|
-
delete this.shaSums[schema];
|
|
97
|
-
this.infoChanged = true;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async refreshPullDate() {
|
|
101
|
-
const [[row]] = await this.conn.query(`SELECT NOW() now`);
|
|
102
|
-
this.pullInfo.lastPull = row.now;
|
|
103
|
-
this.infoChanged = true;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async saveInfo() {
|
|
107
|
-
if (!this.infoChanged) return;
|
|
108
|
-
await fs.writeFile(this.pullFile,
|
|
109
|
-
JSON.stringify(this.pullInfo, null, ' '));
|
|
110
|
-
this.infoChanged = false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
1
|
+
const shajs = require('sha.js');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const Exporter = require('./exporter');
|
|
4
|
+
|
|
5
|
+
module.exports = class ExporterEngine {
|
|
6
|
+
constructor(conn, opts) {
|
|
7
|
+
this.conn = conn;
|
|
8
|
+
this.opts = opts;
|
|
9
|
+
this.pullFile = `${opts.mytDir}/.pullinfo.json`;
|
|
10
|
+
this.exporters = [];
|
|
11
|
+
this.exporterMap = {};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async init () {
|
|
15
|
+
if (await fs.pathExists(this.pullFile)) {
|
|
16
|
+
this.pullInfo = JSON.parse(await fs.readFile(this.pullFile, 'utf8'));
|
|
17
|
+
const lastPull = this.pullInfo.lastPull;
|
|
18
|
+
if (lastPull)
|
|
19
|
+
this.pullInfo.lastPull = new Date(lastPull);
|
|
20
|
+
} else
|
|
21
|
+
this.pullInfo = {
|
|
22
|
+
lastPull: null,
|
|
23
|
+
shaSums: {}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
this.shaSums = this.pullInfo.shaSums;
|
|
27
|
+
this.lastPull = this.pullInfo.lastPull;
|
|
28
|
+
this.infoChanged = false;
|
|
29
|
+
|
|
30
|
+
const types = [
|
|
31
|
+
'function',
|
|
32
|
+
'procedure',
|
|
33
|
+
'view',
|
|
34
|
+
'trigger',
|
|
35
|
+
'event'
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
for (const type of types) {
|
|
39
|
+
const exporter = new Exporter(type, this.opts.replace);
|
|
40
|
+
await exporter.init();
|
|
41
|
+
|
|
42
|
+
this.exporters.push(exporter);
|
|
43
|
+
this.exporterMap[type] = exporter;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async fetchRoutine(type, schema, name) {
|
|
48
|
+
const exporter = this.exporterMap[type];
|
|
49
|
+
const [row] = await exporter.query(this.conn, schema, name);
|
|
50
|
+
return row && exporter.format(row);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async fetchShaSum(type, schema, name) {
|
|
54
|
+
const sql = await this.fetchRoutine(type, schema, name);
|
|
55
|
+
this.setShaSum(type, schema, name, this.shaSum(sql));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
shaSum(sql) {
|
|
59
|
+
if (!sql) return null;
|
|
60
|
+
return shajs('sha256')
|
|
61
|
+
.update(JSON.stringify(sql))
|
|
62
|
+
.digest('hex');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getShaSum(type, schema, name) {
|
|
66
|
+
try {
|
|
67
|
+
return this.shaSums[schema][type][name];
|
|
68
|
+
} catch (e) {};
|
|
69
|
+
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
setShaSum(type, schema, name, shaSum) {
|
|
74
|
+
if (!shaSum) {
|
|
75
|
+
this.deleteShaSum(type, schema, name);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const shaSums = this.shaSums;
|
|
80
|
+
if (!shaSums[schema])
|
|
81
|
+
shaSums[schema] = {};
|
|
82
|
+
if (!shaSums[schema][type])
|
|
83
|
+
shaSums[schema][type] = {};
|
|
84
|
+
shaSums[schema][type][name] = shaSum;
|
|
85
|
+
this.infoChanged = true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
deleteShaSum(type, schema, name) {
|
|
89
|
+
try {
|
|
90
|
+
delete this.shaSums[schema][type][name];
|
|
91
|
+
this.infoChanged = true;
|
|
92
|
+
} catch (e) {};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
deleteSchemaSums(schema) {
|
|
96
|
+
delete this.shaSums[schema];
|
|
97
|
+
this.infoChanged = true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async refreshPullDate() {
|
|
101
|
+
const [[row]] = await this.conn.query(`SELECT NOW() now`);
|
|
102
|
+
this.pullInfo.lastPull = row.now;
|
|
103
|
+
this.infoChanged = true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async saveInfo() {
|
|
107
|
+
if (!this.infoChanged) return;
|
|
108
|
+
await fs.writeFile(this.pullFile,
|
|
109
|
+
JSON.stringify(this.pullInfo, null, ' '));
|
|
110
|
+
this.infoChanged = false;
|
|
111
|
+
}
|
|
112
|
+
}
|
package/lib/exporter.js
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
const ejs = require('ejs');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const SqlString = require('sqlstring');
|
|
4
|
-
|
|
5
|
-
module.exports = class Exporter {
|
|
6
|
-
constructor(objectType, replace) {
|
|
7
|
-
Object.assign(this, {
|
|
8
|
-
objectType,
|
|
9
|
-
replace
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async init() {
|
|
14
|
-
const templateDir = `${__dirname}/../exporters/${this.objectType}`;
|
|
15
|
-
this.sql = await fs.readFile(`${templateDir}.sql`, 'utf8');
|
|
16
|
-
|
|
17
|
-
const templateFile = await fs.readFile(`${templateDir}.ejs`, 'utf8');
|
|
18
|
-
this.template = ejs.compile(templateFile);
|
|
19
|
-
this.attrs = require(`${templateDir}.js`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async query(conn, schema, name) {
|
|
23
|
-
const ops = [];
|
|
24
|
-
function addOp(col, value) {
|
|
25
|
-
ops.push(conn.format('?? = ?', [col, value]));
|
|
26
|
-
}
|
|
27
|
-
if (schema)
|
|
28
|
-
addOp(this.attrs.schemaCol, schema);
|
|
29
|
-
if (name)
|
|
30
|
-
addOp(this.attrs.nameCol, name);
|
|
31
|
-
|
|
32
|
-
const filter = {
|
|
33
|
-
toSqlString() {
|
|
34
|
-
return ops.join(' AND ');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const [res] = await conn.query(this.sql, [filter]);
|
|
39
|
-
return res;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
format(params) {
|
|
43
|
-
const {attrs} = this;
|
|
44
|
-
params = Object.assign({}, attrs.defaults, params)
|
|
45
|
-
const data = {params};
|
|
46
|
-
|
|
47
|
-
if (attrs.formatter)
|
|
48
|
-
attrs.formatter(params);
|
|
49
|
-
|
|
50
|
-
if (attrs.escapeCols)
|
|
51
|
-
for (const escapeCol of attrs.escapeCols) {
|
|
52
|
-
if (params[escapeCol])
|
|
53
|
-
params[escapeCol] = SqlString.escape(params[escapeCol])
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const split = params.definer.split('@');
|
|
57
|
-
data.definer =
|
|
58
|
-
SqlString.escapeId(split[0], true) + '@' +
|
|
59
|
-
SqlString.escapeId(split[1], true);
|
|
60
|
-
|
|
61
|
-
data.name =
|
|
62
|
-
SqlString.escapeId(params.schema, true) + '.' +
|
|
63
|
-
SqlString.escapeId(params.name, true);
|
|
64
|
-
|
|
65
|
-
const objectType = this.objectType.toUpperCase();
|
|
66
|
-
const delimiter = '$$';
|
|
67
|
-
const replace = `CREATE OR REPLACE`;
|
|
68
|
-
|
|
69
|
-
let create;
|
|
70
|
-
if (this.replace) {
|
|
71
|
-
create = `DELIMITER ${delimiter}\n${replace}`
|
|
72
|
-
} else {
|
|
73
|
-
create =
|
|
74
|
-
`DROP ${objectType} IF EXISTS ${data.name};\n`
|
|
75
|
-
+`DELIMITER ${delimiter}\n`
|
|
76
|
-
+`CREATE`;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
data.createOrReplace = `${replace} DEFINER=${data.definer}`
|
|
80
|
-
data.begin = `${create} DEFINER=${data.definer}`;
|
|
81
|
-
data.typeAndName = `${objectType} ${data.name}`;
|
|
82
|
-
data.end = `${delimiter}\nDELIMITER ;`;
|
|
83
|
-
|
|
84
|
-
return this.template(data);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
1
|
+
const ejs = require('ejs');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const SqlString = require('sqlstring');
|
|
4
|
+
|
|
5
|
+
module.exports = class Exporter {
|
|
6
|
+
constructor(objectType, replace) {
|
|
7
|
+
Object.assign(this, {
|
|
8
|
+
objectType,
|
|
9
|
+
replace
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async init() {
|
|
14
|
+
const templateDir = `${__dirname}/../exporters/${this.objectType}`;
|
|
15
|
+
this.sql = await fs.readFile(`${templateDir}.sql`, 'utf8');
|
|
16
|
+
|
|
17
|
+
const templateFile = await fs.readFile(`${templateDir}.ejs`, 'utf8');
|
|
18
|
+
this.template = ejs.compile(templateFile);
|
|
19
|
+
this.attrs = require(`${templateDir}.js`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async query(conn, schema, name) {
|
|
23
|
+
const ops = [];
|
|
24
|
+
function addOp(col, value) {
|
|
25
|
+
ops.push(conn.format('?? = ?', [col, value]));
|
|
26
|
+
}
|
|
27
|
+
if (schema)
|
|
28
|
+
addOp(this.attrs.schemaCol, schema);
|
|
29
|
+
if (name)
|
|
30
|
+
addOp(this.attrs.nameCol, name);
|
|
31
|
+
|
|
32
|
+
const filter = {
|
|
33
|
+
toSqlString() {
|
|
34
|
+
return ops.join(' AND ');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const [res] = await conn.query(this.sql, [filter]);
|
|
39
|
+
return res;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
format(params) {
|
|
43
|
+
const {attrs} = this;
|
|
44
|
+
params = Object.assign({}, attrs.defaults, params)
|
|
45
|
+
const data = {params};
|
|
46
|
+
|
|
47
|
+
if (attrs.formatter)
|
|
48
|
+
attrs.formatter(params);
|
|
49
|
+
|
|
50
|
+
if (attrs.escapeCols)
|
|
51
|
+
for (const escapeCol of attrs.escapeCols) {
|
|
52
|
+
if (params[escapeCol])
|
|
53
|
+
params[escapeCol] = SqlString.escape(params[escapeCol])
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const split = params.definer.split('@');
|
|
57
|
+
data.definer =
|
|
58
|
+
SqlString.escapeId(split[0], true) + '@' +
|
|
59
|
+
SqlString.escapeId(split[1], true);
|
|
60
|
+
|
|
61
|
+
data.name =
|
|
62
|
+
SqlString.escapeId(params.schema, true) + '.' +
|
|
63
|
+
SqlString.escapeId(params.name, true);
|
|
64
|
+
|
|
65
|
+
const objectType = this.objectType.toUpperCase();
|
|
66
|
+
const delimiter = '$$';
|
|
67
|
+
const replace = `CREATE OR REPLACE`;
|
|
68
|
+
|
|
69
|
+
let create;
|
|
70
|
+
if (this.replace) {
|
|
71
|
+
create = `DELIMITER ${delimiter}\n${replace}`
|
|
72
|
+
} else {
|
|
73
|
+
create =
|
|
74
|
+
`DROP ${objectType} IF EXISTS ${data.name};\n`
|
|
75
|
+
+`DELIMITER ${delimiter}\n`
|
|
76
|
+
+`CREATE`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
data.createOrReplace = `${replace} DEFINER=${data.definer}`
|
|
80
|
+
data.begin = `${create} DEFINER=${data.definer}`;
|
|
81
|
+
data.typeAndName = `${objectType} ${data.name}`;
|
|
82
|
+
data.end = `${delimiter}\nDELIMITER ;`;
|
|
83
|
+
|
|
84
|
+
return this.template(data);
|
|
85
|
+
}
|
|
86
|
+
}
|
package/lib/repo.js
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
const nodegit = require('nodegit');
|
|
2
|
-
|
|
3
|
-
async function getStaged(repo) {
|
|
4
|
-
const head = await repo.getHeadCommit();
|
|
5
|
-
|
|
6
|
-
try {
|
|
7
|
-
const emptyTree = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
|
|
8
|
-
const headTree = await (head
|
|
9
|
-
? head.getTree()
|
|
10
|
-
: nodegit.Tree.lookup(repo, emptyTree)
|
|
11
|
-
);
|
|
12
|
-
return await nodegit.Diff.treeToIndex(repo, headTree, null);
|
|
13
|
-
} catch (err) {
|
|
14
|
-
console.warn('Cannot fetch staged changes:', err.message);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async function getUnstaged(repo) {
|
|
19
|
-
const Diff = nodegit.Diff;
|
|
20
|
-
return await Diff.indexToWorkdir(repo, null, {
|
|
21
|
-
flags: Diff.OPTION.SHOW_UNTRACKED_CONTENT
|
|
22
|
-
| Diff.OPTION.RECURSE_UNTRACKED_DIRS
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
module.exports = {
|
|
27
|
-
getStaged,
|
|
28
|
-
getUnstaged
|
|
29
|
-
};
|
|
1
|
+
const nodegit = require('nodegit');
|
|
2
|
+
|
|
3
|
+
async function getStaged(repo) {
|
|
4
|
+
const head = await repo.getHeadCommit();
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
const emptyTree = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
|
|
8
|
+
const headTree = await (head
|
|
9
|
+
? head.getTree()
|
|
10
|
+
: nodegit.Tree.lookup(repo, emptyTree)
|
|
11
|
+
);
|
|
12
|
+
return await nodegit.Diff.treeToIndex(repo, headTree, null);
|
|
13
|
+
} catch (err) {
|
|
14
|
+
console.warn('Cannot fetch staged changes:', err.message);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function getUnstaged(repo) {
|
|
19
|
+
const Diff = nodegit.Diff;
|
|
20
|
+
return await Diff.indexToWorkdir(repo, null, {
|
|
21
|
+
flags: Diff.OPTION.SHOW_UNTRACKED_CONTENT
|
|
22
|
+
| Diff.OPTION.RECURSE_UNTRACKED_DIRS
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
getStaged,
|
|
28
|
+
getUnstaged
|
|
29
|
+
};
|