feat: refs #5123 clean fixes, purge option added

This commit is contained in:
Juan Ferrer 2024-01-17 15:14:35 +01:00
parent 55a47ec99c
commit 85af498e15
5 changed files with 76 additions and 15 deletions

View File

@ -250,7 +250,7 @@ $ myt create [-t <type>] <schema>.<name>
Cleans all already applied versions older than *maxOldVersions*. Cleans all already applied versions older than *maxOldVersions*.
```text ```text
$ myt clean $ myt clean [-p|--purge]
``` ```
## Local server commands ## Local server commands
@ -276,8 +276,7 @@ $ myt fixtures [<remote>]
### run ### run
Builds and starts local database server container. It only rebuilds the image Builds and starts local database server container. It only rebuilds the image
when fixtures have been modified or when the day on which the image was built dump has been modified.
is different to today.
```text ```text
$ myt run [-c|--ci] [-r|--random] $ myt run [-c|--ci] [-r|--random]

View File

@ -8,26 +8,36 @@ const path = require('path');
*/ */
class Clean extends Command { class Clean extends Command {
static usage = { static usage = {
description: 'Cleans old applied versions' description: 'Cleans old applied versions',
params: {
purge: 'Wether to remove non-existent scripts from DB log'
}
}; };
static opts = { static opts = {
alias: {
purge: 'p'
},
boolean: [
'purge'
],
default: { default: {
remote: 'production' remote: 'production'
} }
}; };
async run(myt, opts) { async run(myt, opts) {
await myt.dbConnect(); const conn = await myt.dbConnect();
const versionDirs = await fs.readdir(opts.versionsDir);
const archiveDir = path.join(opts.versionsDir, '.archive');
const dbVersion = await myt.fetchDbVersion() || {}; const dbVersion = await myt.fetchDbVersion() || {};
const number = parseInt(dbVersion.number); const number = parseInt(dbVersion.number);
const oldVersions = []; const oldVersions = [];
const versionDirs = await fs.readdir(opts.versionsDir);
for (const versionDir of versionDirs) { for (const versionDir of versionDirs) {
const version = await myt.loadVersion(versionDir); const version = await myt.loadVersion(versionDir);
const shouldArchive = version const shouldArchive = version
&& version.matchRegex
&& !version.apply && !version.apply
&& parseInt(version.number) < number; && parseInt(version.number) < number;
@ -39,7 +49,6 @@ 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)) if (!await fs.pathExists(archiveDir))
await fs.mkdir(archiveDir); await fs.mkdir(archiveDir);
@ -52,6 +61,60 @@ class Clean extends Command {
console.log(`Old versions archived: ${oldVersions.length}`); console.log(`Old versions archived: ${oldVersions.length}`);
} else } else
console.log(`No versions to archive.`); console.log(`No versions to archive.`);
if (opts.purge) {
const versionDb = new VersionDb(myt, opts.versionsDir);
versionDb.load();
const archiveDb = new VersionDb(myt, archiveDir);
archiveDb.load();
const [res] = await conn.query(
`SELECT number, file FROM versionLog
WHERE code = ?
ORDER BY number, file`,
[opts.code]
);
for (const script of res) {
const hasVersion = await versionDb.hasScript(script);
const hasArchive = await archiveDb.hasScript(script);
if (!hasVersion && !hasArchive) {
await conn.query(
`DELETE FROM versionLog
WHERE code = ? AND number = ? AND file = ?`,
[opts.code, script.number, script.file]
);
}
}
}
}
}
class VersionDb {
constructor(myt, baseDir) {
Object.assign(this, {myt, baseDir});
}
async load() {
const versionMap = this.versionMap = new Map();
if (await fs.pathExists(this.baseDir)) {
const dirs = await fs.readdir(this.baseDir);
for (const dir of dirs) {
const version = this.myt.parseVersionDir(dir);
if (!version) continue;
versionMap.set(version.number, dir);
}
}
return versionMap;
}
async hasScript(script) {
const dir = this.versionMap.get(script.number);
if (!dir) return false;
const scriptPath = path.join(this.baseDir, dir, script.file);
return await fs.pathExists(scriptPath);
} }
} }

View File

@ -9,10 +9,9 @@ const connExt = require('./lib/conn');
const SqlString = require('sqlstring'); const SqlString = require('sqlstring');
/** /**
* Builds the database image and runs a container. It only rebuilds the * Builds the database image and runs a container. It only rebuilds the image
* image when fixtures have been modified or when the day on which the * when dump has been modified. Some workarounds have been used to avoid a bug
* image was built is different to today. Some workarounds have been used * with OverlayFS driver on MacOS.
* to avoid a bug with OverlayFS driver on MacOS.
*/ */
class Run extends Command { class Run extends Command {
static usage = { static usage = {

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "@verdnatura/myt", "name": "@verdnatura/myt",
"version": "1.5.24", "version": "1.5.25",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@verdnatura/myt", "name": "@verdnatura/myt",
"version": "1.5.24", "version": "1.5.25",
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"@sqltools/formatter": "^1.2.5", "@sqltools/formatter": "^1.2.5",

View File

@ -1,6 +1,6 @@
{ {
"name": "@verdnatura/myt", "name": "@verdnatura/myt",
"version": "1.5.24", "version": "1.5.25",
"author": "Verdnatura Levante SL", "author": "Verdnatura Levante SL",
"description": "MySQL version control", "description": "MySQL version control",
"license": "GPL-3.0", "license": "GPL-3.0",