From b503cbfa9f9cde17dc466b6e4f10dfe22859e8dd Mon Sep 17 00:00:00 2001 From: jgallego Date: Wed, 6 Sep 2023 16:34:25 +0200 Subject: [PATCH 1/7] refs #6204 skip files from other environments --- myt-push.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/myt-push.js b/myt-push.js index f7954b5..b0b0e76 100644 --- a/myt-push.js +++ b/myt-push.js @@ -151,6 +151,21 @@ class Push extends Command { function isUndoScript(script) { return /\.undo\.sql$/.test(script); } + function isOtherEnvScript(script, env) { + const splitScript = script.split('.'); + const envPart = splitScript[splitScript.length - 2]; + + if (splitScript.length <= 2) { + return false; + } + + if (!env) { + return !!envPart; + } + + return envPart && envPart !== env; + } + const skipFiles = new Set([ 'README.md', @@ -210,6 +225,9 @@ class Push extends Command { if (isUndoScript(script)) continue; + if (isOtherEnvScript(script, opts.env)) + continue; + const [[row]] = await conn.query( `SELECT errorNumber FROM versionLog WHERE code = ? From 11a57b81684ff2c80b275e7d8dc35385d81dc483 Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 7 Sep 2023 09:27:37 +0200 Subject: [PATCH 2/7] refs #6204 package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4fe2cab..a096914 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@verdnatura/myt", - "version": "1.5.22", + "version": "1.5.23", "author": "Verdnatura Levante SL", "description": "MySQL version control", "license": "GPL-3.0", From 38aec9007326f21fb943b07e82ab8068f588529f Mon Sep 17 00:00:00 2001 From: jgallego Date: Fri, 22 Sep 2023 10:25:06 +0200 Subject: [PATCH 3/7] fixes #6204 tested code --- assets/structure.sql | 5 +++++ myt-push.js | 18 ++++++++++-------- myt.js | 18 +++++++++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/assets/structure.sql b/assets/structure.sql index 368332e..12c713a 100644 --- a/assets/structure.sql +++ b/assets/structure.sql @@ -22,3 +22,8 @@ CREATE TABLE `versionLog` ( ALTER TABLE `versionLog` ADD PRIMARY KEY (`code`,`number`,`file`); + +CREATE TABLE `util`.`versionConfig` ( + `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + `realm` VARCHAR(16) NULL DEFAULT NULL COMMENT 'Data set on which the project runs' +) ENGINE=InnoDB; diff --git a/myt-push.js b/myt-push.js index b0b0e76..380ad1c 100644 --- a/myt-push.js +++ b/myt-push.js @@ -151,19 +151,19 @@ class Push extends Command { function isUndoScript(script) { return /\.undo\.sql$/.test(script); } - function isOtherEnvScript(script, env) { + function isOtherRealmScript(script, realm) { const splitScript = script.split('.'); - const envPart = splitScript[splitScript.length - 2]; + const realmPart = splitScript[splitScript.length - 2]; if (splitScript.length <= 2) { return false; } - if (!env) { - return !!envPart; + if (!realm) { + return !!realmPart; } - - return envPart && envPart !== env; + + return realmPart && realmPart !== realm; } @@ -207,6 +207,8 @@ class Push extends Command { [opts.code, versionNumber] ); + const realm = await myt.fetchDbRealm(); + for (const script of scripts) if (!isUndoScript(script) && versionLog.findIndex(x => x.file == script) === -1) { @@ -218,14 +220,14 @@ class Push extends Command { logVersion(`[${versionNumber}]`.cyan, versionName); for (const script of scripts) { - if (!/^[0-9]{2}-[a-zA-Z0-9_]+(.undo)?\.sql$/.test(script)) { + if (!/^[0-9]{2}-[a-zA-Z0-9_]+(\..+)?\.sql$/.test(script)) { logScript('[W]'.yellow, script, `Wrong file name.`); continue; } if (isUndoScript(script)) continue; - if (isOtherEnvScript(script, opts.env)) + if (isOtherRealmScript(script, realm)) continue; const [[row]] = await conn.query( diff --git a/myt.js b/myt.js index e5c5659..f034fbc 100755 --- a/myt.js +++ b/myt.js @@ -172,7 +172,7 @@ class Myt { const defaultConfig = require(`${__dirname}/assets/myt.default.yml`); const config = Object.assign({}, defaultConfig); - + const configFile = 'myt.config.yml'; const configPath = path.join(opts.workspace, configFile); @@ -205,7 +205,7 @@ class Myt { opts.dumpDir = path.join(opts.mytDir, 'dump'); // Database configuration - + let iniDir = path.join(__dirname, 'assets'); let iniFile = 'db.ini'; @@ -214,10 +214,10 @@ class Myt { iniFile = `${opts.remote}.ini`; } const iniPath = path.join(iniDir, iniFile); - + if (!await fs.pathExists(iniPath)) throw new Error(`Database config file not found: ${iniPath}`); - + let dbConfig; try { const iniData = ini.parse(await fs.readFile(iniPath, 'utf8')).client; @@ -299,7 +299,7 @@ class Myt { AND TABLE_NAME = 'version'`, [opts.versionSchema] ); - + if (!res.tableExists) { const structure = await fs.readFile( `${__dirname}/assets/structure.sql`, 'utf8'); @@ -323,6 +323,14 @@ class Myt { return version; } + + async fetchDbRealm() { + const [[realm]] = await this.conn.query( + `SELECT realm + FROM versionConfig` + ); + return realm?.realm; + } parseVersionDir(versionDir) { const match = versionDir.match(/^([0-9]+)-([a-zA-Z0-9]+)?$/); if (!match) return null; From 5ccb3de3cbc4ce816f134a9de6a144946da9a8dd Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 28 Sep 2023 10:02:40 +0200 Subject: [PATCH 4/7] fixes #6204 regexp makes match --- myt-push.js | 23 ++++++++++++++++++----- myt.js | 8 -------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/myt-push.js b/myt-push.js index 380ad1c..8d3b6c2 100644 --- a/myt-push.js +++ b/myt-push.js @@ -174,6 +174,10 @@ class Push extends Command { if (await fs.pathExists(versionsDir)) { const versionDirs = await fs.readdir(versionsDir); + const [[realm]] = await this.conn.query( + `SELECT realm + FROM versionConfig` + ); for (const versionDir of versionDirs) { if (skipFiles.has(versionDir)) continue; @@ -207,8 +211,6 @@ class Push extends Command { [opts.code, versionNumber] ); - const realm = await myt.fetchDbRealm(); - for (const script of scripts) if (!isUndoScript(script) && versionLog.findIndex(x => x.file == script) === -1) { @@ -220,16 +222,27 @@ class Push extends Command { logVersion(`[${versionNumber}]`.cyan, versionName); for (const script of scripts) { - if (!/^[0-9]{2}-[a-zA-Z0-9_]+(\..+)?\.sql$/.test(script)) { + const match = script.match(/^[0-9]{2}-[a-zA-Z0-9_]+(?:\.(?!undo)([a-zA-Z0-9_]+))?(?:\.undo)?\.sql$/); + + if (!match) { logScript('[W]'.yellow, script, `Wrong file name.`); continue; } + + const skipRealm = match & match[1] && match[1] !== realm; + if (isUndoScript(script)) continue; - if (isOtherRealmScript(script, realm)) - continue; + if (match[1]) { + if (skipRealm) { + continue; + } + if (!realm) { + continue; + } + } const [[row]] = await conn.query( `SELECT errorNumber FROM versionLog WHERE code = ? diff --git a/myt.js b/myt.js index f034fbc..15b21d7 100755 --- a/myt.js +++ b/myt.js @@ -323,14 +323,6 @@ class Myt { return version; } - - async fetchDbRealm() { - const [[realm]] = await this.conn.query( - `SELECT realm - FROM versionConfig` - ); - return realm?.realm; - } parseVersionDir(versionDir) { const match = versionDir.match(/^([0-9]+)-([a-zA-Z0-9]+)?$/); if (!match) return null; From b95b5932923aa89570bc7e94b2725fc2809ca807 Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 28 Sep 2023 10:05:05 +0200 Subject: [PATCH 5/7] fixes #6204 without isOtherRealmScript function --- myt-push.js | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/myt-push.js b/myt-push.js index 8d3b6c2..9fd0507 100644 --- a/myt-push.js +++ b/myt-push.js @@ -151,22 +151,7 @@ class Push extends Command { function isUndoScript(script) { return /\.undo\.sql$/.test(script); } - function isOtherRealmScript(script, realm) { - const splitScript = script.split('.'); - const realmPart = splitScript[splitScript.length - 2]; - - if (splitScript.length <= 2) { - return false; - } - - if (!realm) { - return !!realmPart; - } - - return realmPart && realmPart !== realm; - } - - + const skipFiles = new Set([ 'README.md', '.archive' @@ -235,13 +220,12 @@ class Push extends Command { continue; if (match[1]) { - if (skipRealm) { + if (skipRealm) continue; - } - - if (!realm) { + + if (!realm) continue; - } + } const [[row]] = await conn.query( `SELECT errorNumber FROM versionLog From 65bd0197de8b2de228645064789b23aafd17dd81 Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 5 Oct 2023 08:36:29 +0200 Subject: [PATCH 6/7] fixes #6204 refactor push just one if --- myt-push.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/myt-push.js b/myt-push.js index 9fd0507..ec96400 100644 --- a/myt-push.js +++ b/myt-push.js @@ -214,19 +214,11 @@ class Push extends Command { continue; } - const skipRealm = match & match[1] && match[1] !== realm; + const skipRealm = match[1] && match[1] !== realm; - if (isUndoScript(script)) + if (isUndoScript(script) || skipRealm) continue; - if (match[1]) { - if (skipRealm) - continue; - - if (!realm) - continue; - - } const [[row]] = await conn.query( `SELECT errorNumber FROM versionLog WHERE code = ? From 3897187fb2c6ee3e1133add3ca3ba80d00e178fa Mon Sep 17 00:00:00 2001 From: jgallego Date: Tue, 24 Oct 2023 07:47:42 +0200 Subject: [PATCH 7/7] refs #6204 docs: readme explains new realm funcionality --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 44b48d8..1f10be3 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Each command can have its own specific commandline options. ## Basic information -First of all you have to initalize the workspace. +First of all you have to initialize the workspace. ```text $ myt init @@ -72,7 +72,7 @@ $ myt init Now you can configure Myt using *myt.config.yml* file, located at the root of your workspace. This file should include the project codename and schemas/tables -wich are exported when you use *pull* or *dump* commands. +which are exported when you use *pull* or *dump* commands. Don't forget to initialize git (if it isn't initialized yet). @@ -143,6 +143,38 @@ Don't place your PL/SQL objects here, use the routines folder! `- 00-sameNumbers.sql ``` +### Environment-Specific Versioning with Realms + +#### Overview + +We have introduced a new feature that allows users to apply version-specific changes based on their configured environment, or "realm". This ensures that certain changes are only applied when the user is operating within a specific realm, providing an additional layer of customization and control. + +#### Configuration + +To make use of this feature, you need to configure your realm in the `versionConfig` table. Set your realm by inserting or updating a record in this table. The `realm` field should contain the identifier of your environment. + +#### File Naming Convention + +To designate a file as realm-specific, include a `.your_realm.` segment before the file extension. For example, if your realm is set to 'ab', the file should be named like this: `filename.ab.sql`. + +#### How It Works + +1. **Set your Realm**: Configure your realm in the `versionConfig` table. + +2. **Add Files**: Place your realm-specific files in the `versions` folder. Make sure to follow the naming convention. + +3. **Version Order**: Files are applied in the existing version order. In addition to that, the realm is validated. + +4. **Apply Changes**: Run the usual versioning commands. The realm-specific files will only be applied if your configured realm matches the realm in the file name. + +#### Important Notes + +- If no realm is configured, realm-specific files will be ignored. + +- If you have a realm configured but the realm-specific files belong to a different realm, those files will also be ignored. + +This feature allows for greater flexibility when working in different environments, making it easier to manage realm-specific changes in a shared repository. + ### Local server The local server is created as a MariaDB Docker container using the base dump @@ -169,6 +201,7 @@ Initializes an empty workspace. $ myt init ``` + ### pull Incorporates database routine changes into workspace. @@ -263,14 +296,14 @@ $ myt start ## Why -The main reason for starting this project it's because there are no fully free +The main reason for starting this project is because there are no fully free and open source migration tools available that allow versioning database -routines with an standard CVS system as if they were normal application code. +routines with a standard CVS system as if they were normal application code. Also, the existing tools are too complex and require too much knowledge to -start a small project. +initiate a small project. -## ToDo +## To-Do * Undo changes when there is an error applying a version using "undo" files. * Console logging via events. @@ -280,6 +313,6 @@ start a small project. ## Built With * [Git](https://git-scm.com/) -* [nodejs](https://nodejs.org/) +* [Node.js](https://nodejs.org/) * [NodeGit](https://www.nodegit.org/) -* [docker](https://www.docker.com/) +* [Docker](https://www.docker.com/)