Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(core): Delete boilerplate code across migrations (no-changelog) #5254

Merged
merged 15 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/cli/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ module.exports = {
ignorePatterns: [
'jest.config.js',
// TODO: Remove these
'src/databases/migrations/**',
'src/databases/ormconfig.ts',
],

Expand Down
12 changes: 8 additions & 4 deletions packages/cli/src/Db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Container } from 'typedi';
import type { DataSourceOptions as ConnectionOptions, EntityManager, LoggerOptions } from 'typeorm';
import { DataSource as Connection } from 'typeorm';
import type { TlsOptions } from 'tls';
import type { DatabaseType, IDatabaseCollections } from '@/Interfaces';
import type { IDatabaseCollections } from '@/Interfaces';

import config from '@/config';

Expand All @@ -19,6 +19,8 @@ import {
getPostgresConnectionOptions,
getSqliteConnectionOptions,
} from '@db/config';
import { wrapMigration } from '@db/utils/migrationHelpers';
import type { DatabaseType, Migration } from '@db/types';
import {
AuthIdentityRepository,
AuthProviderSyncHistoryRepository,
Expand Down Expand Up @@ -118,7 +120,7 @@ export async function init(
synchronize: false,
logging: loggingOption,
maxQueryExecutionTime,
migrationsTransactionMode: 'each',
migrationsRun: false,
});

connection = new Connection(connectionOptions);
Expand All @@ -135,15 +137,17 @@ export async function init(
await connection.query(`SET search_path TO ${searchPath.join(',')};`);
}

(connectionOptions.migrations as Migration[]).forEach(wrapMigration);

