/
Db.ts
149 lines (124 loc) · 4.83 KB
/
Db.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import {
DatabaseType,
GenericHelpers,
IDatabaseCollections,
} from './';
import {
UserSettings,
} from 'n8n-core';
import {
ConnectionOptions,
createConnection,
getRepository,
} from 'typeorm';
import { TlsOptions } from 'tls';
import * as config from '../config';
import { entities } from './databases/entities';
export let collections: IDatabaseCollections = {
Credentials: null,
Execution: null,
Workflow: null,
Webhook: null,
Tag: null,
};
import { postgresMigrations } from './databases/postgresdb/migrations';
import { mysqlMigrations } from './databases/mysqldb/migrations';
import { sqliteMigrations } from './databases/sqlite/migrations';
import * as path from 'path';
export async function init(): Promise<IDatabaseCollections> {
const dbType = await GenericHelpers.getConfigValue('database.type') as DatabaseType;
const n8nFolder = UserSettings.getUserN8nFolderPath();
let connectionOptions: ConnectionOptions;
const entityPrefix = config.get('database.tablePrefix');
switch (dbType) {
case 'postgresdb':
const sslCa = await GenericHelpers.getConfigValue('database.postgresdb.ssl.ca') as string;
const sslCert = await GenericHelpers.getConfigValue('database.postgresdb.ssl.cert') as string;
const sslKey = await GenericHelpers.getConfigValue('database.postgresdb.ssl.key') as string;
const sslRejectUnauthorized = await GenericHelpers.getConfigValue('database.postgresdb.ssl.rejectUnauthorized') as boolean;
let ssl: TlsOptions | undefined = undefined;
if (sslCa !== '' || sslCert !== '' || sslKey !== '' || sslRejectUnauthorized !== true) {
ssl = {
ca: sslCa || undefined,
cert: sslCert || undefined,
key: sslKey || undefined,
rejectUnauthorized: sslRejectUnauthorized,
};
}
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.get('database.postgresdb.schema'),
migrations: postgresMigrations,
migrationsRun: true,
migrationsTableName: `${entityPrefix}migrations`,
ssl,
};
break;
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`,
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`,
};
break;
default:
throw new Error(`The database "${dbType}" is currently not supported!`);
}
Object.assign(connectionOptions, {
entities: Object.values(entities),
synchronize: false,
logging: false,
});
let connection = await createConnection(connectionOptions);
if (dbType === 'sqlite') {
// This specific migration changes database metadata.
// A field is now nullable. We need to reconnect so that
// n8n knows it has changed. Happens only on sqlite.
let migrations = [];
try {
migrations = await connection.query(`SELECT id FROM ${entityPrefix}migrations where name = "MakeStoppedAtNullable1607431743769"`);
} catch(error) {
// Migration table does not exist yet - it will be created after migrations run for the first time.
}
// If you remove this call, remember to turn back on the
// setting to run migrations automatically above.
await connection.runMigrations({
transaction: 'none',
});
if (migrations.length === 0) {
await connection.close();
connection = await createConnection(connectionOptions);
}
}
collections.Credentials = getRepository(entities.CredentialsEntity);
collections.Execution = getRepository(entities.ExecutionEntity);
collections.Workflow = getRepository(entities.WorkflowEntity);
collections.Webhook = getRepository(entities.WebhookEntity);
collections.Tag = getRepository(entities.TagEntity);
return collections;
}