mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
fix(Postgres Node): Allow using composite key in upsert queries (#12639)
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <netroy@users.noreply.github.com>
This commit is contained in:
parent
982131a75a
commit
83ce3a9096
|
@ -1151,3 +1151,184 @@ describe('Test PostgresV2, upsert operation', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When matching on all columns', () => {
|
||||
it('dataMode: define, should call runQueries with', async () => {
|
||||
const nodeParameters: IDataObject = {
|
||||
operation: 'upsert',
|
||||
schema: {
|
||||
__rl: true,
|
||||
mode: 'list',
|
||||
value: 'public',
|
||||
},
|
||||
table: {
|
||||
__rl: true,
|
||||
value: 'my_table',
|
||||
mode: 'list',
|
||||
},
|
||||
columns: {
|
||||
matchingColumns: ['id', 'json', 'foo'],
|
||||
value: { id: '5', json: '{ "test": 5 }', foo: 'data 5' },
|
||||
mappingMode: 'defineBelow',
|
||||
},
|
||||
options: {
|
||||
outputColumns: ['json'],
|
||||
nodeVersion: 2.5,
|
||||
},
|
||||
};
|
||||
const columnsInfo: ColumnInfo[] = [
|
||||
{ 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 = [
|
||||
{
|
||||
json: {
|
||||
id: 1,
|
||||
json: {
|
||||
test: 15,
|
||||
},
|
||||
foo: 'data 1',
|
||||
},
|
||||
},
|
||||
];
|
||||
const nodeOptions = nodeParameters.options as IDataObject;
|
||||
|
||||
await upsert.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
runQueries,
|
||||
inputItems,
|
||||
nodeOptions,
|
||||
createMockDb(columnsInfo),
|
||||
);
|
||||
|
||||
expect(runQueries).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
query:
|
||||
'INSERT INTO $1:name.$2:name($6:name) VALUES($6:csv) ON CONFLICT ($3:name,$4:name,$5:name) DO NOTHING RETURNING $7:name',
|
||||
values: [
|
||||
'public',
|
||||
'my_table',
|
||||
'id',
|
||||
'json',
|
||||
'foo',
|
||||
{ id: '5', json: '{ "test": 5 }', foo: 'data 5' },
|
||||
['json'],
|
||||
],
|
||||
},
|
||||
],
|
||||
inputItems,
|
||||
nodeOptions,
|
||||
);
|
||||
});
|
||||
|
||||
it('dataMode: autoMapInputData, should call runQueries with', async () => {
|
||||
const nodeParameters: IDataObject = {
|
||||
operation: 'upsert',
|
||||
schema: {
|
||||
__rl: true,
|
||||
mode: 'list',
|
||||
value: 'public',
|
||||
},
|
||||
table: {
|
||||
__rl: true,
|
||||
value: 'my_table',
|
||||
mode: 'list',
|
||||
},
|
||||
columns: {
|
||||
matchingColumns: ['id', 'json', 'foo'],
|
||||
mappingMode: 'autoMapInputData',
|
||||
},
|
||||
options: { nodeVersion: 2.5 },
|
||||
};
|
||||
const columnsInfo: ColumnInfo[] = [
|
||||
{ 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 = [
|
||||
{
|
||||
json: {
|
||||
id: 1,
|
||||
json: {
|
||||
test: 15,
|
||||
},
|
||||
foo: 'data 1',
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {
|
||||
id: 2,
|
||||
json: {
|
||||
test: 10,
|
||||
},
|
||||
foo: 'data 2',
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {
|
||||
id: 3,
|
||||
json: {
|
||||
test: 5,
|
||||
},
|
||||
foo: 'data 3',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const nodeOptions = nodeParameters.options as IDataObject;
|
||||
|
||||
await upsert.execute.call(
|
||||
createMockExecuteFunction(nodeParameters),
|
||||
runQueries,
|
||||
inputItems,
|
||||
nodeOptions,
|
||||
createMockDb(columnsInfo),
|
||||
);
|
||||
|
||||
expect(runQueries).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
query:
|
||||
'INSERT INTO $1:name.$2:name($6:name) VALUES($6:csv) ON CONFLICT ($3:name,$4:name,$5:name) DO NOTHING RETURNING *',
|
||||
values: [
|
||||
'public',
|
||||
'my_table',
|
||||
'id',
|
||||
'json',
|
||||
'foo',
|
||||
{ id: 1, json: { test: 15 }, foo: 'data 1' },
|
||||
],
|
||||
},
|
||||
{
|
||||
query:
|
||||
'INSERT INTO $1:name.$2:name($6:name) VALUES($6:csv) ON CONFLICT ($3:name,$4:name,$5:name) DO NOTHING RETURNING *',
|
||||
values: [
|
||||
'public',
|
||||
'my_table',
|
||||
'id',
|
||||
'json',
|
||||
'foo',
|
||||
{ id: 2, json: { test: 10 }, foo: 'data 2' },
|
||||
],
|
||||
},
|
||||
{
|
||||
query:
|
||||
'INSERT INTO $1:name.$2:name($6:name) VALUES($6:csv) ON CONFLICT ($3:name,$4:name,$5:name) DO NOTHING RETURNING *',
|
||||
values: [
|
||||
'public',
|
||||
'my_table',
|
||||
'id',
|
||||
'json',
|
||||
'foo',
|
||||
{ id: 3, json: { test: 5 }, foo: 'data 3' },
|
||||
],
|
||||
},
|
||||
],
|
||||
inputItems,
|
||||
nodeOptions,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -285,7 +285,7 @@ export async function execute(
|
|||
valuesLength = valuesLength + 1;
|
||||
values.push(column);
|
||||
});
|
||||
const onConflict = ` ON CONFLICT (${conflictColumns.join(',')}) DO UPDATE `;
|
||||
const onConflict = ` ON CONFLICT (${conflictColumns.join(',')})`;
|
||||
|
||||
const insertQuery = `INSERT INTO $1:name.$2:name($${valuesLength}:name) VALUES($${valuesLength}:csv)${onConflict}`;
|
||||
valuesLength = valuesLength + 1;
|
||||
|
@ -300,7 +300,9 @@ export async function execute(
|
|||
values.push(column, item[column] as string);
|
||||
}
|
||||
|
||||
let query = `${insertQuery} SET ${updates.join(', ')}`;
|
||||
const updateQuery =
|
||||
updates?.length > 0 ? ` DO UPDATE SET ${updates.join(', ')}` : ' DO NOTHING ';
|
||||
let query = `${insertQuery}${updateQuery}`;
|
||||
|
||||
const outputColumns = this.getNodeParameter('options.outputColumns', i, ['*']) as string[];
|
||||
|
||||
|
|
Loading…
Reference in a new issue