refactor(core): Delete more redundant code across migrations (Part 1) (no-changelog) (#6691)
This commit is contained in:
committed by
GitHub
parent
7b27fa5898
commit
b7ca27afcf
@@ -1,56 +1,5 @@
|
||||
import type { MigrationContext, ReversibleMigration } from '@db/types';
|
||||
import { UniqueWorkflowNames1620821879465 } from '../common/1620821879465-UniqueWorkflowNames';
|
||||
|
||||
export class UniqueWorkflowNames1620824779533 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(
|
||||
`
|
||||
SELECT id, name
|
||||
FROM ${tablePrefix}workflow_entity
|
||||
WHERE name = :name
|
||||
ORDER BY "createdAt" ASC
|
||||
`,
|
||||
{ name },
|
||||
{},
|
||||
);
|
||||
|
||||
const duplicates = (await queryRunner.query(duplicatesQuery, parameters)) as Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
}>;
|
||||
|
||||
if (duplicates.length > 1) {
|
||||
await Promise.all(
|
||||
// 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(
|
||||
`UPDATE ${tablePrefix}workflow_entity
|
||||
SET name = :name
|
||||
WHERE id = '${id}'
|
||||
`,
|
||||
{ name: `${name} ${index + 1}` },
|
||||
{},
|
||||
);
|
||||
|
||||
return queryRunner.query(updateQuery, updateParams);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE UNIQUE INDEX "IDX_${tablePrefix}a252c527c4c89237221fe2c0ab" ON ${tablePrefix}workflow_entity ("name") `,
|
||||
);
|
||||
}
|
||||
|
||||
async down({ queryRunner, tablePrefix }: MigrationContext) {
|
||||
await queryRunner.query(`DROP INDEX "IDX_${tablePrefix}a252c527c4c89237221fe2c0ab"`);
|
||||
}
|
||||
export class UniqueWorkflowNames1620824779533 extends UniqueWorkflowNames1620821879465 {
|
||||
indexSuffix = 'a252c527c4c89237221fe2c0ab';
|
||||
}
|
||||
|
||||
@@ -1,301 +1,3 @@
|
||||
/* 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';
|
||||
import { UpdateWorkflowCredentials1630330987096 } from '../common/1630330987096-UpdateWorkflowCredentials';
|
||||
|
||||
// replacing the credentials in workflows and execution
|
||||
// `nodeType: name` changes to `nodeType: { id, name }`
|
||||
|
||||
export class UpdateWorkflowCredentials1630419189837 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
|
||||
FROM ${tablePrefix}workflow_entity
|
||||
`;
|
||||
|
||||
// @ts-ignore
|
||||
await runInBatches(queryRunner, workflowsQuery, (workflows) => {
|
||||
workflows.forEach(async (workflow) => {
|
||||
const nodes = workflow.nodes;
|
||||
let credentialsUpdated = false;
|
||||
// @ts-ignore
|
||||
nodes.forEach((node) => {
|
||||
if (node.credentials) {
|
||||
const allNodeCredentials = Object.entries(node.credentials);
|
||||
for (const [type, name] of allNodeCredentials) {
|
||||
if (typeof name === 'string') {
|
||||
const matchingCredentials = credentialsEntities.find(
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (credentialsUpdated) {
|
||||
const [updateQuery, updateParams] =
|
||||
queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`
|
||||
UPDATE ${tablePrefix}workflow_entity
|
||||
SET nodes = :nodes
|
||||
WHERE id = '${workflow.id}'
|
||||
`,
|
||||
{ nodes: JSON.stringify(nodes) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const waitingExecutionsQuery = `
|
||||
SELECT id, "workflowData"
|
||||
FROM ${tablePrefix}execution_entity
|
||||
WHERE "waitTill" IS NOT NULL AND finished = FALSE
|
||||
`;
|
||||
// @ts-ignore
|
||||
await runInBatches(queryRunner, waitingExecutionsQuery, (waitingExecutions) => {
|
||||
waitingExecutions.forEach(async (execution) => {
|
||||
const data = execution.workflowData;
|
||||
let credentialsUpdated = false;
|
||||
// @ts-ignore
|
||||
data.nodes.forEach((node) => {
|
||||
if (node.credentials) {
|
||||
const allNodeCredentials = Object.entries(node.credentials);
|
||||
for (const [type, name] of allNodeCredentials) {
|
||||
if (typeof name === 'string') {
|
||||
const matchingCredentials = credentialsEntities.find(
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (credentialsUpdated) {
|
||||
const [updateQuery, updateParams] =
|
||||
queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`
|
||||
UPDATE ${tablePrefix}execution_entity
|
||||
SET "workflowData" = :data
|
||||
WHERE id = '${execution.id}'
|
||||
`,
|
||||
{ data: JSON.stringify(data) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const retryableExecutions = await queryRunner.query(`
|
||||
SELECT id, "workflowData"
|
||||
FROM ${tablePrefix}execution_entity
|
||||
WHERE "waitTill" IS NULL AND finished = FALSE AND mode != 'retry'
|
||||
ORDER BY "startedAt" DESC
|
||||
LIMIT 200
|
||||
`);
|
||||
|
||||
// @ts-ignore
|
||||
retryableExecutions.forEach(async (execution) => {
|
||||
const data = execution.workflowData;
|
||||
let credentialsUpdated = false;
|
||||
// @ts-ignore
|
||||
data.nodes.forEach((node) => {
|
||||
if (node.credentials) {
|
||||
const allNodeCredentials = Object.entries(node.credentials);
|
||||
for (const [type, name] of allNodeCredentials) {
|
||||
if (typeof name === 'string') {
|
||||
// @ts-ignore
|
||||
const matchingCredentials = credentialsEntities.find(
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.name === name && credentials.type === type,
|
||||
);
|
||||
node.credentials[type] = { id: matchingCredentials?.id || null, name };
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (credentialsUpdated) {
|
||||
const [updateQuery, updateParams] = queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`
|
||||
UPDATE ${tablePrefix}execution_entity
|
||||
SET "workflowData" = :data
|
||||
WHERE id = '${execution.id}'
|
||||
`,
|
||||
{ data: JSON.stringify(data) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
FROM ${tablePrefix}workflow_entity
|
||||
`;
|
||||
// @ts-ignore
|
||||
await runInBatches(queryRunner, workflowsQuery, (workflows) => {
|
||||
workflows.forEach(async (workflow) => {
|
||||
const nodes = workflow.nodes;
|
||||
let credentialsUpdated = false;
|
||||
// @ts-ignore
|
||||
nodes.forEach((node) => {
|
||||
if (node.credentials) {
|
||||
const allNodeCredentials = Object.entries(node.credentials);
|
||||
for (const [type, creds] of allNodeCredentials) {
|
||||
if (typeof creds === 'object') {
|
||||
// @ts-ignore
|
||||
const matchingCredentials = credentialsEntities.find(
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.id === creds.id && credentials.type === type,
|
||||
);
|
||||
if (matchingCredentials) {
|
||||
node.credentials[type] = matchingCredentials.name;
|
||||
} else {
|
||||
// @ts-ignore
|
||||
node.credentials[type] = creds.name;
|
||||
}
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (credentialsUpdated) {
|
||||
const [updateQuery, updateParams] =
|
||||
queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`
|
||||
UPDATE ${tablePrefix}workflow_entity
|
||||
SET nodes = :nodes
|
||||
WHERE id = '${workflow.id}'
|
||||
`,
|
||||
{ nodes: JSON.stringify(nodes) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const waitingExecutionsQuery = `
|
||||
SELECT id, "workflowData"
|
||||
FROM ${tablePrefix}execution_entity
|
||||
WHERE "waitTill" IS NOT NULL AND finished = FALSE
|
||||
`;
|
||||
// @ts-ignore
|
||||
await runInBatches(queryRunner, waitingExecutionsQuery, (waitingExecutions) => {
|
||||
waitingExecutions.forEach(async (execution) => {
|
||||
const data = execution.workflowData;
|
||||
let credentialsUpdated = false;
|
||||
// @ts-ignore
|
||||
data.nodes.forEach((node) => {
|
||||
if (node.credentials) {
|
||||
const allNodeCredentials = Object.entries(node.credentials);
|
||||
for (const [type, creds] of allNodeCredentials) {
|
||||
if (typeof creds === 'object') {
|
||||
// @ts-ignore
|
||||
const matchingCredentials = credentialsEntities.find(
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.id === creds.id && credentials.type === type,
|
||||
);
|
||||
if (matchingCredentials) {
|
||||
node.credentials[type] = matchingCredentials.name;
|
||||
} else {
|
||||
// @ts-ignore
|
||||
node.credentials[type] = creds.name;
|
||||
}
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (credentialsUpdated) {
|
||||
const [updateQuery, updateParams] =
|
||||
queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`
|
||||
UPDATE ${tablePrefix}execution_entity
|
||||
SET "workflowData" = :data
|
||||
WHERE id = '${execution.id}'
|
||||
`,
|
||||
{ data: JSON.stringify(data) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const retryableExecutions = await queryRunner.query(`
|
||||
SELECT id, "workflowData"
|
||||
FROM ${tablePrefix}execution_entity
|
||||
WHERE "waitTill" IS NULL AND finished = FALSE AND mode != 'retry'
|
||||
ORDER BY "startedAt" DESC
|
||||
LIMIT 200
|
||||
`);
|
||||
// @ts-ignore
|
||||
retryableExecutions.forEach(async (execution) => {
|
||||
const data = execution.workflowData;
|
||||
let credentialsUpdated = false;
|
||||
// @ts-ignore
|
||||
data.nodes.forEach((node) => {
|
||||
if (node.credentials) {
|
||||
const allNodeCredentials = Object.entries(node.credentials);
|
||||
for (const [type, creds] of allNodeCredentials) {
|
||||
if (typeof creds === 'object') {
|
||||
// @ts-ignore
|
||||
const matchingCredentials = credentialsEntities.find(
|
||||
// @ts-ignore
|
||||
(credentials) => credentials.id === creds.id && credentials.type === type,
|
||||
);
|
||||
if (matchingCredentials) {
|
||||
node.credentials[type] = matchingCredentials.name;
|
||||
} else {
|
||||
// @ts-ignore
|
||||
node.credentials[type] = creds.name;
|
||||
}
|
||||
credentialsUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (credentialsUpdated) {
|
||||
const [updateQuery, updateParams] = queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`
|
||||
UPDATE ${tablePrefix}execution_entity
|
||||
SET "workflowData" = :data
|
||||
WHERE id = '${execution.id}'
|
||||
`,
|
||||
{ data: JSON.stringify(data) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
export class UpdateWorkflowCredentials1630419189837 extends UpdateWorkflowCredentials1630330987096 {}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type { InsertResult, MigrationContext, ReversibleMigration } from '@db/types';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { loadSurveyFromDisk } from '@db/utils/migrationHelpers';
|
||||
|
||||
export class CreateUserManagement1646992772331 implements ReversibleMigration {
|
||||
async up({ queryRunner, tablePrefix }: MigrationContext) {
|
||||
async up({ queryRunner, tablePrefix, loadSurveyFromDisk }: MigrationContext) {
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE ${tablePrefix}role (
|
||||
"id" serial NOT NULL,
|
||||
|
||||
@@ -1,69 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
import { AddNodeIds1658930531669 } from '../common/1658930531669-AddNodeIds';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
import type { MigrationContext, ReversibleMigration } from '@db/types';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { runInBatches } from '@db/utils/migrationHelpers';
|
||||
|
||||
// add node ids in workflow objects
|
||||
|
||||
export class AddNodeIds1658932090381 implements ReversibleMigration {
|
||||
async up({ queryRunner, tablePrefix }: MigrationContext) {
|
||||
const workflowsQuery = `
|
||||
SELECT id, nodes
|
||||
FROM ${tablePrefix}workflow_entity
|
||||
`;
|
||||
|
||||
// @ts-ignore
|
||||
await runInBatches(queryRunner, workflowsQuery, (workflows) => {
|
||||
workflows.forEach(async (workflow) => {
|
||||
const nodes = workflow.nodes;
|
||||
// @ts-ignore
|
||||
nodes.forEach((node) => {
|
||||
if (!node.id) {
|
||||
node.id = uuid();
|
||||
}
|
||||
});
|
||||
|
||||
const [updateQuery, updateParams] = queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`
|
||||
UPDATE ${tablePrefix}workflow_entity
|
||||
SET nodes = :nodes
|
||||
WHERE id = '${workflow.id}'
|
||||
`,
|
||||
{ nodes: JSON.stringify(nodes) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async down({ queryRunner, tablePrefix }: MigrationContext) {
|
||||
const workflowsQuery = `
|
||||
SELECT id, nodes
|
||||
FROM ${tablePrefix}workflow_entity
|
||||
`;
|
||||
|
||||
// @ts-ignore
|
||||
await runInBatches(queryRunner, workflowsQuery, (workflows) => {
|
||||
workflows.forEach(async (workflow) => {
|
||||
const nodes = workflow.nodes;
|
||||
// @ts-ignore
|
||||
nodes.forEach((node) => delete node.id);
|
||||
|
||||
const [updateQuery, updateParams] = queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`UPDATE ${tablePrefix}workflow_entity
|
||||
SET nodes = :nodes
|
||||
WHERE id = '${workflow.id}'`,
|
||||
{ nodes: JSON.stringify(nodes) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
export class AddNodeIds1658932090381 extends AddNodeIds1658930531669 {}
|
||||
|
||||
@@ -1,32 +1,3 @@
|
||||
import type { MigrationContext, IrreversibleMigration } from '@db/types';
|
||||
import { runInBatches } from '@db/utils/migrationHelpers';
|
||||
import { addJsonKeyToPinDataColumn } from '../sqlite/1659888469333-AddJsonKeyPinData';
|
||||
import { AddJsonKeyPinData1659888469333 } from '../common/1659888469333-AddJsonKeyPinData';
|
||||
|
||||
/**
|
||||
* Convert JSON-type `pinData` column in `workflow_entity` table from
|
||||
* `{ [nodeName: string]: IDataObject[] }` to `{ [nodeName: string]: INodeExecutionData[] }`
|
||||
*/
|
||||
export class AddJsonKeyPinData1659902242948 implements IrreversibleMigration {
|
||||
async up(context: MigrationContext) {
|
||||
const { queryRunner, tablePrefix } = context;
|
||||
const workflowTable = `${tablePrefix}workflow_entity`;
|
||||
|
||||
const PINDATA_SELECT_QUERY = `
|
||||
SELECT id, "pinData"
|
||||
FROM ${workflowTable}
|
||||
WHERE "pinData" IS NOT NULL;
|
||||
`;
|
||||
|
||||
const PINDATA_UPDATE_STATEMENT = `
|
||||
UPDATE ${workflowTable}
|
||||
SET "pinData" = :pinData
|
||||
WHERE id = :id;
|
||||
`;
|
||||
|
||||
await runInBatches(
|
||||
queryRunner,
|
||||
PINDATA_SELECT_QUERY,
|
||||
addJsonKeyToPinDataColumn(context, PINDATA_UPDATE_STATEMENT),
|
||||
);
|
||||
}
|
||||
}
|
||||
export class AddJsonKeyPinData1659902242948 extends AddJsonKeyPinData1659888469333 {}
|
||||
|
||||
@@ -1,31 +1,3 @@
|
||||
import type { MigrationContext, ReversibleMigration } from '@db/types';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { AddWorkflowVersionIdColumn1669739707124 } from '../common/1669739707124-AddWorkflowVersionIdColumn';
|
||||
|
||||
export class AddWorkflowVersionIdColumn1669739707126 implements ReversibleMigration {
|
||||
async up({ queryRunner, tablePrefix }: MigrationContext) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE ${tablePrefix}workflow_entity ADD COLUMN "versionId" CHAR(36)`,
|
||||
);
|
||||
|
||||
const workflowIds = (await queryRunner.query(`
|
||||
SELECT id
|
||||
FROM ${tablePrefix}workflow_entity
|
||||
`)) as Array<{ id: number }>;
|
||||
|
||||
for (const { id } of workflowIds) {
|
||||
const [updateQuery, updateParams] = queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`UPDATE ${tablePrefix}workflow_entity
|
||||
SET "versionId" = :versionId
|
||||
WHERE id = '${id}'`,
|
||||
{ versionId: uuidv4() },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
}
|
||||
}
|
||||
|
||||
async down({ queryRunner, tablePrefix }: MigrationContext) {
|
||||
await queryRunner.query(`ALTER TABLE ${tablePrefix}workflow_entity DROP COLUMN "versionId"`);
|
||||
}
|
||||
}
|
||||
export class AddWorkflowVersionIdColumn1669739707126 extends AddWorkflowVersionIdColumn1669739707124 {}
|
||||
|
||||
@@ -1,53 +1,3 @@
|
||||
import type { MigrationContext, ReversibleMigration } from '@db/types';
|
||||
import { StatisticsNames } from '@db/entities/WorkflowStatistics';
|
||||
import { RemoveWorkflowDataLoadedFlag1671726148419 } from '../common/1671726148419-RemoveWorkflowDataLoadedFlag';
|
||||
|
||||
export class RemoveWorkflowDataLoadedFlag1671726148421 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 = (await queryRunner.query(`
|
||||
SELECT id, "dataLoaded"
|
||||
FROM ${tablePrefix}workflow_entity
|
||||
`)) as Array<{ id: number; dataLoaded: boolean }>;
|
||||
|
||||
workflowIds.map(async ({ id, dataLoaded }) => {
|
||||
if (dataLoaded) {
|
||||
const [insertQuery, insertParams] = queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`
|
||||
INSERT INTO ${tablePrefix}workflow_statistics ("workflowId", name, count, "latestEvent") VALUES
|
||||
(:id, :name, 1, CURRENT_TIMESTAMP(3))
|
||||
`,
|
||||
{ id, name: StatisticsNames.dataLoaded },
|
||||
{},
|
||||
);
|
||||
|
||||
return queryRunner.query(insertQuery, insertParams);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
await queryRunner.query(`ALTER TABLE ${tablePrefix}workflow_entity DROP COLUMN "dataLoaded"`);
|
||||
}
|
||||
|
||||
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 = (await queryRunner.query(`
|
||||
SELECT "workflowId"
|
||||
FROM ${tablePrefix}workflow_statistics
|
||||
WHERE name = '${StatisticsNames.dataLoaded}'
|
||||
`)) as Array<{ workflowId: string }>;
|
||||
workflowsIds.map(async ({ workflowId }) => {
|
||||
return queryRunner.query(`
|
||||
UPDATE ${tablePrefix}workflow_entity
|
||||
SET "dataLoaded" = true
|
||||
WHERE id = '${workflowId}'`);
|
||||
});
|
||||
|
||||
await queryRunner.query(
|
||||
`DELETE FROM ${tablePrefix}workflow_statistics WHERE name = '${StatisticsNames.dataLoaded}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
export class RemoveWorkflowDataLoadedFlag1671726148421 extends RemoveWorkflowDataLoadedFlag1671726148419 {}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import type { MigrationContext, ReversibleMigration } from '@db/types';
|
||||
import { LDAP_DEFAULT_CONFIGURATION, LDAP_FEATURE_NAME } from '@/Ldap/constants';
|
||||
|
||||
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;`,
|
||||
);
|
||||
|
||||
await queryRunner.query(`
|
||||
INSERT INTO ${tablePrefix}settings (key, value, "loadOnStartup")
|
||||
VALUES ('${LDAP_FEATURE_NAME}', '${JSON.stringify(LDAP_DEFAULT_CONFIGURATION)}', true)
|
||||
`);
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE IF NOT EXISTS "${tablePrefix}auth_identity" (
|
||||
"userId" uuid REFERENCES "${tablePrefix}user" (id),
|
||||
"providerId" VARCHAR(64) NOT NULL,
|
||||
"providerType" VARCHAR(32) NOT NULL,
|
||||
"createdAt" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY("providerId", "providerType")
|
||||
);`,
|
||||
);
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE IF NOT EXISTS "${tablePrefix}auth_provider_sync_history" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"providerType" VARCHAR(32) NOT NULL,
|
||||
"runMode" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"startedAt" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"endedAt" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"scanned" INTEGER NOT NULL,
|
||||
"created" INTEGER NOT NULL,
|
||||
"updated" INTEGER NOT NULL,
|
||||
"disabled" INTEGER NOT NULL,
|
||||
"error" TEXT
|
||||
);`,
|
||||
);
|
||||
}
|
||||
|
||||
async down({ queryRunner, tablePrefix }: MigrationContext) {
|
||||
await queryRunner.query(`DROP TABLE "${tablePrefix}auth_provider_sync_history"`);
|
||||
await queryRunner.query(`DROP TABLE "${tablePrefix}auth_identity"`);
|
||||
|
||||
await queryRunner.query(
|
||||
`DELETE FROM ${tablePrefix}settings WHERE key = '${LDAP_FEATURE_NAME}'`,
|
||||
);
|
||||
await queryRunner.query(`ALTER TABLE "${tablePrefix}user" DROP COLUMN disabled`);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import type { IConnections, INode } from 'n8n-workflow';
|
||||
import type { MigrationContext, IrreversibleMigration } from '@db/types';
|
||||
import { NodeTypes } from '@/NodeTypes';
|
||||
import { Container } from 'typedi';
|
||||
|
||||
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: INode[]; connections: IConnections }>;
|
||||
|
||||
const nodeTypes = Container.get(NodeTypes);
|
||||
|
||||
workflows.forEach(async (workflow) => {
|
||||
const { connections, nodes } = workflow;
|
||||
|
||||
const nodesThatCannotReceiveInput: string[] = nodes.reduce((acc, node) => {
|
||||
try {
|
||||
const nodeType = nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
||||
if ((nodeType.description.inputs?.length ?? []) === 0) {
|
||||
acc.push(node.name);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn(`Migration ${migrationName} failed with error: ${(error as Error).message}`);
|
||||
}
|
||||
return acc;
|
||||
}, [] as string[]);
|
||||
|
||||
Object.keys(connections).forEach((sourceNodeName) => {
|
||||
const connection = connections[sourceNodeName];
|
||||
const outputs = Object.keys(connection);
|
||||
|
||||
outputs.forEach((outputConnectionName /* Like `main` */) => {
|
||||
const outputConnection = connection[outputConnectionName];
|
||||
|
||||
// It filters out all connections that are connected to a node that cannot receive input
|
||||
outputConnection.forEach((outputConnectionItem, outputConnectionItemIdx) => {
|
||||
outputConnection[outputConnectionItemIdx] = outputConnectionItem.filter(
|
||||
(outgoingConnections) =>
|
||||
!nodesThatCannotReceiveInput.includes(outgoingConnections.node),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Update database with new connections
|
||||
const [updateQuery, updateParams] = queryRunner.connection.driver.escapeQueryWithParameters(
|
||||
`UPDATE "${tablePrefix}workflow_entity"
|
||||
SET connections = :connections
|
||||
WHERE id = '${workflow.id}'`,
|
||||
{ connections: JSON.stringify(connections) },
|
||||
{},
|
||||
);
|
||||
|
||||
await queryRunner.query(updateQuery, updateParams);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,8 @@ import { AddTriggerCountColumn1669823906995 } from './1669823906995-AddTriggerCo
|
||||
import { RemoveWorkflowDataLoadedFlag1671726148421 } from './1671726148421-RemoveWorkflowDataLoadedFlag';
|
||||
import { MessageEventBusDestinations1671535397530 } from './1671535397530-MessageEventBusDestinations';
|
||||
import { DeleteExecutionsWithWorkflows1673268682475 } from './1673268682475-DeleteExecutionsWithWorkflows';
|
||||
import { CreateLdapEntities1674509946020 } from './1674509946020-CreateLdapEntities';
|
||||
import { PurgeInvalidWorkflowConnections1675940580449 } from './1675940580449-PurgeInvalidWorkflowConnections';
|
||||
import { CreateLdapEntities1674509946020 } from '../common/1674509946020-CreateLdapEntities';
|
||||
import { PurgeInvalidWorkflowConnections1675940580449 } from '../common/1675940580449-PurgeInvalidWorkflowConnections';
|
||||
import { AddStatusToExecutions1674138566000 } from './1674138566000-AddStatusToExecutions';
|
||||
import { MigrateExecutionStatus1676996103000 } from './1676996103000-MigrateExecutionStatus';
|
||||
import { UpdateRunningExecutionStatus1677236854063 } from './1677236854063-UpdateRunningExecutionStatus';
|
||||
|
||||
Reference in New Issue
Block a user