if (!testConnectionOptions && dbType === 'sqlite') {
// This specific migration changes database metadata.
// A field is now nullable. We need to reconnect so that
// n8n knows it has changed. Happens only on sqlite.
let migrations = [];
try {
const entityPrefix = config.getEnv('database.tablePrefix');
const tablePrefix = config.getEnv('database.tablePrefix');
migrations = await connection.query(
`SELECT id FROM ${entityPrefix}migrations where name = "MakeStoppedAtNullable1607431743769"`,
`SELECT id FROM ${tablePrefix}migrations where name = "MakeStoppedAtNullable1607431743769"`,
);
} catch (error) {
// Migration table does not exist yet - it will be created after migrations run for the first time.
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/Interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import type { FindOperator } from 'typeorm';

import type { ChildProcess } from 'child_process';

import type { DatabaseType } from '@db/types';
import type { AuthProviderType } from '@db/entities/AuthIdentity';
import type { Role } from '@db/entities/Role';
import type { SharedCredentials } from '@db/entities/SharedCredentials';
Expand Down Expand Up @@ -160,7 +161,6 @@ export type ICredentialsDecryptedDb = ICredentialsBase & ICredentialsDecrypted;

export type ICredentialsDecryptedResponse = ICredentialsDecryptedDb;

export type DatabaseType = 'mariadb' | 'postgresdb' | 'mysqldb' | 'sqlite';
export type SaveExecutionDataType = 'all' | 'none';

export interface IExecutionBase {
Expand Down
3 changes: 1 addition & 2 deletions packages/cli/src/databases/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { entities } from './entities';
import { mysqlMigrations } from './migrations/mysqldb';
import { postgresMigrations } from './migrations/postgresdb';
import { sqliteMigrations } from './migrations/sqlite';
import type { DatabaseType } from '@/Interfaces';
import type { DatabaseType } from '@db/types';
import config from '@/config';

const entitiesDir = path.resolve(__dirname, 'entities');
Expand All @@ -35,7 +35,6 @@ const getDBConnectionOptions = (dbType: DatabaseType) => {
return {
entityPrefix,
entities: Object.values(entities),
migrationsRun: false,
migrationsTableName: `${entityPrefix}migrations`,
cli: { entitiesDir, migrationsDir },
...connectionDetails,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,45 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

import config from '@/config';
import type { MigrationContext, MigrationInterface } from '@db/types';

export class InitialMigration1588157391238 implements MigrationInterface {
name = 'InitialMigration1588157391238';

async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'CREATE TABLE IF NOT EXISTS `' +
tablePrefix +
'credentials_entity` (`id` int NOT NULL AUTO_INCREMENT, `name` varchar(128) NOT NULL, `data` text NOT NULL, `type` varchar(32) NOT NULL, `nodesAccess` json NOT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, INDEX `IDX_' +
tablePrefix +
'07fde106c0b471d8cc80a64fc8` (`type`), PRIMARY KEY (`id`)) ENGINE=InnoDB',
undefined,
);
await queryRunner.query(
'CREATE TABLE IF NOT EXISTS `' +
tablePrefix +
'execution_entity` (`id` int NOT NULL AUTO_INCREMENT, `data` text NOT NULL, `finished` tinyint NOT NULL, `mode` varchar(255) NOT NULL, `retryOf` varchar(255) NULL, `retrySuccessId` varchar(255) NULL, `startedAt` datetime NOT NULL, `stoppedAt` datetime NOT NULL, `workflowData` json NOT NULL, `workflowId` varchar(255) NULL, INDEX `IDX_' +
tablePrefix +
'c4d999a5e90784e8caccf5589d` (`workflowId`), PRIMARY KEY (`id`)) ENGINE=InnoDB',
undefined,
);
await queryRunner.query(
'CREATE TABLE IF NOT EXISTS`' +
tablePrefix +
'workflow_entity` (`id` int NOT NULL AUTO_INCREMENT, `name` varchar(128) NOT NULL, `active` tinyint NOT NULL, `nodes` json NOT NULL, `connections` json NOT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, `settings` json NULL, `staticData` json NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB',
undefined,
);
}

async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

await queryRunner.query('DROP TABLE `' + tablePrefix + 'workflow_entity`', undefined);
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query('DROP TABLE `' + tablePrefix + 'workflow_entity`');
netroy marked this conversation as resolved.
Show resolved Hide resolved
await queryRunner.query(
'DROP INDEX `IDX_' +
tablePrefix +
'c4d999a5e90784e8caccf5589d` ON `' +
tablePrefix +
'execution_entity`',
undefined,
);
await queryRunner.query('DROP TABLE `' + tablePrefix + 'execution_entity`', undefined);
await queryRunner.query('DROP TABLE `' + tablePrefix + 'execution_entity`');
await queryRunner.query(
'DROP INDEX `IDX_' +
tablePrefix +
'07fde106c0b471d8cc80a64fc8` ON `' +
tablePrefix +
'credentials_entity`',
undefined,
);
await queryRunner.query('DROP TABLE `' + tablePrefix + 'credentials_entity`', undefined);
await queryRunner.query('DROP TABLE `' + tablePrefix + 'credentials_entity`');
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

import config from '@/config';
import type { MigrationContext, MigrationInterface } from '@db/types';

export class WebhookModel1592447867632 implements MigrationInterface {
name = 'WebhookModel1592447867632';

async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS ${tablePrefix}webhook_entity (workflowId int NOT NULL, webhookPath varchar(255) NOT NULL, method varchar(255) NOT NULL, node varchar(255) NOT NULL, PRIMARY KEY (webhookPath, method)) ENGINE=InnoDB`,
);
}

async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
ivov marked this conversation as resolved.
Show resolved Hide resolved
await queryRunner.query(`DROP TABLE ${tablePrefix}webhook_entity`);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

import config from '@/config';
import type { MigrationContext, MigrationInterface } from '@db/types';

export class CreateIndexStoppedAt1594902918301 implements MigrationInterface {
name = 'CreateIndexStoppedAt1594902918301';

async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'CREATE INDEX `IDX_' +
tablePrefix +
Expand All @@ -17,9 +11,7 @@ export class CreateIndexStoppedAt1594902918301 implements MigrationInterface {
);
}

async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'DROP INDEX `IDX_' +
tablePrefix +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

import config from '@/config';
import type { MigrationContext, MigrationInterface } from '@db/types';

export class MakeStoppedAtNullable1607431743767 implements MigrationInterface {
async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'ALTER TABLE `' + tablePrefix + 'execution_entity` MODIFY `stoppedAt` datetime',
undefined,
);
}

async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'ALTER TABLE `' + tablePrefix + 'execution_entity` MODIFY `stoppedAt` datetime NOT NULL',
undefined,
);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import type { MigrationContext, MigrationInterface } from '@db/types';

export class AddWebhookId1611149998770 implements MigrationInterface {
name = 'AddWebhookId1611149998770';

async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'ALTER TABLE `' + tablePrefix + 'webhook_entity` ADD `webhookId` varchar(255) NULL',
);
Expand All @@ -22,9 +17,7 @@ export class AddWebhookId1611149998770 implements MigrationInterface {
);
}

async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'DROP INDEX `IDX_' +
tablePrefix +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import type { MigrationContext, MigrationInterface } from '@db/types';

export class ChangeDataSize1615306975123 implements MigrationInterface {
name = 'ChangeDataSize1615306975123';

async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'ALTER TABLE `' + tablePrefix + 'execution_entity` MODIFY COLUMN `data` MEDIUMTEXT NOT NULL',
);
}

async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'ALTER TABLE `' + tablePrefix + 'execution_entity` MODIFY COLUMN `data` TEXT NOT NULL',
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import type { MigrationContext, MigrationInterface } from '@db/types';

export class CreateTagEntity1617268711084 implements MigrationInterface {
name = 'CreateTagEntity1617268711084';

async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async up({ queryRunner, tablePrefix }: MigrationContext) {
// create tags table + relationship with workflow entity

await queryRunner.query(
Expand Down Expand Up @@ -78,9 +73,7 @@ export class CreateTagEntity1617268711084 implements MigrationInterface {
);
}

async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async down({ queryRunner, tablePrefix }: MigrationContext) {
// `createdAt` and `updatedAt`

await queryRunner.query(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import type { MigrationContext, MigrationInterface } from '@db/types';

export class ChangeCredentialDataSize1620729500000 implements MigrationInterface {
name = 'ChangeCredentialDataSize1620729500000';

async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'ALTER TABLE `' +
tablePrefix +
'credentials_entity` MODIFY COLUMN `type` varchar(128) NOT NULL',
);
}

async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');

async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
'ALTER TABLE `' +
tablePrefix +
Expand Down
Loading