From eb3fffd2035d197a948c3555c53d6eb6f79f37f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Fri, 4 Nov 2022 14:23:58 +0100 Subject: [PATCH] refactor: consolidate database configs (#4522) * consolidate db configs * allow using custom file-name for the sqlite db * remove the unused `logging` config. it's overwritten in Db.ts --- packages/cli/config/schema.ts | 6 ++ packages/cli/src/Db.ts | 56 ++++++------------ packages/cli/src/databases/config.ts | 79 +++++++++++++++++++++++++ packages/cli/src/databases/ormconfig.ts | 77 ++++-------------------- 4 files changed, 112 insertions(+), 106 deletions(-) create mode 100644 packages/cli/src/databases/config.ts diff --git a/packages/cli/config/schema.ts b/packages/cli/config/schema.ts index 045f676a22..c19532b665 100644 --- a/packages/cli/config/schema.ts +++ b/packages/cli/config/schema.ts @@ -136,6 +136,12 @@ export const schema = { }, }, sqlite: { + database: { + doc: 'SQLite Database file name', + format: String, + default: 'database.sqlite', + env: 'DB_SQLITE_DATABASE', + }, executeVacuumOnStartup: { doc: 'Runs VACUUM operation on startup to rebuild the database. Reduces filesize and optimizes indexes. WARNING: This is a long running blocking operation. Will increase start-up time.', format: Boolean, diff --git a/packages/cli/src/Db.ts b/packages/cli/src/Db.ts index a58c543869..b69aa63314 100644 --- a/packages/cli/src/Db.ts +++ b/packages/cli/src/Db.ts @@ -4,7 +4,6 @@ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable no-case-declarations */ /* eslint-disable @typescript-eslint/naming-convention */ -import { UserSettings } from 'n8n-core'; import { Connection, ConnectionOptions, @@ -17,7 +16,6 @@ import { Repository, } from 'typeorm'; import { TlsOptions } from 'tls'; -import path from 'path'; // eslint-disable-next-line import/no-cycle import { DatabaseType, GenericHelpers, IDatabaseCollections } from '.'; @@ -25,10 +23,13 @@ import config from '../config'; // eslint-disable-next-line import/no-cycle import { entities } from './databases/entities'; - -import { postgresMigrations } from './databases/migrations/postgresdb'; -import { mysqlMigrations } from './databases/migrations/mysqldb'; -import { sqliteMigrations } from './databases/migrations/sqlite'; +import { + getMariaDBConnectionOptions, + getMysqlConnectionOptions, + getOptionOverrides, + getPostgresConnectionOptions, + getSqliteConnectionOptions, +} from './databases/config'; export let isInitialized = false; export const collections = {} as IDatabaseCollections; @@ -51,7 +52,6 @@ export async function init( if (isInitialized) return collections; const dbType = (await GenericHelpers.getConfigValue('database.type')) as DatabaseType; - const n8nFolder = UserSettings.getUserN8nFolderPath(); let connectionOptions: ConnectionOptions; @@ -84,17 +84,8 @@ export async function init( } connectionOptions = { - type: 'postgres', - entityPrefix, - database: (await GenericHelpers.getConfigValue('database.postgresdb.database')) as string, - host: (await GenericHelpers.getConfigValue('database.postgresdb.host')) as string, - password: (await GenericHelpers.getConfigValue('database.postgresdb.password')) as string, - port: (await GenericHelpers.getConfigValue('database.postgresdb.port')) as number, - username: (await GenericHelpers.getConfigValue('database.postgresdb.user')) as string, - schema: config.getEnv('database.postgresdb.schema'), - migrations: postgresMigrations, - migrationsRun: true, - migrationsTableName: `${entityPrefix}migrations`, + ...getPostgresConnectionOptions(), + ...(await getOptionOverrides('postgresdb')), ssl, }; @@ -103,29 +94,14 @@ export async function init( case 'mariadb': case 'mysqldb': connectionOptions = { - type: dbType === 'mysqldb' ? 'mysql' : 'mariadb', - database: (await GenericHelpers.getConfigValue('database.mysqldb.database')) as string, - entityPrefix, - host: (await GenericHelpers.getConfigValue('database.mysqldb.host')) as string, - password: (await GenericHelpers.getConfigValue('database.mysqldb.password')) as string, - port: (await GenericHelpers.getConfigValue('database.mysqldb.port')) as number, - username: (await GenericHelpers.getConfigValue('database.mysqldb.user')) as string, - migrations: mysqlMigrations, - migrationsRun: true, - migrationsTableName: `${entityPrefix}migrations`, + ...(dbType === 'mysqldb' ? getMysqlConnectionOptions() : getMariaDBConnectionOptions()), + ...(await getOptionOverrides('mysqldb')), timezone: 'Z', // set UTC as default }; break; case 'sqlite': - connectionOptions = { - type: 'sqlite', - database: path.join(n8nFolder, 'database.sqlite'), - entityPrefix, - migrations: sqliteMigrations, - migrationsRun: false, // migrations for sqlite will be ran manually for now; see below - migrationsTableName: `${entityPrefix}migrations`, - }; + connectionOptions = getSqliteConnectionOptions(); break; default: @@ -149,13 +125,15 @@ export async function init( } } + const maxQueryExecutionTime = (await GenericHelpers.getConfigValue( + 'database.logging.maxQueryExecutionTime', + )) as string; + Object.assign(connectionOptions, { entities: Object.values(entities), synchronize: false, logging: loggingOption, - maxQueryExecutionTime: (await GenericHelpers.getConfigValue( - 'database.logging.maxQueryExecutionTime', - )) as string, + maxQueryExecutionTime, }); connection = await createConnection(connectionOptions); diff --git a/packages/cli/src/databases/config.ts b/packages/cli/src/databases/config.ts new file mode 100644 index 0000000000..3b743db72a --- /dev/null +++ b/packages/cli/src/databases/config.ts @@ -0,0 +1,79 @@ +import path from 'path'; +import type { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'; +import type { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions'; +import type { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions'; +import { UserSettings } from 'n8n-core'; + +import { entities } from './entities'; +import { mysqlMigrations } from './migrations/mysqldb'; +import { postgresMigrations } from './migrations/postgresdb'; +import { sqliteMigrations } from './migrations/sqlite'; +import type { DatabaseType } from '../Interfaces'; +import config from '../../config'; +import { getConfigValue } from '../GenericHelpers'; + +const entitiesDir = path.resolve('src', 'databases', 'entities'); + +const getDBConnectionOptions = (dbType: DatabaseType) => { + const entityPrefix = config.getEnv('database.tablePrefix'); + const migrationsDir = path.resolve('src', 'databases', 'migrations', dbType); + const configDBType = dbType === 'mariadb' ? 'mysqldb' : dbType; + const connectionDetails = + configDBType === 'sqlite' + ? { + database: path.resolve( + UserSettings.getUserN8nFolderPath(), + config.getEnv('database.sqlite.database'), + ), + } + : { + database: config.getEnv(`database.${configDBType}.database`), + username: config.getEnv(`database.${configDBType}.user`), + password: config.getEnv(`database.${configDBType}.password`), + host: config.getEnv(`database.${configDBType}.host`), + port: config.getEnv(`database.${configDBType}.port`), + }; + return { + name: dbType, + entityPrefix, + entities: Object.values(entities), + migrationsRun: true, + migrationsTableName: `${entityPrefix}migrations`, + cli: { entitiesDir, migrationsDir }, + ...connectionDetails, + }; +}; + +export const getOptionOverrides = async (dbType: 'postgresdb' | 'mysqldb') => ({ + database: (await getConfigValue(`database.${dbType}.database`)) as string, + host: (await getConfigValue(`database.${dbType}.host`)) as string, + port: (await getConfigValue(`database.${dbType}.port`)) as number, + username: (await getConfigValue(`database.${dbType}.user`)) as string, + password: (await getConfigValue(`database.${dbType}.password`)) as string, +}); + +export const getSqliteConnectionOptions = (): SqliteConnectionOptions => ({ + type: 'sqlite', + ...getDBConnectionOptions('sqlite'), + migrationsRun: false, // sqlite migrations are manually run in `Db.ts` + migrations: sqliteMigrations, +}); + +export const getPostgresConnectionOptions = (): PostgresConnectionOptions => ({ + type: 'postgres', + ...getDBConnectionOptions('postgresdb'), + schema: config.getEnv('database.postgresdb.schema'), + migrations: postgresMigrations, +}); + +export const getMysqlConnectionOptions = (): MysqlConnectionOptions => ({ + type: 'mysql', + ...getDBConnectionOptions('mysqldb'), + migrations: mysqlMigrations, +}); + +export const getMariaDBConnectionOptions = (): MysqlConnectionOptions => ({ + type: 'mariadb', + ...getDBConnectionOptions('mysqldb'), + migrations: mysqlMigrations, +}); diff --git a/packages/cli/src/databases/ormconfig.ts b/packages/cli/src/databases/ormconfig.ts index 43c0339b52..dced87e075 100644 --- a/packages/cli/src/databases/ormconfig.ts +++ b/packages/cli/src/databases/ormconfig.ts @@ -1,70 +1,13 @@ -import path from 'path'; -import { UserSettings } from 'n8n-core'; -import { entities } from './entities'; - -const MIGRATIONS_DIR = path.resolve('src', 'databases', 'migrations'); -const ENTITIES_DIR = path.resolve('src', 'databases', 'entities'); +import { + getMariaDBConnectionOptions, + getMysqlConnectionOptions, + getPostgresConnectionOptions, + getSqliteConnectionOptions, +} from './config'; export default [ - { - name: 'sqlite', - type: 'sqlite', - logging: true, - entities: Object.values(entities), - database: path.resolve(UserSettings.getUserN8nFolderPath(), 'database.sqlite'), - migrations: [path.resolve(MIGRATIONS_DIR, 'sqlite', 'index.ts')], - cli: { - entitiesDir: ENTITIES_DIR, - migrationsDir: path.resolve(MIGRATIONS_DIR, 'sqlite'), - }, - }, - { - name: 'postgres', - type: 'postgres', - database: 'n8n', - schema: 'public', - username: 'postgres', - password: '', - host: 'localhost', - port: 5432, - logging: false, - entities: Object.values(entities), - migrations: [path.resolve(MIGRATIONS_DIR, 'postgresdb', 'index.ts')], - cli: { - entitiesDir: ENTITIES_DIR, - migrationsDir: path.resolve(MIGRATIONS_DIR, 'postgresdb'), - }, - }, - { - name: 'mysql', - type: 'mysql', - database: 'n8n', - username: 'root', - password: 'password', - host: 'localhost', - port: 3306, - logging: false, - entities: Object.values(entities), - migrations: [path.resolve(MIGRATIONS_DIR, 'mysqldb', 'index.ts')], - cli: { - entitiesDir: ENTITIES_DIR, - migrationsDir: path.resolve(MIGRATIONS_DIR, 'mysqldb'), - }, - }, - { - name: 'mariadb', - type: 'mariadb', - database: 'n8n', - username: 'root', - password: 'password', - host: 'localhost', - port: 3306, - logging: false, - entities: Object.values(entities), - migrations: [path.resolve(MIGRATIONS_DIR, 'mysqldb', 'index.ts')], - cli: { - entitiesDir: ENTITIES_DIR, - migrationsDir: path.resolve(MIGRATIONS_DIR, 'mysqldb'), - }, - }, + getSqliteConnectionOptions(), + getPostgresConnectionOptions(), + getMysqlConnectionOptions(), + getMariaDBConnectionOptions(), ];