refs #5123, #4036 archive versions, replace option, run cmd optimization

This commit is contained in:
Juan Ferrer 2023-01-25 18:16:43 +01:00
parent 021e3cb083
commit d5ffaccecf
17 changed files with 125 additions and 99 deletions

View File

@ -1,6 +1,6 @@
versionSchema: myt versionSchema: myt
versionDigits: 5 versionDigits: 5
maxOldVersions: 30 maxOldVersions: 20
sumViews: true sumViews: true
schemas: schemas:
- myt - myt

View File

@ -1,21 +1,18 @@
DROP EVENT IF EXISTS <%- schema %>.<%- name %>; <%- begin %> <%- typeAndName %><%
DELIMITER $$ if (params.type == 'RECURRING') { %>
CREATE DEFINER=<%- definer %> EVENT <%- schema %>.<%- name %><% ON SCHEDULE EVERY <%- params.intervalValue %> <%- params.intervalField %><%
if (locals.type == 'RECURRING') { %> if (params.starts) { %>
ON SCHEDULE EVERY <%- intervalValue %> <%- intervalField %><% STARTS <%- params.starts %><%
if (locals.starts) { %>
STARTS <%- starts %><%
} }
if (locals.ends) { %> if (params.ends) { %>
ENDS <%- ends %><% ENDS <%- params.ends %><%
} }
} else { %> } else { %>
ON SCHEDULE AT <%- executeAt %><% ON SCHEDULE AT <%- params.executeAt %><%
} %> } %>
ON COMPLETION <%- onCompletion %> ON COMPLETION <%- params.onCompletion %>
<%- status %><% <%- params.status %><%
if (locals.comment) { %> if (params.comment) { %>
COMMENT <%- comment %><% COMMENT <%- params.comment %><%
} %> } %>
DO <%- body %>$$ DO <%- params.body %><%- end %>
DELIMITER ;

View File

@ -1,20 +1,17 @@
DROP FUNCTION IF EXISTS <%- schema %>.<%- name %>; <%- begin %> <%- typeAndName %>(<%- params.paramList %>)
DELIMITER $$ RETURNS <%- params.returns %><%
CREATE DEFINER=<%- definer %> FUNCTION <%- schema %>.<%- name %>(<%- locals.paramList %>) if (params.isDeterministic == 'NO') { %>
RETURNS <%- returns %><%
if (locals.isDeterministic == 'NO') { %>
NOT DETERMINISTIC<% NOT DETERMINISTIC<%
} else { %> } else { %>
DETERMINISTIC<% DETERMINISTIC<%
} }
if (locals.dataAccess) { %> if (params.dataAccess) { %>
<%- dataAccess %><% <%- params.dataAccess %><%
} }
if (locals.securityType == 'INVOKER') { %> if (params.securityType == 'INVOKER') { %>
SQL SECURITY <%- securityType %><% SQL SECURITY <%- params.securityType %><%
} }
if (locals.comment) { %> if (params.comment) { %>
COMMENT <%- comment %><% COMMENT <%- params.comment %><%
} %> } %>
<%- body %>$$ <%- params.body %><%- end %>
DELIMITER ;

View File

@ -1,14 +1,11 @@
DROP PROCEDURE IF EXISTS <%- schema %>.<%- name %>; <%- begin %> <%- typeAndName %>(<%- params.paramList %>)<%
DELIMITER $$ if (params.dataAccess) { %>
CREATE DEFINER=<%- definer %> PROCEDURE <%- schema %>.<%- name %>(<%- locals.paramList %>)<% <%- params.dataAccess %><%
if (locals.dataAccess) { %>
<%- dataAccess %><%
} }
if (locals.securityType == 'INVOKER') { %> if (params.securityType == 'INVOKER') { %>
SQL SECURITY <%- securityType %><% SQL SECURITY <%- params.securityType %><%
} }
if (locals.comment) { %> if (params.comment) { %>
COMMENT <%- comment %><% COMMENT <%- params.comment %><%
} %> } %>
<%- body %>$$ <%- params.body %><%- end %>
DELIMITER ;

View File

@ -1,7 +1,4 @@
DROP TRIGGER IF EXISTS <%- schema %>.<%- name %>; <%- begin %> <%- typeAndName %>
DELIMITER $$ <%- params.actionTiming %> <%- params.actionType %> ON `<%- params.table %>`
CREATE DEFINER=<%- definer %> TRIGGER <%- schema %>.<%- name %>
<%- actionTiming %> <%- actionType %> ON `<%- table %>`
FOR EACH ROW FOR EACH ROW
<%- body %>$$ <%- params.body %><%- end %>
DELIMITER ;

View File

