diff --git a/.github/workflows/ci-postgres-mysql.yml b/.github/workflows/ci-postgres.yml similarity index 56% rename from .github/workflows/ci-postgres-mysql.yml rename to .github/workflows/ci-postgres.yml index 3b569979e63e8..0fe17c9a4cf97 100644 --- a/.github/workflows/ci-postgres-mysql.yml +++ b/.github/workflows/ci-postgres.yml @@ -1,4 +1,4 @@ -name: Test Postgres and MySQL schemas +name: Test Postgres schemas on: schedule: @@ -14,7 +14,7 @@ on: - packages/cli/test/shared/db/** - packages/@n8n/db/** - packages/cli/**/__tests__/** - - .github/workflows/ci-postgres-mysql.yml + - .github/workflows/ci-postgres.yml - .github/docker-compose.yml concurrency: @@ -53,65 +53,6 @@ jobs: working-directory: packages/cli run: pnpm test:sqlite - mariadb: - name: MariaDB - needs: build - runs-on: blacksmith-4vcpu-ubuntu-2204 - timeout-minutes: 30 - if: false - env: - DB_MYSQLDB_PASSWORD: password - DB_MYSQLDB_POOL_SIZE: 1 - DB_MYSQLDB_CONNECTION_TIMEOUT: 120000 - DB_MYSQLDB_ACQUIRE_TIMEOUT: 120000 - DB_MYSQLDB_TIMEOUT: 120000 - NODE_OPTIONS: '--max-old-space-size=7168' - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Setup and Build - uses: ./.github/actions/setup-nodejs - - - name: Start MariaDB - uses: isbang/compose-action@802a148945af6399a338c7906c267331b39a71af # v2.0.0 - with: - compose-file: ./.github/docker-compose.yml - services: | - mariadb - - - name: Test MariaDB - working-directory: packages/cli - run: pnpm test:mariadb --testTimeout 120000 - - mysql: - name: MySQL 8.4 - needs: build - runs-on: blacksmith-2vcpu-ubuntu-2204 - timeout-minutes: 20 - if: false - env: - DB_MYSQLDB_PASSWORD: password - DB_MYSQLDB_POOL_SIZE: 1 - DB_MYSQLDB_CONNECTION_TIMEOUT: 120000 - DB_MYSQLDB_ACQUIRE_TIMEOUT: 120000 - DB_MYSQLDB_TIMEOUT: 120000 - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Setup and Build - uses: ./.github/actions/setup-nodejs - - - name: Start MySQL - uses: isbang/compose-action@802a148945af6399a338c7906c267331b39a71af # v2.0.0 - with: - compose-file: ./.github/docker-compose.yml - services: mysql-8.4 - - - name: Test MySQL - working-directory: packages/cli - # We sleep here due to flakiness with DB tests if we connect to the database too soon - run: sleep 2s && pnpm test:mysql --testTimeout 120000 - postgres: name: Postgres needs: build @@ -149,4 +90,4 @@ jobs: status: ${{ job.status }} channel: '#alerts-build' webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} - message: Postgres, MariaDB or MySQL tests failed (${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + message: Postgres tests failed (${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) diff --git a/packages/@n8n/api-types/src/frontend-settings.ts b/packages/@n8n/api-types/src/frontend-settings.ts index 46f0413db2f2e..5b437b2aca465 100644 --- a/packages/@n8n/api-types/src/frontend-settings.ts +++ b/packages/@n8n/api-types/src/frontend-settings.ts @@ -64,7 +64,7 @@ export interface FrontendSettings { settingsMode?: 'public' | 'authenticated'; inE2ETests: boolean; isDocker: boolean; - databaseType: 'sqlite' | 'mariadb' | 'mysqldb' | 'postgresdb'; + databaseType: 'sqlite' | 'postgresdb'; endpointForm: string; endpointFormTest: string; endpointFormWaiting: string; diff --git a/packages/@n8n/backend-test-utils/src/test-db.ts b/packages/@n8n/backend-test-utils/src/test-db.ts index e7d1e4b35e990..c00781e4d858c 100644 --- a/packages/@n8n/backend-test-utils/src/test-db.ts +++ b/packages/@n8n/backend-test-utils/src/test-db.ts @@ -12,15 +12,14 @@ let isInitialized = false; /** * Generate options for a bootstrap DB connection, to create and drop test databases. */ -export const getBootstrapDBOptions = (dbType: 'postgresdb' | 'mysqldb'): DataSourceOptions => { +export const getBootstrapDBOptions = (dbType: 'postgresdb'): DataSourceOptions => { const globalConfig = Container.get(GlobalConfig); - const type = dbType === 'postgresdb' ? 'postgres' : 'mysql'; return { - type, + type: 'postgres', ...Container.get(DbConnectionOptions).getOverrides(dbType), - database: type, + database: 'postgres', entityPrefix: globalConfig.database.tablePrefix, - schema: dbType === 'postgresdb' ? globalConfig.database.postgresdb.schema : undefined, + schema: globalConfig.database.postgresdb.schema, }; }; @@ -42,12 +41,6 @@ export async function init() { await bootstrapPostgres.destroy(); globalConfig.database.postgresdb.database = testDbName; - } else if (dbType === 'mysqldb' || dbType === 'mariadb') { - const bootstrapMysql = await new Connection(getBootstrapDBOptions('mysqldb')).initialize(); - await bootstrapMysql.query(`CREATE DATABASE ${testDbName} DEFAULT CHARACTER SET utf8mb4`); - await bootstrapMysql.destroy(); - - globalConfig.database.mysqldb.database = testDbName; } const dbConnection = Container.get(DbConnection); @@ -97,44 +90,31 @@ type EntityName = */ export async function truncate(entities: EntityName[]) { const connection = Container.get(Connection); - const dbType = connection.options.type; - - // Disable FK checks for MySQL/MariaDB to handle circular dependencies - if (dbType === 'mysql' || dbType === 'mariadb') { - await connection.query('SET FOREIGN_KEY_CHECKS=0'); - } - try { - // Collect junction tables to clean - const junctionTablesToClean = new Set(); - - // Find all junction tables associated with the entities being truncated - for (const name of entities) { - try { - const metadata = connection.getMetadata(name); - for (const relation of metadata.manyToManyRelations) { - if (relation.junctionEntityMetadata) { - const junctionTableName = relation.junctionEntityMetadata.tablePath; - junctionTablesToClean.add(junctionTableName); - } + // Collect junction tables to clean + const junctionTablesToClean = new Set(); + + // Find all junction tables associated with the entities being truncated + for (const name of entities) { + try { + const metadata = connection.getMetadata(name); + for (const relation of metadata.manyToManyRelations) { + if (relation.junctionEntityMetadata) { + const junctionTableName = relation.junctionEntityMetadata.tablePath; + junctionTablesToClean.add(junctionTableName); } - } catch (error) { - // Skip } + } catch (error) { + // Skip } + } - // Clean junction tables first (since they reference the entities) - for (const tableName of junctionTablesToClean) { - await connection.query(`DELETE FROM ${tableName}`); - } + // Clean junction tables first (since they reference the entities) + for (const tableName of junctionTablesToClean) { + await connection.query(`DELETE FROM ${tableName}`); + } - for (const name of entities) { - await connection.getRepository(name).delete({}); - } - } finally { - // Re-enable FK checks - if (dbType === 'mysql' || dbType === 'mariadb') { - await connection.query('SET FOREIGN_KEY_CHECKS=1'); - } + for (const name of entities) { + await connection.getRepository(name).delete({}); } } diff --git a/packages/@n8n/config/src/configs/__tests__/database.config.test.ts b/packages/@n8n/config/src/configs/__tests__/database.config.test.ts index e50273462ec65..90edb51b981d6 100644 --- a/packages/@n8n/config/src/configs/__tests__/database.config.test.ts +++ b/packages/@n8n/config/src/configs/__tests__/database.config.test.ts @@ -8,7 +8,7 @@ describe('DatabaseConfig', () => { jest.clearAllMocks(); }); - test.each(['sqlite', 'mariadb', 'mysqldb', 'postgresdb'] satisfies Array)( + test.each(['sqlite', 'postgresdb'] satisfies Array)( '`isLegacySqlite` returns false if dbType is `%s`', (dbType) => { const databaseConfig = Container.get(DatabaseConfig); diff --git a/packages/@n8n/config/src/configs/database.config.ts b/packages/@n8n/config/src/configs/database.config.ts index fc60af9e41834..33480c32cda0b 100644 --- a/packages/@n8n/config/src/configs/database.config.ts +++ b/packages/@n8n/config/src/configs/database.config.ts @@ -5,17 +5,6 @@ import { Config, Env, Nested } from '../decorators'; const dbLoggingOptionsSchema = z.enum(['query', 'error', 'schema', 'warn', 'info', 'log', 'all']); type DbLoggingOptions = z.infer; -class MySqlMariaDbNotSupportedError extends Error { - // Workaround to not get this reported to Sentry - readonly cause: { level: 'warning' } = { - level: 'warning', - }; - - constructor() { - super('MySQL and MariaDB have been removed. Please migrate to PostgreSQL.'); - } -} - @Config class LoggingConfig { /** Whether database logging is enabled. */ @@ -103,33 +92,6 @@ class PostgresConfig { ssl: PostgresSSLConfig; } -@Config -class MysqlConfig { - /** @deprecated MySQL database name */ - @Env('DB_MYSQLDB_DATABASE') - database: string = 'n8n'; - - /** MySQL database host */ - @Env('DB_MYSQLDB_HOST') - host: string = 'localhost'; - - /** MySQL database password */ - @Env('DB_MYSQLDB_PASSWORD') - password: string = ''; - - /** MySQL database port */ - @Env('DB_MYSQLDB_PORT') - port: number = 3306; - - /** MySQL database user */ - @Env('DB_MYSQLDB_USER') - user: string = 'root'; - - /** MySQL connection pool size */ - @Env('DB_MYSQLDB_POOL_SIZE') - poolSize: number = 10; -} - const sqlitePoolSizeSchema = z.coerce.number().int().gte(1); @Config @@ -157,7 +119,7 @@ export class SqliteConfig { executeVacuumOnStartup: boolean = false; } -const dbTypeSchema = z.enum(['sqlite', 'mariadb', 'mysqldb', 'postgresdb']); +const dbTypeSchema = z.enum(['sqlite', 'postgresdb']); type DbType = z.infer; @Config @@ -189,15 +151,6 @@ export class DatabaseConfig { @Nested postgresdb: PostgresConfig; - @Nested - mysqldb: MysqlConfig; - @Nested sqlite: SqliteConfig; - - sanitize() { - if (this.type === 'mariadb' || this.type === 'mysqldb') { - throw new MySqlMariaDbNotSupportedError(); - } - } } diff --git a/packages/@n8n/config/test/config.test.ts b/packages/@n8n/config/test/config.test.ts index b50a4065a9bbd..1d127c95ced0c 100644 --- a/packages/@n8n/config/test/config.test.ts +++ b/packages/@n8n/config/test/config.test.ts @@ -68,14 +68,6 @@ describe('GlobalConfig', () => { maxQueryExecutionTime: 0, options: 'error', }, - mysqldb: { - database: 'n8n', - host: 'localhost', - password: '', - port: 3306, - user: 'root', - poolSize: 10, - }, postgresdb: { database: 'n8n', host: 'localhost', @@ -451,7 +443,6 @@ describe('GlobalConfig', () => { ...defaultConfig, database: { logging: defaultConfig.database.logging, - mysqldb: defaultConfig.database.mysqldb, postgresdb: { ...defaultConfig.database.postgresdb, host: 'some-host', diff --git a/packages/@n8n/db/src/connection/__tests__/db-connection-options.test.ts b/packages/@n8n/db/src/connection/__tests__/db-connection-options.test.ts index 5e3f1300509de..1a7d5310021ec 100644 --- a/packages/@n8n/db/src/connection/__tests__/db-connection-options.test.ts +++ b/packages/@n8n/db/src/connection/__tests__/db-connection-options.test.ts @@ -3,7 +3,6 @@ import type { GlobalConfig, InstanceSettingsConfig } from '@n8n/config'; import { mock } from 'jest-mock-extended'; import path from 'path'; -import { mysqlMigrations } from '../../migrations/mysqldb'; import { postgresMigrations } from '../../migrations/postgresdb'; import { sqliteMigrations } from '../../migrations/sqlite'; import { DbConnectionOptions } from '../db-connection-options'; @@ -149,57 +148,6 @@ describe('DbConnectionOptions', () => { }); }); - describe('for MySQL / MariaDB', () => { - beforeEach(() => { - dbConfig.mysqldb = { - database: 'test_db', - host: 'localhost', - port: 3306, - user: 'root', - password: 'password', - poolSize: 10, - }; - }); - - it('should return MySQL connection options when type is mysqldb', () => { - dbConfig.type = 'mysqldb'; - - const result = dbConnectionOptions.getOptions(); - - expect(result).toEqual({ - type: 'mysql', - ...commonOptions, - database: 'test_db', - host: 'localhost', - port: 3306, - username: 'root', - password: 'password', - migrations: mysqlMigrations, - timezone: 'Z', - poolSize: 10, - }); - }); - - it('should return MariaDB connection options when type is mariadb', () => { - dbConfig.type = 'mariadb'; - - const result = dbConnectionOptions.getOptions(); - - expect(result).toEqual({ - type: 'mariadb', - ...commonOptions, - database: 'test_db', - host: 'localhost', - port: 3306, - username: 'root', - password: 'password', - migrations: mysqlMigrations, - timezone: 'Z', - poolSize: 10, - }); - }); - }); - describe('logging', () => { beforeEach(() => { dbConfig.type = 'sqlite'; diff --git a/packages/@n8n/db/src/connection/__tests__/db-connection.test.ts b/packages/@n8n/db/src/connection/__tests__/db-connection.test.ts index 9411c0bd6d179..2addb2c7b299a 100644 --- a/packages/@n8n/db/src/connection/__tests__/db-connection.test.ts +++ b/packages/@n8n/db/src/connection/__tests__/db-connection.test.ts @@ -3,7 +3,7 @@ import type { Logger } from '@n8n/backend-common'; import type { DatabaseConfig } from '@n8n/config'; import { DataSource, type DataSourceOptions } from '@n8n/typeorm'; import { mock, mockDeep } from 'jest-mock-extended'; -import type { BinaryDataConfig, ErrorReporter } from 'n8n-core'; +import type { ErrorReporter } from 'n8n-core'; import { DbConnectionTimeoutError } from 'n8n-workflow'; import * as migrationHelper from '../../migrations/migration-helpers'; @@ -24,10 +24,6 @@ describe('DbConnection', () => { const errorReporter = mock(); const databaseConfig = mock(); const logger = mock(); - const binaryDataConfig = mock({ - availableModes: ['filesystem'], - dbMaxFileSize: 512, - }); const dataSource = mockDeep({ options: { migrations } }); const connectionOptions = mockDeep(); const postgresOptions: DataSourceOptions = { @@ -46,13 +42,7 @@ describe('DbConnection', () => { connectionOptions.getOptions.mockReturnValue(postgresOptions); (DataSource as jest.Mock) = jest.fn().mockImplementation(() => dataSource); - dbConnection = new DbConnection( - errorReporter, - connectionOptions, - databaseConfig, - logger, - binaryDataConfig, - ); + dbConnection = new DbConnection(errorReporter, connectionOptions, databaseConfig, logger); }); describe('init', () => { @@ -206,7 +196,6 @@ describe('DbConnection', () => { pingIntervalSeconds: 1, }), logger, - binaryDataConfig, ); // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/@n8n/db/src/connection/db-connection-options.ts b/packages/@n8n/db/src/connection/db-connection-options.ts index 6934904df7dc9..488c13b3aea54 100644 --- a/packages/@n8n/db/src/connection/db-connection-options.ts +++ b/packages/@n8n/db/src/connection/db-connection-options.ts @@ -2,7 +2,6 @@ import { ModuleRegistry } from '@n8n/backend-common'; import { DatabaseConfig, InstanceSettingsConfig } from '@n8n/config'; import { Service } from '@n8n/di'; import type { DataSourceOptions, LoggerOptions } from '@n8n/typeorm'; -import type { MysqlConnectionOptions } from '@n8n/typeorm/driver/mysql/MysqlConnectionOptions'; import type { PostgresConnectionOptions } from '@n8n/typeorm/driver/postgres/PostgresConnectionOptions'; import type { SqliteConnectionOptions } from '@n8n/typeorm/driver/sqlite/SqliteConnectionOptions'; import type { SqlitePooledConnectionOptions } from '@n8n/typeorm/driver/sqlite-pooled/SqlitePooledConnectionOptions'; @@ -11,7 +10,6 @@ import type { TlsOptions } from 'node:tls'; import path from 'path'; import { entities } from '../entities'; -import { mysqlMigrations } from '../migrations/mysqldb'; import { postgresMigrations } from '../migrations/postgresdb'; import { sqliteMigrations } from '../migrations/sqlite'; import { subscribers } from '../subscribers'; @@ -24,7 +22,7 @@ export class DbConnectionOptions { private readonly moduleRegistry: ModuleRegistry, ) {} - getOverrides(dbType: 'postgresdb' | 'mysqldb') { + getOverrides(dbType: 'postgresdb') { const dbConfig = this.config[dbType]; return { database: dbConfig.database, @@ -42,9 +40,6 @@ export class DbConnectionOptions { return this.getSqliteConnectionOptions(); case 'postgresdb': return this.getPostgresConnectionOptions(); - case 'mariadb': - case 'mysqldb': - return this.getMysqlConnectionOptions(dbType); default: throw new UserError('Database type currently not supported', { extra: { dbType } }); } @@ -133,16 +128,4 @@ export class DbConnectionOptions { }, }; } - - private getMysqlConnectionOptions(dbType: 'mariadb' | 'mysqldb'): MysqlConnectionOptions { - const { mysqldb: mysqlConfig } = this.config; - return { - type: dbType === 'mysqldb' ? 'mysql' : 'mariadb', - ...this.getCommonOptions(), - ...this.getOverrides('mysqldb'), - poolSize: mysqlConfig.poolSize, - migrations: mysqlMigrations, - timezone: 'Z', // set UTC as default - }; - } } diff --git a/packages/@n8n/db/src/connection/db-connection.ts b/packages/@n8n/db/src/connection/db-connection.ts index 17824f0441b90..3bebdd37b3050 100644 --- a/packages/@n8n/db/src/connection/db-connection.ts +++ b/packages/@n8n/db/src/connection/db-connection.ts @@ -4,7 +4,7 @@ import { Time } from '@n8n/constants'; import { Memoized } from '@n8n/decorators'; import { Container, Service } from '@n8n/di'; import { DataSource } from '@n8n/typeorm'; -import { BinaryDataConfig, ErrorReporter } from 'n8n-core'; +import { ErrorReporter } from 'n8n-core'; import { DbConnectionTimeoutError, ensureError, OperationalError } from 'n8n-workflow'; import { setTimeout as setTimeoutP } from 'timers/promises'; @@ -33,7 +33,6 @@ export class DbConnection { private readonly connectionOptions: DbConnectionOptions, private readonly databaseConfig: DatabaseConfig, private readonly logger: Logger, - private readonly binaryDataConfig: BinaryDataConfig, ) { this.dataSource = new DataSource(this.options); Container.set(DataSource, this.dataSource); @@ -63,21 +62,6 @@ export class DbConnection { throw error; } - if ( - (options.type === 'mysql' || options.type === 'mariadb') && - this.binaryDataConfig.availableModes.includes('database') - ) { - const maxAllowedPacket = this.binaryDataConfig.dbMaxFileSize * 1024 * 1024; - try { - await this.dataSource.query(`SET GLOBAL max_allowed_packet = ${maxAllowedPacket}`); - } catch { - this.logger.warn( - `Failed to set \`max_allowed_packet\` to ${maxAllowedPacket} bytes on your MySQL server. ` + - `Please set \`max_allowed_packet\` to at least ${this.binaryDataConfig.dbMaxFileSize} MiB in your MySQL server configuration.`, - ); - } - } - connectionState.connected = true; if (!inTest) this.scheduleNextPing(); } diff --git a/packages/@n8n/db/src/entities/abstract-entity.ts b/packages/@n8n/db/src/entities/abstract-entity.ts index 1e66e13afe10c..7ed9558fb5800 100644 --- a/packages/@n8n/db/src/entities/abstract-entity.ts +++ b/packages/@n8n/db/src/entities/abstract-entity.ts @@ -15,20 +15,17 @@ import { generateNanoId } from '../utils/generators'; export const { type: dbType } = Container.get(GlobalConfig).database; -const timestampSyntax = { +const timestampSyntaxMap = { sqlite: "STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')", postgresdb: 'CURRENT_TIMESTAMP(3)', - mysqldb: 'CURRENT_TIMESTAMP(3)', - mariadb: 'CURRENT_TIMESTAMP(3)', -}[dbType]; +} as const; +const timestampSyntax = timestampSyntaxMap[dbType]; export const jsonColumnType = dbType === 'sqlite' ? 'simple-json' : 'json'; export const datetimeColumnType = dbType === 'postgresdb' ? 'timestamptz' : 'datetime'; const binaryColumnTypeMap = { sqlite: 'blob', postgresdb: 'bytea', - mysqldb: 'longblob', - mariadb: 'longblob', } as const; const binaryColumnType = binaryColumnTypeMap[dbType]; diff --git a/packages/@n8n/db/src/index.ts b/packages/@n8n/db/src/index.ts index 54db96c74aaac..0c988479603b2 100644 --- a/packages/@n8n/db/src/index.ts +++ b/packages/@n8n/db/src/index.ts @@ -29,7 +29,6 @@ export * from './subscribers'; export { Column as DslColumn } from './migrations/dsl/column'; export { CreateTable } from './migrations/dsl/table'; export { sqliteMigrations } from './migrations/sqlite'; -export { mysqlMigrations } from './migrations/mysqldb'; export { postgresMigrations } from './migrations/postgresdb'; export { wrapMigration } from './migrations/migration-helpers'; diff --git a/packages/@n8n/db/src/migrations/common/1620821879465-UniqueWorkflowNames.ts b/packages/@n8n/db/src/migrations/common/1620821879465-UniqueWorkflowNames.ts index 714d2f28e28e0..31b4feeecfa25 100644 --- a/packages/@n8n/db/src/migrations/common/1620821879465-UniqueWorkflowNames.ts +++ b/packages/@n8n/db/src/migrations/common/1620821879465-UniqueWorkflowNames.ts @@ -4,7 +4,7 @@ import type { MigrationContext, ReversibleMigration } from '../migration-types'; export class UniqueWorkflowNames1620821879465 implements ReversibleMigration { protected indexSuffix = '943d8f922be094eb507cb9a7f9'; - async up({ isMysql, escape, runQuery }: MigrationContext) { + async up({ escape, runQuery }: MigrationContext) { const tableName = escape.tableName('workflow_entity'); const workflowNames: Array> = await runQuery( `SELECT name FROM ${tableName}`, @@ -30,18 +30,11 @@ export class UniqueWorkflowNames1620821879465 implements ReversibleMigration { } const indexName = escape.indexName(this.indexSuffix); - await runQuery( - isMysql - ? `ALTER TABLE ${tableName} ADD UNIQUE INDEX ${indexName} (${escape.columnName('name')})` - : `CREATE UNIQUE INDEX ${indexName} ON ${tableName} ("name")`, - ); + await runQuery(`CREATE UNIQUE INDEX ${indexName} ON ${tableName} ("name")`); } - async down({ isMysql, escape, runQuery }: MigrationContext) { - const tableName = escape.tableName('workflow_entity'); + async down({ escape, runQuery }: MigrationContext) { const indexName = escape.indexName(this.indexSuffix); - await runQuery( - isMysql ? `ALTER TABLE ${tableName} DROP INDEX ${indexName}` : `DROP INDEX ${indexName}`, - ); + await runQuery(`DROP INDEX ${indexName}`); } } diff --git a/packages/@n8n/db/src/migrations/common/1674509946020-CreateLdapEntities.ts b/packages/@n8n/db/src/migrations/common/1674509946020-CreateLdapEntities.ts index 8846da118e812..3a678ba5df11a 100644 --- a/packages/@n8n/db/src/migrations/common/1674509946020-CreateLdapEntities.ts +++ b/packages/@n8n/db/src/migrations/common/1674509946020-CreateLdapEntities.ts @@ -3,7 +3,7 @@ import { LDAP_FEATURE_NAME, LDAP_DEFAULT_CONFIGURATION } from '@n8n/constants'; import type { MigrationContext, ReversibleMigration } from '../migration-types'; export class CreateLdapEntities1674509946020 implements ReversibleMigration { - async up({ escape, dbType, isMysql, runQuery }: MigrationContext) { + async up({ escape, dbType, runQuery }: MigrationContext) { const userTable = escape.tableName('user'); await runQuery(`ALTER TABLE ${userTable} ADD COLUMN disabled BOOLEAN NOT NULL DEFAULT false;`); @@ -23,7 +23,7 @@ export class CreateLdapEntities1674509946020 implements ReversibleMigration { ${escape.columnName('createdAt')} timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, ${escape.columnName('updatedAt')} timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(${escape.columnName('providerId')}, ${escape.columnName('providerType')}) - )${isMysql ? "ENGINE='InnoDB'" : ''}`, + )`, ); const idColumn = @@ -53,8 +53,7 @@ export class CreateLdapEntities1674509946020 implements ReversibleMigration { ${escape.columnName('updated')} INTEGER NOT NULL, ${escape.columnName('disabled')} INTEGER NOT NULL, ${escape.columnName('error')} TEXT - ${isMysql ? ',PRIMARY KEY (`id`)' : ''} - )${isMysql ? "ENGINE='InnoDB'" : ''}`, + )`, ); } diff --git a/packages/@n8n/db/src/migrations/common/1714133768519-CreateProject.ts b/packages/@n8n/db/src/migrations/common/1714133768519-CreateProject.ts index 6bf6ef5f0661a..13d9dcd96076a 100644 --- a/packages/@n8n/db/src/migrations/common/1714133768519-CreateProject.ts +++ b/packages/@n8n/db/src/migrations/common/1714133768519-CreateProject.ts @@ -1,6 +1,5 @@ import type { ProjectRole } from '@n8n/permissions'; import { UserError } from 'n8n-workflow'; -import { nanoid } from 'nanoid'; import type { User } from '../../entities'; import { generateNanoId } from '../../utils/generators'; @@ -76,7 +75,6 @@ export class CreateProject1714133768519 implements ReversibleMigration { relationTableName: RelationTable, { escape, - isMysql, runQuery, schemaBuilder: { addForeignKey, addColumns, addNotNull, createIndex, column }, }: MigrationContext, @@ -97,11 +95,7 @@ export class CreateProject1714133768519 implements ReversibleMigration { ON T.${c.userId} = S.${c.userId} WHERE P.id IS NOT NULL `; - const swQuery = isMysql - ? `UPDATE ${relationTable}, (${subQuery}) as mapping - SET ${relationTable}.${c.projectId} = mapping.${c.projectId} - WHERE ${relationTable}.${c.userId} = mapping.${c.userId}` - : `UPDATE ${relationTable} + const swQuery = `UPDATE ${relationTable} SET ${c.projectId} = mapping.${c.projectId} FROM (${subQuery}) as mapping WHERE ${relationTable}.${c.userId} = mapping.${c.userId}`; @@ -237,7 +231,7 @@ export class CreateProject1714133768519 implements ReversibleMigration { await this.alterSharedWorkflow(context); } - async down({ isMysql, logger, escape, runQuery, schemaBuilder: sb }: MigrationContext) { + async down({ logger, escape, runQuery, schemaBuilder: sb }: MigrationContext) { const { t, c } = escapeNames(escape); // 0. check if all projects are personal projects @@ -268,7 +262,7 @@ export class CreateProject1714133768519 implements ReversibleMigration { // TypeORM creates predictable names based on the columnName. // So the current shared_workflow table's foreignKey for workflowId would // clash with this one if we don't create a random name. - name: isMysql ? nanoid() : undefined, + name: undefined, }) .withForeignKey('userId', { tableName: table.user, @@ -306,7 +300,7 @@ export class CreateProject1714133768519 implements ReversibleMigration { // TypeORM creates predictable names based on the columnName. // So the current shared_credentials table's foreignKey for credentialsId would // clash with this one if we don't create a random name. - name: isMysql ? nanoid() : undefined, + name: undefined, }) .withForeignKey('userId', { tableName: table.user, diff --git a/packages/@n8n/db/src/migrations/common/1720101653148-AddConstraintToExecutionMetadata.ts b/packages/@n8n/db/src/migrations/common/1720101653148-AddConstraintToExecutionMetadata.ts index 8c958855ae6d5..a309169c9f037 100644 --- a/packages/@n8n/db/src/migrations/common/1720101653148-AddConstraintToExecutionMetadata.ts +++ b/packages/@n8n/db/src/migrations/common/1720101653148-AddConstraintToExecutionMetadata.ts @@ -33,22 +33,11 @@ export class AddConstraintToExecutionMetadata1720101653148 implements Reversible // In MySQL foreignKey names must be unique across all tables and // TypeORM creates predictable names based on the columnName. // So the temp table's foreignKey clashes with the current table's. - name: context.isMysql ? nanoid() : undefined, + name: undefined, }) .withIndexOn(['executionId', 'key'], true); - if (context.isMysql) { - await context.runQuery(` - INSERT INTO ${executionMetadataTableTemp} (${id}, ${executionId}, ${key}, ${value}) - SELECT MAX(${id}) as ${id}, ${executionId}, ${key}, MAX(${value}) - FROM ${executionMetadataTable} - GROUP BY ${executionId}, ${key} - ON DUPLICATE KEY UPDATE - id = IF(VALUES(${id}) > ${executionMetadataTableTemp}.${id}, VALUES(${id}), ${executionMetadataTableTemp}.${id}), - value = IF(VALUES(${id}) > ${executionMetadataTableTemp}.${id}, VALUES(${value}), ${executionMetadataTableTemp}.${value}); - `); - } else { - await context.runQuery(` + await context.runQuery(` INSERT INTO ${executionMetadataTableTemp} (${id}, ${executionId}, ${key}, ${value}) SELECT MAX(${id}) as ${id}, ${executionId}, ${key}, MAX(${value}) FROM ${executionMetadataTable} @@ -58,7 +47,6 @@ export class AddConstraintToExecutionMetadata1720101653148 implements Reversible value = EXCLUDED.value WHERE EXCLUDED.id > ${executionMetadataTableTemp}.id; `); - } await dropTable(executionMetadataTableRaw); await context.runQuery( @@ -97,7 +85,7 @@ export class AddConstraintToExecutionMetadata1720101653148 implements Reversible // In MySQL foreignKey names must be unique across all tables and // TypeORM creates predictable names based on the columnName. // So the temp table's foreignKey clashes with the current table's. - name: context.isMysql ? nanoid() : undefined, + name: undefined, }); await context.runQuery(` diff --git a/packages/@n8n/db/src/migrations/common/1723796243146-RefactorExecutionIndices.ts b/packages/@n8n/db/src/migrations/common/1723796243146-RefactorExecutionIndices.ts index 32d45946980ac..1b3adc2e7c894 100644 --- a/packages/@n8n/db/src/migrations/common/1723796243146-RefactorExecutionIndices.ts +++ b/packages/@n8n/db/src/migrations/common/1723796243146-RefactorExecutionIndices.ts @@ -31,7 +31,7 @@ import type { MigrationContext, ReversibleMigration } from '../migration-types'; * - `deletedAt` for query at `ExecutionRepository.hardDeleteSoftDeletedExecutions` */ export class RefactorExecutionIndices1723796243146 implements ReversibleMigration { - async up({ schemaBuilder, isPostgres, isSqlite, isMysql, runQuery, escape }: MigrationContext) { + async up({ schemaBuilder, isPostgres, isSqlite, runQuery, escape }: MigrationContext) { if (isSqlite || isPostgres) { const executionEntity = escape.tableName('execution_entity'); @@ -59,10 +59,6 @@ export class RefactorExecutionIndices1723796243146 implements ReversibleMigratio ON ${executionEntity} (${stoppedAt}, ${status}, ${deletedAt}) WHERE ${stoppedAt} IS NOT NULL AND ${deletedAt} IS NULL; `); - } else if (isMysql) { - await schemaBuilder.createIndex('execution_entity', ['workflowId', 'startedAt']); - await schemaBuilder.createIndex('execution_entity', ['waitTill', 'status', 'deletedAt']); - await schemaBuilder.createIndex('execution_entity', ['stoppedAt', 'status', 'deletedAt']); } if (isSqlite) { @@ -77,13 +73,6 @@ export class RefactorExecutionIndices1723796243146 implements ReversibleMigratio }); } - if (isMysql) { - await schemaBuilder.dropIndex('execution_entity', ['status'], { - customIndexName: 'IDX_8b6f3f9ae234f137d707b98f3bf43584', - skipIfMissing: true, - }); - } - // all DBs await schemaBuilder.dropIndex( @@ -98,10 +87,9 @@ export class RefactorExecutionIndices1723796243146 implements ReversibleMigratio skipIfMissing: true, }); await schemaBuilder.dropIndex('execution_entity', ['workflowId', 'id'], { - customIndexName: - isPostgres || isMysql - ? 'idx_execution_entity_workflow_id_id' - : 'IDX_81fc04c8a17de15835713505e4', + customIndexName: isPostgres + ? 'idx_execution_entity_workflow_id_id' + : 'IDX_81fc04c8a17de15835713505e4', skipIfMissing: true, }); } diff --git a/packages/@n8n/db/src/migrations/common/1724951148974-AddApiKeysTable.ts b/packages/@n8n/db/src/migrations/common/1724951148974-AddApiKeysTable.ts index a5e8f0764a9d3..d592969377a3b 100644 --- a/packages/@n8n/db/src/migrations/common/1724951148974-AddApiKeysTable.ts +++ b/packages/@n8n/db/src/migrations/common/1724951148974-AddApiKeysTable.ts @@ -61,7 +61,6 @@ export class AddApiKeysTable1724951148974 implements ReversibleMigration { runQuery, schemaBuilder: { dropTable, addColumns, createIndex, column }, escape, - isMysql, }: MigrationContext) { const userTable = escape.tableName('user'); const userApiKeysTable = escape.tableName('user_api_keys'); @@ -74,16 +73,7 @@ export class AddApiKeysTable1724951148974 implements ReversibleMigration { await createIndex('user', ['apiKey'], true); - const queryToGetUsersApiKeys = isMysql - ? ` - SELECT ${userIdColumn}, - ${apiKeyColumn}, - ${createdAtColumn} - FROM ${userApiKeysTable} u - WHERE ${createdAtColumn} = (SELECT Min(${createdAtColumn}) - FROM ${userApiKeysTable} - WHERE ${userIdColumn} = u.${userIdColumn});` - : ` + const queryToGetUsersApiKeys = ` SELECT DISTINCT ON (${userIdColumn}) ${userIdColumn}, ${apiKeyColumn}, ${createdAtColumn} diff --git a/packages/@n8n/db/src/migrations/common/1729607673464-UpdateProcessedDataValueColumnToText.ts b/packages/@n8n/db/src/migrations/common/1729607673464-UpdateProcessedDataValueColumnToText.ts index 028178dff0dc0..79e2b8e43571f 100644 --- a/packages/@n8n/db/src/migrations/common/1729607673464-UpdateProcessedDataValueColumnToText.ts +++ b/packages/@n8n/db/src/migrations/common/1729607673464-UpdateProcessedDataValueColumnToText.ts @@ -2,33 +2,23 @@ import type { MigrationContext, ReversibleMigration } from '../migration-types'; const processedDataTableName = 'processed_data'; export class UpdateProcessedDataValueColumnToText1729607673464 implements ReversibleMigration { - async up({ schemaBuilder: { addNotNull }, isMysql, runQuery, tablePrefix }: MigrationContext) { + async up({ schemaBuilder: { addNotNull }, runQuery, tablePrefix }: MigrationContext) { const prefixedTableName = `${tablePrefix}${processedDataTableName}`; await runQuery(`ALTER TABLE ${prefixedTableName} ADD COLUMN value_temp TEXT;`); await runQuery(`UPDATE ${prefixedTableName} SET value_temp = value;`); await runQuery(`ALTER TABLE ${prefixedTableName} DROP COLUMN value;`); - if (isMysql) { - await runQuery(`ALTER TABLE ${prefixedTableName} CHANGE value_temp value TEXT NOT NULL;`); - } else { - await runQuery(`ALTER TABLE ${prefixedTableName} RENAME COLUMN value_temp TO value`); - await addNotNull(processedDataTableName, 'value'); - } + await runQuery(`ALTER TABLE ${prefixedTableName} RENAME COLUMN value_temp TO value`); + await addNotNull(processedDataTableName, 'value'); } - async down({ schemaBuilder: { addNotNull }, isMysql, runQuery, tablePrefix }: MigrationContext) { + async down({ schemaBuilder: { addNotNull }, runQuery, tablePrefix }: MigrationContext) { const prefixedTableName = `${tablePrefix}${processedDataTableName}`; await runQuery(`ALTER TABLE ${prefixedTableName} ADD COLUMN value_temp VARCHAR(255);`); await runQuery(`UPDATE ${prefixedTableName} SET value_temp = value;`); await runQuery(`ALTER TABLE ${prefixedTableName} DROP COLUMN value;`); - if (isMysql) { - await runQuery( - `ALTER TABLE ${prefixedTableName} CHANGE value_temp value VARCHAR(255) NOT NULL;`, - ); - } else { - await runQuery(`ALTER TABLE ${prefixedTableName} RENAME COLUMN value_temp TO value`); - await addNotNull(processedDataTableName, 'value'); - } + await runQuery(`ALTER TABLE ${prefixedTableName} RENAME COLUMN value_temp TO value`); + await addNotNull(processedDataTableName, 'value'); } } diff --git a/packages/@n8n/db/src/migrations/common/1745322634000-CleanEvaluations.ts b/packages/@n8n/db/src/migrations/common/1745322634000-CleanEvaluations.ts index 7ed240169e03e..668fadc901b97 100644 --- a/packages/@n8n/db/src/migrations/common/1745322634000-CleanEvaluations.ts +++ b/packages/@n8n/db/src/migrations/common/1745322634000-CleanEvaluations.ts @@ -8,8 +8,6 @@ export class ClearEvaluation1745322634000 implements IrreversibleMigration { queryRunner, tablePrefix, isSqlite, - isPostgres, - isMysql, }: MigrationContext) { // Drop test_metric, test_definition await dropTable(testCaseExecutionTableName); @@ -17,9 +15,7 @@ export class ClearEvaluation1745322634000 implements IrreversibleMigration { await dropTable('test_metric'); if (isSqlite) { await queryRunner.query(`DROP TABLE IF EXISTS ${tablePrefix}test_definition;`); - } else if (isPostgres) { - await queryRunner.query(`DROP TABLE IF EXISTS ${tablePrefix}test_definition CASCADE;`); - } else if (isMysql) { + } else { await queryRunner.query(`DROP TABLE IF EXISTS ${tablePrefix}test_definition CASCADE;`); } diff --git a/packages/@n8n/db/src/migrations/common/1759399811000-ChangeValueTypesForInsights.ts b/packages/@n8n/db/src/migrations/common/1759399811000-ChangeValueTypesForInsights.ts index 3bf3b474fc8fc..e9c380fc8fabf 100644 --- a/packages/@n8n/db/src/migrations/common/1759399811000-ChangeValueTypesForInsights.ts +++ b/packages/@n8n/db/src/migrations/common/1759399811000-ChangeValueTypesForInsights.ts @@ -10,7 +10,6 @@ const VALUE_COLUMN_NAME = 'value'; export class ChangeValueTypesForInsights1759399811000 implements IrreversibleMigration { async up({ isSqlite, - isMysql, isPostgres, escape, copyTable, @@ -76,13 +75,6 @@ export class ChangeValueTypesForInsights1759399811000 implements IrreversibleMig await queryRunner.query( `ALTER TABLE ${tempInsightsByPeriodTable} RENAME TO ${insightsByPeriodTable};`, ); - } else if (isMysql) { - await queryRunner.query( - `ALTER TABLE ${insightsRawTable} MODIFY COLUMN ${valueColumnName} BIGINT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${insightsByPeriodTable} MODIFY COLUMN ${valueColumnName} BIGINT NOT NULL;`, - ); } else if (isPostgres) { await queryRunner.query( `ALTER TABLE ${insightsRawTable} ALTER COLUMN ${valueColumnName} TYPE BIGINT;`, diff --git a/packages/@n8n/db/src/migrations/common/1760020838000-UniqueRoleNames.ts b/packages/@n8n/db/src/migrations/common/1760020838000-UniqueRoleNames.ts index d067f939353f6..2fb4f14e1bb72 100644 --- a/packages/@n8n/db/src/migrations/common/1760020838000-UniqueRoleNames.ts +++ b/packages/@n8n/db/src/migrations/common/1760020838000-UniqueRoleNames.ts @@ -2,7 +2,7 @@ import type { Role } from '../../entities'; import type { MigrationContext, ReversibleMigration } from '../migration-types'; export class UniqueRoleNames1760020838000 implements ReversibleMigration { - async up({ isMysql, escape, runQuery }: MigrationContext) { + async up({ escape, runQuery }: MigrationContext) { const tableName = escape.tableName('role'); const displayNameColumn = escape.columnName('displayName'); const slugColumn = escape.columnName('slug'); @@ -43,22 +43,11 @@ export class UniqueRoleNames1760020838000 implements ReversibleMigration { } const indexName = escape.indexName('UniqueRoleDisplayName'); - // MySQL cannot create an index on a column with a type of TEXT or BLOB without a length limit - // The (100) specifies the maximum length of the index key - // meaning that only the first 100 characters of the displayName column will be used for indexing - // But since in our DTOs we limit the displayName to 100 characters, we can safely use this prefix length - await runQuery( - isMysql - ? `CREATE UNIQUE INDEX ${indexName} ON ${tableName} (${displayNameColumn}(100))` - : `CREATE UNIQUE INDEX ${indexName} ON ${tableName} (${displayNameColumn})`, - ); + await runQuery(`CREATE UNIQUE INDEX ${indexName} ON ${tableName} (${displayNameColumn})`); } - async down({ isMysql, escape, runQuery }: MigrationContext) { - const tableName = escape.tableName('role'); + async down({ escape, runQuery }: MigrationContext) { const indexName = escape.indexName('UniqueRoleDisplayName'); - await runQuery( - isMysql ? `ALTER TABLE ${tableName} DROP INDEX ${indexName}` : `DROP INDEX ${indexName}`, - ); + await runQuery(`DROP INDEX ${indexName}`); } } diff --git a/packages/@n8n/db/src/migrations/common/1763572724000-ChangeOAuthStateColumnToUnboundedVarchar.ts b/packages/@n8n/db/src/migrations/common/1763572724000-ChangeOAuthStateColumnToUnboundedVarchar.ts index 7e22cee750211..fb9259c784a85 100644 --- a/packages/@n8n/db/src/migrations/common/1763572724000-ChangeOAuthStateColumnToUnboundedVarchar.ts +++ b/packages/@n8n/db/src/migrations/common/1763572724000-ChangeOAuthStateColumnToUnboundedVarchar.ts @@ -8,7 +8,6 @@ export class ChangeOAuthStateColumnToUnboundedVarchar1763572724000 { async up({ isSqlite, - isMysql, isPostgres, escape, copyTable, @@ -48,16 +47,6 @@ export class ChangeOAuthStateColumnToUnboundedVarchar1763572724000 await dropTable(TABLE_NAME); await queryRunner.query(`ALTER TABLE ${tempTableName} RENAME TO ${tableName};`); - } else if (isMysql) { - await queryRunner.query( - `ALTER TABLE ${tableName} MODIFY COLUMN ${escape.columnName('state')} TEXT;`, - ); - await queryRunner.query( - `ALTER TABLE ${tableName} MODIFY COLUMN ${escape.columnName('codeChallenge')} TEXT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tableName} MODIFY COLUMN ${escape.columnName('redirectUri')} TEXT NOT NULL;`, - ); } else if (isPostgres) { await queryRunner.query( `ALTER TABLE ${tableName} ALTER COLUMN ${escape.columnName('state')} TYPE VARCHAR,` + diff --git a/packages/@n8n/db/src/migrations/dsl/column.ts b/packages/@n8n/db/src/migrations/dsl/column.ts index 9aef4e433e5ba..2924d7f4e9399 100644 --- a/packages/@n8n/db/src/migrations/dsl/column.ts +++ b/packages/@n8n/db/src/migrations/dsl/column.ts @@ -159,7 +159,6 @@ export class Column { length, primaryKeyConstraintName, } = this; - const isMysql = 'mysql' in driver; const isPostgres = 'postgres' in driver; const isSqlite = 'sqlite' in driver; @@ -173,8 +172,6 @@ export class Column { if (options.type === 'int' && isSqlite) { options.type = 'integer'; - } else if (type === 'boolean' && isMysql) { - options.type = 'tinyint(1)'; } else if (type === 'timestamptz') { options.type = isPostgres ? 'timestamptz' : 'datetime'; } else if (type === 'timestamp') { @@ -182,15 +179,11 @@ export class Column { } else if (type === 'json' && isSqlite) { options.type = 'text'; } else if (type === 'uuid') { - // mysql does not support uuid type - if (isMysql) options.type = 'varchar(36)'; // we haven't been defining length on "uuid" varchar on sqlite if (isSqlite) options.type = 'varchar'; } else if (type === 'double') { if (isPostgres) { options.type = 'double precision'; - } else if (isMysql) { - options.type = 'double'; } else if (isSqlite) { options.type = 'real'; } @@ -199,8 +192,6 @@ export class Column { } else if (type === 'binary') { if (isPostgres) { options.type = 'bytea'; - } else if (isMysql) { - options.type = 'longblob'; } else if (isSqlite) { options.type = 'blob'; } @@ -220,7 +211,7 @@ export class Column { if (isGenerated2) { options.isGenerated = true; - options.generationStrategy = type === 'uuid' ? 'uuid' : isMysql ? 'increment' : 'identity'; + options.generationStrategy = type === 'uuid' ? 'uuid' : 'identity'; } if (isPrimary || isGenerated || isGenerated2) { diff --git a/packages/@n8n/db/src/migrations/migration-helpers.ts b/packages/@n8n/db/src/migrations/migration-helpers.ts index ce4aeb497d45b..b8bfa68947b15 100644 --- a/packages/@n8n/db/src/migrations/migration-helpers.ts +++ b/packages/@n8n/db/src/migrations/migration-helpers.ts @@ -90,17 +90,15 @@ function parseJson(data: string | T): T { const globalConfig = Container.get(GlobalConfig); const dbType = globalConfig.database.type; -const isMysql = ['mariadb', 'mysqldb'].includes(dbType); const isSqlite = dbType === 'sqlite'; const isPostgres = dbType === 'postgresdb'; -const dbName = globalConfig.database[dbType === 'mariadb' ? 'mysqldb' : dbType].database; +const dbName = globalConfig.database[dbType].database; const tablePrefix = globalConfig.database.tablePrefix; const createContext = (queryRunner: QueryRunner, migration: Migration): MigrationContext => ({ logger: Container.get(Logger), tablePrefix, dbType, - isMysql, isSqlite, isPostgres, dbName, diff --git a/packages/@n8n/db/src/migrations/migration-types.ts b/packages/@n8n/db/src/migrations/migration-types.ts index fdd427b87951b..ea23e45c402a1 100644 --- a/packages/@n8n/db/src/migrations/migration-types.ts +++ b/packages/@n8n/db/src/migrations/migration-types.ts @@ -3,14 +3,13 @@ import type { QueryRunner, ObjectLiteral } from '@n8n/typeorm'; import type { createSchemaBuilder } from './dsl'; -export type DatabaseType = 'mariadb' | 'postgresdb' | 'mysqldb' | 'sqlite'; +export type DatabaseType = 'postgresdb' | 'sqlite'; export interface MigrationContext { logger: Logger; queryRunner: QueryRunner; tablePrefix: string; dbType: DatabaseType; - isMysql: boolean; isSqlite: boolean; isPostgres: boolean; dbName: string; diff --git a/packages/@n8n/db/src/migrations/mysqldb/1588157391238-InitialMigration.ts b/packages/@n8n/db/src/migrations/mysqldb/1588157391238-InitialMigration.ts deleted file mode 100644 index 80d589916bc0e..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1588157391238-InitialMigration.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class InitialMigration1588157391238 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'CREATE TABLE IF NOT EXISTS `' + - tablePrefix + - 'credentials_entity` (`id` int NOT NULL AUTO_INCREMENT, `name` varchar(128) NOT NULL, `data` text NOT NULL, `type` varchar(32) NOT NULL, `nodesAccess` json NOT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, INDEX `IDX_' + - tablePrefix + - '07fde106c0b471d8cc80a64fc8` (`type`), PRIMARY KEY (`id`)) ENGINE=InnoDB', - ); - await queryRunner.query( - 'CREATE TABLE IF NOT EXISTS `' + - tablePrefix + - 'execution_entity` (`id` int NOT NULL AUTO_INCREMENT, `data` text NOT NULL, `finished` tinyint NOT NULL, `mode` varchar(255) NOT NULL, `retryOf` varchar(255) NULL, `retrySuccessId` varchar(255) NULL, `startedAt` datetime NOT NULL, `stoppedAt` datetime NOT NULL, `workflowData` json NOT NULL, `workflowId` varchar(255) NULL, INDEX `IDX_' + - tablePrefix + - 'c4d999a5e90784e8caccf5589d` (`workflowId`), PRIMARY KEY (`id`)) ENGINE=InnoDB', - ); - await queryRunner.query( - 'CREATE TABLE IF NOT EXISTS`' + - tablePrefix + - 'workflow_entity` (`id` int NOT NULL AUTO_INCREMENT, `name` varchar(128) NOT NULL, `active` tinyint NOT NULL, `nodes` json NOT NULL, `connections` json NOT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, `settings` json NULL, `staticData` json NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query('DROP TABLE `' + tablePrefix + 'workflow_entity`'); - await queryRunner.query( - 'DROP INDEX `IDX_' + - tablePrefix + - 'c4d999a5e90784e8caccf5589d` ON `' + - tablePrefix + - 'execution_entity`', - ); - await queryRunner.query('DROP TABLE `' + tablePrefix + 'execution_entity`'); - await queryRunner.query( - 'DROP INDEX `IDX_' + - tablePrefix + - '07fde106c0b471d8cc80a64fc8` ON `' + - tablePrefix + - 'credentials_entity`', - ); - await queryRunner.query('DROP TABLE `' + tablePrefix + 'credentials_entity`'); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1592447867632-WebhookModel.ts b/packages/@n8n/db/src/migrations/mysqldb/1592447867632-WebhookModel.ts deleted file mode 100644 index 34d8ca33d8d61..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1592447867632-WebhookModel.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class WebhookModel1592447867632 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `CREATE TABLE IF NOT EXISTS ${tablePrefix}webhook_entity (workflowId int NOT NULL, webhookPath varchar(255) NOT NULL, method varchar(255) NOT NULL, node varchar(255) NOT NULL, PRIMARY KEY (webhookPath, method)) ENGINE=InnoDB`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`DROP TABLE ${tablePrefix}webhook_entity`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1594902918301-CreateIndexStoppedAt.ts b/packages/@n8n/db/src/migrations/mysqldb/1594902918301-CreateIndexStoppedAt.ts deleted file mode 100644 index afecd45ce03bd..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1594902918301-CreateIndexStoppedAt.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CreateIndexStoppedAt1594902918301 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'CREATE INDEX `IDX_' + - tablePrefix + - 'cefb067df2402f6aed0638a6c1` ON `' + - tablePrefix + - 'execution_entity` (`stoppedAt`)', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'DROP INDEX `IDX_' + - tablePrefix + - 'cefb067df2402f6aed0638a6c1` ON `' + - tablePrefix + - 'execution_entity`', - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1607431743767-MakeStoppedAtNullable.ts b/packages/@n8n/db/src/migrations/mysqldb/1607431743767-MakeStoppedAtNullable.ts deleted file mode 100644 index 80f8a92275d7e..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1607431743767-MakeStoppedAtNullable.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class MakeStoppedAtNullable1607431743767 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'execution_entity` MODIFY `stoppedAt` datetime', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'execution_entity` MODIFY `stoppedAt` datetime NOT NULL', - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1611149998770-AddWebhookId.ts b/packages/@n8n/db/src/migrations/mysqldb/1611149998770-AddWebhookId.ts deleted file mode 100644 index f1d40b76fb0c5..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1611149998770-AddWebhookId.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class AddWebhookId1611149998770 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'webhook_entity` ADD `webhookId` varchar(255) NULL', - ); - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'webhook_entity` ADD `pathLength` int NULL', - ); - await queryRunner.query( - 'CREATE INDEX `IDX_' + - tablePrefix + - '742496f199721a057051acf4c2` ON `' + - tablePrefix + - 'webhook_entity` (`webhookId`, `method`, `pathLength`)', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'DROP INDEX `IDX_' + - tablePrefix + - '742496f199721a057051acf4c2` ON `' + - tablePrefix + - 'webhook_entity`', - ); - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'webhook_entity` DROP COLUMN `pathLength`', - ); - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'webhook_entity` DROP COLUMN `webhookId`', - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1615306975123-ChangeDataSize.ts b/packages/@n8n/db/src/migrations/mysqldb/1615306975123-ChangeDataSize.ts deleted file mode 100644 index 3d96058701d51..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1615306975123-ChangeDataSize.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class ChangeDataSize1615306975123 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'execution_entity` MODIFY COLUMN `data` MEDIUMTEXT NOT NULL', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'execution_entity` MODIFY COLUMN `data` TEXT NOT NULL', - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1617268711084-CreateTagEntity.ts b/packages/@n8n/db/src/migrations/mysqldb/1617268711084-CreateTagEntity.ts deleted file mode 100644 index ff70956976aa7..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1617268711084-CreateTagEntity.ts +++ /dev/null @@ -1,150 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CreateTagEntity1617268711084 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - // create tags table + relationship with workflow entity - - await queryRunner.query( - 'CREATE TABLE `' + - tablePrefix + - 'tag_entity` (`id` int NOT NULL AUTO_INCREMENT, `name` varchar(24) NOT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, UNIQUE INDEX `IDX_' + - tablePrefix + - '8f949d7a3a984759044054e89b` (`name`), PRIMARY KEY (`id`)) ENGINE=InnoDB', - ); - await queryRunner.query( - 'CREATE TABLE `' + - tablePrefix + - 'workflows_tags` (`workflowId` int NOT NULL, `tagId` int NOT NULL, INDEX `IDX_' + - tablePrefix + - '54b2f0343d6a2078fa13744386` (`workflowId`), INDEX `IDX_' + - tablePrefix + - '77505b341625b0b4768082e217` (`tagId`), PRIMARY KEY (`workflowId`, `tagId`)) ENGINE=InnoDB', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'workflows_tags` ADD CONSTRAINT `FK_' + - tablePrefix + - '54b2f0343d6a2078fa137443869` FOREIGN KEY (`workflowId`) REFERENCES `' + - tablePrefix + - 'workflow_entity`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'workflows_tags` ADD CONSTRAINT `FK_' + - tablePrefix + - '77505b341625b0b4768082e2171` FOREIGN KEY (`tagId`) REFERENCES `' + - tablePrefix + - 'tag_entity`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION', - ); - - // set default dates for `createdAt` and `updatedAt` - - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'credentials_entity` CHANGE `createdAt` `createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'credentials_entity` CHANGE `updatedAt` `updatedAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'tag_entity` CHANGE `createdAt` `createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'tag_entity` CHANGE `updatedAt` `updatedAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'workflow_entity` CHANGE `createdAt` `createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'workflow_entity` CHANGE `updatedAt` `updatedAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - // `createdAt` and `updatedAt` - - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'workflow_entity` CHANGE `updatedAt` `updatedAt` datetime NOT NULL', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'workflow_entity` CHANGE `createdAt` `createdAt` datetime NOT NULL', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'tag_entity` CHANGE `updatedAt` `updatedAt` datetime NOT NULL', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'tag_entity` CHANGE `createdAt` `createdAt` datetime NOT NULL', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'credentials_entity` CHANGE `updatedAt` `updatedAt` datetime NOT NULL', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'credentials_entity` CHANGE `createdAt` `createdAt` datetime NOT NULL', - ); - - // tags - - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'workflows_tags` DROP FOREIGN KEY `FK_' + - tablePrefix + - '77505b341625b0b4768082e2171`', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'workflows_tags` DROP FOREIGN KEY `FK_' + - tablePrefix + - '54b2f0343d6a2078fa137443869`', - ); - await queryRunner.query( - 'DROP INDEX `IDX_' + - tablePrefix + - '77505b341625b0b4768082e217` ON `' + - tablePrefix + - 'workflows_tags`', - ); - await queryRunner.query( - 'DROP INDEX `IDX_' + - tablePrefix + - '54b2f0343d6a2078fa13744386` ON `' + - tablePrefix + - 'workflows_tags`', - ); - await queryRunner.query('DROP TABLE `' + tablePrefix + 'workflows_tags`'); - await queryRunner.query( - 'DROP INDEX `IDX_' + - tablePrefix + - '8f949d7a3a984759044054e89b` ON `' + - tablePrefix + - 'tag_entity`', - ); - await queryRunner.query('DROP TABLE `' + tablePrefix + 'tag_entity`'); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1620729500000-ChangeCredentialDataSize.ts b/packages/@n8n/db/src/migrations/mysqldb/1620729500000-ChangeCredentialDataSize.ts deleted file mode 100644 index b79096769c5d6..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1620729500000-ChangeCredentialDataSize.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class ChangeCredentialDataSize1620729500000 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'credentials_entity` MODIFY COLUMN `type` varchar(128) NOT NULL', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'credentials_entity` MODIFY COLUMN `type` varchar(32) NOT NULL', - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1620826335440-UniqueWorkflowNames.ts b/packages/@n8n/db/src/migrations/mysqldb/1620826335440-UniqueWorkflowNames.ts deleted file mode 100644 index b453f6b73228b..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1620826335440-UniqueWorkflowNames.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { UniqueWorkflowNames1620821879465 } from '../common/1620821879465-UniqueWorkflowNames'; - -export class UniqueWorkflowNames1620826335440 extends UniqueWorkflowNames1620821879465 {} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1623936588000-CertifyCorrectCollation.ts b/packages/@n8n/db/src/migrations/mysqldb/1623936588000-CertifyCorrectCollation.ts deleted file mode 100644 index 3f77b1dfe1f8a..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1623936588000-CertifyCorrectCollation.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { MigrationContext, IrreversibleMigration } from '../migration-types'; - -export class CertifyCorrectCollation1623936588000 implements IrreversibleMigration { - async up({ queryRunner, tablePrefix, dbType, dbName }: MigrationContext) { - if (dbType === 'mariadb') { - // This applies to MySQL only. - return; - } - - const checkCollationExistence = (await queryRunner.query( - "show collation where collation like 'utf8mb4_0900_ai_ci';", - )) as unknown[]; - let collation = 'utf8mb4_general_ci'; - if (checkCollationExistence.length > 0) { - collation = 'utf8mb4_0900_ai_ci'; - } - - await queryRunner.query( - `ALTER DATABASE \`${dbName}\` CHARACTER SET utf8mb4 COLLATE ${collation};`, - ); - - for (const tableName of [ - 'credentials_entity', - 'execution_entity', - 'tag_entity', - 'webhook_entity', - 'workflow_entity', - 'workflows_tags', - ]) { - await queryRunner.query( - `ALTER TABLE ${tablePrefix}${tableName} CONVERT TO CHARACTER SET utf8mb4 COLLATE ${collation};`, - ); - } - } - - // There is no down migration in this case as we already expect default collation to be utf8mb4 - // The up migration exists simply to enforce that n8n will work with older mysql versions -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1626183952959-AddWaitColumn.ts b/packages/@n8n/db/src/migrations/mysqldb/1626183952959-AddWaitColumn.ts deleted file mode 100644 index 57ee6d81f3dd4..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1626183952959-AddWaitColumn.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class AddWaitColumnId1626183952959 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'execution_entity` ADD `waitTill` DATETIME NULL', - ); - await queryRunner.query( - 'CREATE INDEX `IDX_' + - tablePrefix + - 'ca4a71b47f28ac6ea88293a8e2` ON `' + - tablePrefix + - 'execution_entity` (`waitTill`)', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'DROP INDEX `IDX_' + - tablePrefix + - 'ca4a71b47f28ac6ea88293a8e2` ON `' + - tablePrefix + - 'execution_entity`', - ); - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'execution_entity` DROP COLUMN `waitTill`', - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1630451444017-UpdateWorkflowCredentials.ts b/packages/@n8n/db/src/migrations/mysqldb/1630451444017-UpdateWorkflowCredentials.ts deleted file mode 100644 index cbc3464cb4882..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1630451444017-UpdateWorkflowCredentials.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { UpdateWorkflowCredentials1630330987096 } from '../common/1630330987096-UpdateWorkflowCredentials'; - -export class UpdateWorkflowCredentials1630451444017 extends UpdateWorkflowCredentials1630330987096 {} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1644424784709-AddExecutionEntityIndexes.ts b/packages/@n8n/db/src/migrations/mysqldb/1644424784709-AddExecutionEntityIndexes.ts deleted file mode 100644 index 949fef61a35b6..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1644424784709-AddExecutionEntityIndexes.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class AddExecutionEntityIndexes1644424784709 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}c4d999a5e90784e8caccf5589d\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}ca4a71b47f28ac6ea88293a8e2\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}06da892aaf92a48e7d3e400003\` ON \`${tablePrefix}execution_entity\` (\`workflowId\`, \`waitTill\`, \`id\`)`, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}78d62b89dc1433192b86dce18a\` ON \`${tablePrefix}execution_entity\` (\`workflowId\`, \`finished\`, \`id\`)`, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}1688846335d274033e15c846a4\` ON \`${tablePrefix}execution_entity\` (\`finished\`, \`id\`)`, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}b94b45ce2c73ce46c54f20b5f9\` ON \`${tablePrefix}execution_entity\` (\`waitTill\`, \`id\`)`, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}81fc04c8a17de15835713505e4\` ON \`${tablePrefix}execution_entity\` (\`workflowId\`, \`id\`)`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}81fc04c8a17de15835713505e4\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}b94b45ce2c73ce46c54f20b5f9\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}1688846335d274033e15c846a4\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}78d62b89dc1433192b86dce18a\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}06da892aaf92a48e7d3e400003\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}ca4a71b47f28ac6ea88293a8e2\` ON \`${tablePrefix}execution_entity\` (\`waitTill\`)`, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}c4d999a5e90784e8caccf5589d\` ON \`${tablePrefix}execution_entity\` (\`workflowId\`)`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1646992772331-CreateUserManagement.ts b/packages/@n8n/db/src/migrations/mysqldb/1646992772331-CreateUserManagement.ts deleted file mode 100644 index 817c2722d952e..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1646992772331-CreateUserManagement.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { v4 as uuid } from 'uuid'; - -import type { InsertResult, MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CreateUserManagement1646992772331 implements ReversibleMigration { - async up({ queryRunner, tablePrefix, loadSurveyFromDisk }: MigrationContext) { - await queryRunner.query( - `CREATE TABLE ${tablePrefix}role ( - \`id\` int NOT NULL AUTO_INCREMENT, - \`name\` varchar(32) NOT NULL, - \`scope\` varchar(255) NOT NULL, - \`createdAt\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - \`updatedAt\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (\`id\`), - UNIQUE KEY \`UQ_${tablePrefix}5b49d0f504f7ef31045a1fb2eb8\` (\`scope\`,\`name\`) - ) ENGINE=InnoDB;`, - ); - - await queryRunner.query( - `CREATE TABLE ${tablePrefix}user ( - \`id\` VARCHAR(36) NOT NULL, - \`email\` VARCHAR(255) NULL DEFAULT NULL, - \`firstName\` VARCHAR(32) NULL DEFAULT NULL, - \`lastName\` VARCHAR(32) NULL DEFAULT NULL, - \`password\` VARCHAR(255) NULL DEFAULT NULL, - \`resetPasswordToken\` VARCHAR(255) NULL DEFAULT NULL, - \`resetPasswordTokenExpiration\` INT NULL DEFAULT NULL, - \`personalizationAnswers\` TEXT NULL DEFAULT NULL, - \`createdAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - \`updatedAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - \`globalRoleId\` INT NOT NULL, - PRIMARY KEY (\`id\`), - UNIQUE INDEX \`IDX_${tablePrefix}e12875dfb3b1d92d7d7c5377e2\` (\`email\` ASC), - INDEX \`FK_${tablePrefix}f0609be844f9200ff4365b1bb3d\` (\`globalRoleId\` ASC) - ) ENGINE=InnoDB;`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}user\` ADD CONSTRAINT \`FK_${tablePrefix}f0609be844f9200ff4365b1bb3d\` FOREIGN KEY (\`globalRoleId\`) REFERENCES \`${tablePrefix}role\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - - await queryRunner.query( - `CREATE TABLE ${tablePrefix}shared_workflow ( - \`createdAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - \`updatedAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - \`roleId\` INT NOT NULL, - \`userId\` VARCHAR(36) NOT NULL, - \`workflowId\` INT NOT NULL, - INDEX \`FK_${tablePrefix}3540da03964527aa24ae014b780x\` (\`roleId\` ASC), - INDEX \`FK_${tablePrefix}82b2fd9ec4e3e24209af8160282x\` (\`userId\` ASC), - INDEX \`FK_${tablePrefix}b83f8d2530884b66a9c848c8b88x\` (\`workflowId\` ASC), - PRIMARY KEY (\`userId\`, \`workflowId\`) - ) ENGINE=InnoDB;`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}shared_workflow\` ADD CONSTRAINT \`FK_${tablePrefix}3540da03964527aa24ae014b780\` FOREIGN KEY (\`roleId\`) REFERENCES \`${tablePrefix}role\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}shared_workflow\` ADD CONSTRAINT \`FK_${tablePrefix}82b2fd9ec4e3e24209af8160282\` FOREIGN KEY (\`userId\`) REFERENCES \`${tablePrefix}user\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}shared_workflow\` ADD CONSTRAINT \`FK_${tablePrefix}b83f8d2530884b66a9c848c8b88\` FOREIGN KEY (\`workflowId\`) REFERENCES \`${tablePrefix}workflow_entity\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - - await queryRunner.query( - `CREATE TABLE ${tablePrefix}shared_credentials ( - \`createdAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - \`updatedAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - \`roleId\` INT NOT NULL, - \`userId\` VARCHAR(36) NOT NULL, - \`credentialsId\` INT NOT NULL, - INDEX \`FK_${tablePrefix}c68e056637562000b68f480815a\` (\`roleId\` ASC), - INDEX \`FK_${tablePrefix}484f0327e778648dd04f1d70493\` (\`userId\` ASC), - INDEX \`FK_${tablePrefix}68661def1d4bcf2451ac8dbd949\` (\`credentialsId\` ASC), - PRIMARY KEY (\`userId\`, \`credentialsId\`) - ) ENGINE=InnoDB;`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}shared_credentials\` ADD CONSTRAINT \`FK_${tablePrefix}484f0327e778648dd04f1d70493\` FOREIGN KEY (\`userId\`) REFERENCES \`${tablePrefix}user\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}shared_credentials\` ADD CONSTRAINT \`FK_${tablePrefix}68661def1d4bcf2451ac8dbd949\` FOREIGN KEY (\`credentialsId\`) REFERENCES \`${tablePrefix}credentials_entity\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}shared_credentials\` ADD CONSTRAINT \`FK_${tablePrefix}c68e056637562000b68f480815a\` FOREIGN KEY (\`roleId\`) REFERENCES \`${tablePrefix}role\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - - await queryRunner.query( - `CREATE TABLE ${tablePrefix}settings ( - \`key\` VARCHAR(255) NOT NULL, - \`value\` TEXT NOT NULL, - \`loadOnStartup\` TINYINT(1) NOT NULL DEFAULT 0, - PRIMARY KEY (\`key\`) - ) ENGINE=InnoDB;`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_entity DROP INDEX IDX_${tablePrefix}943d8f922be094eb507cb9a7f9`, - ); - - // Insert initial roles - await queryRunner.query( - `INSERT INTO ${tablePrefix}role (name, scope) VALUES ("owner", "global");`, - ); - - const instanceOwnerRole = (await queryRunner.query( - 'SELECT LAST_INSERT_ID() as insertId', - )) as InsertResult; - - await queryRunner.query( - `INSERT INTO ${tablePrefix}role (name, scope) VALUES ("member", "global");`, - ); - - await queryRunner.query( - `INSERT INTO ${tablePrefix}role (name, scope) VALUES ("owner", "workflow");`, - ); - - const workflowOwnerRole = (await queryRunner.query( - 'SELECT LAST_INSERT_ID() as insertId', - )) as InsertResult; - - await queryRunner.query( - `INSERT INTO ${tablePrefix}role (name, scope) VALUES ("owner", "credential");`, - ); - - const credentialOwnerRole = (await queryRunner.query( - 'SELECT LAST_INSERT_ID() as insertId', - )) as InsertResult; - - const survey = loadSurveyFromDisk(); - - const ownerUserId = uuid(); - - await queryRunner.query( - `INSERT INTO ${tablePrefix}user (id, globalRoleId, personalizationAnswers) values (?, ?, ?)`, - [ownerUserId, instanceOwnerRole[0].insertId, survey], - ); - - await queryRunner.query( - `INSERT INTO ${tablePrefix}shared_workflow (createdAt, updatedAt, roleId, userId, workflowId) select - NOW(), NOW(), '${workflowOwnerRole[0].insertId}', '${ownerUserId}', id FROM ${tablePrefix}workflow_entity`, - ); - - await queryRunner.query( - `INSERT INTO ${tablePrefix}shared_credentials (createdAt, updatedAt, roleId, userId, credentialsId) SELECT NOW(), NOW(), '${credentialOwnerRole[0].insertId}', '${ownerUserId}', id FROM ${tablePrefix}credentials_entity`, - ); - - await queryRunner.query( - `INSERT INTO ${tablePrefix}settings (\`key\`, value, loadOnStartup) VALUES ("userManagement.isInstanceOwnerSetUp", "false", 1), ("userManagement.skipInstanceOwnerSetup", "false", 1)`, - ); - - await queryRunner.query( - `INSERT INTO ${tablePrefix}settings (\`key\`, value, loadOnStartup) VALUES ("ui.banners.dismissed", JSON_ARRAY('V1'), 1)`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_entity ADD UNIQUE INDEX \`IDX_${tablePrefix}943d8f922be094eb507cb9a7f9\` (\`name\`)`, - ); - - await queryRunner.query(`DROP TABLE "${tablePrefix}shared_credentials"`); - await queryRunner.query(`DROP TABLE "${tablePrefix}shared_workflow"`); - await queryRunner.query(`DROP TABLE "${tablePrefix}user"`); - await queryRunner.query(`DROP TABLE "${tablePrefix}role"`); - await queryRunner.query(`DROP TABLE "${tablePrefix}settings"`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1648740597343-LowerCaseUserEmail.ts b/packages/@n8n/db/src/migrations/mysqldb/1648740597343-LowerCaseUserEmail.ts deleted file mode 100644 index a9c9d4540395e..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1648740597343-LowerCaseUserEmail.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { MigrationContext, IrreversibleMigration } from '../migration-types'; - -export class LowerCaseUserEmail1648740597343 implements IrreversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(` - UPDATE ${tablePrefix}user - SET email = LOWER(email); - `); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1652254514003-CommunityNodes.ts b/packages/@n8n/db/src/migrations/mysqldb/1652254514003-CommunityNodes.ts deleted file mode 100644 index 52a3b294c043d..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1652254514003-CommunityNodes.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CommunityNodes1652254514003 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 NULL DEFAULT CURRENT_TIMESTAMP,' + - '`updatedAt` datetime NULL DEFAULT CURRENT_TIMESTAMP,' + - 'PRIMARY KEY (`packageName`)' + - ') ENGINE=InnoDB;', - ); - - await queryRunner.query( - `CREATE TABLE \`${tablePrefix}installed_nodes\` (` + - '`name` char(200) NOT NULL,' + - '`type` char(200) NOT NULL,' + - "`latestVersion` int NOT NULL DEFAULT '1'," + - '`package` char(214) NOT NULL,' + - 'PRIMARY KEY (`name`),' + - `INDEX \`FK_${tablePrefix}73f857fc5dce682cef8a99c11dbddbc969618951\` (\`package\` ASC)` + - ") ENGINE='InnoDB';", - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}installed_nodes\` ADD CONSTRAINT \`FK_${tablePrefix}73f857fc5dce682cef8a99c11dbddbc969618951\` FOREIGN KEY (\`package\`) REFERENCES \`${tablePrefix}installed_packages\`(\`packageName\`) ON DELETE CASCADE ON UPDATE CASCADE`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_entity ADD UNIQUE INDEX \`IDX_${tablePrefix}943d8f922be094eb507cb9a7f9\` (\`name\`)`, - ); - - await queryRunner.query(`DROP TABLE "${tablePrefix}installed_nodes"`); - await queryRunner.query(`DROP TABLE "${tablePrefix}installed_packages"`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1652367743993-AddUserSettings.ts b/packages/@n8n/db/src/migrations/mysqldb/1652367743993-AddUserSettings.ts deleted file mode 100644 index 40838da245612..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1652367743993-AddUserSettings.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class AddUserSettings1652367743993 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'user` ADD COLUMN `settings` json NULL DEFAULT NULL', - ); - await queryRunner.query( - 'ALTER TABLE `' + - tablePrefix + - 'user` CHANGE COLUMN `personalizationAnswers` `personalizationAnswers` json NULL DEFAULT NULL', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query('ALTER TABLE `' + tablePrefix + 'user` DROP COLUMN `settings`'); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1652905585850-AddAPIKeyColumn.ts b/packages/@n8n/db/src/migrations/mysqldb/1652905585850-AddAPIKeyColumn.ts deleted file mode 100644 index 58216e727e0c8..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1652905585850-AddAPIKeyColumn.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class AddAPIKeyColumn1652905585850 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'user` ADD COLUMN `apiKey` VARCHAR(255)', - ); - await queryRunner.query( - 'CREATE UNIQUE INDEX `UQ_' + - tablePrefix + - 'ie0zomxves9w3p774drfrkxtj5` ON `' + - tablePrefix + - 'user` (`apiKey`)', - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `DROP INDEX \`UQ_${tablePrefix}ie0zomxves9w3p774drfrkxtj5\` ON \`${tablePrefix}user\``, - ); - await queryRunner.query('ALTER TABLE `' + tablePrefix + 'user` DROP COLUMN `apiKey`'); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1654090101303-IntroducePinData.ts b/packages/@n8n/db/src/migrations/mysqldb/1654090101303-IntroducePinData.ts deleted file mode 100644 index 1dd46f9b05f4f..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1654090101303-IntroducePinData.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class IntroducePinData1654090101303 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`ALTER TABLE \`${tablePrefix}workflow_entity\` ADD \`pinData\` json`); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}workflow_entity\` DROP COLUMN \`pinData\``, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1658932910559-AddNodeIds.ts b/packages/@n8n/db/src/migrations/mysqldb/1658932910559-AddNodeIds.ts deleted file mode 100644 index 2d05873470b81..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1658932910559-AddNodeIds.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { AddNodeIds1658930531669 } from '../common/1658930531669-AddNodeIds'; - -export class AddNodeIds1658932910559 extends AddNodeIds1658930531669 {} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1659895550980-AddJsonKeyPinData.ts b/packages/@n8n/db/src/migrations/mysqldb/1659895550980-AddJsonKeyPinData.ts deleted file mode 100644 index 656197a645d79..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1659895550980-AddJsonKeyPinData.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { AddJsonKeyPinData1659888469333 } from '../common/1659888469333-AddJsonKeyPinData'; - -export class AddJsonKeyPinData1659895550980 extends AddJsonKeyPinData1659888469333 {} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1660062385367-CreateCredentialsUserRole.ts b/packages/@n8n/db/src/migrations/mysqldb/1660062385367-CreateCredentialsUserRole.ts deleted file mode 100644 index eceff11e8b904..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1660062385367-CreateCredentialsUserRole.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CreateCredentialsUserRole1660062385367 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(` - INSERT IGNORE INTO ${tablePrefix}role (name, scope) - VALUES ("user", "credential"); - `); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(` - DELETE FROM ${tablePrefix}role WHERE name='user' AND scope='credential'; - `); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1663755770894-CreateWorkflowsEditorRole.ts b/packages/@n8n/db/src/migrations/mysqldb/1663755770894-CreateWorkflowsEditorRole.ts deleted file mode 100644 index 29d76af39dba0..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1663755770894-CreateWorkflowsEditorRole.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CreateWorkflowsEditorRole1663755770894 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(` - INSERT IGNORE INTO ${tablePrefix}role (name, scope) - VALUES ("editor", "workflow") - `); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(` - DELETE FROM ${tablePrefix}role WHERE name='user' AND scope='workflow'; - `); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1664196174002-WorkflowStatistics.ts b/packages/@n8n/db/src/migrations/mysqldb/1664196174002-WorkflowStatistics.ts deleted file mode 100644 index 3fa4ba440ab34..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1664196174002-WorkflowStatistics.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class WorkflowStatistics1664196174002 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `CREATE TABLE ${tablePrefix}workflow_statistics ( - count INTEGER DEFAULT 0, - latestEvent DATETIME, - name VARCHAR(128) NOT NULL, - workflowId INTEGER, - PRIMARY KEY(workflowId, name), - FOREIGN KEY(workflowId) REFERENCES ${tablePrefix}workflow_entity(id) ON DELETE CASCADE - )`, - ); - - // Add dataLoaded column to workflow table - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_entity ADD COLUMN dataLoaded BOOLEAN DEFAULT false`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`DROP TABLE "${tablePrefix}workflow_statistics"`); - await queryRunner.query(`ALTER TABLE ${tablePrefix}workflow_entity DROP COLUMN dataLoaded`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1665484192213-CreateCredentialUsageTable.ts b/packages/@n8n/db/src/migrations/mysqldb/1665484192213-CreateCredentialUsageTable.ts deleted file mode 100644 index 13128a6bae5c5..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1665484192213-CreateCredentialUsageTable.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CreateCredentialUsageTable1665484192213 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `CREATE TABLE \`${tablePrefix}credential_usage\` (` + - '`workflowId` int NOT NULL,' + - '`nodeId` char(200) NOT NULL,' + - "`credentialId` int NOT NULL DEFAULT '1'," + - '`createdAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,' + - '`updatedAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,' + - 'PRIMARY KEY (`workflowId`, `nodeId`, `credentialId`)' + - ") ENGINE='InnoDB';", - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}credential_usage\` ADD CONSTRAINT \`FK_${tablePrefix}518e1ece107b859ca6ce9ed2487f7e23\` FOREIGN KEY (\`workflowId\`) REFERENCES \`${tablePrefix}workflow_entity\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}credential_usage\` ADD CONSTRAINT \`FK_${tablePrefix}7ce200a20ade7ae89fa7901da896993f\` FOREIGN KEY (\`credentialId\`) REFERENCES \`${tablePrefix}credentials_entity\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`DROP TABLE "${tablePrefix}credential_usage"`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1665754637026-RemoveCredentialUsageTable.ts b/packages/@n8n/db/src/migrations/mysqldb/1665754637026-RemoveCredentialUsageTable.ts deleted file mode 100644 index 509c89caae2a6..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1665754637026-RemoveCredentialUsageTable.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class RemoveCredentialUsageTable1665754637026 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`DROP TABLE \`${tablePrefix}credential_usage\``); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `CREATE TABLE \`${tablePrefix}credential_usage\` (` + - '`workflowId` int NOT NULL,' + - '`nodeId` char(200) NOT NULL,' + - "`credentialId` int NOT NULL DEFAULT '1'," + - '`createdAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,' + - '`updatedAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,' + - 'PRIMARY KEY (`workflowId`, `nodeId`, `credentialId`)' + - ") ENGINE='InnoDB';", - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}credential_usage\` ADD CONSTRAINT \`FK_${tablePrefix}518e1ece107b859ca6ce9ed2487f7e23\` FOREIGN KEY (\`workflowId\`) REFERENCES \`${tablePrefix}workflow_entity\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}credential_usage\` ADD CONSTRAINT \`FK_${tablePrefix}7ce200a20ade7ae89fa7901da896993f\` FOREIGN KEY (\`credentialId\`) REFERENCES \`${tablePrefix}credentials_entity\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1669739707125-AddWorkflowVersionIdColumn.ts b/packages/@n8n/db/src/migrations/mysqldb/1669739707125-AddWorkflowVersionIdColumn.ts deleted file mode 100644 index 84844f4251c37..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1669739707125-AddWorkflowVersionIdColumn.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { AddWorkflowVersionIdColumn1669739707124 } from '../common/1669739707124-AddWorkflowVersionIdColumn'; - -export class AddWorkflowVersionIdColumn1669739707125 extends AddWorkflowVersionIdColumn1669739707124 {} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1669823906994-AddTriggerCountColumn.ts b/packages/@n8n/db/src/migrations/mysqldb/1669823906994-AddTriggerCountColumn.ts deleted file mode 100644 index 36effd442d80d..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1669823906994-AddTriggerCountColumn.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class AddTriggerCountColumn1669823906994 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 ActiveWorkflowManager.ts - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`ALTER TABLE ${tablePrefix}workflow_entity DROP COLUMN triggerCount`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1671535397530-MessageEventBusDestinations.ts b/packages/@n8n/db/src/migrations/mysqldb/1671535397530-MessageEventBusDestinations.ts deleted file mode 100644 index 4edae4f656b1e..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1671535397530-MessageEventBusDestinations.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -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 NOT NULL DEFAULT CURRENT_TIMESTAMP, ' + - '`updatedAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP' + - ") ENGINE='InnoDB';", - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`DROP TABLE "${tablePrefix}event_destinations"`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1671726148420-RemoveWorkflowDataLoadedFlag.ts b/packages/@n8n/db/src/migrations/mysqldb/1671726148420-RemoveWorkflowDataLoadedFlag.ts deleted file mode 100644 index dc96f7d591ca0..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1671726148420-RemoveWorkflowDataLoadedFlag.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { RemoveWorkflowDataLoadedFlag1671726148419 } from '../common/1671726148419-RemoveWorkflowDataLoadedFlag'; - -export class RemoveWorkflowDataLoadedFlag1671726148420 extends RemoveWorkflowDataLoadedFlag1671726148419 {} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1673268682475-DeleteExecutionsWithWorkflows.ts b/packages/@n8n/db/src/migrations/mysqldb/1673268682475-DeleteExecutionsWithWorkflows.ts deleted file mode 100644 index a205282dc66b8..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1673268682475-DeleteExecutionsWithWorkflows.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class DeleteExecutionsWithWorkflows1673268682475 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`ALTER TABLE \`${tablePrefix}execution_entity\` MODIFY workflowId INT`); - - const workflowIds = (await queryRunner.query(` - SELECT id FROM \`${tablePrefix}workflow_entity\` - `)) as Array<{ id: number }>; - - await queryRunner.query( - `DELETE FROM \`${tablePrefix}execution_entity\` - WHERE workflowId IS NOT NULL - ${workflowIds.length ? `AND workflowId NOT IN (${workflowIds.map(({ id }) => id).join()})` : ''}`, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}execution_entity\` - ADD CONSTRAINT \`FK_${tablePrefix}execution_entity_workflowId\` - FOREIGN KEY (\`workflowId\`) REFERENCES \`${tablePrefix}workflow_entity\`(\`id\`) - ON DELETE CASCADE`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}execution_entity\` - DROP FOREIGN KEY \`FK_${tablePrefix}execution_entity_workflowId\``, - ); - - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}execution_entity\` MODIFY workflowId varchar(255);`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1674138566000-AddStatusToExecutions.ts b/packages/@n8n/db/src/migrations/mysqldb/1674138566000-AddStatusToExecutions.ts deleted file mode 100644 index 0ce72f3795953..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1674138566000-AddStatusToExecutions.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class AddStatusToExecutions1674138566000 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}execution_entity\` ADD COLUMN \`status\` VARCHAR(255)`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `ALTER TABLE \`${tablePrefix}execution_entity\` DROP COLUMN \`status\``, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1676996103000-MigrateExecutionStatus.ts b/packages/@n8n/db/src/migrations/mysqldb/1676996103000-MigrateExecutionStatus.ts deleted file mode 100644 index d8f354b0258ea..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1676996103000-MigrateExecutionStatus.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { MigrationContext, IrreversibleMigration } from '../migration-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;`, - ); - await queryRunner.query( - `UPDATE \`${tablePrefix}execution_entity\` SET status='failed' WHERE status IS NULL AND finished=0 AND \`stoppedAt\` IS NOT NULL;`, - ); - await queryRunner.query( - `UPDATE \`${tablePrefix}execution_entity\` SET status='success' WHERE status IS NULL AND finished=1 AND \`stoppedAt\` IS NOT NULL;`, - ); - await queryRunner.query( - `UPDATE \`${tablePrefix}execution_entity\` SET status='crashed' WHERE status IS NULL;`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1677236788851-UpdateRunningExecutionStatus.ts b/packages/@n8n/db/src/migrations/mysqldb/1677236788851-UpdateRunningExecutionStatus.ts deleted file mode 100644 index f67b524213ae3..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1677236788851-UpdateRunningExecutionStatus.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { MigrationContext, IrreversibleMigration } from '../migration-types'; - -export class UpdateRunningExecutionStatus1677236788851 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;`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1677501636753-CreateVariables.ts b/packages/@n8n/db/src/migrations/mysqldb/1677501636753-CreateVariables.ts deleted file mode 100644 index 28a6b0ac4d6e2..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1677501636753-CreateVariables.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CreateVariables1677501636753 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(` - CREATE TABLE ${tablePrefix}variables ( - id int(11) auto_increment NOT NULL PRIMARY KEY, - \`key\` VARCHAR(50) NOT NULL, - \`type\` VARCHAR(50) DEFAULT 'string' NOT NULL, - value VARCHAR(255) NULL, - UNIQUE (\`key\`) - ) - ENGINE=InnoDB; - `); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`DROP TABLE ${tablePrefix}variables;`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1679416281779-CreateExecutionMetadataTable.ts b/packages/@n8n/db/src/migrations/mysqldb/1679416281779-CreateExecutionMetadataTable.ts deleted file mode 100644 index 2d506de5c7f6f..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1679416281779-CreateExecutionMetadataTable.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class CreateExecutionMetadataTable1679416281779 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `CREATE TABLE ${tablePrefix}execution_metadata ( - id int(11) auto_increment NOT NULL PRIMARY KEY, - executionId int(11) NOT NULL, - \`key\` TEXT NOT NULL, - value TEXT NOT NULL, - CONSTRAINT \`${tablePrefix}execution_metadata_FK\` FOREIGN KEY (\`executionId\`) REFERENCES \`${tablePrefix}execution_entity\` (\`id\`) ON DELETE CASCADE, - INDEX \`IDX_${tablePrefix}6d44376da6c1058b5e81ed8a154e1fee106046eb\` (\`executionId\` ASC) - ) - ENGINE=InnoDB`, - ); - - // Remove indices that are no longer needed since the addition of the status column - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}06da892aaf92a48e7d3e400003\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}78d62b89dc1433192b86dce18a\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}1688846335d274033e15c846a4\` ON \`${tablePrefix}execution_entity\``, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}cefb067df2402f6aed0638a6c1\` ON \`${tablePrefix}execution_entity\``, - ); - - // Add index to the new status column - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}8b6f3f9ae234f137d707b98f3bf43584\` ON \`${tablePrefix}execution_entity\` (\`status\`, \`workflowId\`)`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`DROP TABLE "${tablePrefix}execution_metadata"`); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}06da892aaf92a48e7d3e400003\` ON \`${tablePrefix}execution_entity\` (\`workflowId\`, \`waitTill\`, \`id\`)`, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}78d62b89dc1433192b86dce18a\` ON \`${tablePrefix}execution_entity\` (\`workflowId\`, \`finished\`, \`id\`)`, - ); - await queryRunner.query( - `CREATE INDEX \`IDX_${tablePrefix}1688846335d274033e15c846a4\` ON \`${tablePrefix}execution_entity\` (\`finished\`, \`id\`)`, - ); - await queryRunner.query( - 'CREATE INDEX `IDX_' + - tablePrefix + - 'cefb067df2402f6aed0638a6c1` ON `' + - tablePrefix + - 'execution_entity` (`stoppedAt`)', - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}8b6f3f9ae234f137d707b98f3bf43584\` ON \`${tablePrefix}execution_entity\``, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1681134145996-AddUserActivatedProperty.ts b/packages/@n8n/db/src/migrations/mysqldb/1681134145996-AddUserActivatedProperty.ts deleted file mode 100644 index 10af6e1f6091b..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1681134145996-AddUserActivatedProperty.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { UserSettings } from '../../entities/types-db'; -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -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', true) AS settings - FROM ${tablePrefix}workflow_statistics AS ws - JOIN ${tablePrefix}shared_workflow as sw - ON ws.workflowId = sw.workflowId - JOIN ${tablePrefix}role AS r - ON r.id = sw.roleId - JOIN ${tablePrefix}user AS u - ON u.id = sw.userId - WHERE ws.name = 'production_success' - AND r.name = 'owner' - AND r.scope = 'workflow'`, - )) as UserSettings[]; - - const updatedUsers = activatedUsers.map(async (user) => { - /* - MariaDB returns settings as a string and MySQL as a JSON - */ - const userSettings = - typeof user.settings === 'string' ? user.settings : JSON.stringify(user.settings); - await queryRunner.query( - `UPDATE ${tablePrefix}user SET settings = '${userSettings}' WHERE id = '${user.id}' `, - ); - }); - - await Promise.all(updatedUsers); - - if (!activatedUsers.length) { - await queryRunner.query( - `UPDATE ${tablePrefix}user SET settings = JSON_SET(COALESCE(settings, '{}'), '$.userActivated', false)`, - ); - } else { - const activatedUserIds = activatedUsers.map((user) => `'${user.id}'`).join(','); - - await queryRunner.query( - `UPDATE ${tablePrefix}user SET settings = JSON_SET(COALESCE(settings, '{}'), '$.userActivated', false) WHERE id NOT IN (${activatedUserIds})`, - ); - } - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `UPDATE ${tablePrefix}user SET settings = JSON_REMOVE(settings, '$.userActivated')`, - ); - await queryRunner.query(`UPDATE ${tablePrefix}user SET settings = NULL WHERE settings = '{}'`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1681134145997-RemoveSkipOwnerSetup.ts b/packages/@n8n/db/src/migrations/mysqldb/1681134145997-RemoveSkipOwnerSetup.ts deleted file mode 100644 index 50fd22dd52a7b..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1681134145997-RemoveSkipOwnerSetup.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { IrreversibleMigration, MigrationContext } from '../migration-types'; - -export class RemoveSkipOwnerSetup1681134145997 implements IrreversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `DELETE FROM ${tablePrefix}settings WHERE \`key\` = 'userManagement.skipInstanceOwnerSetup';`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1690000000001-MigrateIntegerKeysToString.ts b/packages/@n8n/db/src/migrations/mysqldb/1690000000001-MigrateIntegerKeysToString.ts deleted file mode 100644 index 1115a920e9dd1..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1690000000001-MigrateIntegerKeysToString.ts +++ /dev/null @@ -1,275 +0,0 @@ -import type { MigrationContext, IrreversibleMigration } from '../migration-types'; - -const COLLATION_57 = 'utf8mb4_general_ci'; -const COLLATION_80 = 'utf8mb4_0900_ai_ci'; - -export class MigrateIntegerKeysToString1690000000001 implements IrreversibleMigration { - async up({ queryRunner, tablePrefix, dbType }: MigrationContext) { - let collation: string; - if (dbType === 'mariadb') { - collation = COLLATION_57; - } else { - const dbVersionQuery = (await queryRunner.query('SELECT @@version')) as - | Array<{ '@@version': string }> - | undefined; - collation = COLLATION_80; - if (dbVersionQuery?.length === 1) { - const dbVersion = dbVersionQuery[0]['@@version']; - if (dbVersion.startsWith('5.7')) { - collation = COLLATION_57; - } - } - } - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_entity CHANGE id tmp_id int NOT NULL AUTO_INCREMENT;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_entity ADD COLUMN id varchar(36) NOT NULL;`, - ); - await queryRunner.query(`UPDATE ${tablePrefix}workflow_entity SET id = CONVERT(tmp_id, CHAR);`); - await queryRunner.query( - `CREATE UNIQUE INDEX \`TMP_idx_${tablePrefix}workflow_entity_id\` ON ${tablePrefix}workflow_entity (\`id\`);`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}tag_entity CHANGE id tmp_id int NOT NULL AUTO_INCREMENT;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}tag_entity ADD COLUMN id varchar(36) NOT NULL;`, - ); - await queryRunner.query(`UPDATE ${tablePrefix}tag_entity SET id = CONVERT(tmp_id, CHAR);`); - await queryRunner.query( - `CREATE UNIQUE INDEX \`TMP_idx_${tablePrefix}tag_entity_id\` ON ${tablePrefix}tag_entity (\`id\`);`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags CHANGE workflowId tmp_workflowId int NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags ADD COLUMN \`workflowId\` varchar(36) CHARACTER SET utf8mb4 COLLATE ${collation} NOT NULL;`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}workflows_tags SET \`workflowId\` = CONVERT(\`tmp_workflowId\`, CHAR);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags CHANGE tagId tmp_tagId int NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags ADD COLUMN \`tagId\` varchar(36) NOT NULL;`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}workflows_tags SET \`tagId\` = CONVERT(\`tmp_tagId\`, CHAR);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags DROP PRIMARY KEY, ADD PRIMARY KEY (\`workflowId\`, \`tagId\`);`, - ); - await queryRunner.query( - `CREATE INDEX \`idx_${tablePrefix}workflows_tags_workflow_id\` ON ${tablePrefix}workflows_tags (\`workflowId\`);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags DROP FOREIGN KEY \`FK_${tablePrefix}54b2f0343d6a2078fa137443869\`;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags ADD CONSTRAINT \`fk_${tablePrefix}workflows_tags_workflow_id\` FOREIGN KEY (\`workflowId\`) REFERENCES ${tablePrefix}workflow_entity(id) ON DELETE CASCADE ON UPDATE NO ACTION;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags DROP FOREIGN KEY \`FK_${tablePrefix}77505b341625b0b4768082e2171\`;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags ADD CONSTRAINT \`fk_${tablePrefix}workflows_tags_tag_id\` FOREIGN KEY (\`tagId\`) REFERENCES ${tablePrefix}tag_entity(id) ON DELETE CASCADE ON UPDATE NO ACTION;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflows_tags DROP COLUMN \`tmp_workflowId\`;`, - ); - await queryRunner.query(`ALTER TABLE ${tablePrefix}workflows_tags DROP COLUMN \`tmp_tagId\`;`); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_workflow CHANGE workflowId tmp_workflowId int NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_workflow ADD COLUMN \`workflowId\` varchar(36) CHARACTER SET utf8mb4 COLLATE ${collation} NOT NULL;`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}shared_workflow SET \`workflowId\` = CONVERT(\`tmp_workflowId\`, CHAR);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_workflow DROP PRIMARY KEY, ADD PRIMARY KEY (\`userId\`, \`workflowId\`);`, - ); - await queryRunner.query( - `CREATE INDEX \`idx_${tablePrefix}shared_workflow_workflow_id\` ON ${tablePrefix}shared_workflow (\`workflowId\`);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_workflow DROP FOREIGN KEY \`FK_${tablePrefix}b83f8d2530884b66a9c848c8b88\`;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_workflow ADD CONSTRAINT \`fk_${tablePrefix}shared_workflow_workflow_id\` FOREIGN KEY (\`workflowId\`) REFERENCES ${tablePrefix}workflow_entity(id) ON DELETE CASCADE ON UPDATE NO ACTION;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_workflow DROP COLUMN \`tmp_workflowId\`;`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_statistics CHANGE workflowId tmp_workflowId int NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_statistics ADD COLUMN \`workflowId\` varchar(36) CHARACTER SET utf8mb4 COLLATE ${collation} NOT NULL;`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}workflow_statistics SET \`workflowId\` = CONVERT(\`tmp_workflowId\`, CHAR);`, - ); - await queryRunner.query( - `CREATE INDEX \`idx_${tablePrefix}workflow_statistics_workflow_id\` ON ${tablePrefix}workflow_statistics (\`workflowId\`);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_statistics DROP FOREIGN KEY \`${tablePrefix}workflow_statistics_ibfk_1\`;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_statistics ADD CONSTRAINT \`fk_${tablePrefix}workflow_statistics_workflow_id\` FOREIGN KEY (\`workflowId\`) REFERENCES ${tablePrefix}workflow_entity(id) ON DELETE CASCADE ON UPDATE NO ACTION;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_statistics DROP PRIMARY KEY, ADD PRIMARY KEY (\`workflowId\`, \`name\`);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_statistics DROP COLUMN \`tmp_workflowId\`;`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}webhook_entity CHANGE workflowId tmp_workflowId int NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}webhook_entity ADD COLUMN \`workflowId\` varchar(36) CHARACTER SET utf8mb4 COLLATE ${collation} NOT NULL;`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}webhook_entity SET \`workflowId\` = CONVERT(\`tmp_workflowId\`, CHAR);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}webhook_entity DROP COLUMN \`tmp_workflowId\`;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}webhook_entity ADD CONSTRAINT \`fk_${tablePrefix}webhook_entity_workflow_id\` FOREIGN KEY (\`workflowId\`) REFERENCES ${tablePrefix}workflow_entity(id) ON DELETE CASCADE ON UPDATE NO ACTION;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}execution_entity CHANGE workflowId tmp_workflowId int NULL;`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}execution_entity ADD COLUMN \`workflowId\` varchar(36) CHARACTER SET utf8mb4 COLLATE ${collation};`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}execution_entity SET \`workflowId\` = CONVERT(\`tmp_workflowId\`, CHAR);`, - ); - await queryRunner.query( - `CREATE INDEX \`idx_${tablePrefix}execution_entity_workflow_id_id\` ON ${tablePrefix}execution_entity (\`workflowId\`,\`id\`);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}execution_entity DROP FOREIGN KEY \`FK_${tablePrefix}execution_entity_workflowId\`;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}execution_entity ADD CONSTRAINT \`fk_${tablePrefix}execution_entity_workflow_id\` FOREIGN KEY (\`workflowId\`) REFERENCES ${tablePrefix}workflow_entity(id) ON DELETE CASCADE ON UPDATE NO ACTION;`, - ); - await queryRunner.query( - `DROP INDEX \`IDX_${tablePrefix}81fc04c8a17de15835713505e4\` ON ${tablePrefix}execution_entity;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}execution_entity DROP COLUMN \`tmp_workflowId\`;`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_entity MODIFY COLUMN tmp_id INT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}workflow_entity DROP PRIMARY KEY, ADD PRIMARY KEY (\`id\`);`, - ); - await queryRunner.query( - `DROP INDEX \`TMP_idx_${tablePrefix}workflow_entity_id\` ON ${tablePrefix}workflow_entity;`, - ); - await queryRunner.query(`ALTER TABLE ${tablePrefix}workflow_entity DROP COLUMN tmp_id;`); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}tag_entity MODIFY COLUMN tmp_id INT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}tag_entity DROP PRIMARY KEY, ADD PRIMARY KEY (\`id\`);`, - ); - await queryRunner.query( - `DROP INDEX \`TMP_idx_${tablePrefix}tag_entity_id\` ON ${tablePrefix}tag_entity;`, - ); - await queryRunner.query(`ALTER TABLE ${tablePrefix}tag_entity DROP COLUMN tmp_id;`); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}credentials_entity CHANGE id tmp_id int NOT NULL AUTO_INCREMENT;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}credentials_entity ADD COLUMN id varchar(36) CHARACTER SET utf8mb4 COLLATE ${collation} NOT NULL;`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}credentials_entity SET id = CONVERT(tmp_id, CHAR);`, - ); - await queryRunner.query( - `CREATE UNIQUE INDEX \`TMP_idx_${tablePrefix}credentials_entity_id\` ON ${tablePrefix}credentials_entity (\`id\`);`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_credentials CHANGE credentialsId tmp_credentialsId int NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_credentials ADD COLUMN credentialsId varchar(36) CHARACTER SET utf8mb4 COLLATE ${collation} NOT NULL;`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}shared_credentials SET credentialsId = CONVERT(tmp_credentialsId, CHAR);`, - ); - await queryRunner.query( - `CREATE INDEX \`idx_${tablePrefix}shared_credentials_id\` ON ${tablePrefix}shared_credentials (\`credentialsId\`);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_credentials DROP FOREIGN KEY \`FK_${tablePrefix}68661def1d4bcf2451ac8dbd949\`;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_credentials ADD CONSTRAINT \`fk_${tablePrefix}shared_credentials_credentials_id\` FOREIGN KEY (\`credentialsId\`) REFERENCES ${tablePrefix}credentials_entity(id) ON DELETE CASCADE ON UPDATE NO ACTION;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_credentials MODIFY COLUMN tmp_credentialsId INT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_credentials DROP PRIMARY KEY, ADD PRIMARY KEY (\`userId\`,\`credentialsId\`);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}shared_credentials DROP COLUMN tmp_credentialsId;`, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}credentials_entity MODIFY COLUMN tmp_id INT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}credentials_entity DROP PRIMARY KEY, ADD PRIMARY KEY (\`id\`);`, - ); - await queryRunner.query( - `DROP INDEX \`TMP_idx_${tablePrefix}credentials_entity_id\` ON ${tablePrefix}credentials_entity;`, - ); - await queryRunner.query(`ALTER TABLE ${tablePrefix}credentials_entity DROP COLUMN tmp_id;`); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}variables CHANGE id tmp_id int NOT NULL AUTO_INCREMENT;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}variables ADD COLUMN \`id\` varchar(36) NOT NULL;`, - ); - await queryRunner.query( - `UPDATE ${tablePrefix}variables SET \`id\` = CONVERT(\`tmp_id\`, CHAR);`, - ); - await queryRunner.query( - `CREATE UNIQUE INDEX \`TMP_idx_${tablePrefix}variables_id\` ON ${tablePrefix}variables (\`id\`);`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}variables CHANGE \`tmp_id\` \`tmp_id\` int NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}variables DROP PRIMARY KEY, ADD PRIMARY KEY (\`id\`);`, - ); - await queryRunner.query(`ALTER TABLE ${tablePrefix}variables DROP COLUMN \`tmp_id\`;`); - await queryRunner.query( - `DROP INDEX \`TMP_idx_${tablePrefix}variables_id\` ON ${tablePrefix}variables;`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1690000000030-SeparateExecutionData.ts b/packages/@n8n/db/src/migrations/mysqldb/1690000000030-SeparateExecutionData.ts deleted file mode 100644 index 6a71bc6713fe6..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1690000000030-SeparateExecutionData.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class SeparateExecutionData1690000000030 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `CREATE TABLE ${tablePrefix}execution_data ( - executionId int(11) NOT NULL primary key, - workflowData json NOT NULL, - data MEDIUMTEXT NOT NULL, - CONSTRAINT \`${tablePrefix}execution_data_FK\` FOREIGN KEY (\`executionId\`) REFERENCES \`${tablePrefix}execution_entity\` (\`id\`) ON DELETE CASCADE - ) - ENGINE=InnoDB`, - ); - - await queryRunner.query( - `INSERT INTO ${tablePrefix}execution_data ( - executionId, - workflowData, - data) - SELECT id, workflowData, data FROM ${tablePrefix}execution_entity - `, - ); - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}execution_entity DROP COLUMN workflowData, DROP COLUMN data`, - ); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query( - `ALTER TABLE ${tablePrefix}execution_entity - ADD workflowData json NULL, - ADD data MEDIUMTEXT NULL`, - ); - - await queryRunner.query( - `UPDATE ${tablePrefix}execution_entity SET workflowData = ${tablePrefix}execution_data.workflowData, data = ${tablePrefix}execution_data.data - FROM ${tablePrefix}execution_data WHERE ${tablePrefix}execution_data.executionId = ${tablePrefix}execution_entity.id`, - ); - - await queryRunner.query(`DROP TABLE ${tablePrefix}execution_data`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1690000000031-FixExecutionDataType.ts b/packages/@n8n/db/src/migrations/mysqldb/1690000000031-FixExecutionDataType.ts deleted file mode 100644 index 811f0037d1751..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1690000000031-FixExecutionDataType.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { MigrationContext, IrreversibleMigration } from '../migration-types'; - -export class FixExecutionDataType1690000000031 implements IrreversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - /** - * SeparateExecutionData migration for MySQL/MariaDB accidentally changed the data-type for `data` column to `TEXT`. - * This migration changes it back. - * The previous migration has been patched to avoid converting to `TEXT`, which might fail. - * - * For any users who already ran the previous migration, this migration should fix the column type. - * For any users who run these migrations in the same batch, this migration would be no-op, as the column type is already `MEDIUMTEXT` - */ - await queryRunner.query( - 'ALTER TABLE `' + tablePrefix + 'execution_data` MODIFY COLUMN `data` MEDIUMTEXT', - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1717498465931-AddActivatedAtUserSetting.ts b/packages/@n8n/db/src/migrations/mysqldb/1717498465931-AddActivatedAtUserSetting.ts deleted file mode 100644 index f179c8522dcad..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1717498465931-AddActivatedAtUserSetting.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -export class AddActivatedAtUserSetting1717498465931 implements ReversibleMigration { - async up({ queryRunner, escape }: MigrationContext) { - const now = Date.now(); - await queryRunner.query( - `UPDATE ${escape.tableName('user')} - SET settings = JSON_SET(COALESCE(settings, '{}'), '$.userActivatedAt', '${now}') - WHERE settings IS NOT NULL AND JSON_EXTRACT(settings, '$.userActivated') = true`, - ); - } - - async down({ queryRunner, escape }: MigrationContext) { - await queryRunner.query( - `UPDATE ${escape.tableName('user')} - SET settings = JSON_REMOVE(settings, '$.userActivatedAt') - WHERE settings IS NOT NULL`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1731582748663-MigrateTestDefinitionKeyToString.ts b/packages/@n8n/db/src/migrations/mysqldb/1731582748663-MigrateTestDefinitionKeyToString.ts deleted file mode 100644 index f39fcc93fb855..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1731582748663-MigrateTestDefinitionKeyToString.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { MigrationContext, IrreversibleMigration } from '../migration-types'; - -export class MigrateTestDefinitionKeyToString1731582748663 implements IrreversibleMigration { - async up(context: MigrationContext) { - const { queryRunner, tablePrefix } = context; - - await queryRunner.query( - `ALTER TABLE ${tablePrefix}test_definition CHANGE id tmp_id int NOT NULL AUTO_INCREMENT;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}test_definition ADD COLUMN id varchar(36) NOT NULL;`, - ); - await queryRunner.query(`UPDATE ${tablePrefix}test_definition SET id = CONVERT(tmp_id, CHAR);`); - await queryRunner.query( - `CREATE INDEX \`TMP_idx_${tablePrefix}test_definition_id\` ON ${tablePrefix}test_definition (\`id\`);`, - ); - - // Note: this part was missing in initial release and was added after. Without it the migration run successfully, - // but left the table in inconsistent state, because it didn't finish changing the primary key and deleting the old one. - // This prevented the next migration from running on MySQL 8.4.4 - await queryRunner.query( - `ALTER TABLE ${tablePrefix}test_definition MODIFY COLUMN tmp_id INT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}test_definition DROP PRIMARY KEY, ADD PRIMARY KEY (\`id\`);`, - ); - await queryRunner.query( - `DROP INDEX \`TMP_idx_${tablePrefix}test_definition_id\` ON ${tablePrefix}test_definition;`, - ); - await queryRunner.query(`ALTER TABLE ${tablePrefix}test_definition DROP COLUMN tmp_id;`); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1732271325258-CreateTestMetricTable.ts b/packages/@n8n/db/src/migrations/mysqldb/1732271325258-CreateTestMetricTable.ts deleted file mode 100644 index 4298a96c9e329..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1732271325258-CreateTestMetricTable.ts +++ /dev/null @@ -1,49 +0,0 @@ -import assert from 'node:assert'; - -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -const testMetricEntityTableName = 'test_metric'; - -export class CreateTestMetricTable1732271325258 implements ReversibleMigration { - async up({ schemaBuilder: { createTable, column }, queryRunner, tablePrefix }: MigrationContext) { - // Check if the previous migration MigrateTestDefinitionKeyToString1731582748663 properly updated the primary key - const table = await queryRunner.getTable(`${tablePrefix}test_definition`); - assert(table, 'test_definition table not found'); - - const brokenPrimaryColumn = table.primaryColumns.some( - (c) => c.name === 'tmp_id' && c.isPrimary, - ); - - if (brokenPrimaryColumn) { - // The migration was completed, but left the table in inconsistent state, let's finish the primary key change - await queryRunner.query( - `ALTER TABLE ${tablePrefix}test_definition MODIFY COLUMN tmp_id INT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}test_definition DROP PRIMARY KEY, ADD PRIMARY KEY (\`id\`);`, - ); - await queryRunner.query( - `DROP INDEX \`TMP_idx_${tablePrefix}test_definition_id\` ON ${tablePrefix}test_definition;`, - ); - await queryRunner.query(`ALTER TABLE ${tablePrefix}test_definition DROP COLUMN tmp_id;`); - } - // End of test_definition PK check - - await createTable(testMetricEntityTableName) - .withColumns( - column('id').varchar(36).primary.notNull, - column('name').varchar(255).notNull, - column('testDefinitionId').varchar(36).notNull, - ) - .withIndexOn('testDefinitionId') - .withForeignKey('testDefinitionId', { - tableName: 'test_definition', - columnName: 'id', - onDelete: 'CASCADE', - }).withTimestamps; - } - - async down({ schemaBuilder: { dropTable } }: MigrationContext) { - await dropTable(testMetricEntityTableName); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1736172058779-AddStatsColumnsToTestRun.ts b/packages/@n8n/db/src/migrations/mysqldb/1736172058779-AddStatsColumnsToTestRun.ts deleted file mode 100644 index 8ab60dfe0d45f..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1736172058779-AddStatsColumnsToTestRun.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -const columns = ['totalCases', 'passedCases', 'failedCases'] as const; - -// Note: This migration was separated from common after release to remove column check constraints -// because they were causing issues with MySQL - -export class AddStatsColumnsToTestRun1736172058779 implements ReversibleMigration { - async up({ escape, runQuery }: MigrationContext) { - const tableName = escape.tableName('test_run'); - const columnNames = columns.map((name) => escape.columnName(name)); - - // Values can be NULL only if the test run is new, otherwise they must be non-negative integers. - // Test run might be cancelled or interrupted by unexpected error at any moment, so values can be either NULL or non-negative integers. - for (const name of columnNames) { - await runQuery(`ALTER TABLE ${tableName} ADD COLUMN ${name} INT;`); - } - } - - async down({ escape, runQuery }: MigrationContext) { - const tableName = escape.tableName('test_run'); - const columnNames = columns.map((name) => escape.columnName(name)); - - for (const name of columnNames) { - await runQuery(`ALTER TABLE ${tableName} DROP COLUMN ${name}`); - } - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1739873751194-FixTestDefinitionPrimaryKey.ts b/packages/@n8n/db/src/migrations/mysqldb/1739873751194-FixTestDefinitionPrimaryKey.ts deleted file mode 100644 index 1158c29b0b95c..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1739873751194-FixTestDefinitionPrimaryKey.ts +++ /dev/null @@ -1,44 +0,0 @@ -import assert from 'node:assert'; - -import type { MigrationContext, IrreversibleMigration } from '../migration-types'; - -export class FixTestDefinitionPrimaryKey1739873751194 implements IrreversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - /** - * MigrateTestDefinitionKeyToString migration for MySQL/MariaDB had missing part, - * and didn't complete primary key type change and deletion of the temporary column. - * - * This migration checks if table is in inconsistent state and finishes the primary key type change when needed. - * - * The MigrateTestDefinitionKeyToString migration has been patched to properly change the primary key. - * - * As the primary key issue might prevent the CreateTestMetricTable migration from running successfully on MySQL 8.4.4, - * the CreateTestMetricTable also contains the patch. - * - * For users who already ran the MigrateTestDefinitionKeyToString and CreateTestMetricTable, this migration should fix the primary key. - * For users who run these migrations in the same batch, this migration would be no-op, as the test_definition table should be already fixed - * by either of the previous patched migrations. - */ - - const table = await queryRunner.getTable(`${tablePrefix}test_definition`); - assert(table, 'test_definition table not found'); - - const brokenPrimaryColumn = table.primaryColumns.some( - (c) => c.name === 'tmp_id' && c.isPrimary, - ); - - if (brokenPrimaryColumn) { - // The migration was completed, but left the table in inconsistent state, let's finish the primary key change - await queryRunner.query( - `ALTER TABLE ${tablePrefix}test_definition MODIFY COLUMN tmp_id INT NOT NULL;`, - ); - await queryRunner.query( - `ALTER TABLE ${tablePrefix}test_definition DROP PRIMARY KEY, ADD PRIMARY KEY (\`id\`);`, - ); - await queryRunner.query( - `DROP INDEX \`TMP_idx_${tablePrefix}test_definition_id\` ON ${tablePrefix}test_definition;`, - ); - await queryRunner.query(`ALTER TABLE ${tablePrefix}test_definition DROP COLUMN tmp_id;`); - } - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1740445074052-UpdateParentFolderIdColumn.ts b/packages/@n8n/db/src/migrations/mysqldb/1740445074052-UpdateParentFolderIdColumn.ts deleted file mode 100644 index 6141492255786..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1740445074052-UpdateParentFolderIdColumn.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { BaseMigration, MigrationContext } from '../migration-types'; - -export class UpdateParentFolderIdColumn1740445074052 implements BaseMigration { - async up({ escape, queryRunner }: MigrationContext) { - const workflowTableName = escape.tableName('workflow_entity'); - const folderTableName = escape.tableName('folder'); - const parentFolderIdColumn = escape.columnName('parentFolderId'); - const idColumn = escape.columnName('id'); - - await queryRunner.query( - `ALTER TABLE ${workflowTableName} ADD CONSTRAINT fk_workflow_parent_folder FOREIGN KEY (${parentFolderIdColumn}) REFERENCES ${folderTableName}(${idColumn}) ON DELETE CASCADE`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1758794506893-AddProjectIdToVariableTable.ts b/packages/@n8n/db/src/migrations/mysqldb/1758794506893-AddProjectIdToVariableTable.ts deleted file mode 100644 index 0c89afec82738..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1758794506893-AddProjectIdToVariableTable.ts +++ /dev/null @@ -1,92 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -const VARIABLES_TABLE_NAME = 'variables'; -const UNIQUE_PROJECT_KEY_INDEX_NAME = 'variables_project_key_unique'; -const UNIQUE_GLOBAL_KEY_INDEX_NAME = 'variables_global_key_unique'; -const PROJECT_ID_FOREIGN_KEY_NAME = 'variables_projectId_foreign'; - -/** - * Adds a projectId column to the variables table to support project-scoped variables. - * In MySQL, also adds a generated column (globalKey) to enforce uniqueness - * for global variables (where projectId is null). - */ -export class AddProjectIdToVariableTable1758794506893 implements ReversibleMigration { - async up({ - schemaBuilder: { addColumns, column, dropIndex, addForeignKey }, - queryRunner, - escape, - }: MigrationContext) { - const variablesTableName = escape.tableName(VARIABLES_TABLE_NAME); - - // Drop the old unique index on key - await dropIndex(VARIABLES_TABLE_NAME, ['key'], { customIndexName: 'key' }); - - // Add projectId and globalKey columns - await addColumns(VARIABLES_TABLE_NAME, [column('projectId').varchar(36)]); - - // Add generated column for global uniqueness - // Null values are considered unique in MySQL, so we create a generated column - // that contains the key when projectId is null, and null otherwise. - await queryRunner.query(` - ALTER TABLE ${variablesTableName} - ADD COLUMN globalKey VARCHAR(255) GENERATED ALWAYS AS ( - CASE WHEN projectId IS NULL THEN \`key\` ELSE NULL END - ) STORED; - `); - - // Add foreign key to project - // Create it after the generated column to avoid limits of mysql - // https://dev.mysql.com/doc/refman/8.4/en/create-table-foreign-keys.html - // "A foreign key constraint on a stored generated column cannot use CASCADE" - await addForeignKey( - VARIABLES_TABLE_NAME, - 'projectId', - ['project', 'id'], - PROJECT_ID_FOREIGN_KEY_NAME, - ); - - // Unique index for project-specific variables - await queryRunner.query(` - CREATE UNIQUE INDEX ${UNIQUE_PROJECT_KEY_INDEX_NAME} - ON ${variablesTableName} (projectId, \`key\`); - `); - - // Unique index for global variables - await queryRunner.query(` - CREATE UNIQUE INDEX ${UNIQUE_GLOBAL_KEY_INDEX_NAME} - ON ${variablesTableName} (globalKey); - `); - } - - // Down migration do not use typeorm helpers - // to prevent error with generated columns - // because typeorm tries to fetch the column details from typeorm metadata - async down({ queryRunner, escape }: MigrationContext) { - const variablesTableName = escape.tableName(VARIABLES_TABLE_NAME); - - // Delete the rows with a non-null projectId (data loss) - await queryRunner.query(`DELETE FROM ${variablesTableName} WHERE projectId IS NOT NULL;`); - - // Drop the generated column index - await queryRunner.query(`DROP INDEX ${UNIQUE_GLOBAL_KEY_INDEX_NAME} ON ${variablesTableName};`); - - // Drop the generated column - await queryRunner.query(`ALTER TABLE ${variablesTableName} DROP COLUMN globalKey;`); - - // Drop the project id column, foreign key and its associated index - await queryRunner.query( - `ALTER TABLE ${variablesTableName} DROP FOREIGN KEY ${PROJECT_ID_FOREIGN_KEY_NAME};`, - ); - - await queryRunner.query( - `DROP INDEX ${UNIQUE_PROJECT_KEY_INDEX_NAME} ON ${variablesTableName};`, - ); - - await queryRunner.query(`ALTER TABLE ${variablesTableName} DROP COLUMN projectId;`); - - // Reset the original unique index on key - await queryRunner.query( - `ALTER TABLE ${variablesTableName} ADD CONSTRAINT \`key\` UNIQUE (\`key\`);`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1760965142113-DropUnusedChatHubColumns.ts b/packages/@n8n/db/src/migrations/mysqldb/1760965142113-DropUnusedChatHubColumns.ts deleted file mode 100644 index db5e60ab83372..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1760965142113-DropUnusedChatHubColumns.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -const table = { - messages: 'chat_hub_messages', -} as const; - -export class DropUnusedChatHubColumns1760965142113 implements ReversibleMigration { - async up({ - runQuery, - tablePrefix, - schemaBuilder: { addColumns, dropColumns, column }, - }: MigrationContext) { - // MySQL needs to drop foreign keys before dropping a column (turnId) that uses it. - // Name of the FK depends on table prefix, so we can't just hardcode it. - const tableName = `${tablePrefix}${table.messages}`; - const foreignKeys: Array<{ name: string }> = await runQuery( - `SELECT CONSTRAINT_NAME AS name - FROM information_schema.KEY_COLUMN_USAGE - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = '${tableName}' - AND COLUMN_NAME = 'turnId' - AND REFERENCED_TABLE_NAME IS NOT NULL;`, - ); - - // There should only be one, but just in case handle multiple - for (const { name } of foreignKeys) { - await runQuery(`ALTER TABLE \`${tableName}\` DROP FOREIGN KEY \`${name}\`;`); - } - await dropColumns(table.messages, ['turnId', 'runIndex', 'state']); - - await addColumns(table.messages, [ - column('status') - .varchar(16) - .default("'success'") - .notNull.comment( - 'ChatHubMessageStatus enum, eg. "success", "error", "running", "cancelled"', - ), - ]); - } - - async down({ - schemaBuilder: { dropColumns, addColumns, column, addForeignKey }, - }: MigrationContext) { - await dropColumns(table.messages, ['status']); - await addColumns(table.messages, [ - column('turnId').uuid, - column('runIndex') - .int.notNull.default(0) - .comment('The nth attempt this message has been generated/retried this turn'), - column('state') - .varchar(16) - .default("'active'") - .notNull.comment('ChatHubMessageState enum: "active", "superseded", "hidden", "deleted"'), - ]); - await addForeignKey(table.messages, 'turnId', [table.messages, 'id'], undefined, 'CASCADE'); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1761047826451-AddWorkflowVersionColumn.ts b/packages/@n8n/db/src/migrations/mysqldb/1761047826451-AddWorkflowVersionColumn.ts deleted file mode 100644 index 041d9534ffd72..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1761047826451-AddWorkflowVersionColumn.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -/** - * MySQL-specific migration to add versionCounter column and trigger for auto-incrementing. - */ -export class AddWorkflowVersionColumn1761047826451 implements ReversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - const tableName = `${tablePrefix}workflow_entity`; - const triggerName = `${tablePrefix}workflow_version_increment`; - - // Add versionCounter column - await queryRunner.query( - `ALTER TABLE \`${tableName}\` ADD COLUMN \`versionCounter\` int NOT NULL DEFAULT 1`, - ); - - // Create trigger that increments version counter before update. - // NOTE: we're modifying the NEW record before the update happens, so we do it BEFORE the update. - await queryRunner.query(` - CREATE TRIGGER \`${triggerName}\` - BEFORE UPDATE ON \`${tableName}\` - FOR EACH ROW - BEGIN - IF OLD.versionCounter = NEW.versionCounter THEN - SET NEW.versionCounter = OLD.versionCounter + 1; - END IF; - END; - `); - } - - async down({ queryRunner, tablePrefix }: MigrationContext) { - const tableName = `${tablePrefix}workflow_entity`; - const triggerName = `${tablePrefix}workflow_version_increment`; - - // Drop trigger - await queryRunner.query(`DROP TRIGGER IF EXISTS \`${triggerName}\``); - - // Drop column - await queryRunner.query(`ALTER TABLE \`${tableName}\` DROP COLUMN \`versionCounter\``); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1761655473000-ChangeDependencyInfoToJson.ts b/packages/@n8n/db/src/migrations/mysqldb/1761655473000-ChangeDependencyInfoToJson.ts deleted file mode 100644 index 5662529865962..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1761655473000-ChangeDependencyInfoToJson.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IrreversibleMigration, MigrationContext } from '../migration-types'; - -/** - * MySQL-specific migration to change the `dependencyInfo` column in `workflow_dependency` table from VARCHAR(255) to JSON. - * Handles both MySQL and MariaDB. - */ -export class ChangeDependencyInfoToJson1761655473000 implements IrreversibleMigration { - async up({ queryRunner, tablePrefix }: MigrationContext) { - const tableName = `${tablePrefix}workflow_dependency`; - - await queryRunner.query( - `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`dependencyInfo\` JSON NULL COMMENT 'Additional info about the dependency, interpreted based on type'`, - ); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/1761830340990-AddToolsColumnToChatHubTables.ts b/packages/@n8n/db/src/migrations/mysqldb/1761830340990-AddToolsColumnToChatHubTables.ts deleted file mode 100644 index d493362971ccf..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/1761830340990-AddToolsColumnToChatHubTables.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { MigrationContext, ReversibleMigration } from '../migration-types'; - -const table = { - sessions: 'chat_hub_sessions', - agents: 'chat_hub_agents', -} as const; - -export class AddToolsColumnToChatHubTables1761830340990 implements ReversibleMigration { - async up({ schemaBuilder: { addColumns, column }, queryRunner, tablePrefix }: MigrationContext) { - await addColumns(table.sessions, [ - column('tools').json.notNull.comment('Tools available to the agent as JSON node definitions'), - ]); - await addColumns(table.agents, [ - column('tools').json.notNull.comment('Tools available to the agent as JSON node definitions'), - ]); - - // Add a default value for existing rows - await Promise.all( - [ - `UPDATE \`${tablePrefix}${table.sessions}\` SET \`tools\` = '[]' WHERE JSON_TYPE(\`tools\`) = 'NULL'`, - `UPDATE \`${tablePrefix}${table.agents}\` SET \`tools\` = '[]' WHERE JSON_TYPE(\`tools\`) = 'NULL'`, - ].map(async (query) => { - await queryRunner.query(query); - }), - ); - } - - async down({ schemaBuilder: { dropColumns } }: MigrationContext) { - await dropColumns(table.sessions, ['tools']); - await dropColumns(table.agents, ['tools']); - } -} diff --git a/packages/@n8n/db/src/migrations/mysqldb/index.ts b/packages/@n8n/db/src/migrations/mysqldb/index.ts deleted file mode 100644 index 9d539a63e7562..0000000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/index.ts +++ /dev/null @@ -1,264 +0,0 @@ -import { InitialMigration1588157391238 } from './1588157391238-InitialMigration'; -import { WebhookModel1592447867632 } from './1592447867632-WebhookModel'; -import { CreateIndexStoppedAt1594902918301 } from './1594902918301-CreateIndexStoppedAt'; -import { MakeStoppedAtNullable1607431743767 } from './1607431743767-MakeStoppedAtNullable'; -import { AddWebhookId1611149998770 } from './1611149998770-AddWebhookId'; -import { ChangeDataSize1615306975123 } from './1615306975123-ChangeDataSize'; -import { CreateTagEntity1617268711084 } from './1617268711084-CreateTagEntity'; -import { ChangeCredentialDataSize1620729500000 } from './1620729500000-ChangeCredentialDataSize'; -import { UniqueWorkflowNames1620826335440 } from './1620826335440-UniqueWorkflowNames'; -import { CertifyCorrectCollation1623936588000 } from './1623936588000-CertifyCorrectCollation'; -import { AddWaitColumnId1626183952959 } from './1626183952959-AddWaitColumn'; -import { UpdateWorkflowCredentials1630451444017 } from './1630451444017-UpdateWorkflowCredentials'; -import { AddExecutionEntityIndexes1644424784709 } from './1644424784709-AddExecutionEntityIndexes'; -import { CreateUserManagement1646992772331 } from './1646992772331-CreateUserManagement'; -import { LowerCaseUserEmail1648740597343 } from './1648740597343-LowerCaseUserEmail'; -import { CommunityNodes1652254514003 } from './1652254514003-CommunityNodes'; -import { AddUserSettings1652367743993 } from './1652367743993-AddUserSettings'; -import { AddAPIKeyColumn1652905585850 } from './1652905585850-AddAPIKeyColumn'; -import { IntroducePinData1654090101303 } from './1654090101303-IntroducePinData'; -import { AddNodeIds1658932910559 } from './1658932910559-AddNodeIds'; -import { AddJsonKeyPinData1659895550980 } from './1659895550980-AddJsonKeyPinData'; -import { CreateCredentialsUserRole1660062385367 } from './1660062385367-CreateCredentialsUserRole'; -import { CreateWorkflowsEditorRole1663755770894 } from './1663755770894-CreateWorkflowsEditorRole'; -import { WorkflowStatistics1664196174002 } from './1664196174002-WorkflowStatistics'; -import { CreateCredentialUsageTable1665484192213 } from './1665484192213-CreateCredentialUsageTable'; -import { RemoveCredentialUsageTable1665754637026 } from './1665754637026-RemoveCredentialUsageTable'; -import { AddWorkflowVersionIdColumn1669739707125 } from './1669739707125-AddWorkflowVersionIdColumn'; -import { AddTriggerCountColumn1669823906994 } from './1669823906994-AddTriggerCountColumn'; -import { MessageEventBusDestinations1671535397530 } from './1671535397530-MessageEventBusDestinations'; -import { RemoveWorkflowDataLoadedFlag1671726148420 } from './1671726148420-RemoveWorkflowDataLoadedFlag'; -import { DeleteExecutionsWithWorkflows1673268682475 } from './1673268682475-DeleteExecutionsWithWorkflows'; -import { AddStatusToExecutions1674138566000 } from './1674138566000-AddStatusToExecutions'; -import { MigrateExecutionStatus1676996103000 } from './1676996103000-MigrateExecutionStatus'; -import { UpdateRunningExecutionStatus1677236788851 } from './1677236788851-UpdateRunningExecutionStatus'; -import { CreateVariables1677501636753 } from './1677501636753-CreateVariables'; -import { CreateExecutionMetadataTable1679416281779 } from './1679416281779-CreateExecutionMetadataTable'; -import { AddUserActivatedProperty1681134145996 } from './1681134145996-AddUserActivatedProperty'; -import { RemoveSkipOwnerSetup1681134145997 } from './1681134145997-RemoveSkipOwnerSetup'; -import { MigrateIntegerKeysToString1690000000001 } from './1690000000001-MigrateIntegerKeysToString'; -import { SeparateExecutionData1690000000030 } from './1690000000030-SeparateExecutionData'; -import { FixExecutionDataType1690000000031 } from './1690000000031-FixExecutionDataType'; -import { AddActivatedAtUserSetting1717498465931 } from './1717498465931-AddActivatedAtUserSetting'; -import { MigrateTestDefinitionKeyToString1731582748663 } from './1731582748663-MigrateTestDefinitionKeyToString'; -import { CreateTestMetricTable1732271325258 } from './1732271325258-CreateTestMetricTable'; -import { AddStatsColumnsToTestRun1736172058779 } from './1736172058779-AddStatsColumnsToTestRun'; -import { FixTestDefinitionPrimaryKey1739873751194 } from './1739873751194-FixTestDefinitionPrimaryKey'; -import { UpdateParentFolderIdColumn1740445074052 } from './1740445074052-UpdateParentFolderIdColumn'; -import { AddProjectIdToVariableTable1758794506893 } from './1758794506893-AddProjectIdToVariableTable'; -import { DropUnusedChatHubColumns1760965142113 } from './1760965142113-DropUnusedChatHubColumns'; -import { AddWorkflowVersionColumn1761047826451 } from './1761047826451-AddWorkflowVersionColumn'; -import { ChangeDependencyInfoToJson1761655473000 } from './1761655473000-ChangeDependencyInfoToJson'; -import { AddToolsColumnToChatHubTables1761830340990 } from './1761830340990-AddToolsColumnToChatHubTables'; -import { CreateLdapEntities1674509946020 } from '../common/1674509946020-CreateLdapEntities'; -import { PurgeInvalidWorkflowConnections1675940580449 } from '../common/1675940580449-PurgeInvalidWorkflowConnections'; -import { RemoveResetPasswordColumns1690000000030 } from '../common/1690000000030-RemoveResetPasswordColumns'; -import { AddMfaColumns1690000000030 } from '../common/1690000000040-AddMfaColumns'; -import { CreateWorkflowNameIndex1691088862123 } from '../common/1691088862123-CreateWorkflowNameIndex'; -import { CreateWorkflowHistoryTable1692967111175 } from '../common/1692967111175-CreateWorkflowHistoryTable'; -import { ExecutionSoftDelete1693491613982 } from '../common/1693491613982-ExecutionSoftDelete'; -import { DisallowOrphanExecutions1693554410387 } from '../common/1693554410387-DisallowOrphanExecutions'; -import { AddWorkflowMetadata1695128658538 } from '../common/1695128658538-AddWorkflowMetadata'; -import { ModifyWorkflowHistoryNodesAndConnections1695829275184 } from '../common/1695829275184-ModifyWorkflowHistoryNodesAndConnections'; -import { AddGlobalAdminRole1700571993961 } from '../common/1700571993961-AddGlobalAdminRole'; -import { DropRoleMapping1705429061930 } from '../common/1705429061930-DropRoleMapping'; -import { RemoveFailedExecutionStatus1711018413374 } from '../common/1711018413374-RemoveFailedExecutionStatus'; -import { MoveSshKeysToDatabase1711390882123 } from '../common/1711390882123-MoveSshKeysToDatabase'; -import { RemoveNodesAccess1712044305787 } from '../common/1712044305787-RemoveNodesAccess'; -import { CreateProject1714133768519 } from '../common/1714133768519-CreateProject'; -import { MakeExecutionStatusNonNullable1714133768521 } from '../common/1714133768521-MakeExecutionStatusNonNullable'; -import { AddConstraintToExecutionMetadata1720101653148 } from '../common/1720101653148-AddConstraintToExecutionMetadata'; -import { CreateInvalidAuthTokenTable1723627610222 } from '../common/1723627610222-CreateInvalidAuthTokenTable'; -import { RefactorExecutionIndices1723796243146 } from '../common/1723796243146-RefactorExecutionIndices'; -import { CreateAnnotationTables1724753530828 } from '../common/1724753530828-CreateExecutionAnnotationTables'; -import { AddApiKeysTable1724951148974 } from '../common/1724951148974-AddApiKeysTable'; -import { CreateProcessedDataTable1726606152711 } from '../common/1726606152711-CreateProcessedDataTable'; -import { SeparateExecutionCreationFromStart1727427440136 } from '../common/1727427440136-SeparateExecutionCreationFromStart'; -import { AddMissingPrimaryKeyOnAnnotationTagMapping1728659839644 } from '../common/1728659839644-AddMissingPrimaryKeyOnAnnotationTagMapping'; -import { UpdateProcessedDataValueColumnToText1729607673464 } from '../common/1729607673464-UpdateProcessedDataValueColumnToText'; -import { AddProjectIcons1729607673469 } from '../common/1729607673469-AddProjectIcons'; -import { CreateTestDefinitionTable1730386903556 } from '../common/1730386903556-CreateTestDefinitionTable'; -import { AddDescriptionToTestDefinition1731404028106 } from '../common/1731404028106-AddDescriptionToTestDefinition'; -import { CreateTestRun1732549866705 } from '../common/1732549866705-CreateTestRunTable'; -import { AddMockedNodesColumnToTestDefinition1733133775640 } from '../common/1733133775640-AddMockedNodesColumnToTestDefinition'; -import { AddManagedColumnToCredentialsTable1734479635324 } from '../common/1734479635324-AddManagedColumnToCredentialsTable'; -import { CreateTestCaseExecutionTable1736947513045 } from '../common/1736947513045-CreateTestCaseExecutionTable'; -import { AddErrorColumnsToTestRuns1737715421462 } from '../common/1737715421462-AddErrorColumnsToTestRuns'; -import { CreateFolderTable1738709609940 } from '../common/1738709609940-CreateFolderTable'; -import { CreateAnalyticsTables1739549398681 } from '../common/1739549398681-CreateAnalyticsTables'; -import { RenameAnalyticsToInsights1741167584277 } from '../common/1741167584277-RenameAnalyticsToInsights'; -import { AddScopesColumnToApiKeys1742918400000 } from '../common/1742918400000-AddScopesColumnToApiKeys'; -import { ClearEvaluation1745322634000 } from '../common/1745322634000-CleanEvaluations'; -import { AddWorkflowStatisticsRootCount1745587087521 } from '../common/1745587087521-AddWorkflowStatisticsRootCount'; -import { AddWorkflowArchivedColumn1745934666076 } from '../common/1745934666076-AddWorkflowArchivedColumn'; -import { DropRoleTable1745934666077 } from '../common/1745934666077-DropRoleTable'; -import { AddProjectDescriptionColumn1747824239000 } from '../common/1747824239000-AddProjectDescriptionColumn'; -import { AddLastActiveAtColumnToUser1750252139166 } from '../common/1750252139166-AddLastActiveAtColumnToUser'; -import { AddScopeTables1750252139166 } from '../common/1750252139166-AddScopeTables'; -import { AddRolesTables1750252139167 } from '../common/1750252139167-AddRolesTables'; -import { LinkRoleToUserTable1750252139168 } from '../common/1750252139168-LinkRoleToUserTable'; -import { RemoveOldRoleColumn1750252139170 } from '../common/1750252139170-RemoveOldRoleColumn'; -import { AddInputsOutputsToTestCaseExecution1752669793000 } from '../common/1752669793000-AddInputsOutputsToTestCaseExecution'; -import { LinkRoleToProjectRelationTable1753953244168 } from '../common/1753953244168-LinkRoleToProjectRelationTable'; -import { CreateDataStoreTables1754475614601 } from '../common/1754475614601-CreateDataStoreTables'; -import { ReplaceDataStoreTablesWithDataTables1754475614602 } from '../common/1754475614602-ReplaceDataStoreTablesWithDataTables'; -import { AddTimestampsToRoleAndRoleIndexes1756906557570 } from '../common/1756906557570-AddTimestampsToRoleAndRoleIndexes'; -import { AddAudienceColumnToApiKeys1758731786132 } from '../common/1758731786132-AddAudienceColumnToApiKey'; -import { ChangeValueTypesForInsights1759399811000 } from '../common/1759399811000-ChangeValueTypesForInsights'; -import { CreateChatHubTables1760019379982 } from '../common/1760019379982-CreateChatHubTables'; -import { CreateChatHubAgentTable1760020000000 } from '../common/1760020000000-CreateChatHubAgentTable'; -import { UniqueRoleNames1760020838000 } from '../common/1760020838000-UniqueRoleNames'; -import { CreateOAuthEntities1760116750277 } from '../common/1760116750277-CreateOAuthEntities'; -import { CreateWorkflowDependencyTable1760314000000 } from '../common/1760314000000-CreateWorkflowDependencyTable'; -import { AddAttachmentsToChatHubMessages1761773155024 } from '../common/1761773155024-AddAttachmentsToChatHubMessages'; -import { AddWorkflowDescriptionColumn1762177736257 } from '../common/1762177736257-AddWorkflowDescriptionColumn'; -import { BackfillMissingWorkflowHistoryRecords1762763704614 } from '../common/1762763704614-BackfillMissingWorkflowHistoryRecords'; -import { AddIsGlobalColumnToCredentialsTable1762771954619 } from '../common/1762771954619-IsGlobalGlobalColumnToCredentialsTable'; -import { AddWorkflowHistoryAutoSaveFields1762847206508 } from '../common/1762847206508-AddWorkflowHistoryAutoSaveFields'; -import { AddActiveVersionIdColumn1763047800000 } from '../common/1763047800000-AddActiveVersionIdColumn'; -import { ActivateExecuteWorkflowTriggerWorkflows1763048000000 } from '../common/1763048000000-ActivateExecuteWorkflowTriggerWorkflows'; -import { ChangeOAuthStateColumnToUnboundedVarchar1763572724000 } from '../common/1763572724000-ChangeOAuthStateColumnToUnboundedVarchar'; -import { CreateBinaryDataTable1763716655000 } from '../common/1763716655000-CreateBinaryDataTable'; -import { CreateWorkflowPublishHistoryTable1764167920585 } from '../common/1764167920585-CreateWorkflowPublishHistoryTable'; -import { AddCreatorIdToProjectTable1764276827837 } from '../common/1764276827837-AddCreatorIdToProjectTable'; -import { CreateDynamicCredentialResolverTable1764682447000 } from '../common/1764682447000-CreateCredentialResolverTable'; -import { AddDynamicCredentialEntryTable1764689388394 } from '../common/1764689388394-AddDynamicCredentialEntryTable'; -import { BackfillMissingWorkflowHistoryRecords1765448186933 } from '../common/1765448186933-BackfillMissingWorkflowHistoryRecords'; -import { AddResolvableFieldsToCredentials1765459448000 } from '../common/1765459448000-AddResolvableFieldsToCredentials'; -import { AddIconToAgentTable1765788427674 } from '../common/1765788427674-AddIconToAgentTable'; -import { AddAgentIdForeignKeys1765886667897 } from '../common/1765886667897-AddAgentIdForeignKeys'; -import { AddWorkflowVersionIdToExecutionData1765892199653 } from '../common/1765892199653-AddVersionIdToExecutionData'; -import type { Migration } from '../migration-types'; - -export const mysqlMigrations: Migration[] = [ - InitialMigration1588157391238, - WebhookModel1592447867632, - CreateIndexStoppedAt1594902918301, - AddWebhookId1611149998770, - MakeStoppedAtNullable1607431743767, - ChangeDataSize1615306975123, - ChangeCredentialDataSize1620729500000, - CreateTagEntity1617268711084, - UniqueWorkflowNames1620826335440, - CertifyCorrectCollation1623936588000, - AddWaitColumnId1626183952959, - UpdateWorkflowCredentials1630451444017, - AddExecutionEntityIndexes1644424784709, - CreateUserManagement1646992772331, - LowerCaseUserEmail1648740597343, - AddUserSettings1652367743993, - CommunityNodes1652254514003, - AddAPIKeyColumn1652905585850, - IntroducePinData1654090101303, - AddNodeIds1658932910559, - AddJsonKeyPinData1659895550980, - CreateCredentialsUserRole1660062385367, - CreateWorkflowsEditorRole1663755770894, - CreateCredentialUsageTable1665484192213, - RemoveCredentialUsageTable1665754637026, - AddWorkflowVersionIdColumn1669739707125, - WorkflowStatistics1664196174002, - AddTriggerCountColumn1669823906994, - RemoveWorkflowDataLoadedFlag1671726148420, - MessageEventBusDestinations1671535397530, - DeleteExecutionsWithWorkflows1673268682475, - CreateLdapEntities1674509946020, - PurgeInvalidWorkflowConnections1675940580449, - AddStatusToExecutions1674138566000, - MigrateExecutionStatus1676996103000, - UpdateRunningExecutionStatus1677236788851, - CreateExecutionMetadataTable1679416281779, - CreateVariables1677501636753, - AddUserActivatedProperty1681134145996, - MigrateIntegerKeysToString1690000000001, - SeparateExecutionData1690000000030, - FixExecutionDataType1690000000031, - RemoveSkipOwnerSetup1681134145997, - RemoveResetPasswordColumns1690000000030, - CreateWorkflowNameIndex1691088862123, - AddMfaColumns1690000000030, - CreateWorkflowHistoryTable1692967111175, - DisallowOrphanExecutions1693554410387, - ExecutionSoftDelete1693491613982, - AddWorkflowMetadata1695128658538, - ModifyWorkflowHistoryNodesAndConnections1695829275184, - AddGlobalAdminRole1700571993961, - DropRoleMapping1705429061930, - RemoveFailedExecutionStatus1711018413374, - MoveSshKeysToDatabase1711390882123, - RemoveNodesAccess1712044305787, - CreateProject1714133768519, - MakeExecutionStatusNonNullable1714133768521, - AddActivatedAtUserSetting1717498465931, - AddConstraintToExecutionMetadata1720101653148, - CreateInvalidAuthTokenTable1723627610222, - RefactorExecutionIndices1723796243146, - CreateAnnotationTables1724753530828, - AddApiKeysTable1724951148974, - SeparateExecutionCreationFromStart1727427440136, - CreateProcessedDataTable1726606152711, - AddMissingPrimaryKeyOnAnnotationTagMapping1728659839644, - UpdateProcessedDataValueColumnToText1729607673464, - CreateTestDefinitionTable1730386903556, - AddDescriptionToTestDefinition1731404028106, - MigrateTestDefinitionKeyToString1731582748663, - CreateTestMetricTable1732271325258, - CreateTestRun1732549866705, - AddMockedNodesColumnToTestDefinition1733133775640, - AddManagedColumnToCredentialsTable1734479635324, - AddProjectIcons1729607673469, - AddStatsColumnsToTestRun1736172058779, - CreateTestCaseExecutionTable1736947513045, - AddErrorColumnsToTestRuns1737715421462, - CreateFolderTable1738709609940, - FixTestDefinitionPrimaryKey1739873751194, - CreateAnalyticsTables1739549398681, - UpdateParentFolderIdColumn1740445074052, - RenameAnalyticsToInsights1741167584277, - AddScopesColumnToApiKeys1742918400000, - AddWorkflowStatisticsRootCount1745587087521, - AddWorkflowArchivedColumn1745934666076, - DropRoleTable1745934666077, - ClearEvaluation1745322634000, - AddProjectDescriptionColumn1747824239000, - AddLastActiveAtColumnToUser1750252139166, - AddScopeTables1750252139166, - AddRolesTables1750252139167, - LinkRoleToUserTable1750252139168, - AddInputsOutputsToTestCaseExecution1752669793000, - CreateDataStoreTables1754475614601, - RemoveOldRoleColumn1750252139170, - ReplaceDataStoreTablesWithDataTables1754475614602, - LinkRoleToProjectRelationTable1753953244168, - AddTimestampsToRoleAndRoleIndexes1756906557570, - AddProjectIdToVariableTable1758794506893, - AddAudienceColumnToApiKeys1758731786132, - ChangeValueTypesForInsights1759399811000, - CreateChatHubTables1760019379982, - CreateChatHubAgentTable1760020000000, - UniqueRoleNames1760020838000, - CreateWorkflowDependencyTable1760314000000, - DropUnusedChatHubColumns1760965142113, - AddWorkflowVersionColumn1761047826451, - ChangeDependencyInfoToJson1761655473000, - AddWorkflowDescriptionColumn1762177736257, - CreateOAuthEntities1760116750277, - BackfillMissingWorkflowHistoryRecords1762763704614, - AddIsGlobalColumnToCredentialsTable1762771954619, - AddWorkflowHistoryAutoSaveFields1762847206508, - AddToolsColumnToChatHubTables1761830340990, - ChangeOAuthStateColumnToUnboundedVarchar1763572724000, - AddAttachmentsToChatHubMessages1761773155024, - AddActiveVersionIdColumn1763047800000, - CreateBinaryDataTable1763716655000, - CreateWorkflowPublishHistoryTable1764167920585, - ActivateExecuteWorkflowTriggerWorkflows1763048000000, - AddCreatorIdToProjectTable1764276827837, - CreateDynamicCredentialResolverTable1764682447000, - AddDynamicCredentialEntryTable1764689388394, - BackfillMissingWorkflowHistoryRecords1765448186933, - AddResolvableFieldsToCredentials1765459448000, - AddIconToAgentTable1765788427674, - AddAgentIdForeignKeys1765886667897, - AddWorkflowVersionIdToExecutionData1765892199653, -]; diff --git a/packages/@n8n/db/src/repositories/__tests__/workflow.repository.test.ts b/packages/@n8n/db/src/repositories/__tests__/workflow.repository.test.ts index 773e56bba3b22..2b09bb3295c4e 100644 --- a/packages/@n8n/db/src/repositories/__tests__/workflow.repository.test.ts +++ b/packages/@n8n/db/src/repositories/__tests__/workflow.repository.test.ts @@ -414,34 +414,6 @@ describe('WorkflowRepository', () => { ); }); - it('should left join activeVersion with addSelect and use COALESCE for MySQL', async () => { - const mysqlConfig = mockInstance(GlobalConfig, { - database: { type: 'mysqldb' }, - }); - const mysqlWorkflowRepository = new WorkflowRepository( - entityManager.connection, - mysqlConfig, - folderRepository, - workflowHistoryRepository, - ); - jest.spyOn(mysqlWorkflowRepository, 'createQueryBuilder').mockReturnValue(queryBuilder); - - const workflowIds = ['workflow1']; - const options = { - filter: { triggerNodeTypes: ['n8n-nodes-base.executeWorkflowTrigger'] }, - }; - - await mysqlWorkflowRepository.getMany(workflowIds, options); - - expect(queryBuilder.leftJoin).toHaveBeenCalledWith('workflow.activeVersion', 'activeVersion'); - expect(queryBuilder.addSelect).toHaveBeenCalledWith('activeVersion.versionId'); - // Should use COALESCE to check activeVersion.nodes first, falling back to workflow.nodes - expect(queryBuilder.andWhere).toHaveBeenCalledWith( - '(COALESCE(activeVersion.nodes, workflow.nodes) LIKE :triggerNodeType0)', - { triggerNodeType0: '%n8n-nodes-base.executeWorkflowTrigger%' }, - ); - }); - it('should not join activeVersion again if already joined', async () => { // Simulate activeVersion already being joined Object.defineProperty(queryBuilder, 'expressionMap', { diff --git a/packages/@n8n/db/src/services/auth.roles.service.ts b/packages/@n8n/db/src/services/auth.roles.service.ts index 0152ee1a2562d..98bdf1edc08f9 100644 --- a/packages/@n8n/db/src/services/auth.roles.service.ts +++ b/packages/@n8n/db/src/services/auth.roles.service.ts @@ -3,7 +3,6 @@ import { Service } from '@n8n/di'; // eslint-disable-next-line import-x/order import { ALL_SCOPES, ALL_ROLES, scopeInformation } from '@n8n/permissions'; -// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import import { In } from '@n8n/typeorm'; import { Scope } from '../entities'; diff --git a/packages/@n8n/db/src/utils/__tests__/build-workflows-by-nodes-query.test.ts b/packages/@n8n/db/src/utils/__tests__/build-workflows-by-nodes-query.test.ts index 737b0660fd4ff..ddcb1e4fae4c9 100644 --- a/packages/@n8n/db/src/utils/__tests__/build-workflows-by-nodes-query.test.ts +++ b/packages/@n8n/db/src/utils/__tests__/build-workflows-by-nodes-query.test.ts @@ -28,21 +28,5 @@ describe('WorkflowRepository', () => { expect(whereClause).toContain(expectedInQuery); expect(parameters).toEqual(expectedParameters); }); - - it('should return the correct WHERE clause and parameters for mysqldb', () => { - const nodeTypes = ['HTTP Request', 'Set']; - const expectedWhereClause = - "(JSON_SEARCH(JSON_EXTRACT(workflow.nodes, '$[*].type'), 'one', :nodeType0) IS NOT NULL OR JSON_SEARCH(JSON_EXTRACT(workflow.nodes, '$[*].type'), 'one', :nodeType1) IS NOT NULL)"; - const expectedParameters = { - nodeType0: 'HTTP Request', - nodeType1: 'Set', - nodeTypes, - }; - - const { whereClause, parameters } = buildWorkflowsByNodesQuery(nodeTypes, 'mysqldb'); - - expect(whereClause).toEqual(expectedWhereClause); - expect(parameters).toEqual(expectedParameters); - }); }); }); diff --git a/packages/cli/package.json b/packages/cli/package.json index e9ea838ecc89d..83c8688b26566 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -26,14 +26,10 @@ "test:dev": "N8N_LOG_LEVEL=silent DB_SQLITE_POOL_SIZE=4 DB_TYPE=sqlite jest --watch", "test:sqlite": "N8N_LOG_LEVEL=silent DB_SQLITE_POOL_SIZE=4 DB_TYPE=sqlite jest --config=jest.config.integration.js --no-coverage", "test:postgres": "N8N_LOG_LEVEL=silent DB_TYPE=postgresdb DB_POSTGRESDB_SCHEMA=alt_schema DB_TABLE_PREFIX=test_ jest --config=jest.config.integration.js --no-coverage", - "test:mariadb": "echo true", - "test:mysql": "echo true", "test:win": "set N8N_LOG_LEVEL=silent&& set DB_SQLITE_POOL_SIZE=4&& set DB_TYPE=sqlite&& jest", "test:dev:win": "set N8N_LOG_LEVEL=silent&& set DB_SQLITE_POOL_SIZE=4&& set DB_TYPE=sqlite&& jest --watch", "test:sqlite:win": "set N8N_LOG_LEVEL=silent&& set DB_SQLITE_POOL_SIZE=4&& set DB_TYPE=sqlite&& jest --config=jest.config.integration.js", "test:postgres:win": "set N8N_LOG_LEVEL=silent&& set DB_TYPE=postgresdb&& set DB_POSTGRESDB_SCHEMA=alt_schema&& set DB_TABLE_PREFIX=test_&& jest --config=jest.config.integration.js --no-coverage", - "test:mariadb:win": "echo true", - "test:mysql:win": "echo true", "watch": "tsc-watch -p tsconfig.build.json --onCompilationComplete \"tsc-alias -p tsconfig.build.json\"" }, "bin": { @@ -150,7 +146,6 @@ "ldapts": "4.2.6", "lodash": "catalog:", "luxon": "catalog:", - "mysql2": "catalog:", "n8n-core": "workspace:*", "n8n-editor-ui": "workspace:*", "n8n-nodes-base": "workspace:*", diff --git a/packages/cli/src/databases/repositories/__tests__/execution.repository.test.ts b/packages/cli/src/databases/repositories/__tests__/execution.repository.test.ts index 82964d10d9753..261d94dbd03bc 100644 --- a/packages/cli/src/databases/repositories/__tests__/execution.repository.test.ts +++ b/packages/cli/src/databases/repositories/__tests__/execution.repository.test.ts @@ -75,7 +75,7 @@ describe('ExecutionRepository', () => { }); describe('updateExistingExecution', () => { - test.each(['sqlite', 'postgresdb', 'mysqldb'] as const)( + test.each(['sqlite', 'postgresdb'] as const)( 'should update execution and data in transaction on %s', async (dbType) => { globalConfig.database.type = dbType; diff --git a/packages/cli/src/modules/breaking-changes/rules/v2/__tests__/removed-database-types.rule.test.ts b/packages/cli/src/modules/breaking-changes/rules/v2/__tests__/removed-database-types.rule.test.ts index 6bbb1b49e8165..dfe02f742baca 100644 --- a/packages/cli/src/modules/breaking-changes/rules/v2/__tests__/removed-database-types.rule.test.ts +++ b/packages/cli/src/modules/breaking-changes/rules/v2/__tests__/removed-database-types.rule.test.ts @@ -23,7 +23,7 @@ describe('RemovedDatabaseTypesRule', () => { }); it('should be affected when using MySQL', async () => { - globalConfig.database.type = 'mysqldb'; + globalConfig.database.type = 'mysqldb' as any; const result = await rule.detect(); @@ -33,7 +33,7 @@ describe('RemovedDatabaseTypesRule', () => { }); it('should be affected when using MariaDB', async () => { - globalConfig.database.type = 'mariadb'; + globalConfig.database.type = 'mariadb' as any; const result = await rule.detect(); diff --git a/packages/cli/src/modules/breaking-changes/rules/v2/removed-database-types.rule.ts b/packages/cli/src/modules/breaking-changes/rules/v2/removed-database-types.rule.ts index 8f68f2584ba51..0a28ed4bed9d1 100644 --- a/packages/cli/src/modules/breaking-changes/rules/v2/removed-database-types.rule.ts +++ b/packages/cli/src/modules/breaking-changes/rules/v2/removed-database-types.rule.ts @@ -33,7 +33,7 @@ export class RemovedDatabaseTypesRule implements IBreakingChangeInstanceRule { recommendations: [], }; - const dbType = this.globalConfig.database.type; + const dbType = this.globalConfig.database.type as string; if (dbType === 'mysqldb' || dbType === 'mariadb') { result.isAffected = true; diff --git a/packages/cli/src/modules/data-table/__tests__/data-table-column.repository.test.ts b/packages/cli/src/modules/data-table/__tests__/data-table-column.repository.test.ts index bc9dd93914f7e..245ca7adad39b 100644 --- a/packages/cli/src/modules/data-table/__tests__/data-table-column.repository.test.ts +++ b/packages/cli/src/modules/data-table/__tests__/data-table-column.repository.test.ts @@ -182,7 +182,7 @@ describe('DataTableColumnRepository', () => { it('should call DDL service with correct database type', async () => { // Arrange const newName = 'new_valid_name'; - const dbTypes = ['postgres', 'mysql', 'sqlite'] as const; + const dbTypes = ['postgres', 'sqlite'] as const; for (const dbType of dbTypes) { mockEntityManager.existsBy.mockResolvedValue(false); diff --git a/packages/cli/src/modules/data-table/__tests__/sql-utils.test.ts b/packages/cli/src/modules/data-table/__tests__/sql-utils.test.ts index 2719796b742cb..7dd2a8800714b 100644 --- a/packages/cli/src/modules/data-table/__tests__/sql-utils.test.ts +++ b/packages/cli/src/modules/data-table/__tests__/sql-utils.test.ts @@ -217,24 +217,6 @@ describe('sql-utils', () => { expect(query).toBe('ALTER TABLE "data_table_user_abc" ADD "email" DOUBLE PRECISION'); }); - - it('should generate a valid SQL query for adding columns to a table, mysql', () => { - const tableName = 'data_table_user_abc'; - const column = { name: 'email', type: 'number' as const }; - - const query = addColumnQuery(tableName, column, 'mysql'); - - expect(query).toBe('ALTER TABLE `data_table_user_abc` ADD `email` DOUBLE'); - }); - - it('should generate a valid SQL query for adding columns to a table, mariadb', () => { - const tableName = 'data_table_user_abc'; - const column = { name: 'email', type: 'number' as const }; - - const query = addColumnQuery(tableName, column, 'mariadb'); - - expect(query).toBe('ALTER TABLE `data_table_user_abc` ADD `email` DOUBLE'); - }); }); describe('deleteColumnQuery', () => { @@ -266,8 +248,6 @@ describe('sql-utils', () => { it.each([ ['sqlite', '2024-01-15 10:30:00.123'], ['sqlite-pooled', '2024-01-15 10:30:00.123'], - ['mysql', '2024-01-15 10:30:00.123'], - ['mariadb', '2024-01-15 10:30:00.123'], ['postgres', '2024-01-15T10:30:00.123Z'], ] as const)('should format Date object for %s', (dbType, expected) => { const result = normalizeValueForDatabase( @@ -282,8 +262,6 @@ describe('sql-utils', () => { it.each([ ['sqlite', '2024-01-15 10:30:00.123'], ['sqlite-pooled', '2024-01-15 10:30:00.123'], - ['mysql', '2024-01-15 10:30:00.123'], - ['mariadb', '2024-01-15 10:30:00.123'], ['postgres', '2024-01-15T10:30:00.123Z'], ] as const)('should format ISO date string for %s', (dbType, expected) => { const result = normalizeValueForDatabase('2024-01-15T10:30:00.123Z', 'date', dbType); diff --git a/packages/cli/src/modules/data-table/data-table.repository.ts b/packages/cli/src/modules/data-table/data-table.repository.ts index fa59ce5a21079..2f32d8938cdf7 100644 --- a/packages/cli/src/modules/data-table/data-table.repository.ts +++ b/packages/cli/src/modules/data-table/data-table.repository.ts @@ -354,31 +354,6 @@ export class DataTableRepository extends Repository { break; } - case 'mysqldb': - case 'mariadb': { - const databaseName = this.globalConfig.database.mysqldb.database; - const isMariaDb = dbType === 'mariadb'; - const innodbTables = isMariaDb ? 'INNODB_SYS_TABLES' : 'INNODB_TABLES'; - const innodbTablespaces = isMariaDb ? 'INNODB_SYS_TABLESPACES' : 'INNODB_TABLESPACES'; - sql = ` - SELECT t.TABLE_NAME AS table_name, - COALESCE( - ( - SELECT SUM(ists.ALLOCATED_SIZE) - FROM information_schema.${innodbTables} ist - JOIN information_schema.${innodbTablespaces} ists - ON ists.SPACE = ist.SPACE - WHERE ist.NAME = CONCAT(t.TABLE_SCHEMA, '/', t.TABLE_NAME) - ), - (t.DATA_LENGTH + t.INDEX_LENGTH) - ) AS table_bytes - FROM information_schema.TABLES t - WHERE t.TABLE_SCHEMA = '${databaseName}' - AND t.TABLE_NAME LIKE '${tablePattern}' - `; - break; - } - default: return new Map(); } diff --git a/packages/cli/src/modules/data-table/utils/sql-utils.ts b/packages/cli/src/modules/data-table/utils/sql-utils.ts index a478823fc962f..7f907f8093ac6 100644 --- a/packages/cli/src/modules/data-table/utils/sql-utils.ts +++ b/packages/cli/src/modules/data-table/utils/sql-utils.ts @@ -51,9 +51,6 @@ function dataTableColumnTypeToSql( switch (dbType) { case 'postgres': return 'DOUBLE PRECISION'; - case 'mysql': - case 'mariadb': - return 'DOUBLE'; case 'sqlite': return 'REAL'; default: @@ -123,20 +120,11 @@ export function renameColumnQuery( return `ALTER TABLE ${quotedTableName} RENAME COLUMN ${quotedOldName} TO ${quotedNewName}`; } -export function quoteIdentifier(name: string, dbType: DataSourceOptions['type']): string { - switch (dbType) { - case 'mysql': - case 'mariadb': - return `\`${name}\``; - case 'postgres': - case 'sqlite': - default: - return `"${name}"`; - } +export function quoteIdentifier(name: string, _dbType: DataSourceOptions['type']): string { + // PostgreSQL and SQLite both use double quotes + return `"${name}"`; } -type WithInsertId = { insertId: number }; - const isArrayOf = (data: unknown, itemGuard: (x: unknown) => x is T): data is T[] => Array.isArray(data) && data.every(itemGuard); @@ -148,10 +136,6 @@ const isDate = (value: unknown): value is Date => { return value instanceof Date; }; -function hasInsertId(data: unknown): data is WithInsertId { - return typeof data === 'object' && data !== null && 'insertId' in data && isNumber(data.insertId); -} - function hasRowReturnData(data: unknown): data is DataTableRowReturn { return ( typeof data === 'object' && @@ -172,7 +156,7 @@ function hasRowId(data: unknown): data is Pick { export function extractReturningData(raw: unknown): DataTableRowReturn[] { if (!isArrayOf(raw, hasRowReturnData)) { throw new UnexpectedError( - `Expected INSERT INTO raw to be { id: number; createdAt: string; updatedAt: string }[] on Postgres or MariaDB. Is '${JSON.stringify(raw)}'`, + `Expected INSERT INTO raw to be { id: number; createdAt: string; updatedAt: string }[] on Postgres. Is '${JSON.stringify(raw)}'`, ); } @@ -181,21 +165,14 @@ export function extractReturningData(raw: unknown): DataTableRowReturn[] { export function extractInsertedIds(raw: unknown, dbType: DataSourceOptions['type']): number[] { switch (dbType) { - case 'postgres': - case 'mariadb': { + case 'postgres': { if (!isArrayOf(raw, hasRowId)) { throw new UnexpectedError( - `Expected INSERT INTO raw to be { id: number }[] on Postgres or MariaDB. Is '${JSON.stringify(raw)}'`, + `Expected INSERT INTO raw to be { id: number }[] on Postgres. Is '${JSON.stringify(raw)}'`, ); } return raw.map((r) => r.id); } - case 'mysql': { - if (!hasInsertId(raw)) { - throw new UnexpectedError('Expected INSERT INTO raw.insertId: number for MySQL'); - } - return [raw.insertId]; - } case 'sqlite': default: { if (!isNumber(raw)) { @@ -290,8 +267,8 @@ function formatDateForDatabase( throw new UnexpectedError(`Invalid date: ${String(value)}`); } - // These dbs use DATETIME format without 'T' and 'Z' - if (dbType && ['sqlite', 'sqlite-pooled', 'mysql', 'mariadb'].includes(dbType)) { + // SQLite uses DATETIME format without 'T' and 'Z' + if (dbType && ['sqlite', 'sqlite-pooled'].includes(dbType)) { return date.toISOString().replace('T', ' ').replace('Z', ''); } diff --git a/packages/cli/src/modules/insights/database/repositories/__tests__/insights-by-period-query.helper.test.ts b/packages/cli/src/modules/insights/database/repositories/__tests__/insights-by-period-query.helper.test.ts index 601c90e5e07a5..15e4f9e0a0412 100644 --- a/packages/cli/src/modules/insights/database/repositories/__tests__/insights-by-period-query.helper.test.ts +++ b/packages/cli/src/modules/insights/database/repositories/__tests__/insights-by-period-query.helper.test.ts @@ -21,8 +21,6 @@ describe('getDateRangesCommonTableExpressionQuery', () => { describe.each([ ['sqlite', 'SQLite'], ['postgresdb', 'PostgreSQL'], - ['mysqldb', 'MySQL'], - ['mariadb', 'MariaDB'], ])('%s', (dbType: DatabaseConfig['type']) => { describe('hour periodicity (1 day - startDate == endDate)', () => { test('last 24 hours (endDate is today)', () => { diff --git a/packages/cli/src/modules/insights/database/repositories/insights-by-period-query.helper.ts b/packages/cli/src/modules/insights/database/repositories/insights-by-period-query.helper.ts index 3b90c7d5894a5..dcf6d18c62517 100644 --- a/packages/cli/src/modules/insights/database/repositories/insights-by-period-query.helper.ts +++ b/packages/cli/src/modules/insights/database/repositories/insights-by-period-query.helper.ts @@ -13,7 +13,7 @@ import { DateTime } from 'luxon'; * * @param startDate - The start date of the range (inclusive) * @param endDate - The end date of the range (inclusive, or "now" if today) - * @param dbType - The database type (postgresdb, mysqldb, mariadb, or sqlite) + * @param dbType - The database type (postgresdb or sqlite) * @returns SQL CTE query with `prev_start_date`, `start_date`, and `end_date` columns * - `prev_start_date`: The start of the previous period (used for comparison) * - `start_date`: The start of the current period (inclusive) @@ -67,7 +67,7 @@ export function getDateRangesSelectQuery({ // Database-specific timestamp casting // PostgreSQL requires explicit CAST or :: syntax for timestamp comparisons - // SQLite and MySQL/MariaDB can work with string literals in comparisons + // SQLite can work with string literals in comparisons if (dbType === 'postgresdb') { return sql`SELECT CAST('${prevStartStr}' AS TIMESTAMP) AS prev_start_date, diff --git a/packages/cli/src/modules/insights/database/repositories/insights-by-period.repository.ts b/packages/cli/src/modules/insights/database/repositories/insights-by-period.repository.ts index 68f9788067046..1975089acee4c 100644 --- a/packages/cli/src/modules/insights/database/repositories/insights-by-period.repository.ts +++ b/packages/cli/src/modules/insights/database/repositories/insights-by-period.repository.ts @@ -89,8 +89,6 @@ export class InsightsByPeriodRepository extends Repository { let periodStartExpr = `date('now', '-${maxAgeInDays} days')`; if (dbType === 'postgresdb') { periodStartExpr = `CURRENT_DATE - INTERVAL '${maxAgeInDays} day'`; - } else if (dbType === 'mysqldb' || dbType === 'mariadb') { - periodStartExpr = `DATE_SUB(CURRENT_DATE, INTERVAL ${maxAgeInDays} DAY)`; } return periodStartExpr; @@ -103,12 +101,7 @@ export class InsightsByPeriodRepository extends Repository { periodUnitToCompactInto === 'week' ? "strftime('%Y-%m-%d 00:00:00.000', date(periodStart, '-6 days', 'weekday 1'))" : `strftime('%Y-%m-%d ${periodUnitToCompactInto === 'hour' ? '%H' : '00'}:00:00.000', periodStart)`; - if (dbType === 'mysqldb' || dbType === 'mariadb') { - periodStartExpr = - periodUnitToCompactInto === 'week' - ? "DATE_FORMAT(DATE_SUB(periodStart, INTERVAL WEEKDAY(periodStart) DAY), '%Y-%m-%d 00:00:00')" - : `DATE_FORMAT(periodStart, '%Y-%m-%d ${periodUnitToCompactInto === 'hour' ? '%H' : '00'}:00:00')`; - } else if (dbType === 'postgresdb') { + if (dbType === 'postgresdb') { periodStartExpr = `DATE_TRUNC('${periodUnitToCompactInto}', ${this.escapeField('periodStart')})`; } @@ -223,16 +216,10 @@ export class InsightsByPeriodRepository extends Repository { `; // Database-specific duplicate key logic - let deduplicateQuery: string; - if (dbType === 'mysqldb' || dbType === 'mariadb') { - deduplicateQuery = sql` - ON DUPLICATE KEY UPDATE value = value + VALUES(value)`; - } else { - deduplicateQuery = sql` + const deduplicateQuery = sql` ON CONFLICT(${targetColumnNamesStr}) DO UPDATE SET value = ${this.metadata.tableName}.value + excluded.value RETURNING *`; - } const upsertEvents = sql` ${insertQueryBase} diff --git a/packages/cli/src/utils/__tests__/validate-database-type.test.ts b/packages/cli/src/utils/__tests__/validate-database-type.test.ts index eb954c6b3b42f..0fc71b490d381 100644 --- a/packages/cli/src/utils/__tests__/validate-database-type.test.ts +++ b/packages/cli/src/utils/__tests__/validate-database-type.test.ts @@ -15,9 +15,6 @@ describe('validateDbTypeForExportEntities', () => { it('should not throw an error if the database type is supported', () => { expect(() => validateDbTypeForExportEntities('sqlite')).not.toThrow(); expect(() => validateDbTypeForExportEntities('postgres')).not.toThrow(); - expect(() => validateDbTypeForExportEntities('mysql')).not.toThrow(); - expect(() => validateDbTypeForExportEntities('mariadb')).not.toThrow(); - expect(() => validateDbTypeForExportEntities('mysqldb')).not.toThrow(); expect(() => validateDbTypeForExportEntities('sqlite-pooled')).not.toThrow(); expect(() => validateDbTypeForExportEntities('sqlite-memory')).not.toThrow(); expect(() => validateDbTypeForExportEntities('postgresql')).not.toThrow(); @@ -31,12 +28,6 @@ describe('validateDbTypeForImportEntities', () => { ); }); - it('should throw an error for MySQL/MariaDB (not supported for imports)', () => { - expect(() => validateDbTypeForImportEntities('mysql')).toThrow(); - expect(() => validateDbTypeForImportEntities('mariadb')).toThrow(); - expect(() => validateDbTypeForImportEntities('mysqldb')).toThrow(); - }); - it('should not throw an error if the database type is supported', () => { expect(() => validateDbTypeForImportEntities('sqlite')).not.toThrow(); expect(() => validateDbTypeForImportEntities('postgres')).not.toThrow(); diff --git a/packages/cli/src/utils/validate-database-type.ts b/packages/cli/src/utils/validate-database-type.ts index fdc96ed2abd5f..d92b6da310a05 100644 --- a/packages/cli/src/utils/validate-database-type.ts +++ b/packages/cli/src/utils/validate-database-type.ts @@ -4,9 +4,6 @@ export const supportedTypesForExport = [ 'sqlite-memory', 'postgres', 'postgresql', - 'mysql', - 'mariadb', - 'mysqldb', ]; export const supportedTypesForImport = [ diff --git a/packages/cli/test/teardown.ts b/packages/cli/test/teardown.ts index 1c2819253d66b..902e152113dd8 100644 --- a/packages/cli/test/teardown.ts +++ b/packages/cli/test/teardown.ts @@ -6,13 +6,12 @@ import { DataSource as Connection } from '@n8n/typeorm'; export default async () => { const { type: dbType } = Container.get(GlobalConfig).database; - if (dbType !== 'postgresdb' && dbType !== 'mysqldb') return; + if (dbType !== 'postgresdb') return; const connection = new Connection(testDb.getBootstrapDBOptions(dbType)); await connection.initialize(); - const query = - dbType === 'postgresdb' ? 'SELECT datname as "Database" FROM pg_database' : 'SHOW DATABASES'; + const query = 'SELECT datname as "Database" FROM pg_database'; const results: Array<{ Database: string }> = await connection.query(query); const databases = results .filter(({ Database: dbName }) => dbName.startsWith(testDb.testDbPrefix)) diff --git a/packages/frontend/editor-ui/src/app/composables/useDebugInfo.ts b/packages/frontend/editor-ui/src/app/composables/useDebugInfo.ts index d780236e3d7aa..42a0834d1825e 100644 --- a/packages/frontend/editor-ui/src/app/composables/useDebugInfo.ts +++ b/packages/frontend/editor-ui/src/app/composables/useDebugInfo.ts @@ -61,11 +61,7 @@ export function useDebugInfo() { nodeJsVersion: settingsStore.nodeJsVersion, nodeEnv: settingsStore.nodeEnv, database: - settingsStore.databaseType === 'postgresdb' - ? 'postgres' - : settingsStore.databaseType === 'mysqldb' - ? 'mysql' - : settingsStore.databaseType, + settingsStore.databaseType === 'postgresdb' ? 'postgres' : settingsStore.databaseType, executionMode: settingsStore.isQueueModeEnabled ? settingsStore.isMultiMain ? 'scaling (multi-main)' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a0762e1f358f3..609203eb729e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1651,9 +1651,6 @@ importers: luxon: specifier: 'catalog:' version: 3.4.4 - mysql2: - specifier: 'catalog:' - version: 3.15.0 n8n-core: specifier: workspace:* version: link:../core