Add type casting to postgres queries (#1600)

* 538 add support for casting types in postgres

* Add typing to postgres insert nodes and removed unnecessary field from crate db

* Added placeholder and description for types in postgres

* Adding tests to insert and changes suggested by Ben

*  Minor improvement

Co-authored-by: mutdmour <mutdmour@gmail.com>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
Omar Ajoue
2021-04-03 16:53:47 +02:00
committed by GitHub
parent 3b00c96643
commit f225bbbb84
5 changed files with 193 additions and 33 deletions

View File

@@ -829,7 +829,7 @@ export class HttpRequest implements INodeType {
// Add Content Type if any are set
if (options.bodyContentCustomMimeType) {
if(requestOptions.headers === undefined) {
if (requestOptions.headers === undefined) {
requestOptions.headers = {};
}
requestOptions.headers['Content-Type'] = options.bodyContentCustomMimeType;
@@ -929,7 +929,7 @@ export class HttpRequest implements INodeType {
if (property === 'body') {
continue;
}
returnItem[property] = response![property];
returnItem[property] = response![property];
}
newItem.json = returnItem;

View File

@@ -68,19 +68,22 @@ export async function pgInsert(
const schema = getNodeParam('schema', 0) as string;
let returnFields = (getNodeParam('returnFields', 0) as string).split(',') as string[];
const columnString = getNodeParam('columns', 0) as string;
const columns = columnString.split(',').map(column => column.trim());
const cs = new pgp.helpers.ColumnSet(columns);
const columns = columnString.split(',')
.map(column => column.trim().split(':'))
.map(([name, cast]) => ({ name, cast }));
const te = new pgp.helpers.TableName({ table, schema });
// Prepare the data to insert and copy it to be returned
const insertItems = getItemCopy(items, columns);
const columnNames = columns.map(column => column.name);
const insertItems = getItemCopy(items, columnNames);
const columnSet = new pgp.helpers.ColumnSet(columns);
// Generate the multi-row insert query and return the id of new row
returnFields = returnFields.map(value => value.trim()).filter(value => !!value);
const query =
pgp.helpers.insert(insertItems, cs, te) +
pgp.helpers.insert(insertItems, columnSet, te) +
(returnFields.length ? ` RETURNING ${returnFields.join(',')}` : '');
// Executing the query to insert the data
@@ -109,21 +112,36 @@ export async function pgUpdate(
const updateKey = getNodeParam('updateKey', 0) as string;
const columnString = getNodeParam('columns', 0) as string;
const columns = columnString.split(',').map(column => column.trim());
const [updateColumnName, updateColumnCast] = updateKey.split(':');
const updateColumn = {
name: updateColumnName,
cast: updateColumnCast,
};
const columns = columnString.split(',')
.map(column => column.trim().split(':'))
.map(([name, cast]) => ({ name, cast }));
const te = new pgp.helpers.TableName({ table, schema });
// Make sure that the updateKey does also get queried
if (!columns.includes(updateKey)) {
columns.unshift(updateKey);
const targetCol = columns.find((column) => column.name === updateColumn.name);
if (!targetCol) {
columns.unshift(updateColumn);
}
else if (!targetCol.cast) {
targetCol.cast = updateColumn.cast || targetCol.cast;
}
// Prepare the data to update and copy it to be returned
const updateItems = getItemCopy(items, columns);
const columnNames = columns.map(column => column.name);
const updateItems = getItemCopy(items, columnNames);
const columnSet = new pgp.helpers.ColumnSet(columns);
// Generate the multi-row update query
const query =
pgp.helpers.update(updateItems, columns, te) + ' WHERE v.' + updateKey + ' = t.' + updateKey;
pgp.helpers.update(updateItems, columnSet, te) + ' WHERE v.' + updateColumn.name + ' = t.' + updateColumn.name;
// Executing the query to update the data
await db.none(query);

View File

@@ -116,9 +116,9 @@ export class Postgres implements INodeType {
},
},
default: '',
placeholder: 'id,name,description',
placeholder: 'id:int,name:text,description',
description:
'Comma separated list of the properties which should used as columns for the new rows.',
'Comma separated list of the properties which should used as columns for the new rows.<br>You can use type casting with colons (:) like id:int.',
},
{
displayName: 'Return Fields',
@@ -186,9 +186,9 @@ export class Postgres implements INodeType {
},
},
default: '',
placeholder: 'name,description',
placeholder: 'name:text,description',
description:
'Comma separated list of the properties which should used as columns for rows to update.',
'Comma separated list of the properties which should used as columns for rows to update.<br>You can use type casting with colons (:) like id:int.',
},
],
};

View File

@@ -107,22 +107,6 @@ export class QuestDb implements INodeType {
required: true,
description: 'Name of the table in which to insert data to.',
},
{
displayName: 'Columns',
name: 'columns',
type: 'string',
displayOptions: {
show: {
operation: [
'insert',
],
},
},
default: '',
placeholder: 'id,name,description',
description:
'Comma separated list of the properties which should used as columns for the new rows.',
},
{
displayName: 'Return Fields',
name: 'returnFields',
@@ -194,7 +178,7 @@ export class QuestDb implements INodeType {
}).join(',');
const query = `INSERT INTO ${tableName} (${columns.join(',')}) VALUES (${values});`;
queries.push(query);
queries.push(query);
});
await db.any(pgp.helpers.concat(queries));