diff --git a/README.md b/README.md index d5dcc64..a2f3b62 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Database versioning commands: Local server management commands: * **dump**: Export database structure and fixtures. + * **fixtures**: Export local database fixtures. * **run**: Build and start local database server container. * **start**: Start local database server container. @@ -212,6 +213,15 @@ in *dump* folder. If no remote is specified *production* is used. $ myvc dump [] ``` +### fixtures + +Exports local database fixtures into *dump/fixtures.sql* files. If no remote is +specified *local* is used. + +```text +$ myvc fixtures [] +``` + ### run Builds and starts local database server container. It only rebuilds the image diff --git a/docker.js b/docker.js index 2c14fc7..b53d39e 100644 --- a/docker.js +++ b/docker.js @@ -79,8 +79,10 @@ const docker = { const child = spawn('docker', execArgs, execOptions || undefined); child.on('exit', code => { if (code !== 0) { - const args = JSON.stringify(execArgs); - reject(new Error(`docker: ${args}: exit code ${code}`)); + const quotedArgs = execArgs + .map(x => /\s/g.test(x) ? `"${x}"` : x) + .join(' '); + reject(new Error(`Docker exit code ${code}: 'docker ${quotedArgs}'`)); } else resolve(code); }); diff --git a/myvc-dump.js b/myvc-dump.js index 8b51c9e..aa594c7 100644 --- a/myvc-dump.js +++ b/myvc-dump.js @@ -21,7 +21,6 @@ class Dump { } async run(myvc, opts) { - const conn = await myvc.dbConnect(); const iniPath = path.join(opts.subdir || '', 'remotes', opts.iniFile); const dumpDir = `${opts.myvcDir}/dump`; @@ -63,8 +62,9 @@ class Dump { '--insert-ignore' ]; for (const schema in opts.fixtures) { + const escapedSchema = '`'+ schema.replace('`', '``') +'`'; await dumpStream.write( - `USE ${conn.escapeId(schema, true)};\n`, + `USE ${escapedSchema};\n`, 'utf8' ); diff --git a/myvc-fixtures.js b/myvc-fixtures.js new file mode 100644 index 0000000..372b90d --- /dev/null +++ b/myvc-fixtures.js @@ -0,0 +1,79 @@ + +const MyVC = require('./myvc'); +const fs = require('fs-extra'); +const path = require('path'); +const docker = require('./docker'); + +class Fixtures { + get usage() { + return { + description: 'Dumps local fixtures from database', + operand: 'remote' + }; + } + + get localOpts() { + return { + default: { + remote: 'local' + } + }; + } + + async run(myvc, opts) { + const iniPath = path.join(opts.subdir || '', 'remotes', opts.iniFile); + + const dumpDir = `${opts.myvcDir}/dump`; + if (!await fs.pathExists(dumpDir)) + await fs.mkdir(dumpDir); + + const dumpFile = `${dumpDir}/fixtures.sql`; + const dumpStream = await fs.createWriteStream(dumpFile); + const execOptions = { + stdio: [ + process.stdin, + dumpStream, + process.stderr + ] + }; + + await docker.build(__dirname, { + tag: 'myvc/client', + file: path.join(__dirname, 'server', 'Dockerfile.client') + }, opts.debug); + + const fixturesArgs = [ + `--defaults-file=${iniPath}`, + '--no-create-info', + '--skip-triggers', + '--insert-ignore' + ]; + for (const schema in opts.localFixtures) { + const escapedSchema = '`'+ schema.replace('`', '``') +'`'; + await dumpStream.write( + `USE ${escapedSchema};\n`, + 'utf8' + ); + + const args = fixturesArgs.concat([schema], opts.localFixtures[schema]); + await this.dockerRun('mysqldump', args, execOptions); + } + + await dumpStream.end(); + } + + async dockerRun(command, args, execOptions) { + const commandArgs = [command].concat(args); + await docker.run('myvc/client', commandArgs, { + addHost: 'host.docker.internal:host-gateway', + volume: `${this.opts.myvcDir}:/workspace`, + rm: true + }, execOptions); + } +} + +module.exports = Fixtures; + +if (require.main === module) + new MyVC().run(Fixtures); + diff --git a/myvc.js b/myvc.js index 9741ca0..7f7b982 100755 --- a/myvc.js +++ b/myvc.js @@ -68,6 +68,7 @@ class MyVC { 'version', 'clean', 'dump', + 'fixtures', 'start', 'run' ]; diff --git a/package.json b/package.json index 611f749..e3b92d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "myvc", - "version": "1.4.10", + "version": "1.4.11", "author": "Verdnatura Levante SL", "description": "MySQL Version Control", "license": "GPL-3.0", diff --git a/template/.gitignore b/template/.gitignore index 741926e..24e6ce6 100644 --- a/template/.gitignore +++ b/template/.gitignore @@ -2,3 +2,4 @@ node_modules remotes/*.ini !remotes/local.ini +dump/.changes diff --git a/template/package.json b/template/package.json index cb3d1c4..dd1a63a 100644 --- a/template/package.json +++ b/template/package.json @@ -8,6 +8,6 @@ "type": "git" }, "dependencies": { - "myvc": "^1.4.10" + "myvc": "^1.4.11" } }