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

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-05-05 09:28:59 +00:00
committed by GitHub
parent d5c44987f4
commit 82fe6383ef
122 changed files with 879 additions and 1844 deletions

View File

@@ -1,46 +1,29 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class InitialMigration1588102412422 implements MigrationInterface {
name = 'InitialMigration1588102412422';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class InitialMigration1588102412422 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS "${tablePrefix}credentials_entity" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(128) NOT NULL, "data" text NOT NULL, "type" varchar(128) NOT NULL, "nodesAccess" text NOT NULL, "createdAt" datetime NOT NULL, "updatedAt" datetime NOT NULL)`,
undefined,
);
await queryRunner.query(
`CREATE INDEX IF NOT EXISTS "IDX_${tablePrefix}07fde106c0b471d8cc80a64fc8" ON "${tablePrefix}credentials_entity" ("type") `,
undefined,
);
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS "${tablePrefix}execution_entity" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "data" text NOT NULL, "finished" boolean NOT NULL, "mode" varchar NOT NULL, "retryOf" varchar, "retrySuccessId" varchar, "startedAt" datetime NOT NULL, "stoppedAt" datetime NOT NULL, "workflowData" text NOT NULL, "workflowId" varchar)`,
undefined,
);
await queryRunner.query(
`CREATE INDEX IF NOT EXISTS "IDX_${tablePrefix}c4d999a5e90784e8caccf5589d" ON "${tablePrefix}execution_entity" ("workflowId") `,
undefined,
);
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS "${tablePrefix}workflow_entity" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(128) NOT NULL, "active" boolean NOT NULL, "nodes" text NOT NULL, "connections" text NOT NULL, "createdAt" datetime NOT NULL, "updatedAt" datetime NOT NULL, "settings" text, "staticData" text)`,
undefined,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
await queryRunner.query(`DROP TABLE "${tablePrefix}workflow_entity"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_${tablePrefix}c4d999a5e90784e8caccf5589d"`, undefined);
await queryRunner.query(`DROP TABLE "${tablePrefix}execution_entity"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_${tablePrefix}07fde106c0b471d8cc80a64fc8"`, undefined);
await queryRunner.query(`DROP TABLE "${tablePrefix}credentials_entity"`, undefined);
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE "${tablePrefix}workflow_entity"`);
await queryRunner.query(`DROP INDEX "IDX_${tablePrefix}c4d999a5e90784e8caccf5589d"`);
await queryRunner.query(`DROP TABLE "${tablePrefix}execution_entity"`);
await queryRunner.query(`DROP INDEX "IDX_${tablePrefix}07fde106c0b471d8cc80a64fc8"`);
await queryRunner.query(`DROP TABLE "${tablePrefix}credentials_entity"`);
}
}

View File

@@ -1,24 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class WebhookModel1592445003908 implements MigrationInterface {
name = 'WebhookModel1592445003908';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class WebhookModel1592445003908 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS ${tablePrefix}webhook_entity ("workflowId" integer NOT NULL, "webhookPath" varchar NOT NULL, "method" varchar NOT NULL, "node" varchar NOT NULL, PRIMARY KEY ("webhookPath", "method"))`,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE ${tablePrefix}webhook_entity`);
}
}

View File

@@ -1,25 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CreateIndexStoppedAt1594825041918 implements MigrationInterface {
name = 'CreateIndexStoppedAt1594825041918';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class CreateIndexStoppedAt1594825041918 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE INDEX "IDX_${tablePrefix}cefb067df2402f6aed0638a6c1" ON "${tablePrefix}execution_entity" ("stoppedAt") `,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP INDEX "IDX_${tablePrefix}cefb067df2402f6aed0638a6c1"`);
}
}

View File

@@ -1,30 +1,16 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import type { MigrationContext, IrreversibleMigration } from '@db/types';
export class MakeStoppedAtNullable1607431743769 implements MigrationInterface {
name = 'MakeStoppedAtNullable1607431743769';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
export class MakeStoppedAtNullable1607431743769 implements IrreversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
// SQLite does not allow us to simply "alter column"
// We're hacking the way sqlite identifies tables
// Allowing a column to become nullable
// This is a very strict case when this can be done safely
// As no collateral effects exist.
await queryRunner.query(`PRAGMA writable_schema = 1; `, undefined);
await queryRunner.query('PRAGMA writable_schema = 1;');
await queryRunner.query(
`UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE IF NOT EXISTS "${tablePrefix}execution_entity" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "data" text NOT NULL, "finished" boolean NOT NULL, "mode" varchar NOT NULL, "retryOf" varchar, "retrySuccessId" varchar, "startedAt" datetime NOT NULL, "stoppedAt" datetime, "workflowData" text NOT NULL, "workflowId" varchar)' WHERE NAME = "${tablePrefix}execution_entity";`,
undefined,
);
await queryRunner.query(`PRAGMA writable_schema = 0;`, undefined);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
// This cannot be undone as the table might already have nullable values
await queryRunner.query('PRAGMA writable_schema = 0;');
}
}

View File

@@ -1,17 +1,9 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class AddWebhookId1611071044839 implements MigrationInterface {
name = 'AddWebhookId1611071044839';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class AddWebhookId1611071044839 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE "temporary_webhook_entity" ("workflowId" integer NOT NULL, "webhookPath" varchar NOT NULL, "method" varchar NOT NULL, "node" varchar NOT NULL, "webhookId" varchar, "pathLength" integer, PRIMARY KEY ("webhookPath", "method"))`,
'CREATE TABLE "temporary_webhook_entity" ("workflowId" integer NOT NULL, "webhookPath" varchar NOT NULL, "method" varchar NOT NULL, "node" varchar NOT NULL, "webhookId" varchar, "pathLength" integer, PRIMARY KEY ("webhookPath", "method"))',
);
await queryRunner.query(
`INSERT INTO "temporary_webhook_entity"("workflowId", "webhookPath", "method", "node") SELECT "workflowId", "webhookPath", "method", "node" FROM "${tablePrefix}webhook_entity"`,
@@ -23,13 +15,9 @@ export class AddWebhookId1611071044839 implements MigrationInterface {
await queryRunner.query(
`CREATE INDEX "IDX_${tablePrefix}742496f199721a057051acf4c2" ON "${tablePrefix}webhook_entity" ("webhookId", "method", "pathLength") `,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP INDEX "IDX_${tablePrefix}742496f199721a057051acf4c2"`);
await queryRunner.query(
`ALTER TABLE "${tablePrefix}webhook_entity" RENAME TO "temporary_webhook_entity"`,
@@ -40,6 +28,6 @@ export class AddWebhookId1611071044839 implements MigrationInterface {
await queryRunner.query(
`INSERT INTO "${tablePrefix}webhook_entity"("workflowId", "webhookPath", "method", "node") SELECT "workflowId", "webhookPath", "method", "node" FROM "temporary_webhook_entity"`,
);
await queryRunner.query(`DROP TABLE "temporary_webhook_entity"`);
await queryRunner.query('DROP TABLE "temporary_webhook_entity"');
}
}

