@verdnatura/myt 1.5.19 → 1.5.21

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 (69) hide show
  1. package/.dockerignore +2 -2
  2. package/LICENSE +17 -17
  3. package/README.md +284 -278
  4. package/assets/db.ini +5 -5
  5. package/assets/myt.default.yml +28 -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/helpers/local-fixtures.js +79 -0
  24. package/lib/command.js +19 -13
  25. package/lib/conn.js +141 -141
  26. package/lib/docker.js +133 -133
  27. package/lib/dumper.js +104 -83
  28. package/lib/exporter-engine.js +112 -112
  29. package/lib/exporter.js +86 -86
  30. package/lib/repo.js +29 -29
  31. package/lib/server.js +71 -71
  32. package/lib/util.js +7 -7
  33. package/myt-clean.js +58 -58
  34. package/myt-create.js +74 -74
  35. package/myt-dump.js +134 -75
  36. package/myt-fixtures.js +28 -29
  37. package/myt-init.js +36 -36
  38. package/myt-pull.js +183 -183
  39. package/myt-push.js +575 -568
  40. package/myt-run.js +190 -177
  41. package/myt-start.js +54 -54
  42. package/myt-version.js +218 -218
  43. package/myt.js +378 -361
  44. package/package.json +41 -41
  45. package/server/Dockerfile.base +1 -1
  46. package/server/Dockerfile.client +14 -14
  47. package/server/Dockerfile.dump +13 -16
  48. package/server/Dockerfile.server +25 -25
  49. package/server/docker-dump.sh +4 -4
  50. package/server/docker-fixtures.sh +5 -4
  51. package/server/docker-import.sh +10 -6
  52. package/server/docker-init.sh +23 -20
  53. package/server/docker-start.sh +10 -10
  54. package/server/docker.cnf +9 -9
  55. package/template/dump/Dockerfile.base +1 -1
  56. package/template/dump/dump.after.sql +1 -0
  57. package/template/dump/dump.before.sql +1 -0
  58. package/template/dump/fixtures.after.sql +1 -0
  59. package/template/dump/fixtures.before.sql +1 -0
  60. package/template/myt.config.yml +11 -11
  61. package/template/package.json +13 -13
  62. package/template/remotes/docker.ini +4 -4
  63. package/template/remotes/local.ini +5 -5
  64. package/template/routines/README.md +1 -1
  65. package/template/versions/00001-firstVersion/00-firstScript.sql +1 -1
  66. package/template/versions/README.md +1 -1
  67. package/template/dump/afterDump.sql +0 -1
  68. package/template/dump/beforeDump.sql +0 -1
  69. package/template/dump/fixtures.sql +0 -1
