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

feat(Postgres Node): Options keepAlive and keepAliveInitialDelayMillis #9067

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 17 additions & 0 deletions packages/nodes-base/nodes/Postgres/PostgresTrigger.functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ export async function pgTriggerFunction(

export async function initDB(this: ITriggerFunctions | ILoadOptionsFunctions) {
const credentials = await this.getCredentials('postgres');
const options = this.getNodeParameter('options', {}) as {
connectionTimeout?: number;
delayClosingIdleConnection?: number;
keepAlive?: boolean;
};
const pgp = pgPromise({
// prevent spam in console "WARNING: Creating a duplicate database object for the same connection."
noWarnings: true,
Expand All @@ -99,6 +104,18 @@ export async function initDB(this: ITriggerFunctions | ILoadOptionsFunctions) {
password: credentials.password as string,
};

if (options.connectionTimeout) {
config.connectionTimeoutMillis = options.connectionTimeout * 1000;
}

if (options.keepAlive) {
config.keepAlive = options.keepAlive;
}

if (options.delayClosingIdleConnection) {
config.keepAliveInitialDelayMillis = options.delayClosingIdleConnection * 1000;
}

if (credentials.allowUnauthorizedCerts === true) {
config.ssl = {
rejectUnauthorized: false,
Expand Down
34 changes: 34 additions & 0 deletions packages/nodes-base/nodes/Postgres/PostgresTrigger.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,40 @@ export class PostgresTrigger implements INodeType {
},
],
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Option',
default: {},
options: [
{
displayName: 'Connection Timeout',
name: 'connectionTimeout',
type: 'number',
default: 30,
description: 'Number of seconds reserved for connecting to the database',
},
{
displayName: 'Delay Closing Idle Connection',
name: 'delayClosingIdleConnection',
type: 'number',
default: 0,
description:
'Number of seconds to wait before idle connection would be eligible for closing',
typeOptions: {
minValue: 0,
},
},
{
netroy marked this conversation as resolved.
Show resolved Hide resolved
displayName: 'Keep Alive',
name: 'keepAlive',
type: 'boolean',
default: false,
description: 'Whether to keep the connection alive',
},
],
},
],
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,23 @@ export const optionsCollection: INodeProperties = {
default: 30,
description: 'Number of seconds reserved for connecting to the database',
},
{
displayName: 'Delay Closing Idle Connection',
name: 'delayClosingIdleConnection',
type: 'number',
default: 0,
description: 'Number of seconds to wait before idle connection would be eligible for closing',
typeOptions: {
minValue: 0,
},
},
{
displayName: 'Keep Alive',
name: 'keepAlive',
type: 'boolean',
default: false,
description: 'Whether to keep the connection alive',
},
{
displayName: 'Query Batching',
name: 'queryBatching',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { NodeOperationError } from 'n8n-workflow';

import type {
PgpDatabase,
PostgresNodeOptions,
QueriesRunner,
QueryValues,
QueryWithValues,
Expand Down Expand Up @@ -95,7 +96,7 @@ export async function execute(
this: IExecuteFunctions,
runQueries: QueriesRunner,
items: INodeExecutionData[],
nodeOptions: IDataObject,
nodeOptions: PostgresNodeOptions,
netroy marked this conversation as resolved.
Show resolved Hide resolved
_db?: PgpDatabase,
): Promise<INodeExecutionData[]> {
const queries: QueryWithValues[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import type {
} from 'n8n-workflow';
import { NodeOperationError } from 'n8n-workflow';

import type { PgpDatabase, QueriesRunner, QueryWithValues } from '../../helpers/interfaces';
import type {
PgpDatabase,
PostgresNodeOptions,
QueriesRunner,
QueryWithValues,
} from '../../helpers/interfaces';

import { replaceEmptyStringsByNulls } from '../../helpers/utils';

Expand Down Expand Up @@ -46,7 +51,7 @@ export async function execute(
this: IExecuteFunctions,
runQueries: QueriesRunner,
items: INodeExecutionData[],
nodeOptions: IDataObject,
nodeOptions: PostgresNodeOptions,
_db?: PgpDatabase,
): Promise<INodeExecutionData[]> {
items = replaceEmptyStringsByNulls(items, nodeOptions.replaceEmptyStrings as boolean);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {

import type {
PgpDatabase,
PostgresNodeOptions,
QueriesRunner,
QueryValues,
QueryWithValues,
Expand Down Expand Up @@ -157,7 +158,7 @@ export async function execute(
this: IExecuteFunctions,
runQueries: QueriesRunner,
items: INodeExecutionData[],
nodeOptions: IDataObject,
nodeOptions: PostgresNodeOptions,
db: PgpDatabase,
): Promise<INodeExecutionData[]> {
items = replaceEmptyStringsByNulls(items, nodeOptions.replaceEmptyStrings as boolean);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {

import type {
PgpDatabase,
PostgresNodeOptions,
QueriesRunner,
QueryValues,
QueryWithValues,
Expand Down Expand Up @@ -75,7 +76,7 @@ export async function execute(
this: IExecuteFunctions,
runQueries: QueriesRunner,
items: INodeExecutionData[],
nodeOptions: IDataObject,
nodeOptions: PostgresNodeOptions,
_db?: PgpDatabase,
): Promise<INodeExecutionData[]> {
items = replaceEmptyStringsByNulls(items, nodeOptions.replaceEmptyStrings as boolean);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { NodeOperationError } from 'n8n-workflow';

import type {
PgpDatabase,
PostgresNodeOptions,
QueriesRunner,
QueryValues,
QueryWithValues,
Expand Down Expand Up @@ -194,7 +195,7 @@ export async function execute(
this: IExecuteFunctions,
runQueries: QueriesRunner,
items: INodeExecutionData[],
nodeOptions: IDataObject,
nodeOptions: PostgresNodeOptions,
db: PgpDatabase,
): Promise<INodeExecutionData[]> {
items = replaceEmptyStringsByNulls(items, nodeOptions.replaceEmptyStrings as boolean);
Expand Down Expand Up @@ -279,7 +280,7 @@ export async function execute(
const rowExists = await doesRowExist(db, schema, table, matchValues);
if (!rowExists) {
const descriptionValues: string[] = [];
matchValues.forEach((val, index) => {
matchValues.forEach((_, index) => {
if (index % 2 === 0) {
descriptionValues.push(`${matchValues[index]}=${matchValues[index + 1]}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { NodeOperationError } from 'n8n-workflow';

import type {
PgpDatabase,
PostgresNodeOptions,
QueriesRunner,
QueryValues,
QueryWithValues,
Expand Down Expand Up @@ -193,7 +194,7 @@ export async function execute(
this: IExecuteFunctions,
runQueries: QueriesRunner,
items: INodeExecutionData[],
nodeOptions: IDataObject,
nodeOptions: PostgresNodeOptions,
db: PgpDatabase,
): Promise<INodeExecutionData[]> {
items = replaceEmptyStringsByNulls(items, nodeOptions.replaceEmptyStrings as boolean);
Expand Down
5 changes: 3 additions & 2 deletions packages/nodes-base/nodes/Postgres/v2/actions/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { configureQueryRunner } from '../helpers/utils';
import type { PostgresType } from './node.type';

import * as database from './database/Database.resource';
import type { PostgresNodeCredentials, PostgresNodeOptions } from '../helpers/interfaces';

export async function router(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
let returnData: INodeExecutionData[] = [];
Expand All @@ -14,8 +15,8 @@ export async function router(this: IExecuteFunctions): Promise<INodeExecutionDat
const resource = this.getNodeParameter<PostgresType>('resource', 0);
const operation = this.getNodeParameter('operation', 0);

const credentials = await this.getCredentials('postgres');
const options = this.getNodeParameter('options', 0, {});
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const options = this.getNodeParameter('options', 0, {}) as PostgresNodeOptions;
options.nodeVersion = this.getNode().typeVersion;
options.operation = operation;

Expand Down
34 changes: 34 additions & 0 deletions packages/nodes-base/nodes/Postgres/v2/helpers/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,37 @@ export type QueriesRunner = (
items: INodeExecutionData[],
options: IDataObject,
) => Promise<INodeExecutionData[]>;

export type PostgresNodeOptions = {
nodeVersion?: number;
operation?: string;
cascade?: boolean;
connectionTimeout?: number;
delayClosingIdleConnection?: number;
keepAlive?: boolean;
queryBatching?: QueryMode;
queryReplacement?: string;
outputColumns?: string[];
largeNumbersOutput?: 'numbers' | 'text';
skipOnConflict?: boolean;
replaceEmptyStrings?: boolean;
};

export type PostgresNodeCredentials = {
sshAuthenticateWith: 'password' | 'privateKey';
host: string;
port: number;
database: string;
user: string;
password: string;
allowUnauthorizedCerts?: boolean;
ssl?: 'disable' | 'allow' | 'require' | 'verify' | 'verify-full';
sshTunnel?: boolean;
sshHost?: string;
sshPort?: number;
sshPostgresPort?: number;
sshUser?: string;
sshPassword?: string;
privateKey?: string;
passphrase?: string;
};
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import type {
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
INodeCredentialTestResult,
} from 'n8n-workflow';

import { Client } from 'ssh2';
import { configurePostgres } from '../transport';

import type { PgpClient } from '../helpers/interfaces';
import type { PgpClient, PostgresNodeCredentials } from '../helpers/interfaces';

export async function postgresConnectionTest(
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> {
const credentials = credential.data as IDataObject;
const credentials = credential.data as PostgresNodeCredentials;

let sshClientCreated: Client | undefined = new Client();
let pgpClientCreated: PgpClient | undefined;
Expand Down
5 changes: 3 additions & 2 deletions packages/nodes-base/nodes/Postgres/v2/methods/listSearch.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow';

import { configurePostgres } from '../transport';
import type { PostgresNodeCredentials } from '../helpers/interfaces';

export async function schemaSearch(this: ILoadOptionsFunctions): Promise<INodeListSearchResult> {
const credentials = await this.getCredentials('postgres');
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const options = { nodeVersion: this.getNode().typeVersion };

const { db, sshClient } = await configurePostgres(credentials, options);
Expand All @@ -27,7 +28,7 @@ export async function schemaSearch(this: ILoadOptionsFunctions): Promise<INodeLi
}
}
export async function tableSearch(this: ILoadOptionsFunctions): Promise<INodeListSearchResult> {
const credentials = await this.getCredentials('postgres');
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const options = { nodeVersion: this.getNode().typeVersion };

const { db, sshClient } = await configurePostgres(credentials, options);
Expand Down
3 changes: 2 additions & 1 deletion packages/nodes-base/nodes/Postgres/v2/methods/loadOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import type { ILoadOptionsFunctions, INodePropertyOptions } from 'n8n-workflow';

import { getTableSchema } from '../helpers/utils';
import { configurePostgres } from '../transport';
import type { PostgresNodeCredentials } from '../helpers/interfaces';

export async function getColumns(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const credentials = await this.getCredentials('postgres');
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;
const options = { nodeVersion: this.getNode().typeVersion };

const { db, sshClient } = await configurePostgres(credentials, options);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ILoadOptionsFunctions, ResourceMapperFields, FieldType } from 'n8n-workflow';
import { getEnumValues, getEnums, getTableSchema, uniqueColumns } from '../helpers/utils';
import { configurePostgres } from '../transport';
import type { PostgresNodeCredentials } from '../helpers/interfaces';

const fieldTypeMapping: Partial<Record<FieldType, string[]>> = {
string: ['text', 'varchar', 'character varying', 'character', 'char'],
Expand Down Expand Up @@ -45,7 +46,7 @@ function mapPostgresType(postgresType: string): FieldType {
export async function getMappingColumns(
this: ILoadOptionsFunctions,
): Promise<ResourceMapperFields> {
const credentials = await this.getCredentials('postgres');
const credentials = (await this.getCredentials('postgres')) as PostgresNodeCredentials;

const { db, sshClient } = await configurePostgres(credentials);

Expand Down
Loading
Loading