🔀 Merge branch 'master' of https://github.com/guilhermeagirardi/n8n into guilhermeagirardi-master

This commit is contained in:
Jan Oberhauser 2020-02-11 20:44:46 -08:00
commit c42d13c1e3
12 changed files with 263 additions and 35 deletions

1
.gitignore vendored
View file

@ -11,3 +11,4 @@ google-generated-credentials.json
_START_PACKAGE _START_PACKAGE
.env .env
.vscode .vscode
.idea

View file

@ -51,6 +51,30 @@ export DB_POSTGRESDB_PASSWORD=n8n
n8n start n8n start
``` ```
## MySQL
The compatibility with MySQL was tested, even so, it is advisable to observe the operation of the application with this DB, as it is a new option, recently added. If you spot any problems, feel free to submit a PR.
To use MySQL as database you can provide the following environment variables:
- `DB_TYPE=mysqldb`
- `DB_MYSQLDB_DATABASE` (default: 'n8n')
- `DB_MYSQLDB_HOST` (default: 'localhost')
- `DB_MYSQLDB_PORT` (default: 3306)
- `DB_MYSQLDB_USER` (default: 'root')
- `DB_MYSQLDB_PASSWORD` (default: empty)
```bash
export DB_TYPE=postgresdb
export DB_MYSQLDB_DATABASE=n8n
export DB_MYSQLDB_HOST=mysqldb
export DB_MYSQLDB_PORT=3306
export DB_MYSQLDB_USER=n8n
export DB_MYSQLDB_PASSWORD=n8n
n8n start
```
## SQLite ## SQLite
The default database which gets used if no other one is defined. The default database which gets used if no other one is defined.

View file

