diff --git a/integration-tests/__tests__/deploy-database.spec.js b/integration-tests/__tests__/deploy-database.spec.js index 219a7f676..72578d0bd 100644 --- a/integration-tests/__tests__/deploy-database.spec.js +++ b/integration-tests/__tests__/deploy-database.spec.js @@ -131,6 +131,7 @@ async function testDatabaseDeploy(engine, conn, driver, dbModelsYaml, options) { driver, loadedDbModel: convertModelToEngine(loadedDbModel, driver), dbdiffOptionsExtra, + useTransaction: engine.runDeployInTransaction, }); } diff --git a/integration-tests/engines.js b/integration-tests/engines.js index 48511dedf..02ca03d7d 100644 --- a/integration-tests/engines.js +++ b/integration-tests/engines.js @@ -711,6 +711,7 @@ const firebirdEngine = { }, ], skipOnCI: false, + runDeployInTransaction: true, // skipChangeColumn: true, // skipIndexes: true, // skipStringLength: true, diff --git a/packages/api/src/shell/deployDb.js b/packages/api/src/shell/deployDb.js index abbcc4160..6fcfd943a 100644 --- a/packages/api/src/shell/deployDb.js +++ b/packages/api/src/shell/deployDb.js @@ -20,6 +20,7 @@ const crypto = require('crypto'); * @param {string} options.ignoreNameRegex - regex for ignoring objects by name * @param {string} options.targetSchema - target schema for deployment * @param {number} options.maxMissingTablesRatio - maximum ratio of missing tables in database. Safety check, if missing ratio is highe, deploy is stopped (preventing accidental drop of all tables) + * @param {boolean} options.useTransaction - run deploy in transaction. If not provided, it will be set to true if driver supports transactions */ async function deployDb({ connection, @@ -33,6 +34,7 @@ async function deployDb({ ignoreNameRegex = '', targetSchema = null, maxMissingTablesRatio = undefined, + useTransaction, }) { if (!driver) driver = requireEngineDriver(connection); const dbhan = systemConnection || (await connectUtility(driver, connection, 'read')); @@ -60,7 +62,14 @@ async function deployDb({ maxMissingTablesRatio, }); // console.log('RUNNING DEPLOY SCRIPT:', sql); - await executeQuery({ connection, systemConnection: dbhan, driver, sql, logScriptItems: true }); + await executeQuery({ + connection, + systemConnection: dbhan, + driver, + sql, + logScriptItems: true, + useTransaction, + }); await scriptDeployer.runPost(); } finally { diff --git a/packages/api/src/shell/executeQuery.js b/packages/api/src/shell/executeQuery.js index 3f54267f0..658d3b3dd 100644 --- a/packages/api/src/shell/executeQuery.js +++ b/packages/api/src/shell/executeQuery.js @@ -14,6 +14,7 @@ const logger = getLogger('execQuery'); * @param {string} [options.sql] - SQL query * @param {string} [options.sqlFile] - SQL file * @param {boolean} [options.logScriptItems] - whether to log script items instead of whole script + * @param {boolean} [options.useTransaction] - run query in transaction */ async function executeQuery({ connection = undefined, @@ -22,6 +23,7 @@ async function executeQuery({ sql, sqlFile = undefined, logScriptItems = false, + useTransaction, }) { if (!logScriptItems) { logger.info({ sql: getLimitedQuery(sql) }, `Execute query`); @@ -38,7 +40,7 @@ async function executeQuery({ try { logger.debug(`Running SQL query, length: ${sql.length}`); - await driver.script(dbhan, sql, { logScriptItems }); + await driver.script(dbhan, sql, { logScriptItems, useTransaction }); } finally { if (!systemConnection) { await driver.close(dbhan); diff --git a/packages/dbmodel/bin/dbmodel.js b/packages/dbmodel/bin/dbmodel.js index 68cf72569..8f72a536b 100755 --- a/packages/dbmodel/bin/dbmodel.js +++ b/packages/dbmodel/bin/dbmodel.js @@ -41,13 +41,14 @@ program 'regex, which table data will be loaded and stored in model (in load command)' ) .option('-e, --engine ', 'engine name, eg. mysql@dbgate-plugin-mysql') - .option('--commonjs', 'Creates CommonJS module'); + .option('--commonjs', 'Creates CommonJS module') + .option('--transaction', 'Run deploy query in transaction'); program .command('deploy ') .description('Deploys model to database') .action(modelFolder => { - const { engine, server, user, password, database } = program.opts(); + const { engine, server, user, password, database, transaction } = program.opts(); // const hooks = []; // if (program.autoIndexForeignKeys) hooks.push(dbmodel.hooks.autoIndexForeignKeys); @@ -61,6 +62,7 @@ program database, }, modelFolder, + useTransaction: transaction, }) ); }); diff --git a/packages/types/test-engines.d.ts b/packages/types/test-engines.d.ts index 271c38bb6..3a86bfb11 100644 --- a/packages/types/test-engines.d.ts +++ b/packages/types/test-engines.d.ts @@ -51,6 +51,7 @@ export type TestEngineInfo = { alterTableAddColumnSyntax?: boolean; dbSnapshotBySeconds?: boolean; setNullDefaultInsteadOfDrop?: boolean; + runDeployInTransaction?: boolean; useTextTypeForStrings?: boolean;