diff --git a/.github/ISSUE_TEMPLATE/01-bug.yml b/.github/ISSUE_TEMPLATE/01-bug.yml index a675398e263..4036e79a54c 100644 --- a/.github/ISSUE_TEMPLATE/01-bug.yml +++ b/.github/ISSUE_TEMPLATE/01-bug.yml @@ -76,8 +76,6 @@ body: options: - SQLite (default) - PostgreSQL - - MySQL - - MariaDB default: 0 validations: required: true diff --git a/.github/WORKFLOWS.md b/.github/WORKFLOWS.md index 28d37ae462d..1785f8557a0 100644 --- a/.github/WORKFLOWS.md +++ b/.github/WORKFLOWS.md @@ -173,7 +173,7 @@ These only run if specific files changed: | Files Changed | Workflow | Branch | |------------------------------------------------------------------------|-----------------------------|------------| | `packages/@n8n/task-runner-python/**` | `ci-python.yml` | any | -| `packages/cli/src/databases/**`, `*.entity.ts`, `*.repository.ts` | `test-db-postgres-mysql.yml`| any | +| `packages/cli/src/databases/**`, `*.entity.ts`, `*.repository.ts` | `test-db.yml` | any | | `packages/frontend/@n8n/storybook/**`, design-system, chat | `test-visual-storybook.yml` | master | | `docker/images/n8n-base/Dockerfile` | `build-base-image.yml` | any | | `**/package.json`, `**/turbo.json` | `build-windows.yml` | master | @@ -367,7 +367,7 @@ Push to master/1.x | Schedule (UTC) | Workflow | Purpose | |---------------------------|-----------------------------------|--------------------------| | Daily 00:00 | `docker-build-push.yml` | Nightly Docker images | -| Daily 00:00 | `test-db-postgres-mysql.yml` | Database compatibility | +| Daily 00:00 | `test-db.yml` | Database compatibility | | Daily 00:00 | `test-e2e-performance-reusable.yml`| Performance E2E | | Daily 00:00 | `test-visual-storybook.yml` | Storybook deploy | | Daily 00:00 | `test-visual-chromatic.yml` | Visual regression | diff --git a/.github/docker-compose.yml b/.github/docker-compose.yml index b299d21a754..d741199d221 100644 --- a/.github/docker-compose.yml +++ b/.github/docker-compose.yml @@ -1,25 +1,4 @@ services: - mariadb: - image: mariadb:10.5 - environment: - - MARIADB_DATABASE=n8n - - MARIADB_ROOT_PASSWORD=password - - MARIADB_MYSQL_LOCALHOST_USER=true - ports: - - 3306:3306 - tmpfs: - - /var/lib/mysql - - mysql-8.4: - image: mysql:8.4 - environment: - - MYSQL_DATABASE=n8n - - MYSQL_ROOT_PASSWORD=password - ports: - - 3306:3306 - tmpfs: - - /var/lib/mysql - postgres: image: postgres:16 restart: always diff --git a/.github/workflows/test-db-postgres-mysql.yml b/.github/workflows/test-db.yml similarity index 52% rename from .github/workflows/test-db-postgres-mysql.yml rename to .github/workflows/test-db.yml index df07d8297be..2f98e460812 100644 --- a/.github/workflows/test-db-postgres-mysql.yml +++ b/.github/workflows/test-db.yml @@ -1,8 +1,8 @@ -name: 'Test: DB Postgres MySQL' +name: "Test: DB Postgres" on: schedule: - - cron: '0 0 * * *' + - cron: "0 0 * * *" workflow_dispatch: pull_request: paths: @@ -14,7 +14,7 @@ on: - packages/cli/test/shared/db/** - packages/@n8n/db/** - packages/cli/**/__tests__/** - - .github/workflows/test-db-postgres-mysql.yml + - .github/workflows/test-db.yml - .github/docker-compose.yml concurrency: @@ -22,7 +22,7 @@ concurrency: cancel-in-progress: true env: - NODE_OPTIONS: '--max-old-space-size=3072' + NODE_OPTIONS: "--max-old-space-size=3072" jobs: build: @@ -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 @@ -142,6 +83,6 @@ jobs: if: failure() && github.ref == 'refs/heads/master' with: status: ${{ job.status }} - channel: '#alerts-build' + 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 or SQLite 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 36c21f9d10d..90b6cc67edf 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/migration-test-helpers.ts b/packages/@n8n/backend-test-utils/src/migration-test-helpers.ts index 102d0ab4a71..6801e5a6214 100644 --- a/packages/@n8n/backend-test-utils/src/migration-test-helpers.ts +++ b/packages/@n8n/backend-test-utils/src/migration-test-helpers.ts @@ -17,7 +17,6 @@ export interface TestMigrationContext { queryRunner: QueryRunner; tablePrefix: string; dbType: DatabaseType; - isMysql: boolean; isSqlite: boolean; isPostgres: boolean; escape: { @@ -41,7 +40,6 @@ export function createTestMigrationContext(dataSource: DataSource): TestMigratio queryRunner, tablePrefix, dbType, - isMysql: ['mariadb', 'mysqldb'].includes(dbType), isSqlite: dbType === 'sqlite', isPostgres: dbType === 'postgresdb', escape: { diff --git a/packages/@n8n/backend-test-utils/src/test-db.ts b/packages/@n8n/backend-test-utils/src/test-db.ts index 0c06d6438b1..c91ec0772c2 100644 --- a/packages/@n8n/backend-test-utils/src/test-db.ts +++ b/packages/@n8n/backend-test-utils/src/test-db.ts @@ -4,6 +4,7 @@ import { AuthRolesService, DbConnection, DbConnectionOptions } from '@n8n/db'; import { Container } from '@n8n/di'; import type { DataSourceOptions } from '@n8n/typeorm'; import { DataSource as Connection } from '@n8n/typeorm'; +import assert from 'assert'; import { randomString } from 'n8n-workflow'; export const testDbPrefix = 'n8n_test_'; @@ -12,15 +13,16 @@ 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 = (): DataSourceOptions => { const globalConfig = Container.get(GlobalConfig); - const type = dbType === 'postgresdb' ? 'postgres' : 'mysql'; + assert(globalConfig.database.type === 'postgresdb', 'Database type must be postgresdb'); + return { - type, - ...Container.get(DbConnectionOptions).getOverrides(dbType), - database: type, + type: 'postgres', + ...Container.get(DbConnectionOptions).getPostgresOverrides(), + database: globalConfig.database.postgresdb.database, entityPrefix: globalConfig.database.tablePrefix, - schema: dbType === 'postgresdb' ? globalConfig.database.postgresdb.schema : undefined, + schema: globalConfig.database.postgresdb.schema, }; }; @@ -35,19 +37,11 @@ export async function init() { const testDbName = `${testDbPrefix}${randomString(6, 10).toLowerCase()}_${Date.now()}`; if (dbType === 'postgresdb') { - const bootstrapPostgres = await new Connection( - getBootstrapDBOptions('postgresdb'), - ).initialize(); + const bootstrapPostgres = await new Connection(getBootstrapDBOptions()).initialize(); await bootstrapPostgres.query(`CREATE DATABASE ${testDbName}`); 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); @@ -98,44 +92,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'); + // 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 + } } - try { - // Collect junction tables to clean - const junctionTablesToClean = new Set(); + // Clean junction tables first (since they reference the entities) + for (const tableName of junctionTablesToClean) { + await connection.query(`DELETE FROM ${tableName}`); + } - // 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 - } - } - - // 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/database.config.ts b/packages/@n8n/config/src/configs/database.config.ts index ec05f39e89d..7810f9ba290 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. */ @@ -107,33 +96,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 @@ -155,7 +117,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 @@ -180,15 +142,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 aaa84a50981..872dae37dd9 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', @@ -457,7 +449,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 79b737a1e31..7c5ba405ed6 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'; @@ -136,57 +135,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 9411c0bd6d1..2addb2c7b29 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 1adcc103f2b..2d029508a6c 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 { SqlitePooledConnectionOptions } from '@n8n/typeorm/driver/sqlite-pooled/SqlitePooledConnectionOptions'; import { UserError } from 'n8n-workflow'; @@ -10,7 +9,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'; @@ -23,14 +21,13 @@ export class DbConnectionOptions { private readonly moduleRegistry: ModuleRegistry, ) {} - getOverrides(dbType: 'postgresdb' | 'mysqldb') { - const dbConfig = this.config[dbType]; + getPostgresOverrides() { return { - database: dbConfig.database, - host: dbConfig.host, - port: dbConfig.port, - username: dbConfig.user, - password: dbConfig.password, + database: this.config.postgresdb.database, + host: this.config.postgresdb.host, + port: this.config.postgresdb.port, + username: this.config.postgresdb.user, + password: this.config.postgresdb.password, }; } @@ -41,9 +38,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 } }); } @@ -111,7 +105,7 @@ export class DbConnectionOptions { return { type: 'postgres', ...this.getCommonOptions(), - ...this.getOverrides('postgresdb'), + ...this.getPostgresOverrides(), schema: postgresConfig.schema, poolSize: postgresConfig.poolSize, migrations: postgresMigrations, @@ -123,16 +117,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 e7da2ad9f6c..e215aa456c4 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'; @@ -34,7 +34,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); @@ -67,21 +66,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 1e66e13afe1..cc6451ac820 100644 --- a/packages/@n8n/db/src/entities/abstract-entity.ts +++ b/packages/@n8n/db/src/entities/abstract-entity.ts @@ -18,8 +18,6 @@ export const { type: dbType } = Container.get(GlobalConfig).database; const timestampSyntax = { sqlite: "STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')", postgresdb: 'CURRENT_TIMESTAMP(3)', - mysqldb: 'CURRENT_TIMESTAMP(3)', - mariadb: 'CURRENT_TIMESTAMP(3)', }[dbType]; export const jsonColumnType = dbType === 'sqlite' ? 'simple-json' : 'json'; @@ -27,8 +25,6 @@ export const datetimeColumnType = dbType === 'postgresdb' ? 'timestamptz' : 'dat 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 7d6765e2e62..086d072f2d3 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 714d2f28e28..31b4feeecfa 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 8846da118e8..3a678ba5df1 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/1705429061930-DropRoleMapping.ts b/packages/@n8n/db/src/migrations/common/1705429061930-DropRoleMapping.ts index 71ff6dd1d86..1570e5fbe47 100644 --- a/packages/@n8n/db/src/migrations/common/1705429061930-DropRoleMapping.ts +++ b/packages/@n8n/db/src/migrations/common/1705429061930-DropRoleMapping.ts @@ -42,7 +42,6 @@ export class DropRoleMapping1705429061930 implements ReversibleMigration { private async migrateUp( table: Table, { - dbType, escape, runQuery, schemaBuilder: { addNotNull, addColumns, dropColumns, dropForeignKey, column }, @@ -58,8 +57,7 @@ export class DropRoleMapping1705429061930 implements ReversibleMigration { const roleColumnName = table === 'user' ? 'globalRoleId' : 'roleId'; const roleColumn = escape.columnName(roleColumnName); const scope = roleScopes[table]; - const isMySQL = ['mariadb', 'mysqldb'].includes(dbType); - const roleField = isMySQL ? `CONCAT('${scope}:', R.name)` : `'${scope}:' || R.name`; + const roleField = `'${scope}:' || R.name`; const subQuery = ` SELECT ${roleField} as role, T.${idColumn} as id${ table !== 'user' ? `, T.${uidColumn} as uid` : '' @@ -70,11 +68,7 @@ export class DropRoleMapping1705429061930 implements ReversibleMigration { const where = `WHERE ${tableName}.${idColumn} = mapping.id${ table !== 'user' ? ` AND ${tableName}.${uidColumn} = mapping.uid` : '' }`; - const swQuery = isMySQL - ? `UPDATE ${tableName}, (${subQuery}) as mapping - SET ${tableName}.role = mapping.role - ${where}` - : `UPDATE ${tableName} + const swQuery = `UPDATE ${tableName} SET role = mapping.role FROM (${subQuery}) as mapping ${where}`; @@ -94,7 +88,6 @@ export class DropRoleMapping1705429061930 implements ReversibleMigration { private async migrateDown( table: Table, { - dbType, escape, runQuery, schemaBuilder: { addNotNull, addColumns, dropColumns, addForeignKey, column }, @@ -110,8 +103,7 @@ export class DropRoleMapping1705429061930 implements ReversibleMigration { const uidColumn = escape.columnName(uidColumns[table]); const roleColumn = escape.columnName(roleColumnName); const scope = roleScopes[table]; - const isMySQL = ['mariadb', 'mysqldb'].includes(dbType); - const roleField = isMySQL ? `CONCAT('${scope}:', R.name)` : `'${scope}:' || R.name`; + const roleField = `'${scope}:' || R.name`; const subQuery = ` SELECT R.id as role_id, T.${idColumn} as id${table !== 'user' ? `, T.${uidColumn} as uid` : ''} FROM ${tableName} T @@ -120,11 +112,7 @@ export class DropRoleMapping1705429061930 implements ReversibleMigration { const where = `WHERE ${tableName}.${idColumn} = mapping.id${ table !== 'user' ? ` AND ${tableName}.${uidColumn} = mapping.uid` : '' }`; - const query = isMySQL - ? `UPDATE ${tableName}, (${subQuery}) as mapping - SET ${tableName}.${roleColumn} = mapping.role_id - ${where}` - : `UPDATE ${tableName} + const query = `UPDATE ${tableName} SET ${roleColumn} = mapping.role_id FROM (${subQuery}) as mapping ${where}`; diff --git a/packages/@n8n/db/src/migrations/common/1714133768519-CreateProject.ts b/packages/@n8n/db/src/migrations/common/1714133768519-CreateProject.ts index 6bf6ef5f066..718b576fc44 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 @@ -264,11 +258,7 @@ export class CreateProject1714133768519 implements ReversibleMigration { tableName: 'workflow_entity', columnName: 'id', onDelete: 'CASCADE', - // In MySQL foreignKey names must be unique across all tables and - // 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, @@ -302,11 +292,7 @@ export class CreateProject1714133768519 implements ReversibleMigration { tableName: 'credentials_entity', columnName: 'id', onDelete: 'CASCADE', - // In MySQL foreignKey names must be unique across all tables and - // 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 8c958855ae6..d7b28c865fa 100644 --- a/packages/@n8n/db/src/migrations/common/1720101653148-AddConstraintToExecutionMetadata.ts +++ b/packages/@n8n/db/src/migrations/common/1720101653148-AddConstraintToExecutionMetadata.ts @@ -20,9 +20,6 @@ export class AddConstraintToExecutionMetadata1720101653148 implements Reversible .withColumns( column('id').int.notNull.primary.autoGenerate, column('executionId').int.notNull, - // NOTE: This is a varchar(255) instead of text, because a unique index - // on text is not supported on mysql, also why should we support - // arbitrary length keys? column('key').varchar(255).notNull, column('value').text.notNull, ) @@ -30,25 +27,11 @@ export class AddConstraintToExecutionMetadata1720101653148 implements Reversible tableName: 'execution_entity', columnName: 'id', onDelete: 'CASCADE', - // 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 +41,6 @@ export class AddConstraintToExecutionMetadata1720101653148 implements Reversible value = EXCLUDED.value WHERE EXCLUDED.id > ${executionMetadataTableTemp}.id; `); - } await dropTable(executionMetadataTableRaw); await context.runQuery( @@ -94,10 +76,7 @@ export class AddConstraintToExecutionMetadata1720101653148 implements Reversible tableName: 'execution_entity', columnName: 'id', onDelete: 'CASCADE', - // 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 32d45946980..c9117e0647f 100644 --- a/packages/@n8n/db/src/migrations/common/1723796243146-RefactorExecutionIndices.ts +++ b/packages/@n8n/db/src/migrations/common/1723796243146-RefactorExecutionIndices.ts @@ -13,10 +13,6 @@ import type { MigrationContext, ReversibleMigration } from '../migration-types'; * - `waitTill` * - `status, workflowId` * - * Remove unused indices in MySQL: - * - * - `status` - * * Remove unused indices in all DBs: * * - `waitTill, id` @@ -31,7 +27,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 +55,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 +69,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 +83,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 a5e8f0764a9..d592969377a 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 028178dff0d..79e2b8e4357 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 7ed240169e0..747c49af9e7 100644 --- a/packages/@n8n/db/src/migrations/common/1745322634000-CleanEvaluations.ts +++ b/packages/@n8n/db/src/migrations/common/1745322634000-CleanEvaluations.ts @@ -9,7 +9,6 @@ export class ClearEvaluation1745322634000 implements IrreversibleMigration { tablePrefix, isSqlite, isPostgres, - isMysql, }: MigrationContext) { // Drop test_metric, test_definition await dropTable(testCaseExecutionTableName); @@ -19,8 +18,6 @@ export class ClearEvaluation1745322634000 implements IrreversibleMigration { 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) { - await queryRunner.query(`DROP TABLE IF EXISTS ${tablePrefix}test_definition CASCADE;`); } await createTable(testRunTableName) diff --git a/packages/@n8n/db/src/migrations/common/1750252139167-AddRolesTables.ts b/packages/@n8n/db/src/migrations/common/1750252139167-AddRolesTables.ts index edafcd8d92b..2a1064ffd40 100644 --- a/packages/@n8n/db/src/migrations/common/1750252139167-AddRolesTables.ts +++ b/packages/@n8n/db/src/migrations/common/1750252139167-AddRolesTables.ts @@ -24,7 +24,6 @@ export class AddRolesTables1750252139167 implements ReversibleMigration { schemaBuilder: { createTable, column, createIndex }, queryRunner, tablePrefix, - dbType, }: MigrationContext) { await createTable('role').withColumns( column('slug') @@ -42,30 +41,15 @@ export class AddRolesTables1750252139167 implements ReversibleMigration { .notNull.comment('Indicates if the role is managed by the system and cannot be edited'), ); - // MYSQL - if (dbType === 'postgresdb' || dbType === 'sqlite') { - // POSTGRES - await queryRunner.query( - `CREATE TABLE ${tablePrefix}role_scope ( - "roleSlug" VARCHAR(128) NOT NULL, - "scopeSlug" VARCHAR(128) NOT NULL, - CONSTRAINT "PK_${tablePrefix}role_scope" PRIMARY KEY ("roleSlug", "scopeSlug"), - CONSTRAINT "FK_${tablePrefix}role" FOREIGN KEY ("roleSlug") REFERENCES ${tablePrefix}role ("slug") ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT "FK_${tablePrefix}scope" FOREIGN KEY ("scopeSlug") REFERENCES "${tablePrefix}scope" ("slug") ON DELETE CASCADE ON UPDATE CASCADE - );`, - ); - } else { - // MYSQL - await queryRunner.query( - `CREATE TABLE ${tablePrefix}role_scope ( - \`roleSlug\` VARCHAR(128) NOT NULL, - \`scopeSlug\` VARCHAR(128) NOT NULL, - FOREIGN KEY (\`scopeSlug\`) REFERENCES ${tablePrefix}scope (\`slug\`) ON DELETE CASCADE ON UPDATE CASCADE, - FOREIGN KEY (\`roleSlug\`) REFERENCES ${tablePrefix}role (\`slug\`) ON DELETE CASCADE ON UPDATE CASCADE, - PRIMARY KEY (\`roleSlug\`, \`scopeSlug\`) - ) ENGINE=InnoDB;`, - ); - } + await queryRunner.query( + `CREATE TABLE ${tablePrefix}role_scope ( + "roleSlug" VARCHAR(128) NOT NULL, + "scopeSlug" VARCHAR(128) NOT NULL, + CONSTRAINT "PK_${tablePrefix}role_scope" PRIMARY KEY ("roleSlug", "scopeSlug"), + CONSTRAINT "FK_${tablePrefix}role" FOREIGN KEY ("roleSlug") REFERENCES ${tablePrefix}role ("slug") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "FK_${tablePrefix}scope" FOREIGN KEY ("scopeSlug") REFERENCES "${tablePrefix}scope" ("slug") ON DELETE CASCADE ON UPDATE CASCADE + );`, + ); await createIndex('role_scope', ['scopeSlug']); /* diff --git a/packages/@n8n/db/src/migrations/common/1759399811000-ChangeValueTypesForInsights.ts b/packages/@n8n/db/src/migrations/common/1759399811000-ChangeValueTypesForInsights.ts index 3bf3b474fc8..e9c380fc8fa 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 d067f939353..2fb4f14e1bb 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 7e22cee7502..fb9259c784a 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 9aef4e433e5..2924d7f4e93 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/dsl/table.ts b/packages/@n8n/db/src/migrations/dsl/table.ts index fc9f7a98b6e..7ad50107cbf 100644 --- a/packages/@n8n/db/src/migrations/dsl/table.ts +++ b/packages/@n8n/db/src/migrations/dsl/table.ts @@ -123,7 +123,6 @@ export class CreateTable extends TableOperation { ...(uniqueConstraints.size ? { uniques: [...uniqueConstraints] } : {}), ...(foreignKeys.size ? { foreignKeys: [...foreignKeys] } : {}), ...(checks.size ? { checks: [...checks] } : {}), - ...('mysql' in driver ? { engine: 'InnoDB' } : {}), }), true, ); diff --git a/packages/@n8n/db/src/migrations/migration-helpers.ts b/packages/@n8n/db/src/migrations/migration-helpers.ts index ce4aeb497d4..b8bfa68947b 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 fdd427b8795..ea23e45c402 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 80d589916bc..00000000000 --- 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 34d8ca33d8d..00000000000 --- 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 afecd45ce03..00000000000 --- 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 80f8a92275d..00000000000 --- 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 f1d40b76fb0..00000000000 --- 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 3d96058701d..00000000000 --- 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 ff70956976a..00000000000 --- 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 b79096769c5..00000000000 --- 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 b453f6b7322..00000000000 --- 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 3f77b1dfe1f..00000000000 --- 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 57ee6d81f3d..00000000000 --- 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 cbc3464cb48..00000000000 --- 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 949fef61a35..00000000000 --- 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 817c2722d95..00000000000 --- 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 a9c9d454039..00000000000 --- 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 52a3b294c04..00000000000 --- 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 40838da2456..00000000000 --- 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 58216e727e0..00000000000 --- 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 1dd46f9b05f..00000000000 --- 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 2d05873470b..00000000000 --- 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 656197a645d..00000000000 --- 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 eceff11e8b9..00000000000 --- 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 29d76af39db..00000000000 --- 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 3fa4ba440ab..00000000000 --- 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 13128a6bae5..00000000000 --- 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 509c89caae2..00000000000 --- 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 84844f4251c..00000000000 --- 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 36effd442d8..00000000000 --- 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 4edae4f656b..00000000000 --- 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 dc96f7d591c..00000000000 --- 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 a205282dc66..00000000000 --- 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 0ce72f37959..00000000000 --- 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 d8f354b0258..00000000000 --- 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 f67b524213a..00000000000 --- 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 28a6b0ac4d6..00000000000 --- 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 2d506de5c7f..00000000000 --- 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 10af6e1f609..00000000000 --- 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 50fd22dd52a..00000000000 --- 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 1115a920e9d..00000000000 --- 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 6a71bc6713f..00000000000 --- 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 811f0037d17..00000000000 --- 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 f179c8522dc..00000000000 --- 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 f39fcc93fb8..00000000000 --- 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 4298a96c9e3..00000000000 --- 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 8ab60dfe0d4..00000000000 --- 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 1158c29b0b9..00000000000 --- 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 61414922557..00000000000 --- 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 0c89afec827..00000000000 --- 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 db5e60ab833..00000000000 --- 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 041d9534ffd..00000000000 --- 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 56625298659..00000000000 --- 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 d493362971c..00000000000 --- 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 232cf8bbc3f..00000000000 --- a/packages/@n8n/db/src/migrations/mysqldb/index.ts +++ /dev/null @@ -1,266 +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 { AddPublishedVersionIdToWorkflowDependency1769000000000 } from '../common/1769000000000-AddPublishedVersionIdToWorkflowDependency'; -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, - AddPublishedVersionIdToWorkflowDependency1769000000000, -]; 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 773e56bba3b..2b09bb3295c 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/repositories/execution.repository.ts b/packages/@n8n/db/src/repositories/execution.repository.ts index 1465cc08847..2f779c22aa4 100644 --- a/packages/@n8n/db/src/repositories/execution.repository.ts +++ b/packages/@n8n/db/src/repositories/execution.repository.ts @@ -1109,8 +1109,8 @@ export class ExecutionRepository extends Repository { // Sort the final result after the joins again, because there is no // guarantee that the order is unchanged after performing joins. Especially - // postgres and MySQL returned to the natural order again, listing - // executions in the order they were created. + // postgres returned to the natural order again, listing executions in the + // order they were created. if (query.kind === 'range') { if (query.order?.startedAt === 'DESC') { const table = qb.escape('e'); diff --git a/packages/@n8n/db/src/repositories/workflow-dependency.repository.ts b/packages/@n8n/db/src/repositories/workflow-dependency.repository.ts index 656ec7f93ea..3caa95ca416 100644 --- a/packages/@n8n/db/src/repositories/workflow-dependency.repository.ts +++ b/packages/@n8n/db/src/repositories/workflow-dependency.repository.ts @@ -149,7 +149,7 @@ export class WorkflowDependencyRepository extends Repository // so the prepareTransactionForSqlite step ensures no concurrent writes happen. return await tx.existsBy(WorkflowDependency, whereConditions); } - // For Postgres and MySQL we lock on the workflow row, and only then check the dependency table. + // For Postgres we lock on the workflow row, and only then check the dependency table. // This prevents a race between two concurrent updates. const placeholder = this.databaseConfig.type === 'postgresdb' ? '$1' : '?'; const tableName = this.getTableName('workflow_entity'); diff --git a/packages/@n8n/db/src/repositories/workflow-statistics.repository.ts b/packages/@n8n/db/src/repositories/workflow-statistics.repository.ts index e7f8ffcb4fa..275888ca935 100644 --- a/packages/@n8n/db/src/repositories/workflow-statistics.repository.ts +++ b/packages/@n8n/db/src/repositories/workflow-statistics.repository.ts @@ -2,6 +2,7 @@ import { GlobalConfig } from '@n8n/config'; import { Service } from '@n8n/di'; import { PROJECT_OWNER_ROLE_SLUG } from '@n8n/permissions'; import { DataSource, QueryFailedError, Repository } from '@n8n/typeorm'; +import assert from 'node:assert'; import { ProjectRelation, @@ -106,22 +107,9 @@ export class WorkflowStatisticsRepository extends Repository )) as Array<{ count: string | number }>; return Number(queryResult[0].count) === 1 ? 'insert' : 'update'; - } else { - const queryResult = (await this.query( - `INSERT INTO ${escapedTableName} (count, rootCount, name, workflowId, workflowName, latestEvent) - VALUES (1, ?, ?, ?, ?, NOW()) - ON DUPLICATE KEY - UPDATE - count = count + 1, - rootCount = rootCount + ?, - workflowName = VALUES(workflowName), - latestEvent = NOW();`, - [rootCountIncrement, eventName, workflowId, workflowName ?? null, rootCountIncrement], - )) as { affectedRows: number }; - - // MySQL returns 2 affected rows on update - return queryResult.affectedRows === 1 ? 'insert' : 'update'; } + + assert.fail('Unknown database type'); } catch (error) { console.log('error', error); if (error instanceof QueryFailedError) return 'failed'; diff --git a/packages/@n8n/db/src/repositories/workflow.repository.ts b/packages/@n8n/db/src/repositories/workflow.repository.ts index 95789cb538a..cd14aae6e8b 100644 --- a/packages/@n8n/db/src/repositories/workflow.repository.ts +++ b/packages/@n8n/db/src/repositories/workflow.repository.ts @@ -101,9 +101,9 @@ export class WorkflowRepository extends Repository { const dbType = this.globalConfig.database.type; - if (['postgresdb'].includes(dbType)) { + if (dbType === 'postgresdb') { qb.where("workflow.settings ->> 'errorWorkflow' IS NOT NULL"); - } else if (['mysqldb', 'mariadb', 'sqlite'].includes(dbType)) { + } else if (dbType === 'sqlite') { qb.where("JSON_EXTRACT(workflow.settings, '$.errorWorkflow') IS NOT NULL"); } @@ -137,17 +137,11 @@ export class WorkflowRepository extends Repository { async updateWorkflowTriggerCount(id: string, triggerCount: number): Promise { const qb = this.createQueryBuilder('workflow'); - const dbType = this.globalConfig.database.type; return await qb .update() .set({ triggerCount, - updatedAt: () => { - if (['mysqldb', 'mariadb'].includes(dbType)) { - return 'updatedAt'; - } - return '"updatedAt"'; - }, + updatedAt: () => '"updatedAt"', }) .where('id = :id', { id }) .execute(); @@ -501,14 +495,10 @@ export class WorkflowRepository extends Repository { if (filter.availableInMCP) { // When filtering for true, only match explicit true values - if (['postgresdb'].includes(dbType)) { + if (dbType === 'postgresdb') { qb.andWhere("workflow.settings ->> 'availableInMCP' = :availableInMCP", { availableInMCP: 'true', }); - } else if (['mysqldb', 'mariadb'].includes(dbType)) { - qb.andWhere("JSON_EXTRACT(workflow.settings, '$.availableInMCP') = :availableInMCP", { - availableInMCP: true, - }); } else if (dbType === 'sqlite') { qb.andWhere("JSON_EXTRACT(workflow.settings, '$.availableInMCP') = :availableInMCP", { availableInMCP: 1, // SQLite stores booleans as 0/1 @@ -516,16 +506,11 @@ export class WorkflowRepository extends Repository { } } else { // When filtering for false, match explicit false OR null/undefined (field not set) - if (['postgresdb'].includes(dbType)) { + if (dbType === 'postgresdb') { qb.andWhere( "(workflow.settings ->> 'availableInMCP' = :availableInMCP OR workflow.settings ->> 'availableInMCP' IS NULL)", { availableInMCP: 'false' }, ); - } else if (['mysqldb', 'mariadb'].includes(dbType)) { - qb.andWhere( - "(JSON_EXTRACT(workflow.settings, '$.availableInMCP') = :availableInMCP OR JSON_EXTRACT(workflow.settings, '$.availableInMCP') IS NULL)", - { availableInMCP: false }, - ); } else if (dbType === 'sqlite') { qb.andWhere( "(JSON_EXTRACT(workflow.settings, '$.availableInMCP') = :availableInMCP OR JSON_EXTRACT(workflow.settings, '$.availableInMCP') IS NULL)", @@ -568,7 +553,7 @@ export class WorkflowRepository extends Repository { `COALESCE("activeVersion"."nodes"::text, "workflow"."nodes"::text) LIKE :${paramName}`, ); } else { - // SQLite and MySQL store nodes as text + // SQLite stores nodes as text conditions.push(`COALESCE(activeVersion.nodes, workflow.nodes) LIKE :${paramName}`); } }); 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 737b0660fd4..ddcb1e4fae4 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/@n8n/db/src/utils/build-workflows-by-nodes-query.ts b/packages/@n8n/db/src/utils/build-workflows-by-nodes-query.ts index dd678005348..f69a7cf3a64 100644 --- a/packages/@n8n/db/src/utils/build-workflows-by-nodes-query.ts +++ b/packages/@n8n/db/src/utils/build-workflows-by-nodes-query.ts @@ -1,10 +1,7 @@ /** * Builds the WHERE clause and parameters for a query to find workflows by node types */ -export function buildWorkflowsByNodesQuery( - nodeTypes: string[], - dbType: 'postgresdb' | 'mysqldb' | 'mariadb' | 'sqlite', -) { +export function buildWorkflowsByNodesQuery(nodeTypes: string[], dbType: 'postgresdb' | 'sqlite') { let whereClause: string; const parameters: Record = { nodeTypes }; @@ -17,22 +14,6 @@ export function buildWorkflowsByNodesQuery( WHERE node->>'type' = ANY(:nodeTypes) )`; break; - case 'mysqldb': - case 'mariadb': { - const conditions = nodeTypes - .map( - (_, i) => - `JSON_SEARCH(JSON_EXTRACT(workflow.nodes, '$[*].type'), 'one', :nodeType${i}) IS NOT NULL`, - ) - .join(' OR '); - - whereClause = `(${conditions})`; - - nodeTypes.forEach((nodeType, index) => { - parameters[`nodeType${index}`] = nodeType; - }); - break; - } case 'sqlite': { const conditions = nodeTypes .map( diff --git a/packages/@n8n/db/src/utils/transformers.ts b/packages/@n8n/db/src/utils/transformers.ts index 5beb7f3cb1f..669e7372ceb 100644 --- a/packages/@n8n/db/src/utils/transformers.ts +++ b/packages/@n8n/db/src/utils/transformers.ts @@ -26,7 +26,7 @@ export const objectRetriever: ValueTransformer = { /** * Transformer for sqlite JSON columns to mimic JSON-as-object behavior - * from Postgres and MySQL. + * from Postgres. */ const jsonColumn: ValueTransformer = { to: (value: object): string | object => diff --git a/packages/cli/package.json b/packages/cli/package.json index 807d5598dc1..1ad2a474145 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -28,13 +28,11 @@ "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:postgres:tc": "TESTCONTAINERS_RYUK_DISABLED=true N8N_LOG_LEVEL=silent jest --config=jest.config.integration.testcontainers.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": { @@ -152,7 +150,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 47913d6975c..bf66afdc84e 100644 --- a/packages/cli/src/databases/repositories/__tests__/execution.repository.test.ts +++ b/packages/cli/src/databases/repositories/__tests__/execution.repository.test.ts @@ -79,7 +79,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/executions/execution.service.ts b/packages/cli/src/executions/execution.service.ts index 2f439fc7abd..c5abcc95efd 100644 --- a/packages/cli/src/executions/execution.service.ts +++ b/packages/cli/src/executions/execution.service.ts @@ -627,7 +627,7 @@ export class ExecutionService { ['execution'], ); - // Upsert behavior differs for Postgres, MySQL and sqlite, + // Upsert behavior differs for Postgres and sqlite, // so we need to fetch the annotation to get the ID const annotation = await this.executionAnnotationRepository.findOneOrFail({ where: { 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 deleted file mode 100644 index 6bbb1b49e81..00000000000 --- a/packages/cli/src/modules/breaking-changes/rules/v2/__tests__/removed-database-types.rule.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { mockInstance } from '@n8n/backend-test-utils'; -import { GlobalConfig } from '@n8n/config'; - -import { RemovedDatabaseTypesRule } from '../removed-database-types.rule'; - -describe('RemovedDatabaseTypesRule', () => { - let rule: RemovedDatabaseTypesRule; - let globalConfig: GlobalConfig; - - beforeEach(() => { - globalConfig = mockInstance(GlobalConfig); - rule = new RemovedDatabaseTypesRule(globalConfig); - }); - - describe('detect()', () => { - it('should not be affected when using PostgreSQL', async () => { - globalConfig.database.type = 'postgresdb'; - - const result = await rule.detect(); - - expect(result.isAffected).toBe(false); - expect(result.instanceIssues).toHaveLength(0); - }); - - it('should be affected when using MySQL', async () => { - globalConfig.database.type = 'mysqldb'; - - const result = await rule.detect(); - - expect(result.isAffected).toBe(true); - expect(result.instanceIssues).toHaveLength(1); - expect(result.instanceIssues[0].title).toBe('MySQL database type removed'); - }); - - it('should be affected when using MariaDB', async () => { - globalConfig.database.type = 'mariadb'; - - const result = await rule.detect(); - - expect(result.isAffected).toBe(true); - expect(result.instanceIssues).toHaveLength(1); - expect(result.instanceIssues[0].title).toBe('MariaDB database type removed'); - }); - }); -}); diff --git a/packages/cli/src/modules/breaking-changes/rules/v2/index.ts b/packages/cli/src/modules/breaking-changes/rules/v2/index.ts index 73387b29b51..c64f05b7a3f 100644 --- a/packages/cli/src/modules/breaking-changes/rules/v2/index.ts +++ b/packages/cli/src/modules/breaking-changes/rules/v2/index.ts @@ -7,7 +7,6 @@ import { OAuthCallbackAuthRule } from './oauth-callback-auth.rule'; import { ProcessEnvAccessRule } from './process-env-access.rule'; import { PyodideRemovedRule } from './pyodide-removed.rule'; import { QueueWorkerMaxStalledCountRule } from './queue-worker-max-stalled-count.rule'; -import { RemovedDatabaseTypesRule } from './removed-database-types.rule'; import { RemovedNodesRule } from './removed-nodes.rule'; import { SettingsFilePermissionsRule } from './settings-file-permissions.rule'; import { TaskRunnerDockerImageRule } from './task-runner-docker-image.rule'; @@ -33,7 +32,6 @@ const v2Rules = [ WorkflowHooksDeprecatedRule, QueueWorkerMaxStalledCountRule, TunnelOptionRule, - RemovedDatabaseTypesRule, SettingsFilePermissionsRule, TaskRunnersRule, TaskRunnerDockerImageRule, 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 deleted file mode 100644 index 8f68f2584ba..00000000000 --- a/packages/cli/src/modules/breaking-changes/rules/v2/removed-database-types.rule.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { GlobalConfig } from '@n8n/config'; -import { Service } from '@n8n/di'; - -import type { - BreakingChangeRuleMetadata, - IBreakingChangeInstanceRule, - InstanceDetectionReport, -} from '../../types'; -import { BreakingChangeCategory } from '../../types'; - -@Service() -export class RemovedDatabaseTypesRule implements IBreakingChangeInstanceRule { - constructor(private readonly globalConfig: GlobalConfig) {} - - id: string = 'removed-database-types-v2'; - - getMetadata(): BreakingChangeRuleMetadata { - return { - version: 'v2', - title: 'MySQL/MariaDB database types removed', - description: - 'MySQL and MariaDB database types have been completely removed and will cause n8n to fail on startup', - category: BreakingChangeCategory.database, - severity: 'critical', - documentationUrl: 'https://docs.n8n.io/2-0-breaking-changes/#drop-mysqlmariadb-support', - }; - } - - async detect(): Promise { - const result: InstanceDetectionReport = { - isAffected: false, - instanceIssues: [], - recommendations: [], - }; - - const dbType = this.globalConfig.database.type; - - if (dbType === 'mysqldb' || dbType === 'mariadb') { - result.isAffected = true; - result.instanceIssues.push({ - title: `${dbType === 'mysqldb' ? 'MySQL' : 'MariaDB'} database type removed`, - description: - 'MySQL and MariaDB database types have been completely removed in v2. n8n will fail to start with this database configuration.', - level: 'error', - }); - - result.recommendations.push({ - action: 'Migrate to PostgreSQL or SQLite before upgrading', - description: - 'You must migrate your database to PostgreSQL or SQLite before upgrading to v2. Use the database migration tool if available, or export/import your workflows and credentials.', - }); - } - - return result; - } -} 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 bc9dd93914f..245ca7adad3 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__/data-table-csv.controller.integration.test.ts b/packages/cli/src/modules/data-table/__tests__/data-table-csv.controller.integration.test.ts index 978c7400339..e0499769087 100644 --- a/packages/cli/src/modules/data-table/__tests__/data-table-csv.controller.integration.test.ts +++ b/packages/cli/src/modules/data-table/__tests__/data-table-csv.controller.integration.test.ts @@ -225,7 +225,7 @@ describe('GET /projects/:projectId/data-tables/:dataTableId/download-csv', () => expect(lines[0]).toBe('id,text,number,flag,timestamp,createdAt,updatedAt'); expect(lines[1]).toContain('hello'); expect(lines[1]).toContain('42'); - // Boolean values vary by database: SQLite/MySQL use 0/1, PostgreSQL uses true/false + // Boolean values vary by database: SQLite use 0/1, PostgreSQL uses true/false expect(lines[1]).toMatch(/,(true|1),/); // Check for date in ISO format (timezone may vary) expect(lines[1]).toMatch(/2025-01-15T\d{2}:\d{2}:\d{2}\.\d{3}Z/); diff --git a/packages/cli/src/modules/data-table/__tests__/data-table-ddl.service.test.ts b/packages/cli/src/modules/data-table/__tests__/data-table-ddl.service.test.ts index 29eff14c3ee..fc6ee2ae516 100644 --- a/packages/cli/src/modules/data-table/__tests__/data-table-ddl.service.test.ts +++ b/packages/cli/src/modules/data-table/__tests__/data-table-ddl.service.test.ts @@ -81,27 +81,6 @@ describe('DataTableDDLService', () => { expect(mockEntityManager.query).toHaveBeenCalledWith(expectedQuery); }); - it('should execute rename column query for MySQL', async () => { - // Arrange - const dbType: DataSourceOptions['type'] = 'mysql'; - const expectedQuery = - 'ALTER TABLE `n8n_data_table_user_test-table-id` RENAME COLUMN `old_column` TO `new_column`'; - - (sqlUtils.renameColumnQuery as jest.Mock).mockReturnValue(expectedQuery); - - // Act - await ddlService.renameColumn(dataTableId, oldColumnName, newColumnName, dbType); - - // Assert - expect(sqlUtils.renameColumnQuery).toHaveBeenCalledWith( - tableName, - oldColumnName, - newColumnName, - dbType, - ); - expect(mockEntityManager.query).toHaveBeenCalledWith(expectedQuery); - }); - it('should execute rename column query for SQLite', async () => { // Arrange const dbType: DataSourceOptions['type'] = 'sqlite'; @@ -297,16 +276,6 @@ describe('DataTableDDLService', () => { expectedQuery: 'ALTER TABLE "n8n_data_table_user_test-table-id" RENAME COLUMN "old_column" TO "new_column"', }, - { - dbType: 'mysql', - expectedQuery: - 'ALTER TABLE `n8n_data_table_user_test-table-id` RENAME COLUMN `old_column` TO `new_column`', - }, - { - dbType: 'mariadb', - expectedQuery: - 'ALTER TABLE `n8n_data_table_user_test-table-id` RENAME COLUMN `old_column` TO `new_column`', - }, { dbType: 'sqlite', expectedQuery: @@ -362,7 +331,7 @@ describe('DataTableDDLService', () => { it('should pass all parameters to renameColumnQuery utility', async () => { // Arrange - const dbType: DataSourceOptions['type'] = 'mysql'; + const dbType: DataSourceOptions['type'] = 'postgres'; const expectedQuery = 'ALTER TABLE query'; (sqlUtils.renameColumnQuery as jest.Mock).mockReturnValue(expectedQuery); 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 2719796b742..7dd2a880071 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-rows.repository.ts b/packages/cli/src/modules/data-table/data-table-rows.repository.ts index 13fd33b1158..56abb7cc42b 100644 --- a/packages/cli/src/modules/data-table/data-table-rows.repository.ts +++ b/packages/cli/src/modules/data-table/data-table-rows.repository.ts @@ -50,7 +50,6 @@ type QueryBuilder = SelectQueryBuilder; * * Why the crazy backslashes: * - Postgres/SQLite/Oracle/SQL Server: `ESCAPE '\'` is written as-is. - * - MySQL/MariaDB: the SQL literal itself requires two backslashes (`'\\'`) to mean one. */ function getConditionAndParams( filter: DataTableFilter['filters'][number], @@ -101,14 +100,6 @@ function getConditionAndParams( return [`${columnRef} GLOB :${paramName}`, { [paramName]: globValue }]; } - if (['mysql', 'mariadb'].includes(dbType)) { - const escapedValue = escapeLikeSpecials(value as string); - return [ - `${columnRef} LIKE BINARY :${paramName} ESCAPE '\\\\'`, - { [paramName]: escapedValue }, - ]; - } - // PostgreSQL: LIKE is case-sensitive if (dbType === 'postgres') { const escapedValue = escapeLikeSpecials(value as string); @@ -128,14 +119,6 @@ function getConditionAndParams( ]; } - if (['mysql', 'mariadb'].includes(dbType)) { - const escapedValue = escapeLikeSpecials(value as string); - return [ - `UPPER(${columnRef}) LIKE UPPER(:${paramName}) ESCAPE '\\\\'`, - { [paramName]: escapedValue }, - ]; - } - if (dbType === 'postgres') { const escapedValue = escapeLikeSpecials(value as string); return [`${columnRef} ILIKE :${paramName} ESCAPE '\\'`, { [paramName]: escapedValue }]; @@ -639,7 +622,6 @@ export class DataTableRowsRepository { const dbType = this.dataSource.options.type; const searchTerm = rawSearch.includes('%') ? rawSearch : `%${rawSearch}%`; const isSqlite = ['sqlite', 'sqlite-pooled'].includes(dbType); - const isMy = ['mysql', 'mariadb'].includes(dbType); const isPg = dbType === 'postgres'; const allColumnNames: string[] = columns.map((c) => c.name); @@ -655,11 +637,6 @@ export class DataTableRowsRepository { continue; } - if (isMy) { - conditions.push(`UPPER(CAST(${colRef} AS CHAR)) LIKE UPPER(:search) ESCAPE '\\\\'`); - continue; - } - if (isPg) { conditions.push(`CAST(${colRef} AS TEXT) ILIKE :search ESCAPE '\\'`); continue; 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 fa59ce5a210..2f32d8938cd 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 a478823fc96..0a62c9810e7 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: @@ -125,9 +122,6 @@ export function renameColumnQuery( export function quoteIdentifier(name: string, dbType: DataSourceOptions['type']): string { switch (dbType) { - case 'mysql': - case 'mariadb': - return `\`${name}\``; case 'postgres': case 'sqlite': default: @@ -135,8 +129,6 @@ export function quoteIdentifier(name: string, dbType: DataSourceOptions['type']) } } -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 +140,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 +160,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)}'`, ); } @@ -185,17 +173,11 @@ export function extractInsertedIds(raw: unknown, dbType: DataSourceOptions['type case 'mariadb': { 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)) { @@ -291,7 +273,7 @@ function formatDateForDatabase( } // These dbs use DATETIME format without 'T' and 'Z' - if (dbType && ['sqlite', 'sqlite-pooled', 'mysql', 'mariadb'].includes(dbType)) { + if (dbType && ['sqlite', 'sqlite-pooled'].includes(dbType)) { return date.toISOString().replace('T', ' ').replace('Z', ''); } diff --git a/packages/cli/src/modules/insights/__tests__/insights-by-period-migration.test.ts b/packages/cli/src/modules/insights/__tests__/insights-by-period-migration.test.ts index 344df4d64cb..841b265b015 100644 --- a/packages/cli/src/modules/insights/__tests__/insights-by-period-migration.test.ts +++ b/packages/cli/src/modules/insights/__tests__/insights-by-period-migration.test.ts @@ -102,11 +102,6 @@ describe('ChangeValueTypesForInsights - insights_by_period table', () => { WHERE table_name = ${insightsByPeriodTableName} AND column_name = 'value'`, ); expect(result[0].data_type).toBe('bigint'); - } else if (postMigrationContext.isMysql) { - const result = await postMigrationContext.queryRunner.query( - `SHOW COLUMNS FROM ${insightsByPeriodTableName} LIKE 'value'`, - ); - expect(result[0].Type.toLowerCase()).toContain('bigint'); } // Verify data integrity after migration using SQL diff --git a/packages/cli/src/modules/insights/__tests__/insights-raw-migration.test.ts b/packages/cli/src/modules/insights/__tests__/insights-raw-migration.test.ts index 257fa2cf1a8..26d9d1194fd 100644 --- a/packages/cli/src/modules/insights/__tests__/insights-raw-migration.test.ts +++ b/packages/cli/src/modules/insights/__tests__/insights-raw-migration.test.ts @@ -102,11 +102,6 @@ describe('ChangeValueTypesForInsights - insights_raw table', () => { WHERE table_name = ${insightsRawTableName} AND column_name = 'value'`, ); expect(result[0].data_type).toBe('bigint'); - } else if (postMigrationContext.isMysql) { - const result = await postMigrationContext.queryRunner.query( - `SHOW COLUMNS FROM ${insightsRawTableName} LIKE 'value'`, - ); - expect(result[0].Type.toLowerCase()).toContain('bigint'); } // Verify data integrity after migration using SQL 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 601c90e5e07..15e4f9e0a04 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 3b90c7d5894..dcf6d18c625 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 68f97880670..1975089acee 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 eb954c6b3b4..0fc71b490d3 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 fdc96ed2abd..d92b6da310a 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/src/workflows/workflow-static-data.service.ts b/packages/cli/src/workflows/workflow-static-data.service.ts index 0c20a455524..e0e9b622b24 100644 --- a/packages/cli/src/workflows/workflow-static-data.service.ts +++ b/packages/cli/src/workflows/workflow-static-data.service.ts @@ -1,5 +1,4 @@ import { Logger } from '@n8n/backend-common'; -import { GlobalConfig } from '@n8n/config'; import { WorkflowRepository } from '@n8n/db'; import { Service } from '@n8n/di'; import { ErrorReporter } from 'n8n-core'; @@ -10,7 +9,6 @@ import { isWorkflowIdValid } from '@/utils'; @Service() export class WorkflowStaticDataService { constructor( - private readonly globalConfig: GlobalConfig, private readonly logger: Logger, private readonly errorReporter: ErrorReporter, private readonly workflowRepository: WorkflowRepository, @@ -54,9 +52,6 @@ export class WorkflowStaticDataService { .set({ staticData: newStaticData, updatedAt: () => { - if (['mysqldb', 'mariadb'].includes(this.globalConfig.database.type)) { - return 'updatedAt'; - } return '"updatedAt"'; }, }) diff --git a/packages/cli/test/integration/credentials/credentials.api.ee.test.ts b/packages/cli/test/integration/credentials/credentials.api.ee.test.ts index 7647c663618..47f867900dd 100644 --- a/packages/cli/test/integration/credentials/credentials.api.ee.test.ts +++ b/packages/cli/test/integration/credentials/credentials.api.ee.test.ts @@ -182,7 +182,7 @@ describe('GET /credentials', () => { expect(Array.isArray(ownerCredential.sharedWithProjects)).toBe(true); expect(ownerCredential.sharedWithProjects).toHaveLength(3); - // Fix order issue (MySQL might return items in any order) + // Fix order issue (PostgreSQL might return items in any order) const ownerCredentialsSharedWithOrdered = [...ownerCredential.sharedWithProjects].sort( (a, b) => (a.id < b.id ? -1 : 1), ); diff --git a/packages/cli/test/integration/project.api.test.ts b/packages/cli/test/integration/project.api.test.ts index 0bbbe39132a..54c379efb95 100644 --- a/packages/cli/test/integration/project.api.test.ts +++ b/packages/cli/test/integration/project.api.test.ts @@ -569,17 +569,9 @@ describe('POST /projects/', () => { ownerAgent.post('/projects/').send({ name: 'Test Team Project 6' }), ]); - // Some of the calls above will interleave and may fail with a deadlock - // error on MySQL (this is not an issue on PG or MariaDB). - // That can lead to less projects being created than the quota allows. - // So we're only checking here that we didn't create more projects than - // are allowed instead of checking for a specific number. - // We only want to prevent that this endpoint is exploited. A normal user - // using the FE would almost never hit this and if they do they can retry - // the action. No need to implement rety logic in the controller. - await expect( - Container.get(ProjectRepository).count({ where: { type: 'team' } }), - ).resolves.toBeLessThanOrEqual(maxTeamProjects); + await expect(Container.get(ProjectRepository).count({ where: { type: 'team' } })).resolves.toBe( + maxTeamProjects, + ); }); }); diff --git a/packages/cli/test/migration/1760020838000-unique-role-names.test.ts b/packages/cli/test/migration/1760020838000-unique-role-names.test.ts index 78bb874d70c..f2b93f8126e 100644 --- a/packages/cli/test/migration/1760020838000-unique-role-names.test.ts +++ b/packages/cli/test/migration/1760020838000-unique-role-names.test.ts @@ -275,12 +275,6 @@ describe('UniqueRoleNames Migration', () => { WHERE t.relname = ${tableName} AND i.relname = ${indexName}`, ); expect(uniqueCheck[0].indisunique).toBe(true); - } else if (postMigrationContext.isMysql) { - const result = await postMigrationContext.queryRunner.query( - `SHOW INDEXES FROM ${tableName} WHERE Key_name = ${indexName}`, - ); - expect(result).toHaveLength(1); - expect(result[0].Non_unique).toBe(0); // 0 means unique } // Verify index enforces uniqueness by attempting duplicate insert @@ -336,11 +330,6 @@ describe('UniqueRoleNames Migration', () => { `SELECT indexname FROM pg_indexes WHERE tablename = ${tableName} AND indexname = ${indexName}`, ); expect(result).toHaveLength(1); - } else if (upContext.isMysql) { - const result = await upContext.queryRunner.query( - `SHOW INDEXES FROM ${tableName} WHERE Key_name = ${indexName}`, - ); - expect(result).toHaveLength(1); } await upContext.queryRunner.release(); @@ -365,11 +354,6 @@ describe('UniqueRoleNames Migration', () => { `SELECT indexname FROM pg_indexes WHERE tablename = ${tableName} AND indexname = ${indexName}`, ); expect(result).toHaveLength(0); - } else if (postRollbackContext.isMysql) { - const result = await postRollbackContext.queryRunner.query( - `SHOW INDEXES FROM ${tableName} WHERE Key_name = ${indexName}`, - ); - expect(result).toHaveLength(0); } // Verify duplicate displayNames can be inserted again diff --git a/packages/cli/test/migration/1767018516000-change-workflow-statistics-fk-to-no-action.test.ts b/packages/cli/test/migration/1767018516000-change-workflow-statistics-fk-to-no-action.test.ts index 4eb75f0f59b..f47e53acaeb 100644 --- a/packages/cli/test/migration/1767018516000-change-workflow-statistics-fk-to-no-action.test.ts +++ b/packages/cli/test/migration/1767018516000-change-workflow-statistics-fk-to-no-action.test.ts @@ -14,7 +14,7 @@ const MIGRATION_NAME = 'ChangeWorkflowStatisticsFKToNoAction1767018516000'; /** * Generate parameter placeholders for a given context and count. - * PostgreSQL uses $1, $2, ... while MySQL/SQLite use ? + * PostgreSQL uses $1, $2, ... while SQLite use ? */ function getParamPlaceholders(context: TestMigrationContext, count: number): string { if (context.isPostgres) { diff --git a/packages/cli/test/teardown.ts b/packages/cli/test/teardown.ts index 1c2819253d6..4435cb96eef 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)); + const connection = new Connection(testDb.getBootstrapDBOptions()); 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 d780236e3d7..dc434bd011a 100644 --- a/packages/frontend/editor-ui/src/app/composables/useDebugInfo.ts +++ b/packages/frontend/editor-ui/src/app/composables/useDebugInfo.ts @@ -9,7 +9,7 @@ type DebugInfo = { platform: 'docker (cloud)' | 'docker (self-hosted)' | 'npm'; nodeJsVersion: string; nodeEnv: string | undefined; - database: 'sqlite' | 'mysql' | 'mariadb' | 'postgres'; + database: 'sqlite' | 'postgres'; executionMode: 'regular' | 'scaling (single-main)' | 'scaling (multi-main)'; license: 'community' | 'enterprise (production)' | 'enterprise (sandbox)'; consumerId?: string; @@ -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 2702cca3b7c..25f8376fb82 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1843,9 +1843,6 @@ importers: luxon: specifier: 'catalog:' version: 3.7.2 - mysql2: - specifier: 'catalog:' - version: 3.15.0 n8n-core: specifier: workspace:* version: link:../core