package/lib/server.js CHANGED
@@ -1,71 +1,71 @@
1
-
2
- const mysql = require('mysql2/promise');
3
-
4
- module.exports = class Server {
5
- constructor(ct, dbConfig) {
6
- Object.assign(this, {
7
- ct,
8
- dbConfig
9
- });
10
- }
11
-
12
- wait() {
13
- return new Promise((resolve, reject) => {
14
- const mysql = require('mysql2');
15
-
16
- let interval = 100;
17
- let elapsedTime = 0;
18
- let maxInterval = 4 * 60 * 1000;
19
-
20
- const dbConfig = this.dbConfig;
21
- let myConf = {
22
- user: dbConfig.user,
23
- password: dbConfig.password,
24
- host: dbConfig.host,
25
- port: dbConfig.port
26
- };
27
-
28
- console.log('Waiting for MySQL init process...');
29
-
30
- async function checker() {
31
- elapsedTime += interval;
32
- let status;
33
-
34
- try {
35
- status = await this.ct.inspect({
36
- format: '{{json .State.Status}}'
37
- });
38
- } catch (err) {
39
- return reject(new Error(err.message));
40
- }
41
-
42
- if (status === 'exited')
43
- return reject(new Error('Docker exited, please see the docker logs for more info'));
44
-
45
- const conn = mysql.createConnection(myConf);
46
- conn.on('error', () => {});
47
- conn.connect(err => {
48
- conn.destroy();
49
- if (!err) {
50
- console.log('MySQL process ready.');
51
- return resolve();
52
- }
53
-
54
- if (elapsedTime >= maxInterval)
55
- reject(new Error(`MySQL not initialized whithin ${elapsedTime / 1000} secs`));
56
- else
57
- setTimeout(bindedChecker, interval);
58
- });
59
- }
60
- const bindedChecker = checker.bind(this);
61
- bindedChecker();
62
- });
63
- }
64
-
65
- async rm() {
66
- try {
67
- await this.ct.stop();
68
- await this.ct.rm({volumes: true});
69
- } catch (e) {}
70
- }
71
- };
1
+
2
+ const mysql = require('mysql2/promise');
3
+
4
+ module.exports = class Server {
5
+ constructor(ct, dbConfig) {
6
+ Object.assign(this, {
7
+ ct,
8
+ dbConfig
9
+ });
10
+ }
11
+
12
+ wait() {
13
+ return new Promise((resolve, reject) => {
14
+ const mysql = require('mysql2');
15
+
16
+ let interval = 100;
17
+ let elapsedTime = 0;
18
+ let maxInterval = 4 * 60 * 1000;
19
+
20
+ const dbConfig = this.dbConfig;
21
+ let myConf = {
22
+ user: dbConfig.user,
23
+ password: dbConfig.password,
24
+ host: dbConfig.host,
25
+ port: dbConfig.port
26
+ };
27
+
28
+ console.log('Waiting for MySQL init process...');
29
+
30
+ async function checker() {
31
+ elapsedTime += interval;
32
+ let status;
33
+
34
+ try {
35
+ status = await this.ct.inspect({
36
+ format: '{{json .State.Status}}'
37
+ });
38
+ } catch (err) {
39
+ return reject(new Error(err.message));
40
+ }
41
+
42
+ if (status === 'exited')
43
+ return reject(new Error('Docker exited, please see the docker logs for more info'));
44
+
45
+ const conn = mysql.createConnection(myConf);
46
+ conn.on('error', () => {});
47
+ conn.connect(err => {
48
+ conn.destroy();
49
+ if (!err) {
50
+ console.log('MySQL process ready.');
51
+ return resolve();
52
+ }
53
+
54
+ if (elapsedTime >= maxInterval)
55
+ reject(new Error(`MySQL not initialized whithin ${elapsedTime / 1000} secs`));
56
+ else
57
+ setTimeout(bindedChecker, interval);
58
+ });
59
+ }
60
+ const bindedChecker = checker.bind(this);
61
+ bindedChecker();
62
+ });
63
+ }
64
+
65
+ async rm() {
66
+ try {
67
+ await this.ct.stop();
68
+ await this.ct.rm({volumes: true});
69
+ } catch (e) {}
70
+ }
71
+ };
package/lib/util.js CHANGED
@@ -1,7 +1,7 @@
1
- function camelToSnake(str) {
2
- return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`);
3
- }
4
-
5
- module.exports = {
6
- camelToSnake
7
- };
1
+ function camelToSnake(str) {
2
+ return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`);
3
+ }
4
+
5
+ module.exports = {
6
+ camelToSnake
7
+ };
package/myt-clean.js CHANGED
@@ -1,58 +1,58 @@
1
- const Myt = require('./myt');
2
- const Command = require('./lib/command');
3
- const fs = require('fs-extra');
4
- const path = require('path');
5
-
6
- /**
7
- * Cleans old applied versions.
8
- */
9
- class Clean extends Command {
10
- static usage = {
11
- description: 'Cleans old applied versions'
12
- };
13
-
14
- static opts = {
15
- default: {
16
- remote: 'production'
17
- }
18
- };
19
-
20
- async run(myt, opts) {
21
- await myt.dbConnect();
22
- const version = await myt.fetchDbVersion() || {};
23
- const number = version.number;
24
-
25
- const oldVersions = [];
26
- const versionDirs = await fs.readdir(opts.versionsDir);
27
- for (const versionDir of versionDirs) {
28
- const dirVersion = myt.parseVersionDir(versionDir);
29
- if (!dirVersion) continue;
30
-
31
- if (parseInt(dirVersion.number) < parseInt(number))
32
- oldVersions.push(versionDir);
33
- }
34
-
35
- if (opts.maxOldVersions
36
- && oldVersions.length > opts.maxOldVersions) {
37
- oldVersions.splice(-opts.maxOldVersions);
38
-
39
- const archiveDir = path.join(opts.versionsDir, '.archive');
40
- if (!await fs.pathExists(archiveDir))
41
- await fs.mkdir(archiveDir);
42
-
43
- for (const oldVersion of oldVersions)
44
- await fs.move(
45
- path.join(opts.versionsDir, oldVersion),
46
- path.join(archiveDir, oldVersion)
47
- );
48
-
49
- console.log(`Old versions deleted: ${oldVersions.length}`);
50
- } else
51
- console.log(`No versions to delete.`);
52
- }
53
- }
54
-
55
- module.exports = Clean;
56
-
57
- if (require.main === module)
58
- new Myt().run(Clean);
1
+ const Myt = require('./myt');
2
+ const Command = require('./lib/command');
3
+ const fs = require('fs-extra');
4
+ const path = require('path');
5
+
6
+ /**
7
+ * Cleans old applied versions.
8
+ */
9
+ class Clean extends Command {
10
+ static usage = {
11
+ description: 'Cleans old applied versions'
12
+ };
13
+
14
+ static opts = {
15
+ default: {
16
+ remote: 'production'
17
+ }
18
+ };
19
+
20
+ async run(myt, opts) {
21
+ await myt.dbConnect();
22
+ const version = await myt.fetchDbVersion() || {};
23
+ const number = version.number;
24
+
25
+ const oldVersions = [];
26
+ const versionDirs = await fs.readdir(opts.versionsDir);
27
+ for (const versionDir of versionDirs) {
28
+ const dirVersion = myt.parseVersionDir(versionDir);
29
+ if (!dirVersion) continue;
30
+
31
+ if (parseInt(dirVersion.number) < parseInt(number))
32
+ oldVersions.push(versionDir);
33
+ }
34
+
35
+ if (opts.maxOldVersions
36
+ && oldVersions.length > opts.maxOldVersions) {
37
+ oldVersions.splice(-opts.maxOldVersions);
38
+
39
+ const archiveDir = path.join(opts.versionsDir, '.archive');
40
+ if (!await fs.pathExists(archiveDir))
41
+ await fs.mkdir(archiveDir);
42
+
43
+ for (const oldVersion of oldVersions)
44
+ await fs.move(
45
+ path.join(opts.versionsDir, oldVersion),
46
+ path.join(archiveDir, oldVersion)
47
+ );
48
+
49
+ console.log(`Old versions deleted: ${oldVersions.length}`);
50
+ } else
51
+ console.log(`No versions to delete.`);
52
+ }
53
+ }
54
+
55
+ module.exports = Clean;
56
+
57
+ if (require.main === module)
58
+ new Myt().run(Clean);
package/myt-create.js CHANGED
@@ -1,74 +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, opts.replace);
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);
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, opts.replace);
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);
package/myt-dump.js CHANGED
@@ -1,75 +1,134 @@
1
- const Myt = require('./myt');
2
- const Command = require('./lib/command');
3
- const fs = require('fs-extra');
4
- const Dumper = require('./lib/dumper');
5
-
6
- class Dump extends Command {
7
- static usage = {
8
- description: 'Dumps structure and fixtures from remote',
9
- params: {
10
- lock: 'Whether to lock tables on dump'
11
- },
12
- operand: 'remote'
13
- };
14
-
15
- static opts = {
16
- default: {
17
- remote: 'production'
18
- },
19
- alias: {
20
- lock: 'l'
21
- },
22
- boolean: [
23
- 'lock'
24
- ]
25
- };
26
-
27
- async run(myt, opts) {
28
- const dumper = new Dumper(opts);
29
- await dumper.init('.dump.sql');
30
- const baseArgs = [
31
- `--lock-tables=${opts.lock ? 'true' : 'false'}`
32
- ];
33
-
34
- console.log('Dumping structure.');
35
- let dumpArgs = [
36
- '--default-character-set=utf8',
37
- '--no-data',
38
- '--comments',
39
- '--routines',
40
- '--events',
41
- '--skip-triggers',
42
- '--databases'
43
- ].concat(baseArgs);
44
-
45
- dumpArgs = dumpArgs.concat(opts.schemas);
46
- await dumper.runDump('docker-dump.sh', dumpArgs);
47
-
48
- console.log('Dumping fixtures.');
49
- await dumper.dumpFixtures(opts.fixtures, false, baseArgs);
50
-
51
- console.log('Dumping privileges.');
52
- const privs = opts.privileges;
53
- if (privs && Array.isArray(privs.tables)) {
54
- let args = [
55
- '--no-create-info',
56
- '--skip-triggers',
57
- '--insert-ignore',
58
- '--complete-insert'
59
- ].concat(baseArgs);
60
- if (privs.where) args.push('--where', privs.where);
61
- args = args.concat(['mysql'], privs.tables);
62
-
63
- await dumper.use('mysql');
64
- await dumper.runDump('mysqldump', args);
65
- }
66
-
67
- await dumper.end();
68
- }
69
- }
70
-
71
- module.exports = Dump;
72
-
73
- if (require.main === module)
74
- new Myt().run(Dump);
75
-
1
+ const Myt = require('./myt');
2
+ const Command = require('./lib/command');
3
+ const Dumper = require('./lib/dumper');
4
+ const fs = require('fs-extra');
5
+ const path = require('path');
6
+
7
+ class Dump extends Command {
8
+ static usage = {
9
+ description: 'Dumps structure and fixtures from remote',
10
+ params: {
11
+ lock: 'Whether to lock tables on dump',
12
+ triggers: 'Wether to include triggers into dump'
13
+ },
14
+ operand: 'remote'
15
+ };
16
+
17
+ static opts = {
18
+ default: {
19
+ remote: 'production'
20
+ },
21
+ alias: {
22
+ lock: 'l',
23
+ triggers: 't'
24
+ },
25
+ boolean: [
26
+ 'lock',
27
+ 'triggers'
28
+ ]
29
+ };
30
+
31
+ static messages = {
32
+ dumpStructure: 'Dumping structure.',
33
+ dumpData: 'Dumping data.',
34
+ dumpPrivileges: 'Dumping privileges.',
35
+ dumpTriggers: 'Dumping triggers.'
36
+ };
37
+
38
+ async run(myt, opts) {
39
+ let dumper;
40
+ const dumpDataDir = path.join(opts.dumpDir, '.dump');
41
+ const baseArgs = [
42
+ `--lock-tables=${opts.lock ? 'true' : 'false'}`
43
+ ];
44
+
45
+ await fs.remove(dumpDataDir);
46
+
47
+ // Structure
48
+
49
+ this.emit('dumpStructure');
50
+
51
+ dumper = new Dumper(opts);
52
+ await dumper.init(dumpDataDir, 'structure');
53
+ let dumpArgs = [
54
+ '--default-character-set=utf8',
55
+ '--no-data',
56
+ '--comments',
57
+ '--routines',
58
+ '--events',
59
+ '--skip-triggers'
60
+ ].concat(baseArgs);
61
+
62
+ dumpArgs.push('--databases');
63
+ dumpArgs = dumpArgs.concat(opts.schemas);
64
+ await dumper.runDump('docker-dump.sh', dumpArgs);
65
+ await dumper.end();
66
+
67
+ // Data
68
+
69
+ this.emit('dumpData');
70
+
71
+ dumper = new Dumper(opts);
72
+ await dumper.init(dumpDataDir, 'data');
73
+ await dumper.dumpFixtures(opts.fixtures, false, baseArgs);
74
+ await dumper.end();
75
+
76
+ // Privileges
77
+
78
+ const privs = opts.privileges;
79
+ if (privs) {
80
+ this.emit('dumpPrivileges');
81
+
82
+ dumper = new Dumper(opts);
83
+ await dumper.init(dumpDataDir, 'privileges');
84
+
85
+ const {tables, userTable, where} = privs;
86
+
87
+ if (tables)
88
+ await dumper.dumpPrivileges(tables, baseArgs, where);
89
+
90
+ if (userTable) {
91
+ let userWhere = '';
92
+ for (const cond of [where, privs.userWhere]) {
93
+ if (!cond) continue;
94
+ if (userWhere) userWhere += ' AND ';
95
+ userWhere += cond;
96
+ }
97
+ await dumper.dumpPrivileges([userTable], baseArgs, userWhere);
98
+ }
99
+
100
+ await dumper.end();
101
+ }
102
+
103
+ await dumper.end();
104
+
105
+ // Triggers
106
+
107
+ if (opts.triggers) {
108
+ this.emit('dumpTriggers');
109
+
110
+ const dumper = new Dumper(opts);
111
+ await dumper.init(dumpDataDir, 'triggers');
112
+
113
+ let dumpArgs = [
114
+ '--default-character-set=utf8',
115
+ '--no-create-info',
116
+ '--no-data',
117
+ '--no-create-db',
118
+ '--skip-opt',
119
+ '--comments'
120
+ ].concat(baseArgs);
121
+
122
+ dumpArgs.push('--databases');
123
+ dumpArgs = dumpArgs.concat(opts.schemas);
124
+ await dumper.runDump('mysqldump', dumpArgs);
125
+ await dumper.end();
126
+ }
127
+ }
128
+ }
129
+
130
+ module.exports = Dump;
131
+
132
+ if (require.main === module)
133
+ new Myt().run(Dump);
134
+