Add query parameters for CrateDB, PostgresDB, TimescaleDB and QuestDB (Parametrized Queries) (#1577)

* Adding support to ParameterizedQuery on Postgres Node

* Created another parameter to toggle on replacement so it's clear to users what is happening.

* Fixed lint issues

*  Formatting

* Improvements to questDB node so it is more consistent

* Fixed lint issues

* Fixed typing issue

*  Apply suggestions BHesseldieck

Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>

* Standardized output for postgres and postgres-like nodes

This changes the behavior of CrateDB, Postgres, QuestDB and TimescaleDB
nodes.

The Execute Query operation used to execute multiple queries but return
the result from only one of the queries.

This change causes the node output to containt results from all queries
that ran, making the behavior more consistent across all n8n.

* Fixing lint issues

*  Minor improvements

*  Fix breaking changes files

Co-authored-by: Gustavo Arjones <gustavo.arjones@ank.app>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
Co-authored-by: Jan <janober@users.noreply.github.com>
Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
This commit is contained in:
Omar Ajoue
2021-05-01 00:35:34 +02:00
committed by GitHub
parent 4cf8055224
commit fc54f7c82b
6 changed files with 105 additions and 25 deletions

View File

@@ -60,27 +60,40 @@ export async function pgQuery(
getNodeParam: Function,
pgp: pgPromise.IMain<{}, pg.IClient>,
db: pgPromise.IDatabase<{}, pg.IClient>,
input: INodeExecutionData[],
items: INodeExecutionData[],
continueOnFail: boolean,
overrideMode?: string,
): Promise<IDataObject[]> {
const additionalFields = getNodeParam('additionalFields', 0) as IDataObject;
let valuesArray = [] as string[][];
if (additionalFields.queryParams) {
const propertiesString = additionalFields.queryParams as string;
const properties = propertiesString.split(',').map(column => column.trim());
const paramsItems = getItemsCopy(items, properties);
valuesArray = paramsItems.map((row) => properties.map(col => row[col])) as string[][];
}
const allQueries = [] as Array<{query: string, values?: string[]}>;
for (let i = 0; i < items.length; i++) {
const query = getNodeParam('query', i) as string;
const values = valuesArray[i];
const queryFormat = { query, values };
allQueries.push(queryFormat);
}
const mode = overrideMode ? overrideMode : (additionalFields.mode ?? 'multiple') as string;
if (mode === 'multiple') {
const queries: string[] = [];
for (let i = 0; i < input.length; i++) {
queries.push(getNodeParam('query', i) as string);
}
return (await db.multi(pgp.helpers.concat(queries))).flat(1);
return (await db.multi(pgp.helpers.concat(allQueries))).flat(1);
} else if (mode === 'transaction') {
return db.tx(async t => {
const result: IDataObject[] = [];
for (let i = 0; i < input.length; i++) {
for (let i = 0; i < allQueries.length; i++) {
try {
Array.prototype.push.apply(result, await t.any(getNodeParam('query', i) as string));
Array.prototype.push.apply(result, await t.any(allQueries[i].query, allQueries[i].values));
} catch (err) {
if (continueOnFail === false) throw err;
result.push({ ...input[i].json, code: err.code, message: err.message });
result.push({ ...items[i].json, code: err.code, message: err.message });
return result;
}
}
@@ -89,12 +102,12 @@ export async function pgQuery(
} else if (mode === 'independently') {
return db.task(async t => {
const result: IDataObject[] = [];
for (let i = 0; i < input.length; i++) {
for (let i = 0; i < allQueries.length; i++) {
try {
Array.prototype.push.apply(result, await t.any(getNodeParam('query', i) as string));
Array.prototype.push.apply(result, await t.any(allQueries[i].query, allQueries[i].values));
} catch (err) {
if (continueOnFail === false) throw err;
result.push({ ...input[i].json, code: err.code, message: err.message });
result.push({ ...items[i].json, code: err.code, message: err.message });
}
}
return result;