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..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 @@ -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,13 @@ export async function execute( valueToMatchOn = this.getNodeParameter('valueToMatchOn', i) as string; } + 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.", + ); + } + const tableSchema = await getTableSchema(db, schema, table); item = checkItemAgainstSchema(this.getNode(), item, tableSchema, i); @@ -195,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) { 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); 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= 2.1) { // Always return dates as ISO strings @@ -183,36 +187,3 @@ 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; - }, - }; -})();