Merge pull request '6204-fixturesByEnvironment' (!2) from 6204-fixturesByEnvironment into master

Reviewed-on: #2
This commit is contained in:
Javi Gallego 2023-10-30 06:57:36 +00:00
commit 19b368b219
5 changed files with 64 additions and 17 deletions

View File

@ -64,7 +64,7 @@ Each command can have its own specific commandline options.
## Basic information ## Basic information
First of all you have to initalize the workspace. First of all you have to initialize the workspace.
```text ```text
$ myt init $ myt init
@ -72,7 +72,7 @@ $ myt init
Now you can configure Myt using *myt.config.yml* file, located at the root of 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 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). 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 `- 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 ### Local server
The local server is created as a MariaDB Docker container using the base dump The local server is created as a MariaDB Docker container using the base dump
@ -169,6 +201,7 @@ Initializes an empty workspace.
$ myt init $ myt init
``` ```
### pull ### pull
Incorporates database routine changes into workspace. Incorporates database routine changes into workspace.
@ -263,14 +296,14 @@ $ myt start
## Why ## 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 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 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. * Undo changes when there is an error applying a version using "undo" files.
* Console logging via events. * Console logging via events.
@ -280,6 +313,6 @@ start a small project.
## Built With ## Built With
* [Git](https://git-scm.com/) * [Git](https://git-scm.com/)
* [nodejs](https://nodejs.org/) * [Node.js](https://nodejs.org/)
* [NodeGit](https://www.nodegit.org/) * [NodeGit](https://www.nodegit.org/)
* [docker](https://www.docker.com/) * [Docker](https://www.docker.com/)

View File

@ -22,3 +22,8 @@ CREATE TABLE `versionLog` (
ALTER TABLE `versionLog` ALTER TABLE `versionLog`
ADD PRIMARY KEY (`code`,`number`,`file`); 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;

View File

@ -151,7 +151,7 @@ class Push extends Command {
function isUndoScript(script) { function isUndoScript(script) {
return /\.undo\.sql$/.test(script); return /\.undo\.sql$/.test(script);
} }
const skipFiles = new Set([ const skipFiles = new Set([
'README.md', 'README.md',
'.archive' '.archive'
@ -159,6 +159,10 @@ class Push extends Command {
if (await fs.pathExists(versionsDir)) { if (await fs.pathExists(versionsDir)) {
const versionDirs = await fs.readdir(versionsDir); const versionDirs = await fs.readdir(versionsDir);
const [[realm]] = await this.conn.query(
`SELECT realm
FROM versionConfig`
);
for (const versionDir of versionDirs) { for (const versionDir of versionDirs) {
if (skipFiles.has(versionDir)) continue; if (skipFiles.has(versionDir)) continue;
@ -203,11 +207,16 @@ class Push extends Command {
logVersion(`[${versionNumber}]`.cyan, versionName); logVersion(`[${versionNumber}]`.cyan, versionName);
for (const script of scripts) { for (const script of scripts) {
if (!/^[0-9]{2}-[a-zA-Z0-9_]+(.undo)?\.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.`); logScript('[W]'.yellow, script, `Wrong file name.`);
continue; continue;
} }
if (isUndoScript(script))
const skipRealm = match[1] && match[1] !== realm;
if (isUndoScript(script) || skipRealm)
continue; continue;
const [[row]] = await conn.query( const [[row]] = await conn.query(

10
myt.js
View File

@ -172,7 +172,7 @@ class Myt {
const defaultConfig = require(`${__dirname}/assets/myt.default.yml`); const defaultConfig = require(`${__dirname}/assets/myt.default.yml`);
const config = Object.assign({}, defaultConfig); const config = Object.assign({}, defaultConfig);
const configFile = 'myt.config.yml'; const configFile = 'myt.config.yml';
const configPath = path.join(opts.workspace, configFile); const configPath = path.join(opts.workspace, configFile);
@ -205,7 +205,7 @@ class Myt {
opts.dumpDir = path.join(opts.mytDir, 'dump'); opts.dumpDir = path.join(opts.mytDir, 'dump');
// Database configuration // Database configuration
let iniDir = path.join(__dirname, 'assets'); let iniDir = path.join(__dirname, 'assets');
let iniFile = 'db.ini'; let iniFile = 'db.ini';
@ -214,10 +214,10 @@ class Myt {
iniFile = `${opts.remote}.ini`; iniFile = `${opts.remote}.ini`;
} }
const iniPath = path.join(iniDir, iniFile); const iniPath = path.join(iniDir, iniFile);
if (!await fs.pathExists(iniPath)) if (!await fs.pathExists(iniPath))
throw new Error(`Database config file not found: ${iniPath}`); throw new Error(`Database config file not found: ${iniPath}`);
let dbConfig; let dbConfig;
try { try {
const iniData = ini.parse(await fs.readFile(iniPath, 'utf8')).client; const iniData = ini.parse(await fs.readFile(iniPath, 'utf8')).client;
@ -299,7 +299,7 @@ class Myt {
AND TABLE_NAME = 'version'`, AND TABLE_NAME = 'version'`,
[opts.versionSchema] [opts.versionSchema]
); );
if (!res.tableExists) { if (!res.tableExists) {
const structure = await fs.readFile( const structure = await fs.readFile(
`${__dirname}/assets/structure.sql`, 'utf8'); `${__dirname}/assets/structure.sql`, 'utf8');

View File

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