From 0c9ae471083a075c12ead1470bc8ddff37f4b84f Mon Sep 17 00:00:00 2001 From: Michael Kret Date: Tue, 16 May 2023 09:04:36 +0300 Subject: [PATCH 1/4] :zap: removed reusable connections --- .../nodes/Postgres/v2/actions/router.ts | 9 +-- .../Postgres/v2/methods/credentialTest.ts | 14 +--- .../nodes/Postgres/v2/methods/listSearch.ts | 18 +++-- .../nodes/Postgres/v2/methods/loadOptions.ts | 11 ++- .../nodes/Postgres/v2/transport/index.ts | 68 +++++++++---------- 5 files changed, 61 insertions(+), 59 deletions(-) diff --git a/packages/nodes-base/nodes/Postgres/v2/actions/router.ts b/packages/nodes-base/nodes/Postgres/v2/actions/router.ts index bc4115e8b4572..901bc9f361565 100644 --- a/packages/nodes-base/nodes/Postgres/v2/actions/router.ts +++ b/packages/nodes-base/nodes/Postgres/v2/actions/router.ts @@ -4,9 +4,8 @@ import { NodeOperationError } from 'n8n-workflow'; import type { PostgresType } from './node.type'; import * as database from './database/Database.resource'; -import { Connections } from '../transport'; +import { configurePostgres } from '../transport'; import { configureQueryRunner } from '../helpers/utils'; -import type { ConnectionsData } from '../helpers/interfaces'; export async function router(this: IExecuteFunctions): Promise { let returnData: INodeExecutionData[] = []; @@ -19,11 +18,7 @@ export async function router(this: IExecuteFunctions): Promise { const credentials = await this.getCredentials('postgres'); const options = { nodeVersion: this.getNode().typeVersion }; - const { db } = (await Connections.getInstance(credentials, options)) as ConnectionsData; + const { db, pgp, sshClient } = await configurePostgres(credentials, options); try { const response = await db.any('SELECT schema_name FROM information_schema.schemata'); @@ -19,13 +19,18 @@ export async function schemaSearch(this: ILoadOptionsFunctions): Promise { const credentials = await this.getCredentials('postgres'); const options = { nodeVersion: this.getNode().typeVersion }; - const { db } = (await Connections.getInstance(credentials, options)) as ConnectionsData; + const { db, pgp, sshClient } = await configurePostgres(credentials, options); const schema = this.getNodeParameter('schema', 0, { extractValue: true, @@ -45,5 +50,10 @@ export async function tableSearch(this: ILoadOptionsFunctions): Promise { const credentials = await this.getCredentials('postgres'); const options = { nodeVersion: this.getNode().typeVersion }; - const { db } = (await Connections.getInstance(credentials, options)) as ConnectionsData; + const { db, pgp, sshClient } = await configurePostgres(credentials, options); const schema = this.getNodeParameter('schema', 0, { extractValue: true, @@ -27,6 +27,11 @@ export async function getColumns(this: ILoadOptionsFunctions): Promise Date: Thu, 18 May 2023 10:36:27 +0300 Subject: [PATCH 2/4] :zap: option to prevent warnings spam --- .../nodes/Postgres/v2/transport/index.ts | 39 +++---------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/packages/nodes-base/nodes/Postgres/v2/transport/index.ts b/packages/nodes-base/nodes/Postgres/v2/transport/index.ts index aaeb0b195ce6d..4fe375ceff233 100644 --- a/packages/nodes-base/nodes/Postgres/v2/transport/index.ts +++ b/packages/nodes-base/nodes/Postgres/v2/transport/index.ts @@ -45,7 +45,11 @@ export async function configurePostgres( options: IDataObject = {}, createdSshClient?: Client, ) { - const pgp = pgPromise(); + const pgp = pgPromise({ + // prevent spam in console "WARNING: Creating a duplicate database object for the same connection." + // duplicate connections created when auto loading parameters, they are closed imidiatly after, but several could be open at the same time + noWarnings: true, + }); if (typeof options.nodeVersion == 'number' && options.nodeVersion >= 2.1) { // Always return dates as ISO strings @@ -183,36 +187,3 @@ export async function configurePostgres( return { db, pgp, sshClient }; } } - -// export const Connections = (function () { -// let instance: { db: PgpDatabase; pgp: PgpClient; sshClient?: Client } | null = null; - -// return { -// async getInstance( -// credentials: IDataObject = {}, -// options: IDataObject = {}, -// reload = false, -// createdSshClient?: Client, -// nulify = false, -// ) { -// if (nulify) { -// instance = null; -// return instance; -// } - -// if (instance !== null && reload) { -// if (instance.sshClient) { -// instance.sshClient.end(); -// } -// instance.pgp.end(); - -// instance = null; -// } - -// if (instance === null && Object.keys(credentials).length) { -// instance = await configurePostgres(credentials, options, createdSshClient); -// } -// return instance; -// }, -// }; -// })(); From 9d5cf445876aa7edcd12909dbb33e05fd4ee67a5 Mon Sep 17 00:00:00 2001 From: Michael Kret Date: Fri, 19 May 2023 13:37:47 +0300 Subject: [PATCH 3/4] :zap: better errors messages --- .../v2/actions/database/update.operation.ts | 15 +++++++++++++++ .../v2/actions/database/upsert.operation.ts | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/nodes-base/nodes/Postgres/v2/actions/database/update.operation.ts b/packages/nodes-base/nodes/Postgres/v2/actions/database/update.operation.ts index be474904b6df9..f4bbd3c426295 100644 --- a/packages/nodes-base/nodes/Postgres/v2/actions/database/update.operation.ts +++ b/packages/nodes-base/nodes/Postgres/v2/actions/database/update.operation.ts @@ -1,5 +1,6 @@ import type { IExecuteFunctions } from 'n8n-core'; import type { IDataObject, INodeExecutionData, INodeProperties } from 'n8n-workflow'; +import { NodeOperationError } from 'n8n-workflow'; import { updateDisplayOptions } from '../../../../../utils/utilities'; @@ -181,6 +182,20 @@ export async function execute( valueToMatchOn = this.getNodeParameter('valueToMatchOn', i) as string; } + if (!item[columnToMatchOn]) { + throw new NodeOperationError( + this.getNode(), + "Column to match on not found in input item. Add a column to match on or set the 'Data Mode' to 'Define Below' to define the value to match on.", + ); + } + + if (item[columnToMatchOn] && Object.keys(item).length === 1) { + throw new NodeOperationError( + this.getNode(), + "Add values to update to the input item or set the 'Data Mode' to 'Define Below' to define the values to update.", + ); + } + const tableSchema = await getTableSchema(db, schema, table); item = checkItemAgainstSchema(this.getNode(), item, tableSchema, i); diff --git a/packages/nodes-base/nodes/Postgres/v2/actions/database/upsert.operation.ts b/packages/nodes-base/nodes/Postgres/v2/actions/database/upsert.operation.ts index 972f171d9cd0f..74c5ffe0584a7 100644 --- a/packages/nodes-base/nodes/Postgres/v2/actions/database/upsert.operation.ts +++ b/packages/nodes-base/nodes/Postgres/v2/actions/database/upsert.operation.ts @@ -1,5 +1,6 @@ import type { IExecuteFunctions } from 'n8n-core'; import type { IDataObject, INodeExecutionData, INodeProperties } from 'n8n-workflow'; +import { NodeOperationError } from 'n8n-workflow'; import { updateDisplayOptions } from '../../../../../utils/utilities'; @@ -179,6 +180,20 @@ export async function execute( item[columnToMatchOn] = this.getNodeParameter('valueToMatchOn', i) as string; } + if (!item[columnToMatchOn]) { + throw new NodeOperationError( + this.getNode(), + "Column to match on not found in input item. Add a column to match on or set the 'Data Mode' to 'Define Below' to define the value to match on.", + ); + } + + if (item[columnToMatchOn] && Object.keys(item).length === 1) { + throw new NodeOperationError( + this.getNode(), + "Add values to update or insert to the input item or set the 'Data Mode' to 'Define Below' to define the values to insert or update.", + ); + } + const tableSchema = await getTableSchema(db, schema, table); item = checkItemAgainstSchema(this.getNode(), item, tableSchema, i); From ccfe271713c83d0406b37ed16af7bf6296b64004 Mon Sep 17 00:00:00 2001 From: Michael Kret Date: Fri, 19 May 2023 14:18:28 +0300 Subject: [PATCH 4/4] :zap: fix update errors --- .../v2/actions/database/update.operation.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/nodes-base/nodes/Postgres/v2/actions/database/update.operation.ts b/packages/nodes-base/nodes/Postgres/v2/actions/database/update.operation.ts index f4bbd3c426295..94b7f42414930 100644 --- a/packages/nodes-base/nodes/Postgres/v2/actions/database/update.operation.ts +++ b/packages/nodes-base/nodes/Postgres/v2/actions/database/update.operation.ts @@ -182,20 +182,13 @@ export async function execute( valueToMatchOn = this.getNodeParameter('valueToMatchOn', i) as string; } - if (!item[columnToMatchOn]) { + if (!item[columnToMatchOn] && dataMode === 'autoMapInputData') { throw new NodeOperationError( this.getNode(), "Column to match on not found in input item. Add a column to match on or set the 'Data Mode' to 'Define Below' to define the value to match on.", ); } - if (item[columnToMatchOn] && Object.keys(item).length === 1) { - throw new NodeOperationError( - this.getNode(), - "Add values to update to the input item or set the 'Data Mode' to 'Define Below' to define the values to update.", - ); - } - const tableSchema = await getTableSchema(db, schema, table); item = checkItemAgainstSchema(this.getNode(), item, tableSchema, i); @@ -210,6 +203,13 @@ export async function execute( const updateColumns = Object.keys(item).filter((column) => column !== columnToMatchOn); + if (!Object.keys(updateColumns).length) { + throw new NodeOperationError( + this.getNode(), + "Add values to update to the input item or set the 'Data Mode' to 'Define Below' to define the values to update.", + ); + } + const updates: string[] = []; for (const column of updateColumns) {