@ -1,7 +1,7 @@
CREATE OR REPLACE DEFINER=<%- definer %> <%- createOrReplace %>
SQL SECURITY <%- securityType %> SQL SECURITY <%- params.securityType %>
VIEW <%- schema %>.<%- name %> <%- typeAndName %>
AS <%- definition %><% AS <%- params.definition %><%
if (locals.checkOption != 'NONE') { %> if (params.checkOption != 'NONE') { %>
WITH <%- checkOption %> CHECK OPTION<% WITH <%- params.checkOption %> CHECK OPTION<%
} %> } %>

View File

@ -3,9 +3,10 @@ const fs = require('fs-extra');
const Exporter = require('./exporter'); const Exporter = require('./exporter');
module.exports = class ExporterEngine { module.exports = class ExporterEngine {
constructor(conn, mytDir) { constructor(conn, opts) {
this.conn = conn; this.conn = conn;
this.pullFile = `${mytDir}/.pullinfo.json`; this.opts = opts;
this.pullFile = `${opts.mytDir}/.pullinfo.json`;
this.exporters = []; this.exporters = [];
this.exporterMap = {}; this.exporterMap = {};
} }
@ -35,7 +36,7 @@ module.exports = class ExporterEngine {
]; ];
for (const type of types) { for (const type of types) {
const exporter = new Exporter(type); const exporter = new Exporter(type, this.opts.replace);
await exporter.init(); await exporter.init();
this.exporters.push(exporter); this.exporters.push(exporter);

View File

@ -3,8 +3,11 @@ const fs = require('fs-extra');
const SqlString = require('sqlstring'); const SqlString = require('sqlstring');
module.exports = class Exporter { module.exports = class Exporter {
constructor(objectType) { constructor(objectType, replace) {
this.objectType = objectType; Object.assign(this, {
objectType,
replace
});
} }
async init() { async init() {
@ -38,7 +41,8 @@ module.exports = class Exporter {
format(params) { format(params) {
const {attrs} = this; const {attrs} = this;
params = Object.assign({}, attrs.defaults, params); params = Object.assign({}, attrs.defaults, params)
const data = {params};
if (attrs.formatter) if (attrs.formatter)
attrs.formatter(params); attrs.formatter(params);
@ -50,12 +54,33 @@ module.exports = class Exporter {
} }
const split = params.definer.split('@'); const split = params.definer.split('@');
params.schema = SqlString.escapeId(params.schema, true); data.definer =
params.name = SqlString.escapeId(params.name, true);
params.definer =
SqlString.escapeId(split[0], true) + '@' + SqlString.escapeId(split[0], true) + '@' +
SqlString.escapeId(split[1], 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);
} }
} }

View File

@ -1,6 +1,7 @@
const Myt = require('./myt'); const Myt = require('./myt');
const Command = require('./lib/command'); const Command = require('./lib/command');
const fs = require('fs-extra'); const fs = require('fs-extra');
const path = require('path');
/** /**
* Cleans old applied versions. * Cleans old applied versions.
@ -35,9 +36,15 @@ class Clean extends Command {
&& oldVersions.length > opts.maxOldVersions) { && oldVersions.length > opts.maxOldVersions) {
oldVersions.splice(-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) for (const oldVersion of oldVersions)
await fs.remove(`${opts.versionsDir}/${oldVersion}`, await fs.move(
{recursive: true}); path.join(opts.versionsDir, oldVersion),
path.join(archiveDir, oldVersion)
);
console.log(`Old versions deleted: ${oldVersions.length}`); console.log(`Old versions deleted: ${oldVersions.length}`);
} else } else

View File

@ -53,7 +53,7 @@ class Create extends Command {
break; break;
} }
const exporter = new Exporter(opts.type); const exporter = new Exporter(opts.type, opts.replace);
await exporter.init(); await exporter.init();
const sql = exporter.format(params); const sql = exporter.format(params);

View File

@ -85,7 +85,7 @@ class Pull extends Command {
console.log(`Incorporating routine changes.`); console.log(`Incorporating routine changes.`);
const engine = new ExporterEngine(conn, opts.mytDir); const engine = new ExporterEngine(conn, opts);
await engine.init(); await engine.init();
const shaSums = engine.shaSums; const shaSums = engine.shaSums;

View File

@ -288,7 +288,7 @@ class Push extends Command {
); );
} }
const engine = new ExporterEngine(conn, opts.mytDir); const engine = new ExporterEngine(conn, opts);
await engine.init(); await engine.init();
async function finalize() { async function finalize() {

View File

@ -42,25 +42,30 @@ class Run extends Command {
// Build base image // Build base image
let serverDockerfile = path.join(dumpDir, 'Dockerfile'); let basePath = dumpDir;
if (!await fs.pathExists(serverDockerfile)) let baseDockerfile = path.join(dumpDir, 'Dockerfile');
serverDockerfile = path.join(serverDir, 'Dockerfile.base');
await docker.build(__dirname, { if (!await fs.pathExists(baseDockerfile)) {
basePath = serverDir;
baseDockerfile = path.join(serverDir, 'Dockerfile.base');
}
await docker.build(basePath, {
tag: 'myt/base', tag: 'myt/base',
file: serverDockerfile file: baseDockerfile
}, opts.debug); }, opts.debug);
// Build server image // Build server image
await docker.build(__dirname, { await docker.build(serverDir, {
tag: 'myt/server', tag: 'myt/server',
file: path.join(serverDir, 'Dockerfile.server') file: path.join(serverDir, 'Dockerfile.server')
}, opts.debug); }, opts.debug);
// Build dump image // Build dump image
await docker.build(opts.mytDir, { const dumpContext = path.join(opts.mytDir, 'dump');
await docker.build(dumpContext, {
tag: opts.code, tag: opts.code,
file: path.join(serverDir, 'Dockerfile.dump') file: path.join(serverDir, 'Dockerfile.dump')
}, opts.debug); }, opts.debug);

30
package-lock.json generated
View File

@ -1,17 +1,17 @@
{ {
"name": "@verdnatura/myt", "name": "@verdnatura/myt",
"version": "1.5.9", "version": "1.5.11",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@verdnatura/myt", "name": "@verdnatura/myt",
"version": "1.5.9", "version": "1.5.11",
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"@sqltools/formatter": "^1.2.5", "@sqltools/formatter": "^1.2.5",
"colors": "^1.4.0", "colors": "^1.4.0",
"ejs": "^3.1.6", "ejs": "^3.1.8",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"getopts": "^2.3.0", "getopts": "^2.3.0",
"ini": "^1.3.8", "ini": "^1.3.8",
@ -462,9 +462,9 @@
} }
}, },
"node_modules/ejs": { "node_modules/ejs": {
"version": "3.1.7", "version": "3.1.8",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
"integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==", "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
"dependencies": { "dependencies": {
"jake": "^10.8.5" "jake": "^10.8.5"
}, },
@ -868,9 +868,9 @@
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
}, },
"node_modules/json5": { "node_modules/json5": {
"version": "2.2.1", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
"bin": { "bin": {
"json5": "lib/cli.js" "json5": "lib/cli.js"
}, },
@ -2198,9 +2198,9 @@
} }
}, },
"ejs": { "ejs": {
"version": "3.1.7", "version": "3.1.8",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
"integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==", "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
"requires": { "requires": {
"jake": "^10.8.5" "jake": "^10.8.5"
} }
@ -2538,9 +2538,9 @@
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
}, },
"json5": { "json5": {
"version": "2.2.1", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ=="
}, },
"jsonfile": { "jsonfile": {
"version": "4.0.0", "version": "4.0.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "@verdnatura/myt", "name": "@verdnatura/myt",
"version": "1.5.9", "version": "1.5.11",
"author": "Verdnatura Levante SL", "author": "Verdnatura Levante SL",
"description": "MySQL version control", "description": "MySQL version control",
"license": "GPL-3.0", "license": "GPL-3.0",
@ -14,7 +14,7 @@
"dependencies": { "dependencies": {
"@sqltools/formatter": "^1.2.5", "@sqltools/formatter": "^1.2.5",
"colors": "^1.4.0", "colors": "^1.4.0",
"ejs": "^3.1.6", "ejs": "^3.1.8",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"getopts": "^2.3.0", "getopts": "^2.3.0",
"ini": "^1.3.8", "ini": "^1.3.8",

View File

@ -3,9 +3,9 @@ FROM myt/server
USER root USER root
COPY \ COPY \
dump/.dump.sql \ .dump.sql \
dump/beforeDump.sql \ beforeDump.sql \
dump/afterDump.sql \ afterDump.sql \
dump/ dump/
RUN gosu mysql docker-init.sh RUN gosu mysql docker-init.sh

View File

@ -8,11 +8,11 @@ RUN mkdir /mysql-data \
WORKDIR /workspace WORKDIR /workspace
COPY server/docker.cnf /etc/mysql/conf.d/ COPY docker.cnf /etc/mysql/conf.d/
COPY \ COPY \
server/docker-init.sh \ docker-init.sh \
server/docker-import.sh \ docker-import.sh \
server/docker-start.sh \ docker-start.sh \
/usr/local/bin/ /usr/local/bin/
USER mysql USER mysql