View File

@@ -1,15 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CreateTagEntity1617213344594 implements MigrationInterface {
name = 'CreateTagEntity1617213344594';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class CreateTagEntity1617213344594 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
// create tags table + relationship with workflow entity
await queryRunner.query(
@@ -68,13 +60,9 @@ export class CreateTagEntity1617213344594 implements MigrationInterface {
await queryRunner.query(
`ALTER TABLE "${tablePrefix}temporary_workflow_entity" RENAME TO "${tablePrefix}workflow_entity"`,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
// `createdAt` and `updatedAt`
await queryRunner.query(

View File

@@ -1,19 +1,11 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class UniqueWorkflowNames1620821879465 implements MigrationInterface {
name = 'UniqueWorkflowNames1620821879465';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
const workflowNames = await queryRunner.query(`
SELECT name
FROM "${tablePrefix}workflow_entity"
`);
export class UniqueWorkflowNames1620821879465 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
const workflowNames = (await queryRunner.query(`
SELECT name
FROM "${tablePrefix}workflow_entity"
`)) as Array<{ name: string }>;
for (const { name } of workflowNames) {
const [duplicatesQuery, parameters] = queryRunner.connection.driver.escapeQueryWithParameters(
@@ -27,12 +19,16 @@ export class UniqueWorkflowNames1620821879465 implements MigrationInterface {
{},
);
const duplicates = await queryRunner.query(duplicatesQuery, parameters);
const duplicates = (await queryRunner.query(duplicatesQuery, parameters)) as Array<{
id: number;
name: string;
}>;
if (duplicates.length > 1) {
await Promise.all(
duplicates.map(({ id, name }: { id: number; name: string }, index: number) => {
if (index === 0) return Promise.resolve();
// eslint-disable-next-line @typescript-eslint/no-shadow
duplicates.map(async ({ id, name }, index: number) => {
if (index === 0) return;
const [updateQuery, updateParams] =
queryRunner.connection.driver.escapeQueryWithParameters(
`
@@ -53,12 +49,9 @@ export class UniqueWorkflowNames1620821879465 implements MigrationInterface {
await queryRunner.query(
`CREATE UNIQUE INDEX "IDX_${tablePrefix}943d8f922be094eb507cb9a7f9" ON "${tablePrefix}workflow_entity" ("name") `,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP INDEX "IDX_${tablePrefix}943d8f922be094eb507cb9a7f9"`);
}
}

View File

@@ -1,19 +1,10 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class AddWaitColumn1621707690587 implements MigrationInterface {
name = 'AddWaitColumn1621707690587';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class AddWaitColumn1621707690587 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE IF EXISTS "${tablePrefix}temporary_execution_entity"`);
await queryRunner.query(
`CREATE TABLE "${tablePrefix}temporary_execution_entity" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "data" text NOT NULL, "finished" boolean NOT NULL, "mode" varchar NOT NULL, "retryOf" varchar, "retrySuccessId" varchar, "startedAt" datetime NOT NULL, "stoppedAt" datetime, "workflowData" text NOT NULL, "workflowId" varchar, "waitTill" DATETIME)`,
undefined,
);
await queryRunner.query(
`INSERT INTO "${tablePrefix}temporary_execution_entity"("id", "data", "finished", "mode", "retryOf", "retrySuccessId", "startedAt", "stoppedAt", "workflowData", "workflowId") SELECT "id", "data", "finished", "mode", "retryOf", "retrySuccessId", "startedAt", "stoppedAt", "workflowData", "workflowId" FROM "${tablePrefix}execution_entity"`,
@@ -28,16 +19,11 @@ export class AddWaitColumn1621707690587 implements MigrationInterface {
await queryRunner.query(
`CREATE INDEX "IDX_${tablePrefix}ca4a71b47f28ac6ea88293a8e2" ON "${tablePrefix}execution_entity" ("waitTill")`,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS "${tablePrefix}temporary_execution_entity" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "data" text NOT NULL, "finished" boolean NOT NULL, "mode" varchar NOT NULL, "retryOf" varchar, "retrySuccessId" varchar, "startedAt" datetime NOT NULL, "stoppedAt" datetime, "workflowData" text NOT NULL, "workflowId" varchar)`,
undefined,
);
await queryRunner.query(
`INSERT INTO "${tablePrefix}temporary_execution_entity"("id", "data", "finished", "mode", "retryOf", "retrySuccessId", "startedAt", "stoppedAt", "workflowData", "workflowId") SELECT "id", "data", "finished", "mode", "retryOf", "retrySuccessId", "startedAt", "stoppedAt", "workflowData", "workflowId" FROM "${tablePrefix}execution_entity"`,

View File

@@ -1,23 +1,22 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
/* eslint-disable n8n-local-rules/no-uncaught-json-parse */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import type { MigrationContext, ReversibleMigration } from '@db/types';
import { runInBatches } from '@db/utils/migrationHelpers';
// replacing the credentials in workflows and execution
// `nodeType: name` changes to `nodeType: { id, name }`
export class UpdateWorkflowCredentials1630330987096 implements MigrationInterface {
name = 'UpdateWorkflowCredentials1630330987096';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
const credentialsEntities = await queryRunner.query(`
export class UpdateWorkflowCredentials1630330987096 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
const credentialsEntities = (await queryRunner.query(`
SELECT id, name, type
FROM "${tablePrefix}credentials_entity"
`);
`)) as Array<{ id: string; name: string; type: string }>;
const workflowsQuery = `
SELECT id, nodes
@@ -57,7 +56,7 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
{},
);
queryRunner.query(updateQuery, updateParams);
await queryRunner.query(updateQuery, updateParams);
}
});
});
@@ -100,7 +99,7 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
{},
);
queryRunner.query(updateQuery, updateParams);
await queryRunner.query(updateQuery, updateParams);
}
});
});
@@ -143,20 +142,16 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
{},
);
queryRunner.query(updateQuery, updateParams);
await queryRunner.query(updateQuery, updateParams);
}
});
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
const credentialsEntities = await queryRunner.query(`
async down({ queryRunner, tablePrefix }: MigrationContext) {
const credentialsEntities = (await queryRunner.query(`
SELECT id, name, type
FROM "${tablePrefix}credentials_entity"
`);
`)) as Array<{ id: string; name: string; type: string }>;
const workflowsQuery = `
SELECT id, nodes
@@ -176,7 +171,9 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
for (const [type, creds] of allNodeCredentials) {
if (typeof creds === 'object') {
const matchingCredentials = credentialsEntities.find(
// @ts-ignore double-equals because creds.id can be string or number
// @ts-ignore
// double-equals because creds.id can be string or number
// eslint-disable-next-line eqeqeq
(credentials) => credentials.id == creds.id && credentials.type === type,
);
if (matchingCredentials) {
@@ -202,7 +199,7 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
{},
);
queryRunner.query(updateQuery, updateParams);
await queryRunner.query(updateQuery, updateParams);
}
});
});
@@ -226,7 +223,9 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
for (const [type, creds] of allNodeCredentials) {
if (typeof creds === 'object') {
const matchingCredentials = credentialsEntities.find(
// @ts-ignore double-equals because creds.id can be string or number
// @ts-ignore
// double-equals because creds.id can be string or number
// eslint-disable-next-line eqeqeq
(credentials) => credentials.id == creds.id && credentials.type === type,
);
if (matchingCredentials) {
@@ -276,7 +275,9 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
for (const [type, creds] of allNodeCredentials) {
if (typeof creds === 'object') {
const matchingCredentials = credentialsEntities.find(
// @ts-ignore double-equals because creds.id can be string or number
// @ts-ignore
// double-equals because creds.id can be string or number
// eslint-disable-next-line eqeqeq
(credentials) => credentials.id == creds.id && credentials.type === type,
);
if (matchingCredentials) {
@@ -301,7 +302,7 @@ export class UpdateWorkflowCredentials1630330987096 implements MigrationInterfac
{},
);
queryRunner.query(updateQuery, updateParams);
await queryRunner.query(updateQuery, updateParams);
}
});
}

View File

@@ -1,14 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class AddExecutionEntityIndexes1644421939510 implements MigrationInterface {
name = 'AddExecutionEntityIndexes1644421939510';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class AddExecutionEntityIndexes1644421939510 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP INDEX IF EXISTS 'IDX_${tablePrefix}c4d999a5e90784e8caccf5589d'`);
await queryRunner.query(`DROP INDEX IF EXISTS 'IDX_${tablePrefix}ca4a71b47f28ac6ea88293a8e2'`);
@@ -28,12 +21,9 @@ export class AddExecutionEntityIndexes1644421939510 implements MigrationInterfac
await queryRunner.query(
`CREATE INDEX IF NOT EXISTS 'IDX_${tablePrefix}81fc04c8a17de15835713505e4' ON '${tablePrefix}execution_entity' ('workflowId', 'id') `,
);
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP INDEX 'IDX_${tablePrefix}81fc04c8a17de15835713505e4'`);
await queryRunner.query(`DROP INDEX 'IDX_${tablePrefix}b94b45ce2c73ce46c54f20b5f9'`);
await queryRunner.query(`DROP INDEX 'IDX_${tablePrefix}1688846335d274033e15c846a4'`);

View File

@@ -1,16 +1,9 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import type { InsertResult, MigrationContext, ReversibleMigration } from '@db/types';
import { v4 as uuid } from 'uuid';
import config from '@/config';
import { loadSurveyFromDisk, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CreateUserManagement1646992772331 implements MigrationInterface {
name = 'CreateUserManagement1646992772331';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import { loadSurveyFromDisk } from '@db/utils/migrationHelpers';
export class CreateUserManagement1646992772331 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE "${tablePrefix}role" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(32) NOT NULL, "scope" varchar NOT NULL, "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), CONSTRAINT "UQ_${tablePrefix}5b49d0f504f7ef31045a1fb2eb8" UNIQUE ("scope", "name"))`,
);
@@ -49,7 +42,9 @@ export class CreateUserManagement1646992772331 implements MigrationInterface {
VALUES ("owner", "global");
`);
const instanceOwnerRole = await queryRunner.query('SELECT last_insert_rowid() as insertId');
const instanceOwnerRole = (await queryRunner.query(
'SELECT last_insert_rowid() as insertId',
)) as InsertResult;
await queryRunner.query(`
INSERT INTO "${tablePrefix}role" (name, scope)
@@ -61,14 +56,18 @@ export class CreateUserManagement1646992772331 implements MigrationInterface {
VALUES ("owner", "workflow");
`);
const workflowOwnerRole = await queryRunner.query('SELECT last_insert_rowid() as insertId');
const workflowOwnerRole = (await queryRunner.query(
'SELECT last_insert_rowid() as insertId',
)) as InsertResult;
await queryRunner.query(`
INSERT INTO "${tablePrefix}role" (name, scope)
VALUES ("owner", "credential");
`);
const credentialOwnerRole = await queryRunner.query('SELECT last_insert_rowid() as insertId');
const credentialOwnerRole = (await queryRunner.query(
'SELECT last_insert_rowid() as insertId',
)) as InsertResult;
const survey = loadSurveyFromDisk();
@@ -95,12 +94,9 @@ export class CreateUserManagement1646992772331 implements MigrationInterface {
INSERT INTO "${tablePrefix}settings" (key, value, loadOnStartup) values
('userManagement.isInstanceOwnerSetUp', 'false', true), ('userManagement.skipInstanceOwnerSetup', 'false', true)
`);
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE UNIQUE INDEX "IDX_${tablePrefix}943d8f922be094eb507cb9a7f9" ON "${tablePrefix}workflow_entity" ("name") `,
);

View File

@@ -1,22 +1,10 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class LowerCaseUserEmail1648740597343 implements MigrationInterface {
name = 'LowerCaseUserEmail1648740597343';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, IrreversibleMigration } from '@db/types';
export class LowerCaseUserEmail1648740597343 implements IrreversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`
UPDATE "${tablePrefix}user"
SET email = LOWER(email);
`);
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {}
}

View File

@@ -1,42 +1,32 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CommunityNodes1652254514001 implements MigrationInterface {
name = 'CommunityNodes1652254514001';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.get('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class CommunityNodes1652254514001 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE "${tablePrefix}installed_packages" (` +
`"packageName" char(214) NOT NULL,` +
`"installedVersion" char(50) NOT NULL,` +
`"authorName" char(70) NULL,` +
`"authorEmail" char(70) NULL,` +
`"createdAt" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')',` +
`"updatedAt" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')',` +
`PRIMARY KEY("packageName")` +
`);`,
'"packageName" char(214) NOT NULL,' +
'"installedVersion" char(50) NOT NULL,' +
'"authorName" char(70) NULL,' +
'"authorEmail" char(70) NULL,' +
"\"createdAt\" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'," +
"\"updatedAt\" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'," +
'PRIMARY KEY("packageName")' +
');',
);
await queryRunner.query(
`CREATE TABLE "${tablePrefix}installed_nodes" (` +
`"name" char(200) NOT NULL,` +
`"type" char(200) NOT NULL,` +
`"latestVersion" INTEGER DEFAULT 1,` +
`"package" char(214) NOT NULL,` +
`PRIMARY KEY("name"),` +
'"name" char(200) NOT NULL,' +
'"type" char(200) NOT NULL,' +
'"latestVersion" INTEGER DEFAULT 1,' +
'"package" char(214) NOT NULL,' +
'PRIMARY KEY("name"),' +
`FOREIGN KEY("package") REFERENCES "${tablePrefix}installed_packages"("packageName") ON DELETE CASCADE ON UPDATE CASCADE` +
`);`,
');',
);
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.get('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE "${tablePrefix}installed_nodes"`);
await queryRunner.query(`DROP TABLE "${tablePrefix}installed_packages"`);
}

View File

@@ -1,17 +1,9 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class AddUserSettings1652367743993 implements MigrationInterface {
name = 'AddUserSettings1652367743993';
transaction = false;
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
export class AddUserSettings1652367743993 implements ReversibleMigration {
transaction = false as const;
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query('PRAGMA foreign_keys=OFF');
await queryRunner.query(
@@ -28,13 +20,9 @@ export class AddUserSettings1652367743993 implements MigrationInterface {
);
await queryRunner.query('PRAGMA foreign_keys=ON');
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`ALTER TABLE "${tablePrefix}user" RENAME TO "temporary_user"`);
await queryRunner.query(
`CREATE TABLE "${tablePrefix}user" ("id" varchar PRIMARY KEY NOT NULL, "email" varchar(255), "firstName" varchar(32), "lastName" varchar(32), "password" varchar, "resetPasswordToken" varchar, "resetPasswordTokenExpiration" integer DEFAULT NULL, "personalizationAnswers" text, "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "globalRoleId" integer NOT NULL, CONSTRAINT "FK_${tablePrefix}f0609be844f9200ff4365b1bb3d" FOREIGN KEY ("globalRoleId") REFERENCES "${tablePrefix}role" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`,
@@ -42,7 +30,7 @@ export class AddUserSettings1652367743993 implements MigrationInterface {
await queryRunner.query(
`INSERT INTO "${tablePrefix}user"("id", "email", "firstName", "lastName", "password", "resetPasswordToken", "resetPasswordTokenExpiration", "personalizationAnswers", "createdAt", "updatedAt", "globalRoleId") SELECT "id", "email", "firstName", "lastName", "password", "resetPasswordToken", "resetPasswordTokenExpiration", "personalizationAnswers", "createdAt", "updatedAt", "globalRoleId" FROM "temporary_user"`,
);
await queryRunner.query(`DROP TABLE "temporary_user"`);
await queryRunner.query('DROP TABLE "temporary_user"');
await queryRunner.query(
`CREATE UNIQUE INDEX "UQ_${tablePrefix}e12875dfb3b1d92d7d7c5377e2" ON "${tablePrefix}user" ("email")`,
);

View File

@@ -1,17 +1,9 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class AddAPIKeyColumn1652905585850 implements MigrationInterface {
name = 'AddAPIKeyColumn1652905585850';
transaction = false;
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
export class AddAPIKeyColumn1652905585850 implements ReversibleMigration {
transaction = false as const;
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query('PRAGMA foreign_keys=OFF');
await queryRunner.query(
@@ -31,13 +23,9 @@ export class AddAPIKeyColumn1652905585850 implements MigrationInterface {
);
await queryRunner.query('PRAGMA foreign_keys=ON');
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`ALTER TABLE "${tablePrefix}user" RENAME TO "temporary_user"`);
await queryRunner.query(
`CREATE TABLE "${tablePrefix}user" ("id" varchar PRIMARY KEY NOT NULL, "email" varchar(255), "firstName" varchar(32), "lastName" varchar(32), "password" varchar, "resetPasswordToken" varchar, "resetPasswordTokenExpiration" integer DEFAULT NULL, "personalizationAnswers" text, "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "globalRoleId" integer NOT NULL, "settings" text, CONSTRAINT "FK_${tablePrefix}f0609be844f9200ff4365b1bb3d" FOREIGN KEY ("globalRoleId") REFERENCES "${tablePrefix}role" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`,
@@ -45,7 +33,7 @@ export class AddAPIKeyColumn1652905585850 implements MigrationInterface {
await queryRunner.query(
`INSERT INTO "${tablePrefix}user"("id", "email", "firstName", "lastName", "password", "resetPasswordToken", "resetPasswordTokenExpiration", "personalizationAnswers", "createdAt", "updatedAt", "globalRoleId", "settings") SELECT "id", "email", "firstName", "lastName", "password", "resetPasswordToken", "resetPasswordTokenExpiration", "personalizationAnswers", "createdAt", "updatedAt", "globalRoleId", "settings" FROM "temporary_user"`,
);
await queryRunner.query(`DROP TABLE "temporary_user"`);
await queryRunner.query('DROP TABLE "temporary_user"');
await queryRunner.query(
`CREATE UNIQUE INDEX "UQ_${tablePrefix}e12875dfb3b1d92d7d7c5377e2" ON "${tablePrefix}user" ("email")`,
);

View File

@@ -1,25 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import config from '@/config';
export class IntroducePinData1654089251344 implements MigrationInterface {
name = 'IntroducePinData1654089251344';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class IntroducePinData1654089251344 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` ADD COLUMN "pinData" text`,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` RENAME TO "temporary_workflow_entity"`,
);
@@ -30,6 +18,6 @@ export class IntroducePinData1654089251344 implements MigrationInterface {
await queryRunner.query(
`INSERT INTO \`${tablePrefix}workflow_entity\` ("id", "name", "active", "nodes", "connections", "createdAt", "updatedAt", "settings", "staticData") SELECT "id", "name", "active", "nodes", "connections", "createdAt", "updatedAt", "settings", "staticData" FROM "temporary_workflow_entity"`,
);
await queryRunner.query(`DROP TABLE "temporary_workflow_entity"`);
await queryRunner.query('DROP TABLE "temporary_workflow_entity"');
}
}

View File

@@ -1,20 +1,18 @@
import { INode } from 'n8n-workflow';
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable n8n-local-rules/no-uncaught-json-parse */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import type { INode } from 'n8n-workflow';
import type { MigrationContext, ReversibleMigration } from '@db/types';
import { runInBatches } from '@db/utils/migrationHelpers';
import { v4 as uuid } from 'uuid';
// add node ids in workflow objects
export class AddNodeIds1658930531669 implements MigrationInterface {
name = 'AddNodeIds1658930531669';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
export class AddNodeIds1658930531669 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
const workflowsQuery = `
SELECT id, nodes
FROM "${tablePrefix}workflow_entity"
@@ -40,16 +38,12 @@ export class AddNodeIds1658930531669 implements MigrationInterface {
{},
);
queryRunner.query(updateQuery, updateParams);
await queryRunner.query(updateQuery, updateParams);
});
});
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
const workflowsQuery = `
SELECT id, nodes
FROM "${tablePrefix}workflow_entity"
@@ -72,7 +66,7 @@ export class AddNodeIds1658930531669 implements MigrationInterface {
{},
);
queryRunner.query(updateQuery, updateParams);
await queryRunner.query(updateQuery, updateParams);
});
});
}

View File

@@ -1,24 +1,17 @@
import {
logMigrationStart,
logMigrationEnd,
runInBatches,
getTablePrefix,
escapeQuery,
} from '@db/utils/migrationHelpers';
import type { MigrationInterface, QueryRunner } from 'typeorm';
import { isJsonKeyObject, PinData } from '@db/utils/migrations.types';
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-use-before-define */
import type { IDataObject, INodeExecutionData } from 'n8n-workflow';
import type { MigrationContext, IrreversibleMigration } from '@db/types';
import { runInBatches, escapeQuery } from '@db/utils/migrationHelpers';
/**
* Convert TEXT-type `pinData` column in `workflow_entity` table from
* `{ [nodeName: string]: IDataObject[] }` to `{ [nodeName: string]: INodeExecutionData[] }`
*/
export class AddJsonKeyPinData1659888469333 implements MigrationInterface {
name = 'AddJsonKeyPinData1659888469333';
async up(queryRunner: QueryRunner) {
logMigrationStart(this.name);
const workflowTable = `${getTablePrefix()}workflow_entity`;
export class AddJsonKeyPinData1659888469333 implements IrreversibleMigration {
async up(context: MigrationContext) {
const { queryRunner, tablePrefix } = context;
const workflowTable = `${tablePrefix}workflow_entity`;
const PINDATA_SELECT_QUERY = `
SELECT id, pinData
@@ -35,30 +28,45 @@ export class AddJsonKeyPinData1659888469333 implements MigrationInterface {
await runInBatches(
queryRunner,
PINDATA_SELECT_QUERY,
addJsonKeyToPinDataColumn(queryRunner, PINDATA_UPDATE_STATEMENT),
addJsonKeyToPinDataColumn(context, PINDATA_UPDATE_STATEMENT),
);
logMigrationEnd(this.name);
}
async down() {
// irreversible migration
}
}
namespace PinData {
export type Old = { [nodeName: string]: IDataObject[] };
export type New = { [nodeName: string]: INodeExecutionData[] };
export type FetchedWorkflow = { id: number; pinData: string | Old };
}
function isObjectLiteral(maybeObject: unknown): maybeObject is { [key: string]: string } {
return typeof maybeObject === 'object' && maybeObject !== null && !Array.isArray(maybeObject);
}
function isJsonKeyObject(item: unknown): item is {
json: unknown;
[keys: string]: unknown;
} {
if (!isObjectLiteral(item)) return false;
return Object.keys(item).includes('json');
}
export const addJsonKeyToPinDataColumn =
(queryRunner: QueryRunner, updateStatement: string) =>
({ queryRunner }: MigrationContext, updateStatement: string) =>
async (fetchedWorkflows: PinData.FetchedWorkflow[]) => {
makeUpdateParams(fetchedWorkflows).forEach((param) => {
const params = {
pinData: param.pinData,
id: param.id,
};
await Promise.all(
makeUpdateParams(fetchedWorkflows).map(async (param) => {
const params = {
pinData: param.pinData,
id: param.id,
};
const [escapedStatement, escapedParams] = escapeQuery(queryRunner, updateStatement, params);
queryRunner.query(escapedStatement, escapedParams);
});
const [escapedStatement, escapedParams] = escapeQuery(queryRunner, updateStatement, params);
return queryRunner.query(escapedStatement, escapedParams);
}),
);
};
function makeUpdateParams(fetchedWorkflows: PinData.FetchedWorkflow[]) {
@@ -77,6 +85,7 @@ function makeUpdateParams(fetchedWorkflows: PinData.FetchedWorkflow[]) {
}
const newPinDataPerWorkflow = Object.keys(pinDataPerWorkflow).reduce<PinData.New>(
// eslint-disable-next-line @typescript-eslint/no-shadow
(newPinDataPerWorkflow, nodeName) => {
let pinDataPerNode = pinDataPerWorkflow[nodeName];

View File

@@ -1,27 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config from '@/config';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CreateCredentialsUserRole1660062385367 implements MigrationInterface {
name = 'CreateCredentialsUserRole1660062385367';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class CreateCredentialsUserRole1660062385367 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`
INSERT INTO "${tablePrefix}role" (name, scope)
VALUES ("user", "credential")
ON CONFLICT DO NOTHING;
`);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`
DELETE FROM "${tablePrefix}role" WHERE name='user' AND scope='credential';
`);

View File

@@ -1,26 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CreateWorkflowsEditorRole1663755770892 implements MigrationInterface {
name = 'CreateWorkflowsEditorRole1663755770892';
async up(queryRunner: QueryRunner) {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class CreateWorkflowsEditorRole1663755770892 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`
INSERT INTO "${tablePrefix}role" (name, scope)
VALUES ("editor", "workflow")
ON CONFLICT DO NOTHING;
`);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner) {
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`
DELETE FROM "${tablePrefix}role" WHERE name='user' AND scope='workflow';
`);

View File

@@ -1,15 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart } from '../../utils/migrationHelpers';
import config from '@/config';
export class WorkflowStatistics1664196174000 implements MigrationInterface {
name = 'WorkflowStatistics1664196174000';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class WorkflowStatistics1664196174000 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE \`${tablePrefix}workflow_statistics\` (
"count" INTEGER DEFAULT 0,
@@ -25,13 +17,9 @@ export class WorkflowStatistics1664196174000 implements MigrationInterface {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` ADD COLUMN "dataLoaded" BOOLEAN DEFAULT false`,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE "${tablePrefix}workflow_statistics"`);
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` DROP COLUMN "dataLoaded"`,

View File

@@ -1,33 +1,22 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CreateCredentialUsageTable1665484192211 implements MigrationInterface {
name = 'CreateCredentialUsageTable1665484192211';
async up(queryRunner: QueryRunner) {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class CreateCredentialUsageTable1665484192211 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE "${tablePrefix}credential_usage" (` +
`"workflowId" integer NOT NULL,` +
`"nodeId" varchar NOT NULL,` +
`"credentialId" integer NOT NULL,` +
`"createdAt" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')',` +
`"updatedAt" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')',` +
`PRIMARY KEY("workflowId", "nodeId", "credentialId"), ` +
'"workflowId" integer NOT NULL,' +
'"nodeId" varchar NOT NULL,' +
'"credentialId" integer NOT NULL,' +
"\"createdAt\" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'," +
"\"updatedAt\" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'," +
'PRIMARY KEY("workflowId", "nodeId", "credentialId"), ' +
`CONSTRAINT "FK_${tablePrefix}518e1ece107b859ca6ce9ed2487f7e23" FOREIGN KEY ("workflowId") REFERENCES "${tablePrefix}workflow_entity" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, ` +
`CONSTRAINT "FK_${tablePrefix}7ce200a20ade7ae89fa7901da896993f" FOREIGN KEY ("credentialId") REFERENCES "${tablePrefix}credentials_entity" ("id") ON DELETE CASCADE ON UPDATE NO ACTION ` +
`);`,
');',
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner) {
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE "${tablePrefix}credential_usage"`);
}
}

View File

@@ -1,30 +1,22 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class RemoveCredentialUsageTable1665754637024 implements MigrationInterface {
name = 'RemoveCredentialUsageTable1665754637024';
async up(queryRunner: QueryRunner) {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
export class RemoveCredentialUsageTable1665754637024 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE "${tablePrefix}credential_usage"`);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner) {
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE "${tablePrefix}credential_usage" (` +
`"workflowId" integer NOT NULL,` +
`"nodeId" varchar NOT NULL,` +
`"credentialId" integer NOT NULL,` +
`"createdAt" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')',` +
`"updatedAt" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')',` +
`PRIMARY KEY("workflowId", "nodeId", "credentialId"), ` +
'"workflowId" integer NOT NULL,' +
'"nodeId" varchar NOT NULL,' +
'"credentialId" integer NOT NULL,' +
"\"createdAt\" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'," +
"\"updatedAt\" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'," +
'PRIMARY KEY("workflowId", "nodeId", "credentialId"), ' +
`CONSTRAINT "FK_${tablePrefix}518e1ece107b859ca6ce9ed2487f7e23" FOREIGN KEY ("workflowId") REFERENCES "${tablePrefix}workflow_entity" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, ` +
`CONSTRAINT "FK_${tablePrefix}7ce200a20ade7ae89fa7901da896993f" FOREIGN KEY ("credentialId") REFERENCES "${tablePrefix}credentials_entity" ("id") ON DELETE CASCADE ON UPDATE NO ACTION ` +
`);`,
');',
);
}
}

View File

@@ -1,45 +1,31 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import config from '@/config';
import type { MigrationContext, ReversibleMigration } from '@db/types';
import { v4 as uuidv4 } from 'uuid';
export class AddWorkflowVersionIdColumn1669739707124 implements MigrationInterface {
name = 'AddWorkflowVersionIdColumn1669739707124';
async up(queryRunner: QueryRunner) {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
export class AddWorkflowVersionIdColumn1669739707124 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` ADD COLUMN "versionId" char(36)`,
);
const workflowIds: Array<{ id: number }> = await queryRunner.query(`
const workflowIds = (await queryRunner.query(`
SELECT id
FROM "${tablePrefix}workflow_entity"
`);
`)) as Array<{ id: number }>;
workflowIds.map(({ id }) => {
for (const { id } of workflowIds) {
const [updateQuery, updateParams] = queryRunner.connection.driver.escapeQueryWithParameters(
`
UPDATE "${tablePrefix}workflow_entity"
SET versionId = :versionId
WHERE id = '${id}'
`,
`UPDATE "${tablePrefix}workflow_entity"
SET versionId = :versionId
WHERE id = '${id}'`,
{ versionId: uuidv4() },
{},
);
return queryRunner.query(updateQuery, updateParams);
});
logMigrationEnd(this.name);
await queryRunner.query(updateQuery, updateParams);
}
}
async down(queryRunner: QueryRunner) {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` DROP COLUMN "versionId"`,
);

View File

@@ -1,26 +1,14 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import config from '@/config';
export class AddTriggerCountColumn1669823906993 implements MigrationInterface {
name = 'AddTriggerCountColumn1669823906993';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class AddTriggerCountColumn1669823906993 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` ADD COLUMN "triggerCount" integer NOT NULL DEFAULT 0`,
);
// Table will be populated by n8n startup - see ActiveWorkflowRunner.ts
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` DROP COLUMN "triggerCount"`,
);

View File

@@ -1,27 +1,18 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '../../utils/migrationHelpers';
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class MessageEventBusDestinations1671535397530 implements MigrationInterface {
name = 'MessageEventBusDestinations1671535397530';
async up(queryRunner: QueryRunner) {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
export class MessageEventBusDestinations1671535397530 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE "${tablePrefix}event_destinations" (` +
`"id" varchar(36) PRIMARY KEY NOT NULL,` +
`"destination" text NOT NULL,` +
`"createdAt" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')',` +
`"updatedAt" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'` +
`);`,
'"id" varchar(36) PRIMARY KEY NOT NULL,' +
'"destination" text NOT NULL,' +
"\"createdAt\" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'," +
"\"updatedAt\" datetime(3) NOT NULL DEFAULT 'STRFTIME(''%Y-%m-%d %H:%M:%f'', ''NOW'')'" +
');',
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner) {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE "${tablePrefix}event_destinations"`);
logMigrationEnd(this.name);
}
}

View File

@@ -1,23 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import config from '@/config';
import { v4 as uuidv4 } from 'uuid';
import { StatisticsNames } from '@db/entities/WorkflowStatistics';
export class RemoveWorkflowDataLoadedFlag1671726148419 implements MigrationInterface {
name = 'RemoveWorkflowDataLoadedFlag1671726148419';
async up(queryRunner: QueryRunner) {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
import { StatisticsNames } from '@/databases/entities/WorkflowStatistics';
export class RemoveWorkflowDataLoadedFlag1671726148419 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
// If any existing workflow has dataLoaded set to true, insert the relevant information to the statistics table
const workflowIds: Array<{ id: number; dataLoaded: boolean }> = await queryRunner.query(`
const workflowIds = (await queryRunner.query(`
SELECT id, dataLoaded
FROM "${tablePrefix}workflow_entity"
`);
`)) as Array<{ id: number; dataLoaded: boolean }>;
workflowIds.map(({ id, dataLoaded }) => {
workflowIds.map(async ({ id, dataLoaded }) => {
if (dataLoaded) {
const [insertQuery, insertParams] = queryRunner.connection.driver.escapeQueryWithParameters(
`
@@ -36,24 +28,20 @@ export class RemoveWorkflowDataLoadedFlag1671726148419 implements MigrationInter
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` DROP COLUMN "dataLoaded"`,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner) {
const tablePrefix = config.getEnv('database.tablePrefix');
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}workflow_entity\` ADD COLUMN "dataLoaded" BOOLEAN DEFAULT false`,
);
// Search through statistics for any workflows that have the dataLoaded stat
const workflowsIds: Array<{ workflowId: string }> = await queryRunner.query(`
const workflowsIds = (await queryRunner.query(`
SELECT workflowId
FROM "${tablePrefix}workflow_statistics"
WHERE name = '${StatisticsNames.dataLoaded}'
`);
workflowsIds.map(({ workflowId }) => {
`)) as Array<{ workflowId: string }>;
workflowsIds.map(async ({ workflowId }) => {
return queryRunner.query(`
UPDATE "${tablePrefix}workflow_entity"
SET dataLoaded = true

View File

@@ -1,18 +1,12 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class DeleteExecutionsWithWorkflows1673268682475 implements MigrationInterface {
name = 'DeleteExecutionsWithWorkflows1673268682475';
export class DeleteExecutionsWithWorkflows1673268682475 implements ReversibleMigration {
transaction = false as const;
transaction = false;
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
const workflowIds: Array<{ id: number }> = await queryRunner.query(`
async up({ queryRunner, tablePrefix }: MigrationContext) {
const workflowIds = (await queryRunner.query(`
SELECT id FROM "${tablePrefix}workflow_entity"
`);
`)) as Array<{ id: number }>;
await queryRunner.query(
`DELETE FROM "${tablePrefix}execution_entity"
@@ -61,13 +55,9 @@ export class DeleteExecutionsWithWorkflows1673268682475 implements MigrationInte
);
await queryRunner.query('PRAGMA foreign_keys=ON');
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE IF EXISTS "${tablePrefix}temporary_execution_entity"`);
await queryRunner.query(
`CREATE TABLE "${tablePrefix}temporary_execution_entity" (

View File

@@ -1,23 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import config from '@/config';
export class AddStatusToExecutions1674138566000 implements MigrationInterface {
name = 'AddStatusToExecutions1674138566000';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class AddStatusToExecutions1674138566000 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE \`${tablePrefix}execution_entity\` ADD COLUMN "status" varchar`,
);
logMigrationEnd(this.name);
}
public 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\` DROP COLUMN "status"`);
}
}

View File

@@ -1,14 +1,8 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import type { MigrationContext, ReversibleMigration } from '@db/types';
import { LDAP_DEFAULT_CONFIGURATION, LDAP_FEATURE_NAME } from '@/Ldap/constants';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CreateLdapEntities1674509946020 implements MigrationInterface {
name = 'CreateLdapEntities1674509946020';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
export class CreateLdapEntities1674509946020 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`ALTER TABLE ${tablePrefix}user ADD COLUMN disabled BOOLEAN NOT NULL DEFAULT false;`,
);
@@ -44,12 +38,9 @@ export class CreateLdapEntities1674509946020 implements MigrationInterface {
"error" TEXT
);`,
);
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE "${tablePrefix}auth_provider_sync_history"`);
await queryRunner.query(`DROP TABLE "${tablePrefix}auth_identity"`);

View File

@@ -1,29 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import type { IConnections, INode } from 'n8n-workflow';
import { jsonParse } from 'n8n-workflow';
import type { MigrationContext, IrreversibleMigration } from '@db/types';
import { NodeTypes } from '@/NodeTypes';
import { IConnections, INode } from 'n8n-workflow';
import { getLogger } from '@/Logger';
import { Container } from 'typedi';
export class PurgeInvalidWorkflowConnections1675940580449 implements MigrationInterface {
name = 'PurgeInvalidWorkflowConnections1675940580449';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
const workflows: Array<{ id: number; nodes: string; connections: string }> =
await queryRunner.query(`
export class PurgeInvalidWorkflowConnections1675940580449 implements IrreversibleMigration {
async up({ queryRunner, tablePrefix, migrationName, logger }: MigrationContext) {
const workflows = (await queryRunner.query(`
SELECT id, nodes, connections
FROM "${tablePrefix}workflow_entity"
`);
`)) as Array<{ id: number; nodes: string; connections: string }>;
const nodeTypes = Container.get(NodeTypes);
workflows.forEach(async (workflow) => {
let connections: IConnections = JSON.parse(workflow.connections);
const nodes: INode[] = JSON.parse(workflow.nodes);
const connections = jsonParse<IConnections>(workflow.connections);
const nodes = jsonParse<INode[]>(workflow.nodes);
const nodesThatCannotReceiveInput: string[] = nodes.reduce((acc, node) => {
try {
@@ -32,7 +24,7 @@ export class PurgeInvalidWorkflowConnections1675940580449 implements MigrationIn
acc.push(node.name);
}
} catch (error) {
getLogger().warn(`Migration ${this.name} failed with error: ${error.message}`);
logger.warn(`Migration ${migrationName} failed with error: ${(error as Error).message}`);
}
return acc;
}, [] as string[]);
@@ -41,7 +33,7 @@ export class PurgeInvalidWorkflowConnections1675940580449 implements MigrationIn
const connection = connections[sourceNodeName];
const outputs = Object.keys(connection);
outputs.forEach((outputConnectionName /* Like `main` */, idx) => {
outputs.forEach((outputConnectionName /* Like `main` */) => {
const outputConnection = connection[outputConnectionName];
// It filters out all connections that are connected to a node that cannot receive input
@@ -67,11 +59,5 @@ export class PurgeInvalidWorkflowConnections1675940580449 implements MigrationIn
await queryRunner.query(updateQuery, updateParams);
});
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
// No need to revert this migration
}
}

View File

@@ -1,13 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import config from '@/config';
export class MigrateExecutionStatus1676996103000 implements MigrationInterface {
name = 'MigrateExecutionStatus1676996103000';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, IrreversibleMigration } from '@db/types';
export class MigrateExecutionStatus1676996103000 implements IrreversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`UPDATE "${tablePrefix}execution_entity" SET "status" = 'waiting' WHERE "status" IS NULL AND "waitTill" IS NOT NULL;`,
);
@@ -20,9 +14,5 @@ export class MigrateExecutionStatus1676996103000 implements MigrationInterface {
await queryRunner.query(
`UPDATE "${tablePrefix}execution_entity" SET "status" = 'crashed' WHERE "status" IS NULL;`,
);
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {}
}

View File

@@ -1,22 +1,12 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import config from '@/config';
export class UpdateRunningExecutionStatus1677237073720 implements MigrationInterface {
name = 'UpdateRunningExecutionStatus1677237073720';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = config.getEnv('database.tablePrefix');
import type { MigrationContext, IrreversibleMigration } from '@db/types';
export class UpdateRunningExecutionStatus1677237073720 implements IrreversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`UPDATE "${tablePrefix}execution_entity" SET "status" = 'failed' WHERE "status" = 'running' AND "finished"=0 AND "stoppedAt" IS NOT NULL;`,
);
await queryRunner.query(
`UPDATE "${tablePrefix}execution_entity" SET "status" = 'success' WHERE "status" = 'running' AND "finished"=1 AND "stoppedAt" IS NOT NULL;`,
);
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {}
}

View File

@@ -1,13 +1,7 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { logMigrationEnd, logMigrationStart, getTablePrefix } from '@db/utils/migrationHelpers';
import config from '@/config';
export class CreateVariables1677501636752 implements MigrationInterface {
name = 'CreateVariables1677501636752';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class CreateVariables1677501636752 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`
CREATE TABLE ${tablePrefix}variables (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
@@ -17,16 +11,9 @@ export class CreateVariables1677501636752 implements MigrationInterface {
UNIQUE("key")
);
`);
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE ${tablePrefix}variables;`);
logMigrationEnd(this.name);
}
}

View File

@@ -1,13 +1,7 @@
import { MigrationInterface, QueryRunner, Table } from 'typeorm';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
export class CreateExecutionMetadataTable1679416281777 implements MigrationInterface {
name = 'CreateExecutionMetadataTable1679416281777';
public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
import type { MigrationContext, ReversibleMigration } from '@db/types';
export class CreateExecutionMetadataTable1679416281777 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`CREATE TABLE "${tablePrefix}execution_metadata" (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
@@ -41,13 +35,9 @@ export class CreateExecutionMetadataTable1679416281777 implements MigrationInter
await queryRunner.query(`DROP INDEX IF EXISTS 'IDX_${tablePrefix}ca4a71b47f28ac6ea88293a8e2'`);
// Remove index for stoppedAt since it's not used anymore
await queryRunner.query(`DROP INDEX IF EXISTS 'IDX_${tablePrefix}cefb067df2402f6aed0638a6c1'`);
logMigrationEnd(this.name);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(`DROP TABLE "${tablePrefix}execution_metadata"`);
await queryRunner.query(`DROP INDEX IF EXISTS 'IDX_${tablePrefix}b94b45ce2c73ce46c54f20b5f9'`);
await queryRunner.query(`DROP INDEX IF EXISTS 'IDX_${tablePrefix}81fc04c8a17de15835713505e4'`);

View File

@@ -1,16 +1,9 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
import type { MigrationContext, ReversibleMigration } from '@db/types';
import type { UserSettings } from '@/Interfaces';
export class AddUserActivatedProperty1681134145996 implements MigrationInterface {
name = 'AddUserActivatedProperty1681134145996';
async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);
const tablePrefix = getTablePrefix();
const activatedUsers: UserSettings[] = await queryRunner.query(
export class AddUserActivatedProperty1681134145996 implements ReversibleMigration {
async up({ queryRunner, tablePrefix }: MigrationContext) {
const activatedUsers = (await queryRunner.query(
`SELECT DISTINCT sw.userId AS id,
JSON_SET(COALESCE(u.settings, '{}'), '$.userActivated', JSON('true')) AS settings
FROM ${tablePrefix}workflow_statistics AS ws
@@ -23,10 +16,11 @@ export class AddUserActivatedProperty1681134145996 implements MigrationInterface
WHERE ws.name = 'production_success'
AND r.name = 'owner'
AND r.scope = "workflow"`,
);
)) as UserSettings[];
const updatedUsers = activatedUsers.map((user) =>
const updatedUsers = activatedUsers.map(async (user) =>
queryRunner.query(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`UPDATE ${tablePrefix}user SET settings = '${user.settings}' WHERE id = '${user.id}' `,
),
);
@@ -43,12 +37,9 @@ export class AddUserActivatedProperty1681134145996 implements MigrationInterface
`UPDATE ${tablePrefix}user SET settings = JSON_SET(COALESCE(settings, '{}'), '$.userActivated', JSON('false')) WHERE id NOT IN (${activatedUserIds})`,
);
}
logMigrationEnd(this.name);
}
async down(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = getTablePrefix();
async down({ queryRunner, tablePrefix }: MigrationContext) {
await queryRunner.query(
`UPDATE ${tablePrefix}user SET settings = JSON_REMOVE(settings, '$.userActivated')`,
);

View File

@@ -1,3 +1,4 @@
import type { Migration } from '@db/types';
import { InitialMigration1588102412422 } from './1588102412422-InitialMigration';
import { WebhookModel1592445003908 } from './1592445003908-WebhookModel';
import { CreateIndexStoppedAt1594825041918 } from './1594825041918-CreateIndexStoppedAt';
@@ -35,7 +36,7 @@ import { CreateExecutionMetadataTable1679416281777 } from './1679416281777-Creat
import { CreateVariables1677501636752 } from './1677501636752-CreateVariables';
import { AddUserActivatedProperty1681134145996 } from './1681134145996-AddUserActivatedProperty';
const sqliteMigrations = [
const sqliteMigrations: Migration[] = [
InitialMigration1588102412422,
WebhookModel1592445003908,
CreateIndexStoppedAt1594825041918,