diff --git a/assets/myt.default.yml b/assets/myt.default.yml index 687ba47..f9cadf9 100755 --- a/assets/myt.default.yml +++ b/assets/myt.default.yml @@ -1,6 +1,6 @@ versionSchema: myt versionDigits: 5 -maxOldVersions: 30 +maxOldVersions: 20 sumViews: true schemas: - myt diff --git a/exporters/event.ejs b/exporters/event.ejs index b0a1e86..8e91d72 100755 --- a/exporters/event.ejs +++ b/exporters/event.ejs @@ -1,21 +1,18 @@ -DROP EVENT IF EXISTS <%- schema %>.<%- name %>; -DELIMITER $$ -CREATE DEFINER=<%- definer %> EVENT <%- schema %>.<%- name %><% -if (locals.type == 'RECURRING') { %> - ON SCHEDULE EVERY <%- intervalValue %> <%- intervalField %><% - if (locals.starts) { %> - STARTS <%- starts %><% +<%- begin %> <%- typeAndName %><% +if (params.type == 'RECURRING') { %> + ON SCHEDULE EVERY <%- params.intervalValue %> <%- params.intervalField %><% + if (params.starts) { %> + STARTS <%- params.starts %><% } - if (locals.ends) { %> - ENDS <%- ends %><% + if (params.ends) { %> + ENDS <%- params.ends %><% } } else { %> - ON SCHEDULE AT <%- executeAt %><% + ON SCHEDULE AT <%- params.executeAt %><% } %> - ON COMPLETION <%- onCompletion %> - <%- status %><% -if (locals.comment) { %> - COMMENT <%- comment %><% + ON COMPLETION <%- params.onCompletion %> + <%- params.status %><% +if (params.comment) { %> + COMMENT <%- params.comment %><% } %> -DO <%- body %>$$ -DELIMITER ; +DO <%- params.body %><%- end %> diff --git a/exporters/function.ejs b/exporters/function.ejs index 7274cce..fcbe3a7 100755 --- a/exporters/function.ejs +++ b/exporters/function.ejs @@ -1,20 +1,17 @@ -DROP FUNCTION IF EXISTS <%- schema %>.<%- name %>; -DELIMITER $$ -CREATE DEFINER=<%- definer %> FUNCTION <%- schema %>.<%- name %>(<%- locals.paramList %>) - RETURNS <%- returns %><% -if (locals.isDeterministic == 'NO') { %> +<%- begin %> <%- typeAndName %>(<%- params.paramList %>) + RETURNS <%- params.returns %><% +if (params.isDeterministic == 'NO') { %> NOT DETERMINISTIC<% } else { %> DETERMINISTIC<% } -if (locals.dataAccess) { %> - <%- dataAccess %><% +if (params.dataAccess) { %> + <%- params.dataAccess %><% } -if (locals.securityType == 'INVOKER') { %> - SQL SECURITY <%- securityType %><% +if (params.securityType == 'INVOKER') { %> + SQL SECURITY <%- params.securityType %><% } -if (locals.comment) { %> - COMMENT <%- comment %><% +if (params.comment) { %> + COMMENT <%- params.comment %><% } %> -<%- body %>$$ -DELIMITER ; +<%- params.body %><%- end %> diff --git a/exporters/procedure.ejs b/exporters/procedure.ejs index 3fe2e11..3f08199 100755 --- a/exporters/procedure.ejs +++ b/exporters/procedure.ejs @@ -1,14 +1,11 @@ -DROP PROCEDURE IF EXISTS <%- schema %>.<%- name %>; -DELIMITER $$ -CREATE DEFINER=<%- definer %> PROCEDURE <%- schema %>.<%- name %>(<%- locals.paramList %>)<% -if (locals.dataAccess) { %> - <%- dataAccess %><% +<%- begin %> <%- typeAndName %>(<%- params.paramList %>)<% +if (params.dataAccess) { %> + <%- params.dataAccess %><% } -if (locals.securityType == 'INVOKER') { %> - SQL SECURITY <%- securityType %><% +if (params.securityType == 'INVOKER') { %> + SQL SECURITY <%- params.securityType %><% } -if (locals.comment) { %> - COMMENT <%- comment %><% +if (params.comment) { %> + COMMENT <%- params.comment %><% } %> -<%- body %>$$ -DELIMITER ; +<%- params.body %><%- end %> diff --git a/exporters/trigger.ejs b/exporters/trigger.ejs index eb70063..584a71f 100755 --- a/exporters/trigger.ejs +++ b/exporters/trigger.ejs @@ -1,7 +1,4 @@ -DROP TRIGGER IF EXISTS <%- schema %>.<%- name %>; -DELIMITER $$ -CREATE DEFINER=<%- definer %> TRIGGER <%- schema %>.<%- name %> - <%- actionTiming %> <%- actionType %> ON `<%- table %>` +<%- begin %> <%- typeAndName %> + <%- params.actionTiming %> <%- params.actionType %> ON `<%- params.table %>` FOR EACH ROW -<%- body %>$$ -DELIMITER ; +<%- params.body %><%- end %> diff --git a/exporters/view.ejs b/exporters/view.ejs index 6dff4e2..d162acd 100755 --- a/exporters/view.ejs +++ b/exporters/view.ejs @@ -1,7 +1,7 @@ -CREATE OR REPLACE DEFINER=<%- definer %> - SQL SECURITY <%- securityType %> - VIEW <%- schema %>.<%- name %> -AS <%- definition %><% -if (locals.checkOption != 'NONE') { %> -WITH <%- checkOption %> CHECK OPTION<% +<%- createOrReplace %> + SQL SECURITY <%- params.securityType %> + <%- typeAndName %> +AS <%- params.definition %><% +if (params.checkOption != 'NONE') { %> +WITH <%- params.checkOption %> CHECK OPTION<% } %> diff --git a/lib/exporter-engine.js b/lib/exporter-engine.js index d2f81fb..5f16694 100644 --- a/lib/exporter-engine.js +++ b/lib/exporter-engine.js @@ -3,9 +3,10 @@ const fs = require('fs-extra'); const Exporter = require('./exporter'); module.exports = class ExporterEngine { - constructor(conn, mytDir) { + constructor(conn, opts) { this.conn = conn; - this.pullFile = `${mytDir}/.pullinfo.json`; + this.opts = opts; + this.pullFile = `${opts.mytDir}/.pullinfo.json`; this.exporters = []; this.exporterMap = {}; } @@ -35,7 +36,7 @@ module.exports = class ExporterEngine { ]; for (const type of types) { - const exporter = new Exporter(type); + const exporter = new Exporter(type, this.opts.replace); await exporter.init(); this.exporters.push(exporter); diff --git a/lib/exporter.js b/lib/exporter.js index a541573..7c67f75 100644 --- a/lib/exporter.js +++ b/lib/exporter.js @@ -3,8 +3,11 @@ const fs = require('fs-extra'); const SqlString = require('sqlstring'); module.exports = class Exporter { - constructor(objectType) { - this.objectType = objectType; + constructor(objectType, replace) { + Object.assign(this, { + objectType, + replace + }); } async init() { @@ -38,7 +41,8 @@ module.exports = class Exporter { format(params) { const {attrs} = this; - params = Object.assign({}, attrs.defaults, params); + params = Object.assign({}, attrs.defaults, params) + const data = {params}; if (attrs.formatter) attrs.formatter(params); @@ -50,12 +54,33 @@ module.exports = class Exporter { } const split = params.definer.split('@'); - params.schema = SqlString.escapeId(params.schema, true); - params.name = SqlString.escapeId(params.name, true); - params.definer = + data.definer = SqlString.escapeId(split[0], true) + '@' + SqlString.escapeId(split[1], true); - return this.template(params); + data.name = + SqlString.escapeId(params.schema, true) + '.' + + SqlString.escapeId(params.name, true); + + const objectType = this.objectType.toUpperCase(); + const delimiter = '$$'; + const replace = `CREATE OR REPLACE`; + + let create; + if (this.replace) { + create = `DELIMITER ${delimiter}\n${replace}` + } else { + create = + `DROP ${objectType} IF EXISTS ${data.name};\n` + +`DELIMITER ${delimiter}\n` + +`CREATE`; + } + + data.createOrReplace = `${replace} DEFINER=${data.definer}` + data.begin = `${create} DEFINER=${data.definer}`; + data.typeAndName = `${objectType} ${data.name}`; + data.end = `${delimiter}\nDELIMITER ;`; + + return this.template(data); } } diff --git a/myt-clean.js b/myt-clean.js index ff790e1..43d0b31 100644 --- a/myt-clean.js +++ b/myt-clean.js @@ -1,6 +1,7 @@ const Myt = require('./myt'); const Command = require('./lib/command'); const fs = require('fs-extra'); +const path = require('path'); /** * Cleans old applied versions. @@ -35,9 +36,15 @@ class Clean extends Command { && oldVersions.length > opts.maxOldVersions) { oldVersions.splice(-opts.maxOldVersions); + const archiveDir = path.join(opts.versionsDir, '.archive'); + if (!await fs.pathExists(archiveDir)) + await fs.mkdir(archiveDir); + for (const oldVersion of oldVersions) - await fs.remove(`${opts.versionsDir}/${oldVersion}`, - {recursive: true}); + await fs.move( + path.join(opts.versionsDir, oldVersion), + path.join(archiveDir, oldVersion) + ); console.log(`Old versions deleted: ${oldVersions.length}`); } else diff --git a/myt-create.js b/myt-create.js index 2ac011a..9083b63 100755 --- a/myt-create.js +++ b/myt-create.js @@ -53,7 +53,7 @@ class Create extends Command { break; } - const exporter = new Exporter(opts.type); + const exporter = new Exporter(opts.type, opts.replace); await exporter.init(); const sql = exporter.format(params); diff --git a/myt-pull.js b/myt-pull.js index 5606f77..c555240 100755 --- a/myt-pull.js +++ b/myt-pull.js @@ -85,7 +85,7 @@ class Pull extends Command { console.log(`Incorporating routine changes.`); - const engine = new ExporterEngine(conn, opts.mytDir); + const engine = new ExporterEngine(conn, opts); await engine.init(); const shaSums = engine.shaSums; diff --git a/myt-push.js b/myt-push.js index 498686f..ee3a26b 100644 --- a/myt-push.js +++ b/myt-push.js @@ -288,7 +288,7 @@ class Push extends Command { ); } - const engine = new ExporterEngine(conn, opts.mytDir); + const engine = new ExporterEngine(conn, opts); await engine.init(); async function finalize() { diff --git a/myt-run.js b/myt-run.js index 0fd4142..9bd7450 100644 --- a/myt-run.js +++ b/myt-run.js @@ -42,25 +42,30 @@ class Run extends Command { // Build base image - let serverDockerfile = path.join(dumpDir, 'Dockerfile'); - if (!await fs.pathExists(serverDockerfile)) - serverDockerfile = path.join(serverDir, 'Dockerfile.base'); + let basePath = dumpDir; + let baseDockerfile = path.join(dumpDir, 'Dockerfile'); - await docker.build(__dirname, { + if (!await fs.pathExists(baseDockerfile)) { + basePath = serverDir; + baseDockerfile = path.join(serverDir, 'Dockerfile.base'); + } + + await docker.build(basePath, { tag: 'myt/base', - file: serverDockerfile + file: baseDockerfile }, opts.debug); // Build server image - await docker.build(__dirname, { + await docker.build(serverDir, { tag: 'myt/server', file: path.join(serverDir, 'Dockerfile.server') }, opts.debug); // Build dump image - await docker.build(opts.mytDir, { + const dumpContext = path.join(opts.mytDir, 'dump'); + await docker.build(dumpContext, { tag: opts.code, file: path.join(serverDir, 'Dockerfile.dump') }, opts.debug); diff --git a/package-lock.json b/package-lock.json index a39161e..0de8a9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "@verdnatura/myt", - "version": "1.5.9", + "version": "1.5.11", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@verdnatura/myt", - "version": "1.5.9", + "version": "1.5.11", "license": "GPL-3.0", "dependencies": { "@sqltools/formatter": "^1.2.5", "colors": "^1.4.0", - "ejs": "^3.1.6", + "ejs": "^3.1.8", "fs-extra": "^8.1.0", "getopts": "^2.3.0", "ini": "^1.3.8", @@ -462,9 +462,9 @@ } }, "node_modules/ejs": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz", - "integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", "dependencies": { "jake": "^10.8.5" }, @@ -868,9 +868,9 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", "bin": { "json5": "lib/cli.js" }, @@ -2198,9 +2198,9 @@ } }, "ejs": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz", - "integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", "requires": { "jake": "^10.8.5" } @@ -2538,9 +2538,9 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==" }, "jsonfile": { "version": "4.0.0", diff --git a/package.json b/package.json index bbb0252..c0206ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@verdnatura/myt", - "version": "1.5.9", + "version": "1.5.11", "author": "Verdnatura Levante SL", "description": "MySQL version control", "license": "GPL-3.0", @@ -14,7 +14,7 @@ "dependencies": { "@sqltools/formatter": "^1.2.5", "colors": "^1.4.0", - "ejs": "^3.1.6", + "ejs": "^3.1.8", "fs-extra": "^8.1.0", "getopts": "^2.3.0", "ini": "^1.3.8", diff --git a/server/Dockerfile.dump b/server/Dockerfile.dump index 7cc9fed..fdebb71 100644 --- a/server/Dockerfile.dump +++ b/server/Dockerfile.dump @@ -3,9 +3,9 @@ FROM myt/server USER root COPY \ - dump/.dump.sql \ - dump/beforeDump.sql \ - dump/afterDump.sql \ + .dump.sql \ + beforeDump.sql \ + afterDump.sql \ dump/ RUN gosu mysql docker-init.sh diff --git a/server/Dockerfile.server b/server/Dockerfile.server index 83c037f..baa28a1 100644 --- a/server/Dockerfile.server +++ b/server/Dockerfile.server @@ -8,11 +8,11 @@ RUN mkdir /mysql-data \ WORKDIR /workspace -COPY server/docker.cnf /etc/mysql/conf.d/ +COPY docker.cnf /etc/mysql/conf.d/ COPY \ - server/docker-init.sh \ - server/docker-import.sh \ - server/docker-start.sh \ + docker-init.sh \ + docker-import.sh \ + docker-start.sh \ /usr/local/bin/ USER mysql