fix(Postgres Node): Arrays in query replacement fix (#6718)

This commit is contained in:
Michael Kret 2023-07-25 15:34:45 +03:00 committed by GitHub
parent ed09e9c695
commit 4cae091cfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 30 deletions

View file

@ -1,4 +1,10 @@
import type { IDataObject, IExecuteFunctions, IGetNodeParameterOptions, INode } from 'n8n-workflow';
import type {
IDataObject,
IExecuteFunctions,
IGetNodeParameterOptions,
INode,
INodeParameters,
} from 'n8n-workflow';
import type { ColumnInfo, PgpDatabase, QueriesRunner } from '../../v2/helpers/interfaces';
@ -38,6 +44,7 @@ const createMockExecuteFunction = (nodeParameters: IDataObject) => {
return get(nodeParameters, parameter, fallbackValue);
},
getNode() {
node.parameters = { ...node.parameters, ...(nodeParameters as INodeParameters) };
return node;
},
} as unknown as IExecuteFunctions;
@ -252,9 +259,9 @@ describe('Test PostgresV2, insert operation', () => {
options: {},
};
const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' },
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
];
const nodeOptions = nodeParameters.options as IDataObject;
@ -295,9 +302,9 @@ describe('Test PostgresV2, insert operation', () => {
options: {},
};
const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' },
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
];
const inputItems = [
@ -505,9 +512,9 @@ describe('Test PostgresV2, update operation', () => {
},
};
const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' },
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
];
const nodeOptions = nodeParameters.options as IDataObject;
@ -561,9 +568,9 @@ describe('Test PostgresV2, update operation', () => {
options: {},
};
const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' },
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
];
const inputItems = [
@ -664,9 +671,9 @@ describe('Test PostgresV2, upsert operation', () => {
},
};
const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' },
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
];
const nodeOptions = nodeParameters.options as IDataObject;
@ -720,9 +727,9 @@ describe('Test PostgresV2, upsert operation', () => {
options: {},
};
const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' },
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
];
const inputItems = [

View file

@ -61,22 +61,44 @@ export async function execute(
query = query.replace(resolvable, this.evaluateExpression(resolvable, i) as string);
}
let values: IDataObject[] = [];
let values: Array<IDataObject | string> = [];
let queryReplacement = this.getNodeParameter('options.queryReplacement', i, '');
const queryReplacement = this.getNodeParameter('options.queryReplacement', i, '');
if (typeof queryReplacement === 'string') {
queryReplacement = queryReplacement.split(',').map((entry) => entry.trim());
}
const node = this.getNode();
if (Array.isArray(queryReplacement)) {
values = queryReplacement as IDataObject[];
const rawReplacements = (node.parameters.options as IDataObject)?.queryReplacement as string;
if (rawReplacements) {
const rawValues = rawReplacements
.replace(/^=+/, '')
.split(',')
.filter((entry) => entry)
.map((entry) => entry.trim());
for (const rawValue of rawValues) {
const resolvables = getResolvables(rawValue);
if (resolvables.length) {
for (const resolvable of resolvables) {
values.push(this.evaluateExpression(`${resolvable}`, i) as IDataObject);
}
} else {
values.push(rawValue);
}
}
}
} else {
throw new NodeOperationError(
this.getNode(),
'Query Replacement must be a string of comma-separated values, or an array of values',
{ itemIndex: i },
);
if (Array.isArray(queryReplacement)) {
values = queryReplacement as IDataObject[];
} else {
throw new NodeOperationError(
this.getNode(),
'Query Parameters must be a string of comma-separated values or an array of values',
{ itemIndex: i },
);
}
}
queries.push({ query, values });