@ -8,7 +8,7 @@ const config = convict({
database: { database: {
type: { type: {
doc: 'Type of database to use', doc: 'Type of database to use',
format: ['sqlite', 'mongodb', 'postgresdb'], format: ['sqlite', 'mongodb', 'mysqldb', 'postgresdb'],
default: 'sqlite', default: 'sqlite',
env: 'DB_TYPE' env: 'DB_TYPE'
}, },
@ -52,6 +52,38 @@ const config = convict({
env: 'DB_POSTGRESDB_USER' env: 'DB_POSTGRESDB_USER'
}, },
}, },
mysqldb: {
database: {
doc: 'MySQL Database',
format: String,
default: 'n8n',
env: 'DB_MYSQLDB_DATABASE'
},
host: {
doc: 'MySQL Host',
format: String,
default: 'localhost',
env: 'DB_MYSQLDB_HOST'
},
password: {
doc: 'MySQL Password',
format: String,
default: '',
env: 'DB_MYSQLDB_PASSWORD'
},
port: {
doc: 'MySQL Port',
format: Number,
default: 3306,
env: 'DB_MYSQLDB_PORT'
},
user: {
doc: 'MySQL User',
format: String,
default: 'root',
env: 'DB_MYSQLDB_USER'
},
},
}, },
executions: { executions: {

View file

@ -18,6 +18,7 @@ import {
MongoDb, MongoDb,
PostgresDb, PostgresDb,
SQLite, SQLite,
MySQLDb,
} from './databases'; } from './databases';
export let collections: IDatabaseCollections = { export let collections: IDatabaseCollections = {
@ -36,33 +37,53 @@ export async function init(synchronize?: boolean): Promise<IDatabaseCollections>
let connectionOptions: ConnectionOptions; let connectionOptions: ConnectionOptions;
let dbNotExistError: string | undefined; let dbNotExistError: string | undefined;
if (dbType === 'mongodb') { switch (dbType) {
entities = MongoDb; case 'mongodb':
connectionOptions = { entities = MongoDb;
type: 'mongodb', connectionOptions = {
url: await GenericHelpers.getConfigValue('database.mongodb.connectionUrl') as string, type: 'mongodb',
useNewUrlParser: true, url: await GenericHelpers.getConfigValue('database.mongodb.connectionUrl') as string,
}; useNewUrlParser: true,
} else if (dbType === 'postgresdb') { };
dbNotExistError = 'does not exist'; break;
entities = PostgresDb;
connectionOptions = { case 'postgresdb':
type: 'postgres', dbNotExistError = 'does not exist';
database: await GenericHelpers.getConfigValue('database.postgresdb.database') as string, entities = PostgresDb;
host: await GenericHelpers.getConfigValue('database.postgresdb.host') as string, connectionOptions = {
password: await GenericHelpers.getConfigValue('database.postgresdb.password') as string, type: 'postgres',
port: await GenericHelpers.getConfigValue('database.postgresdb.port') as number, database: await GenericHelpers.getConfigValue('database.postgresdb.database') as string,
username: await GenericHelpers.getConfigValue('database.postgresdb.user') as string, host: await GenericHelpers.getConfigValue('database.postgresdb.host') as string,
}; password: await GenericHelpers.getConfigValue('database.postgresdb.password') as string,
} else if (dbType === 'sqlite') { port: await GenericHelpers.getConfigValue('database.postgresdb.port') as number,
dbNotExistError = 'no such table:'; username: await GenericHelpers.getConfigValue('database.postgresdb.user') as string,
entities = SQLite; };
connectionOptions = { break;
type: 'sqlite',
database: path.join(n8nFolder, 'database.sqlite'), case 'mysqldb':
}; dbNotExistError = 'does not exist';
} else { entities = MySQLDb;
throw new Error(`The database "${dbType}" is currently not supported!`); connectionOptions = {
type: 'mysql',
database: await GenericHelpers.getConfigValue('database.mysqldb.database') as string,
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
};
break;
case 'sqlite':
dbNotExistError = 'no such table:';
entities = SQLite;
connectionOptions = {
type: 'sqlite',
database: path.join(n8nFolder, 'database.sqlite'),
};
break;
default:
throw new Error(`The database "${dbType}" is currently not supported!`);
} }
Object.assign(connectionOptions, { Object.assign(connectionOptions, {

View file

@ -87,7 +87,7 @@ export interface ICredentialsDecryptedResponse extends ICredentialsDecryptedDb {
id: string; id: string;
} }
export type DatabaseType = 'mongodb' | 'postgresdb' | 'sqlite'; export type DatabaseType = 'mongodb' | 'postgresdb' | 'mysqldb' | 'sqlite';
export type SaveExecutionDataType = 'all' | 'none'; export type SaveExecutionDataType = 'all' | 'none';
export interface IExecutionBase { export interface IExecutionBase {

View file

@ -205,8 +205,6 @@ export class TestWebhooks {
let workflow: Workflow; let workflow: Workflow;
const workflows: Workflow[] = []; const workflows: Workflow[] = [];
for (const webhookKey of Object.keys(this.testWebhookData)) { for (const webhookKey of Object.keys(this.testWebhookData)) {
console.log('webhookKey: ' + webhookKey);
workflowData = this.testWebhookData[webhookKey].workflowData; workflowData = this.testWebhookData[webhookKey].workflowData;
workflow = new Workflow(workflowData.id.toString(), workflowData.nodes, workflowData.connections, workflowData.active, nodeTypes, workflowData.staticData, workflowData.settings); workflow = new Workflow(workflowData.id.toString(), workflowData.nodes, workflowData.connections, workflowData.active, nodeTypes, workflowData.staticData, workflowData.settings);
workflows.push(); workflows.push();
@ -214,11 +212,8 @@ export class TestWebhooks {
return this.activeWebhooks.removeAll(workflows); return this.activeWebhooks.removeAll(workflows);
} }
} }
let testWebhooksInstance: TestWebhooks | undefined; let testWebhooksInstance: TestWebhooks | undefined;
export function getInstance(): TestWebhooks { export function getInstance(): TestWebhooks {

View file

@ -1,9 +1,11 @@
import * as MongoDb from './mongodb'; import * as MongoDb from './mongodb';
import * as PostgresDb from './postgresdb'; import * as PostgresDb from './postgresdb';
import * as SQLite from './sqlite'; import * as SQLite from './sqlite';
import * as MySQLDb from './mysqldb';
export { export {
MongoDb, MongoDb,
PostgresDb, PostgresDb,
SQLite, SQLite,
MySQLDb,
}; };

View file

@ -0,0 +1,44 @@
import {
ICredentialNodeAccess,
} from 'n8n-workflow';
import {
ICredentialsDb,
} from '../../';
import {
Column,
Entity,
Index,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity()
export class CredentialsEntity implements ICredentialsDb {
@PrimaryGeneratedColumn()
id: number;
@Column({
length: 128
})
name: string;
@Column('text')
data: string;
@Index()
@Column({
length: 32
})
type: string;
@Column('json')
nodesAccess: ICredentialNodeAccess[];
@Column('datetime')
createdAt: Date;
@Column('datetime')
updatedAt: Date;
}

View file

@ -0,0 +1,51 @@
import {
WorkflowExecuteMode,
} from 'n8n-workflow';
import {
IExecutionFlattedDb,
IWorkflowDb,
} from '../../';
import {
Column,
Entity,
Index,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity()
export class ExecutionEntity implements IExecutionFlattedDb {
@PrimaryGeneratedColumn()
id: number;
@Column('text')
data: string;
@Column()
finished: boolean;
@Column('varchar')
mode: WorkflowExecuteMode;
@Column({ nullable: true })
retryOf: string;
@Column({ nullable: true })
retrySuccessId: string;
@Column('datetime')
startedAt: Date;
@Column('datetime')
stoppedAt: Date;
@Column('json')
workflowData: IWorkflowDb;
@Index()
@Column({ nullable: true })
workflowId: string;
}

View file

@ -0,0 +1,55 @@
import {
IConnections,
IDataObject,
INode,
IWorkflowSettings,
} from 'n8n-workflow';
import {
IWorkflowDb,
} from '../../';
import {
Column,
Entity,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity()
export class WorkflowEntity implements IWorkflowDb {
@PrimaryGeneratedColumn()
id: number;
@Column({
length: 128
})
name: string;
@Column()
active: boolean;
@Column('json')
nodes: INode[];
@Column('json')
connections: IConnections;
@Column('datetime')
createdAt: Date;
@Column('datetime')
updatedAt: Date;
@Column({
type: 'json',
nullable: true,
})
settings?: IWorkflowSettings;
@Column({
type: 'json',
nullable: true,
})
staticData?: IDataObject;
}

View file

@ -0,0 +1,3 @@
export * from './CredentialsEntity';
export * from './ExecutionEntity';
export * from './WorkflowEntity';

View file

@ -17,7 +17,7 @@
"build": "vue-cli-service build", "build": "vue-cli-service build",
"dev": "npm run serve", "dev": "npm run serve",
"lint": "vue-cli-service lint", "lint": "vue-cli-service lint",
"serve": "VUE_APP_URL_BASE_API=http://localhost:5678/ vue-cli-service serve", "serve": "cross-env VUE_APP_URL_BASE_API=http://localhost:5678/ vue-cli-service serve",
"test": "npm run test:unit", "test": "npm run test:unit",
"tslint": "tslint -p tsconfig.json -c tslint.json", "tslint": "tslint -p tsconfig.json -c tslint.json",
"test:e2e": "vue-cli-service test:e2e", "test:e2e": "vue-cli-service test:e2e",