Skip to content

Commit

Permalink
refactor import dump to mysql task, split it to separate tasks, add s…
Browse files Browse the repository at this point in the history
…elector of users to use in mysql client during import
  • Loading branch information
ejnshtein committed Jul 5, 2022
1 parent 46a977e commit c24f6bf
Showing 1 changed file with 78 additions and 22 deletions.
100 changes: 78 additions & 22 deletions build-packages/magento-scripts/lib/tasks/mysql/import-dump-to-mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,73 @@
const logger = require('@scandipwa/scandipwa-dev-utils/logger');
const KnownError = require('../../errors/known-error');
const UnknownError = require('../../errors/unknown-error');
const { execAsyncSpawn } = require('../../util/exec-async-command');
const { execAsyncSpawn, execCommandTask } = require('../../util/exec-async-command');
const pathExists = require('../../util/path-exists');

/**
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
*/
const importDumpToMySQL = () => ({
title: 'Importing Database Dump To MySQL',
const copyDatabaseDumpIntoContainer = () => ({
title: 'Copying database dump into container',
task: async (ctx, task) => {
if (!await pathExists(ctx.importDb)) {
throw new KnownError(`Dump file at ${ctx.importDb} does not exist. Please provide correct relative path to the file`);
}
const { config: { docker }, ports } = ctx;
const { mysql } = docker.getContainers(ports);

return task.newListr(
execCommandTask(`docker cp ${ctx.importDb} ${mysql.name}:/dump.sql`, {
logOutput: true
})
);
}
});

/**
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
*/
const runSetGlobalLogBinTrustFunctionCreatorsCommand = () => ({
task: async (ctx, task) => {
const { config: { docker }, ports } = ctx;
const { mysql } = docker.getContainers(ports);

return task.newListr(
execCommandTask(`docker exec ${mysql.name} bash -c 'mysql -uroot -p${mysql.env.MYSQL_ROOT_PASSWORD} -e "SET GLOBAL log_bin_trust_function_creators = 1;"'`)
);
}
});

/**
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
*/
const executeImportDumpSQL = () => ({
task: async (ctx, task) => {
const { config: { docker }, ports } = ctx;
const { mysql } = docker.getContainers(ports);

const userCredentialsForMySQLCLI = await task.prompt({
type: 'Select',
message: 'Which user do you want to use to import db in MySQL client?',
choices: [
{
name: `--user=root --password=${mysql.env.MYSQL_ROOT_PASSWORD}`,
message: `root (${logger.style.command('Probably safest option')})`
},
{
name: `--user=${mysql.env.MYSQL_USER} --password=${mysql.env.MYSQL_PASSWORD}`,
message: `${mysql.env.MYSQL_USER}`
}
]
});

const importCommand = `docker exec ${mysql.name} bash -c "mysql ${userCredentialsForMySQLCLI} magento < ./dump.sql"`;

const startImportTime = Date.now();
const tickInterval = setInterval(() => {
task.title = `Importing Database Dump To MySQL, ${Math.floor((Date.now() - startImportTime) / 1000)}s in progress...`;
}, 1000);

try {
await execAsyncSpawn(
`docker cp ${ctx.importDb} ${mysql.name}:/dump.sql`
);

await execAsyncSpawn(
`docker exec ${mysql.name} bash -c 'mysql -uroot -p${mysql.env.MYSQL_ROOT_PASSWORD} -e "SET GLOBAL log_bin_trust_function_creators = 1;"'`
);

/**
* Using `mysql` instead of `mysqlimport` because `mysqlimport` has permission issues during import
*/
await execAsyncSpawn(
`docker exec ${mysql.name} bash -c "mysql -umagento -pmagento magento < ./dump.sql"`,
importCommand,
{
callback: (t) => {
task.output = t;
Expand All @@ -54,15 +85,40 @@ You can try replacing all occurrences of ${logger.style.misc('utf8mb4_0900_ai_ci
}

throw new UnknownError(`Unexpected error during dump import.\n\n${e}`);
} finally {
clearInterval(tickInterval);
}

clearInterval(tickInterval);

task.title = 'Database imported!';
},
options: {
bottomBar: 10
}
});

/**
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
*/
const importDumpToMySQL = () => ({
title: 'Importing Database Dump To MySQL',
task: async (ctx, task) => {
if (!await pathExists(ctx.importDb)) {
throw new KnownError(`Dump file at ${ctx.importDb} does not exist. Please provide correct relative path to the file`);
}

return task.newListr([
copyDatabaseDumpIntoContainer(),
runSetGlobalLogBinTrustFunctionCreatorsCommand(),
executeImportDumpSQL(),
{
task: () => {
task.title = 'Database imported!';
}
}
], {
rendererOptions: {
collapse: false
}
});
}
});

module.exports = importDumpToMySQL;

0 comments on commit c24f6bf

Please sign in to comment.