@verdnatura/myt 1.5.17 → 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.
Files changed (64) hide show
  1. package/.dockerignore +2 -2
  2. package/LICENSE +17 -17
  3. package/README.md +278 -278
  4. package/assets/db.ini +5 -5
  5. package/assets/myt.default.yml +11 -11
  6. package/assets/structure.sql +24 -24
  7. package/cli.js +4 -4
  8. package/exporters/event.ejs +18 -18
  9. package/exporters/event.js +31 -31
  10. package/exporters/event.sql +19 -19
  11. package/exporters/function.ejs +17 -17
  12. package/exporters/function.js +27 -27
  13. package/exporters/function.sql +16 -16
  14. package/exporters/procedure.ejs +11 -11
  15. package/exporters/procedure.js +23 -23
  16. package/exporters/procedure.sql +14 -14
  17. package/exporters/trigger.ejs +4 -4
  18. package/exporters/trigger.js +10 -10
  19. package/exporters/trigger.sql +13 -13
  20. package/exporters/view.ejs +7 -7
  21. package/exporters/view.js +29 -29
  22. package/exporters/view.sql +12 -12
  23. package/lib/command.js +13 -13
  24. package/lib/conn.js +141 -141
  25. package/lib/docker.js +133 -133
  26. package/lib/dumper.js +83 -83
  27. package/lib/exporter-engine.js +112 -112
  28. package/lib/exporter.js +86 -86
  29. package/lib/repo.js +29 -29
  30. package/lib/server.js +71 -71
  31. package/lib/util.js +7 -7
  32. package/myt-clean.js +58 -58
  33. package/myt-create.js +74 -74
  34. package/myt-dump.js +75 -75
  35. package/myt-fixtures.js +29 -29
  36. package/myt-init.js +36 -36
  37. package/myt-pull.js +183 -183
  38. package/myt-push.js +568 -562
  39. package/myt-run.js +177 -177
  40. package/myt-start.js +54 -54
  41. package/myt-version.js +218 -218
  42. package/myt.js +361 -361
  43. package/package.json +41 -41
  44. package/server/Dockerfile.base +1 -1
  45. package/server/Dockerfile.client +14 -14
  46. package/server/Dockerfile.dump +16 -16
  47. package/server/Dockerfile.server +25 -25
  48. package/server/docker-dump.sh +4 -4
  49. package/server/docker-fixtures.sh +4 -4
  50. package/server/docker-import.sh +6 -6
  51. package/server/docker-init.sh +20 -20
  52. package/server/docker-start.sh +10 -10
  53. package/server/docker.cnf +9 -9
  54. package/template/dump/Dockerfile.base +1 -1
  55. package/template/dump/afterDump.sql +1 -1
  56. package/template/dump/beforeDump.sql +1 -1
  57. package/template/dump/fixtures.sql +1 -1
  58. package/template/myt.config.yml +11 -11
  59. package/template/package.json +13 -13
  60. package/template/remotes/docker.ini +4 -4
  61. package/template/remotes/local.ini +5 -5
  62. package/template/routines/README.md +1 -1
  63. package/template/versions/00001-firstVersion/00-firstScript.sql +1 -1
  64. 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
+ }
@@ -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
+ };