@verdnatura/myt 1.5.6 → 1.5.8
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 +10 -0
- package/exporters/event.ejs +4 -4
- package/exporters/event.js +6 -0
- package/exporters/function.ejs +5 -5
- package/exporters/function.js +4 -0
- package/exporters/procedure.ejs +4 -4
- package/exporters/trigger.js +6 -1
- package/exporters/view.ejs +1 -1
- package/exporters/view.js +4 -0
- package/lib/command.js +3 -6
- package/lib/conn.js +141 -0
- package/lib/dumper.js +83 -0
- package/lib/exporter-engine.js +2 -3
- package/lib/exporter.js +11 -65
- package/lib/repo.js +29 -0
- package/lib/util.js +3 -2
- package/myt-clean.js +1 -2
- package/myt-create.js +74 -0
- package/myt-dump.js +10 -9
- package/myt-fixtures.js +6 -5
- package/myt-init.js +0 -1
- package/myt-pull.js +57 -6
- package/myt-push.js +72 -8
- package/myt-run.js +3 -3
- package/myt-start.js +0 -1
- package/myt-version.js +1 -2
- package/myt.js +45 -337
- package/package.json +2 -2
- package/server/docker-dump.sh +1 -1
- package/template/package.json +1 -1
- package/template/remotes/docker.ini +5 -0
package/README.md
CHANGED
|
@@ -45,6 +45,8 @@ Database versioning commands:
|
|
|
45
45
|
* **pull**: Incorporate database routine changes into workspace.
|
|
46
46
|
* **push**: Apply changes into database.
|
|
47
47
|
* **version**: Creates a new version.
|
|
48
|
+
* **create**: Creates a new routine file.
|
|
49
|
+
* **clean**: Cleans old versions.
|
|
48
50
|
|
|
49
51
|
Local server management commands:
|
|
50
52
|
|
|
@@ -195,6 +197,14 @@ name mixing a color with a plant name.
|
|
|
195
197
|
$ myt version [<name>]
|
|
196
198
|
```
|
|
197
199
|
|
|
200
|
+
### create
|
|
201
|
+
|
|
202
|
+
Creates a new routine file with a default template.
|
|
203
|
+
|
|
204
|
+
```text
|
|
205
|
+
$ myt create [-t <type>] <schema>.<name>
|
|
206
|
+
```
|
|
207
|
+
|
|
198
208
|
### clean
|
|
199
209
|
|
|
200
210
|
Cleans all already applied versions older than *maxOldVersions*.
|
package/exporters/event.ejs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
DROP EVENT IF EXISTS <%- schema %>.<%- name %>;
|
|
2
2
|
DELIMITER $$
|
|
3
3
|
CREATE DEFINER=<%- definer %> EVENT <%- schema %>.<%- name %><%
|
|
4
|
-
if (type == 'RECURRING') { %>
|
|
4
|
+
if (locals.type == 'RECURRING') { %>
|
|
5
5
|
ON SCHEDULE EVERY <%- intervalValue %> <%- intervalField %><%
|
|
6
|
-
if (starts) { %>
|
|
6
|
+
if (locals.starts) { %>
|
|
7
7
|
STARTS <%- starts %><%
|
|
8
8
|
}
|
|
9
|
-
if (ends) { %>
|
|
9
|
+
if (locals.ends) { %>
|
|
10
10
|
ENDS <%- ends %><%
|
|
11
11
|
}
|
|
12
12
|
} else { %>
|
|
@@ -14,7 +14,7 @@ if (type == 'RECURRING') { %>
|
|
|
14
14
|
} %>
|
|
15
15
|
ON COMPLETION <%- onCompletion %>
|
|
16
16
|
<%- status %><%
|
|
17
|
-
if (comment) { %>
|
|
17
|
+
if (locals.comment) { %>
|
|
18
18
|
COMMENT <%- comment %><%
|
|
19
19
|
} %>
|
|
20
20
|
DO <%- body %>$$
|
package/exporters/event.js
CHANGED
package/exporters/function.ejs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
DROP FUNCTION IF EXISTS <%- schema %>.<%- name %>;
|
|
2
2
|
DELIMITER $$
|
|
3
|
-
CREATE DEFINER=<%- definer %> FUNCTION <%- schema %>.<%- name %>(<%- paramList %>)
|
|
3
|
+
CREATE DEFINER=<%- definer %> FUNCTION <%- schema %>.<%- name %>(<%- locals.paramList %>)
|
|
4
4
|
RETURNS <%- returns %><%
|
|
5
|
-
if (isDeterministic == 'NO') { %>
|
|
5
|
+
if (locals.isDeterministic == 'NO') { %>
|
|
6
6
|
NOT DETERMINISTIC<%
|
|
7
7
|
} else { %>
|
|
8
8
|
DETERMINISTIC<%
|
|
9
9
|
}
|
|
10
|
-
if (dataAccess) { %>
|
|
10
|
+
if (locals.dataAccess) { %>
|
|
11
11
|
<%- dataAccess %><%
|
|
12
12
|
}
|
|
13
|
-
if (securityType == 'INVOKER') { %>
|
|
13
|
+
if (locals.securityType == 'INVOKER') { %>
|
|
14
14
|
SQL SECURITY <%- securityType %><%
|
|
15
15
|
}
|
|
16
|
-
if (comment) { %>
|
|
16
|
+
if (locals.comment) { %>
|
|
17
17
|
COMMENT <%- comment %><%
|
|
18
18
|
} %>
|
|
19
19
|
<%- body %>$$
|
package/exporters/function.js
CHANGED
package/exporters/procedure.ejs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
DROP PROCEDURE IF EXISTS <%- schema %>.<%- name %>;
|
|
2
2
|
DELIMITER $$
|
|
3
|
-
CREATE DEFINER=<%- definer %> PROCEDURE <%- schema %>.<%- name %>(<%- paramList %>)<%
|
|
4
|
-
if (dataAccess) { %>
|
|
3
|
+
CREATE DEFINER=<%- definer %> PROCEDURE <%- schema %>.<%- name %>(<%- locals.paramList %>)<%
|
|
4
|
+
if (locals.dataAccess) { %>
|
|
5
5
|
<%- dataAccess %><%
|
|
6
6
|
}
|
|
7
|
-
if (securityType == 'INVOKER') { %>
|
|
7
|
+
if (locals.securityType == 'INVOKER') { %>
|
|
8
8
|
SQL SECURITY <%- securityType %><%
|
|
9
9
|
}
|
|
10
|
-
if (comment) { %>
|
|
10
|
+
if (locals.comment) { %>
|
|
11
11
|
COMMENT <%- comment %><%
|
|
12
12
|
} %>
|
|
13
13
|
<%- body %>$$
|
package/exporters/trigger.js
CHANGED
package/exporters/view.ejs
CHANGED
package/exporters/view.js
CHANGED
|
@@ -4,6 +4,10 @@ const sqlFormatter = require('@sqltools/formatter');
|
|
|
4
4
|
module.exports = {
|
|
5
5
|
schemaCol: 'TABLE_SCHEMA',
|
|
6
6
|
nameCol: 'TABLE_NAME',
|
|
7
|
+
defaults: {
|
|
8
|
+
securityType: 'DEFINER',
|
|
9
|
+
checkOption: 'NONE'
|
|
10
|
+
},
|
|
7
11
|
formatter(params) {
|
|
8
12
|
params.definition = sqlFormatter.format(params.definition, {
|
|
9
13
|
indent: '\t',
|
package/lib/command.js
CHANGED
package/lib/conn.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Executes an SQL script.
|
|
5
|
+
*
|
|
6
|
+
* @param {Connection} conn MySQL connection object
|
|
7
|
+
* @returns {Array<Result>} The resultset
|
|
8
|
+
*/
|
|
9
|
+
async function queryFromFile(conn, file) {
|
|
10
|
+
const sql = await fs.readFile(file, 'utf8');
|
|
11
|
+
return await this.multiQuery(conn, sql);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Executes a multi-query string.
|
|
16
|
+
*
|
|
17
|
+
* @param {Connection} conn MySQL connection object
|
|
18
|
+
* @param {String} sql SQL multi-query string
|
|
19
|
+
* @returns {Array<Result>} The resultset
|
|
20
|
+
*/
|
|
21
|
+
async function multiQuery(conn, sql) {
|
|
22
|
+
let results = [];
|
|
23
|
+
const stmts = this.querySplit(sql);
|
|
24
|
+
|
|
25
|
+
for (const stmt of stmts)
|
|
26
|
+
results = results.concat(await conn.query(stmt));
|
|
27
|
+
|
|
28
|
+
return results;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Splits an SQL muti-query into a single-query array, it does an small
|
|
33
|
+
* parse to correctly handle the DELIMITER statement.
|
|
34
|
+
*
|
|
35
|
+
* @param {Array<String>} stmts The splitted SQL statements
|
|
36
|
+
*/
|
|
37
|
+
function querySplit(sql) {
|
|
38
|
+
const stmts = [];
|
|
39
|
+
let i,
|
|
40
|
+
char,
|
|
41
|
+
token,
|
|
42
|
+
escaped,
|
|
43
|
+
stmtStart;
|
|
44
|
+
|
|
45
|
+
let delimiter = ';';
|
|
46
|
+
const delimiterRe = /\s*delimiter\s+(\S+)[^\S\r\n]*(?:\r?\n|\r|$)/yi;
|
|
47
|
+
|
|
48
|
+
function begins(str) {
|
|
49
|
+
let j;
|
|
50
|
+
for (j = 0; j < str.length; j++)
|
|
51
|
+
if (sql[i + j] != str[j])
|
|
52
|
+
return false;
|
|
53
|
+
i += j;
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (i = 0; i < sql.length;) {
|
|
58
|
+
stmtStart = i;
|
|
59
|
+
|
|
60
|
+
delimiterRe.lastIndex = i;
|
|
61
|
+
const match = sql.match(delimiterRe);
|
|
62
|
+
if (match) {
|
|
63
|
+
delimiter = match[1];
|
|
64
|
+
i += match[0].length;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let delimiterFound = false;
|
|
69
|
+
while (i < sql.length) {
|
|
70
|
+
char = sql[i];
|
|
71
|
+
|
|
72
|
+
if (token) {
|
|
73
|
+
if (!escaped && begins(token.end))
|
|
74
|
+
token = null;
|
|
75
|
+
else {
|
|
76
|
+
escaped = !escaped && token.escape(char);
|
|
77
|
+
i++;
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
delimiterFound = begins(delimiter);
|
|
81
|
+
if (delimiterFound) break;
|
|
82
|
+
|
|
83
|
+
const tok = tokenIndex.get(char);
|
|
84
|
+
if (tok && begins(tok.start))
|
|
85
|
+
token = tok;
|
|
86
|
+
else
|
|
87
|
+
i++;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let len = i - stmtStart;
|
|
92
|
+
if (delimiterFound) len -= delimiter.length;
|
|
93
|
+
const stmt = sql.substr(stmtStart, len);
|
|
94
|
+
|
|
95
|
+
if (!/^\s*$/.test(stmt))
|
|
96
|
+
stmts.push(stmt);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return stmts;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const tokens = {
|
|
103
|
+
string: {
|
|
104
|
+
start: '\'',
|
|
105
|
+
end: '\'',
|
|
106
|
+
escape: char => char == '\'' || char == '\\'
|
|
107
|
+
},
|
|
108
|
+
quotedString: {
|
|
109
|
+
start: '"',
|
|
110
|
+
end: '"',
|
|
111
|
+
escape: char => char == '"' || char == '\\'
|
|
112
|
+
},
|
|
113
|
+
id: {
|
|
114
|
+
start: '`',
|
|
115
|
+
end: '`',
|
|
116
|
+
escape: char => char == '`'
|
|
117
|
+
},
|
|
118
|
+
multiComment: {
|
|
119
|
+
start: '/*',
|
|
120
|
+
end: '*/',
|
|
121
|
+
escape: () => false
|
|
122
|
+
},
|
|
123
|
+
singleComment: {
|
|
124
|
+
start: '-- ',
|
|
125
|
+
end: '\n',
|
|
126
|
+
escape: () => false
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const tokenIndex = new Map();
|
|
131
|
+
for (const tokenId in tokens) {
|
|
132
|
+
const token = tokens[tokenId];
|
|
133
|
+
tokenIndex.set(token.start[0], token);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = {
|
|
137
|
+
queryFromFile,
|
|
138
|
+
multiQuery,
|
|
139
|
+
querySplit,
|
|
140
|
+
tokens
|
|
141
|
+
};
|
package/lib/dumper.js
ADDED
|
@@ -0,0 +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) {
|
|
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
|
+
];
|
|
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,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
const shajs = require('sha.js');
|
|
3
2
|
const fs = require('fs-extra');
|
|
4
3
|
const Exporter = require('./exporter');
|
|
@@ -36,7 +35,7 @@ module.exports = class ExporterEngine {
|
|
|
36
35
|
];
|
|
37
36
|
|
|
38
37
|
for (const type of types) {
|
|
39
|
-
const exporter = new Exporter(
|
|
38
|
+
const exporter = new Exporter(type);
|
|
40
39
|
await exporter.init();
|
|
41
40
|
|
|
42
41
|
this.exporters.push(exporter);
|
|
@@ -46,7 +45,7 @@ module.exports = class ExporterEngine {
|
|
|
46
45
|
|
|
47
46
|
async fetchRoutine(type, schema, name) {
|
|
48
47
|
const exporter = this.exporterMap[type];
|
|
49
|
-
const [row] = await exporter.query(schema, name);
|
|
48
|
+
const [row] = await exporter.query(this.conn, schema, name);
|
|
50
49
|
return row && exporter.format(row);
|
|
51
50
|
}
|
|
52
51
|
|
package/lib/exporter.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
1
|
const ejs = require('ejs');
|
|
3
2
|
const fs = require('fs-extra');
|
|
3
|
+
const SqlString = require('sqlstring');
|
|
4
4
|
|
|
5
5
|
module.exports = class Exporter {
|
|
6
|
-
constructor(
|
|
7
|
-
this.engine = engine;
|
|
6
|
+
constructor(objectType) {
|
|
8
7
|
this.objectType = objectType;
|
|
9
|
-
this.dstDir = `${objectType}s`;
|
|
10
|
-
this.conn = conn;
|
|
11
8
|
}
|
|
12
9
|
|
|
13
10
|
async init() {
|
|
@@ -19,60 +16,7 @@ module.exports = class Exporter {
|
|
|
19
16
|
this.attrs = require(`${templateDir}.js`);
|
|
20
17
|
}
|
|
21
18
|
|
|
22
|
-
async
|
|
23
|
-
const res = await this.query(schema);
|
|
24
|
-
if (!res.length) return;
|
|
25
|
-
|
|
26
|
-
const routineDir = `${exportDir}/${schema}/${this.dstDir}`;
|
|
27
|
-
if (!await fs.pathExists(routineDir))
|
|
28
|
-
await fs.mkdir(routineDir);
|
|
29
|
-
|
|
30
|
-
const routineSet = new Set();
|
|
31
|
-
for (const params of res)
|
|
32
|
-
routineSet.add(params.name);
|
|
33
|
-
|
|
34
|
-
const routines = await fs.readdir(routineDir);
|
|
35
|
-
for (const routineFile of routines) {
|
|
36
|
-
const match = routineFile.match(/^(.*)\.sql$/);
|
|
37
|
-
if (!match) continue;
|
|
38
|
-
const routine = match[1];
|
|
39
|
-
if (!routineSet.has(routine))
|
|
40
|
-
await fs.remove(`${routineDir}/${routine}.sql`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const engine = this.engine;
|
|
44
|
-
|
|
45
|
-
for (const params of res) {
|
|
46
|
-
const routineName = params.name;
|
|
47
|
-
const sql = this.format(params);
|
|
48
|
-
const routineFile = `${routineDir}/${routineName}.sql`;
|
|
49
|
-
|
|
50
|
-
const oldSum = engine.getShaSum(routineName);
|
|
51
|
-
if (oldSum || saveSum) {
|
|
52
|
-
const shaSum = engine.shaSum(sql);
|
|
53
|
-
if (oldSum !== shaSum) {
|
|
54
|
-
engine.setShaSum(
|
|
55
|
-
this.objectType, schema, routineName, shaSum);
|
|
56
|
-
update = true;
|
|
57
|
-
}
|
|
58
|
-
} else if (params.modified && engine.lastPull) {
|
|
59
|
-
if (params.modified > engine.lastPull)
|
|
60
|
-
update = true;
|
|
61
|
-
} else if (await fs.pathExists(routineFile)) {
|
|
62
|
-
const currentSql = await fs.readFile(routineFile, 'utf8');
|
|
63
|
-
if (sql != currentSql)
|
|
64
|
-
update = true;
|
|
65
|
-
} else
|
|
66
|
-
update = true;
|
|
67
|
-
|
|
68
|
-
if (update)
|
|
69
|
-
await fs.writeFile(routineFile, sql);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async query(schema, name) {
|
|
74
|
-
const {conn} = this;
|
|
75
|
-
|
|
19
|
+
async query(conn, schema, name) {
|
|
76
20
|
const ops = [];
|
|
77
21
|
function addOp(col, value) {
|
|
78
22
|
ops.push(conn.format('?? = ?', [col, value]));
|
|
@@ -93,22 +37,24 @@ module.exports = class Exporter {
|
|
|
93
37
|
}
|
|
94
38
|
|
|
95
39
|
format(params) {
|
|
96
|
-
const {
|
|
40
|
+
const {attrs} = this;
|
|
41
|
+
params = Object.assign({}, attrs.defaults, params);
|
|
97
42
|
|
|
98
43
|
if (attrs.formatter)
|
|
99
|
-
attrs.formatter(params
|
|
44
|
+
attrs.formatter(params);
|
|
100
45
|
|
|
101
46
|
if (attrs.escapeCols)
|
|
102
47
|
for (const escapeCol of attrs.escapeCols) {
|
|
103
48
|
if (params[escapeCol])
|
|
104
|
-
params[escapeCol] =
|
|
49
|
+
params[escapeCol] = SqlString.escape(params[escapeCol])
|
|
105
50
|
}
|
|
106
51
|
|
|
107
52
|
const split = params.definer.split('@');
|
|
108
|
-
params.schema =
|
|
109
|
-
params.name =
|
|
53
|
+
params.schema = SqlString.escapeId(params.schema, true);
|
|
54
|
+
params.name = SqlString.escapeId(params.name, true);
|
|
110
55
|
params.definer =
|
|
111
|
-
|
|
56
|
+
SqlString.escapeId(split[0], true) + '@' +
|
|
57
|
+
SqlString.escapeId(split[1], true);
|
|
112
58
|
|
|
113
59
|
return this.template(params);
|
|
114
60
|
}
|
package/lib/repo.js
ADDED
|
@@ -0,0 +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
|
+
};
|
package/lib/util.js
CHANGED
package/myt-clean.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
const Myt = require('./myt');
|
|
3
2
|
const Command = require('./lib/command');
|
|
4
3
|
const fs = require('fs-extra');
|
|
@@ -11,7 +10,7 @@ class Clean extends Command {
|
|
|
11
10
|
description: 'Cleans old applied versions'
|
|
12
11
|
};
|
|
13
12
|
|
|
14
|
-
static
|
|
13
|
+
static opts = {
|
|
15
14
|
default: {
|
|
16
15
|
remote: 'production'
|
|
17
16
|
}
|
package/myt-create.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const Myt = require('./myt');
|
|
2
|
+
const Command = require('./lib/command');
|
|
3
|
+
const Exporter = require('./lib/exporter');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
|
|
6
|
+
class Create extends Command {
|
|
7
|
+
static usage = {
|
|
8
|
+
description: 'Creates a new DB object',
|
|
9
|
+
params: {
|
|
10
|
+
type: 'The object type',
|
|
11
|
+
name: 'The object name, including schema'
|
|
12
|
+
},
|
|
13
|
+
operand: 'name'
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
static opts = {
|
|
17
|
+
alias: {
|
|
18
|
+
type: 't',
|
|
19
|
+
name: 'n'
|
|
20
|
+
},
|
|
21
|
+
string: [
|
|
22
|
+
'type',
|
|
23
|
+
'name'
|
|
24
|
+
],
|
|
25
|
+
default: {
|
|
26
|
+
type: 'procedure'
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
async run(myt, opts) {
|
|
31
|
+
const match = opts.name.match(/^(\w+)\.(\w+)$/);
|
|
32
|
+
if (!match)
|
|
33
|
+
throw new Error('Invalid object name, should contain schema and routine name');
|
|
34
|
+
|
|
35
|
+
const schema = match[1];
|
|
36
|
+
const name = match[2];
|
|
37
|
+
|
|
38
|
+
const params = {
|
|
39
|
+
schema,
|
|
40
|
+
name,
|
|
41
|
+
definer: 'root@localhost'
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
switch (opts.type) {
|
|
45
|
+
case 'event':
|
|
46
|
+
case 'function':
|
|
47
|
+
case 'procedure':
|
|
48
|
+
case 'trigger':
|
|
49
|
+
params.body = "BEGIN\n-- Your code goes here\nEND";
|
|
50
|
+
break;
|
|
51
|
+
case 'view':
|
|
52
|
+
params.definition = "SELECT TRUE"
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const exporter = new Exporter(opts.type);
|
|
57
|
+
await exporter.init();
|
|
58
|
+
const sql = exporter.format(params);
|
|
59
|
+
|
|
60
|
+
const routineDir = `${opts.routinesDir}/${schema}/${opts.type}s`;
|
|
61
|
+
if (!await fs.pathExists(routineDir))
|
|
62
|
+
await fs.mkdir(routineDir);
|
|
63
|
+
|
|
64
|
+
const routineFile = `${routineDir}/${name}.sql`;
|
|
65
|
+
await fs.writeFile(routineFile, sql);
|
|
66
|
+
|
|
67
|
+
console.log('Routine created.');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = Create;
|
|
72
|
+
|
|
73
|
+
if (require.main === module)
|
|
74
|
+
new Myt().run(Create);
|