Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add CrateDB node #768

Merged
merged 1 commit into from
Jul 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions packages/nodes-base/credentials/CrateDb.credentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { ICredentialType, NodePropertyTypes } from 'n8n-workflow';

export class CrateDb implements ICredentialType {
name = 'crateDb';
displayName = 'CrateDB';
properties = [
{
displayName: 'Host',
name: 'host',
type: 'string' as NodePropertyTypes,
default: 'localhost',
},
{
displayName: 'Database',
name: 'database',
type: 'string' as NodePropertyTypes,
default: 'doc',
},
{
displayName: 'User',
name: 'user',
type: 'string' as NodePropertyTypes,
default: 'crate',
},
{
displayName: 'Password',
name: 'password',
type: 'string' as NodePropertyTypes,
typeOptions: {
password: true,
},
default: '',
},
{
displayName: 'SSL',
name: 'ssl',
type: 'options' as NodePropertyTypes,
options: [
{
name: 'disable',
value: 'disable',
},
{
name: 'allow',
value: 'allow',
},
{
name: 'require',
value: 'require',
},
{
name: 'verify (not implemented)',
value: 'verify',
},
{
name: 'verify-full (not implemented)',
value: 'verify-full',
},
],
default: 'disable',
},
{
displayName: 'Port',
name: 'port',
type: 'number' as NodePropertyTypes,
default: 5432,
},
];
}
246 changes: 246 additions & 0 deletions packages/nodes-base/nodes/CrateDb/CrateDb.node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
import { IExecuteFunctions } from 'n8n-core';
import { IDataObject, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';

import * as pgPromise from 'pg-promise';

import { pgInsert, pgQuery, pgUpdate } from '../Postgres/Postgres.node.functions';

export class CrateDb implements INodeType {
description: INodeTypeDescription = {
displayName: 'CrateDB',
name: 'crateDb',
icon: 'file:cratedb.png',
group: ['input'],
version: 1,
description: 'Gets, add and update data in CrateDB.',
defaults: {
name: 'CrateDB',
color: '#47889f',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'crateDb',
required: true,
},
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
options: [
{
name: 'Execute Query',
value: 'executeQuery',
description: 'Executes a SQL query.',
},
{
name: 'Insert',
value: 'insert',
description: 'Insert rows in database.',
},
{
name: 'Update',
value: 'update',
description: 'Updates rows in database.',
},
],
default: 'insert',
description: 'The operation to perform.',
},

// ----------------------------------
// executeQuery
// ----------------------------------
{
displayName: 'Query',
name: 'query',
type: 'string',
typeOptions: {
rows: 5,
},
displayOptions: {
show: {
operation: ['executeQuery'],
},
},
default: '',
placeholder: 'SELECT id, name FROM product WHERE id < 40',
required: true,
description: 'The SQL query to execute.',
},

// ----------------------------------
// insert
// ----------------------------------
{
displayName: 'Schema',
name: 'schema',
type: 'string',
displayOptions: {
show: {
operation: ['insert'],
},
},
default: 'public',
required: true,
description: 'Name of the schema the table belongs to',
},
{
displayName: 'Table',
name: 'table',
type: 'string',
displayOptions: {
show: {
operation: ['insert'],
},
},
default: '',
required: true,
description: 'Name of the table in which to insert data to.',
},
{
displayName: 'Columns',
name: 'columns',
type: 'string',
displayOptions: {
show: {
operation: ['insert'],
},
},
default: '',
placeholder: 'id,name,description',
description:
'Comma separated list of the properties which should used as columns for the new rows.',
},
{
displayName: 'Return Fields',
name: 'returnFields',
type: 'string',
displayOptions: {
show: {
operation: ['insert'],
},
},
default: '*',
description: 'Comma separated list of the fields that the operation will return',
},

// ----------------------------------
// update
// ----------------------------------
{
displayName: 'Table',
name: 'table',
type: 'string',
displayOptions: {
show: {
operation: ['update'],
},
},
default: '',
required: true,
description: 'Name of the table in which to update data in',
},
{
displayName: 'Update Key',
name: 'updateKey',
type: 'string',
displayOptions: {
show: {
operation: ['update'],
},
},
default: 'id',
required: true,
description:
'Name of the property which decides which rows in the database should be updated. Normally that would be "id".',
},
{
displayName: 'Columns',
name: 'columns',
type: 'string',
displayOptions: {
show: {
operation: ['update'],
},
},
default: '',
placeholder: 'name,description',
description:
'Comma separated list of the properties which should used as columns for rows to update.',
},
],
};

async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const credentials = this.getCredentials('crateDb');

if (credentials === undefined) {
throw new Error('No credentials got returned!');
}

const pgp = pgPromise();

const config = {
host: credentials.host as string,
port: credentials.port as number,
database: credentials.database as string,
user: credentials.user as string,
password: credentials.password as string,
ssl: !['disable', undefined].includes(credentials.ssl as string | undefined),
sslmode: (credentials.ssl as string) || 'disable',
};

const db = pgp(config);

let returnItems = [];

const items = this.getInputData();
const operation = this.getNodeParameter('operation', 0) as string;

if (operation === 'executeQuery') {
// ----------------------------------
// executeQuery
// ----------------------------------

const queryResult = await pgQuery(this.getNodeParameter, pgp, db, items);

returnItems = this.helpers.returnJsonArray(queryResult as IDataObject[]);
} else if (operation === 'insert') {
// ----------------------------------
// insert
// ----------------------------------

const [insertData, insertItems] = await pgInsert(this.getNodeParameter, pgp, db, items);

// Add the id to the data
for (let i = 0; i < insertData.length; i++) {
returnItems.push({
json: {
...insertData[i],
...insertItems[i],
},
});
}
} else if (operation === 'update') {
// ----------------------------------
// update
// ----------------------------------

const updateItems = await pgUpdate(this.getNodeParameter, pgp, db, items);

returnItems = this.helpers.returnJsonArray(updateItems);
} else {
await pgp.end();
throw new Error(`The operation "${operation}" is not supported!`);
}

// Close the connection
await pgp.end();

return this.prepareOutputData(returnItems);
}
}
Binary file added packages/nodes-base/nodes/CrateDb/cratedb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions packages/nodes-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"dist/credentials/CodaApi.credentials.js",
"dist/credentials/CopperApi.credentials.js",
"dist/credentials/CalendlyApi.credentials.js",
"dist/credentials/CrateDb.credentials.js",
"dist/credentials/DisqusApi.credentials.js",
"dist/credentials/DriftApi.credentials.js",
"dist/credentials/DriftOAuth2Api.credentials.js",
Expand Down Expand Up @@ -182,6 +183,7 @@
"dist/nodes/Cockpit/Cockpit.node.js",
"dist/nodes/Coda/Coda.node.js",
"dist/nodes/Copper/CopperTrigger.node.js",
"dist/nodes/CrateDb/CrateDb.node.js",
"dist/nodes/Cron.node.js",
"dist/nodes/Crypto.node.js",
"dist/nodes/DateTime.node.js",
Expand Down