From a9fb393e1a260a2dc26ef0f759f541fcde1c722f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Wed, 11 Jan 2023 18:29:31 +0100 Subject: [PATCH] fix: DB revert command shouldn't run full migrations before each revert (#5131) --- packages/cli/src/Db.ts | 102 +++++++++++-------------- packages/cli/src/commands/db/revert.ts | 25 ++---- 2 files changed, 53 insertions(+), 74 deletions(-) diff --git a/packages/cli/src/Db.ts b/packages/cli/src/Db.ts index f56929787e..1c1bad58d9 100644 --- a/packages/cli/src/Db.ts +++ b/packages/cli/src/Db.ts @@ -44,68 +44,57 @@ export function linkRepository( return getRepository(entityClass, connection.name); } +export async function getConnectionOptions(dbType: DatabaseType): Promise { + switch (dbType) { + case 'postgresdb': + const sslCa = (await GenericHelpers.getConfigValue('database.postgresdb.ssl.ca')) as string; + const sslCert = (await GenericHelpers.getConfigValue( + 'database.postgresdb.ssl.cert', + )) as string; + const sslKey = (await GenericHelpers.getConfigValue('database.postgresdb.ssl.key')) as string; + const sslRejectUnauthorized = (await GenericHelpers.getConfigValue( + 'database.postgresdb.ssl.rejectUnauthorized', + )) as boolean; + + let ssl: TlsOptions | undefined; + if (sslCa !== '' || sslCert !== '' || sslKey !== '' || !sslRejectUnauthorized) { + ssl = { + ca: sslCa || undefined, + cert: sslCert || undefined, + key: sslKey || undefined, + rejectUnauthorized: sslRejectUnauthorized, + }; + } + + return { + ...getPostgresConnectionOptions(), + ...(await getOptionOverrides('postgresdb')), + ssl, + }; + + case 'mariadb': + case 'mysqldb': + return { + ...(dbType === 'mysqldb' ? getMysqlConnectionOptions() : getMariaDBConnectionOptions()), + ...(await getOptionOverrides('mysqldb')), + timezone: 'Z', // set UTC as default + }; + + case 'sqlite': + return getSqliteConnectionOptions(); + + default: + throw new Error(`The database "${dbType}" is currently not supported!`); + } +} + export async function init( testConnectionOptions?: ConnectionOptions, ): Promise { if (isInitialized) return collections; const dbType = (await GenericHelpers.getConfigValue('database.type')) as DatabaseType; - - let connectionOptions: ConnectionOptions; - - const entityPrefix = config.getEnv('database.tablePrefix'); - - if (testConnectionOptions) { - connectionOptions = testConnectionOptions; - } else { - switch (dbType) { - case 'postgresdb': - const sslCa = (await GenericHelpers.getConfigValue('database.postgresdb.ssl.ca')) as string; - const sslCert = (await GenericHelpers.getConfigValue( - 'database.postgresdb.ssl.cert', - )) as string; - const sslKey = (await GenericHelpers.getConfigValue( - 'database.postgresdb.ssl.key', - )) as string; - const sslRejectUnauthorized = (await GenericHelpers.getConfigValue( - 'database.postgresdb.ssl.rejectUnauthorized', - )) as boolean; - - let ssl: TlsOptions | undefined; - if (sslCa !== '' || sslCert !== '' || sslKey !== '' || !sslRejectUnauthorized) { - ssl = { - ca: sslCa || undefined, - cert: sslCert || undefined, - key: sslKey || undefined, - rejectUnauthorized: sslRejectUnauthorized, - }; - } - - connectionOptions = { - ...getPostgresConnectionOptions(), - ...(await getOptionOverrides('postgresdb')), - ssl, - }; - - break; - - case 'mariadb': - case 'mysqldb': - connectionOptions = { - ...(dbType === 'mysqldb' ? getMysqlConnectionOptions() : getMariaDBConnectionOptions()), - ...(await getOptionOverrides('mysqldb')), - timezone: 'Z', // set UTC as default - }; - break; - - case 'sqlite': - connectionOptions = getSqliteConnectionOptions(); - break; - - default: - throw new Error(`The database "${dbType}" is currently not supported!`); - } - } + const connectionOptions = testConnectionOptions ?? (await getConnectionOptions(dbType)); let loggingOption: LoggerOptions = (await GenericHelpers.getConfigValue( 'database.logging.enabled', @@ -143,6 +132,7 @@ export async function init( // n8n knows it has changed. Happens only on sqlite. let migrations = []; try { + const entityPrefix = config.getEnv('database.tablePrefix'); migrations = await connection.query( `SELECT id FROM ${entityPrefix}migrations where name = "MakeStoppedAtNullable1607431743769"`, ); diff --git a/packages/cli/src/commands/db/revert.ts b/packages/cli/src/commands/db/revert.ts index 497dae6df1..888f6b2e48 100644 --- a/packages/cli/src/commands/db/revert.ts +++ b/packages/cli/src/commands/db/revert.ts @@ -5,8 +5,8 @@ import { Connection, ConnectionOptions, createConnection } from 'typeorm'; import { LoggerProxy } from 'n8n-workflow'; import { getLogger } from '@/Logger'; - -import * as Db from '@/Db'; +import { getConnectionOptions } from '@/Db'; +import config from '@/config'; export class DbRevertMigrationCommand extends Command { static description = 'Revert last database migration'; @@ -17,35 +17,24 @@ export class DbRevertMigrationCommand extends Command { help: flags.help({ char: 'h' }), }; - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types async run() { const logger = getLogger(); LoggerProxy.init(logger); - // eslint-disable-next-line @typescript-eslint/no-shadow, @typescript-eslint/no-unused-vars - const { flags } = this.parse(DbRevertMigrationCommand); + this.parse(DbRevertMigrationCommand); let connection: Connection | undefined; try { - await Db.init(); - connection = Db.collections.Credentials.manager.connection; - - if (!connection) { - throw new Error('No database connection available.'); - } - - const connectionOptions: ConnectionOptions = Object.assign(connection.options, { + const dbType = config.getEnv('database.type'); + const connectionOptions: ConnectionOptions = { + ...(await getConnectionOptions(dbType)), subscribers: [], synchronize: false, migrationsRun: false, dropSchema: false, logging: ['query', 'error', 'schema'], - }); - - // close connection in order to reconnect with updated options - await connection.close(); + }; connection = await createConnection(connectionOptions); - await connection.undoLastMigration(); await connection.close(); } catch (error) {