From aeb5a1234aa610b333525512085fe3b3bd60abef Mon Sep 17 00:00:00 2001 From: pemontto <939704+pemontto@users.noreply.github.com> Date: Sat, 23 Apr 2022 02:15:55 +1000 Subject: [PATCH] feat(Google Sheets Node): Add upsert support (#2733) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ Add upsert support for Google Sheets * :zap: updated description * :zap: updated display name and description * :zap: Order resources alphabetically Co-authored-by: Michael Kret Co-authored-by: ricardo --- .../nodes/Google/Sheet/GoogleSheet.ts | 21 ++++++++++++++++--- .../nodes/Google/Sheet/GoogleSheets.node.ts | 18 +++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/nodes-base/nodes/Google/Sheet/GoogleSheet.ts b/packages/nodes-base/nodes/Google/Sheet/GoogleSheet.ts index 28d35d5af..d7ff16ef3 100644 --- a/packages/nodes-base/nodes/Google/Sheet/GoogleSheet.ts +++ b/packages/nodes-base/nodes/Google/Sheet/GoogleSheet.ts @@ -268,7 +268,16 @@ export class GoogleSheet { * @returns {Promise} * @memberof GoogleSheet */ - async updateSheetData(inputData: IDataObject[], indexKey: string, range: string, keyRowIndex: number, dataStartRowIndex: number, valueInputMode: ValueInputOption, valueRenderMode: ValueRenderOption): Promise { + async updateSheetData( + inputData: IDataObject[], + indexKey: string, + range: string, + keyRowIndex: number, + dataStartRowIndex: number, + valueInputMode: ValueInputOption, + valueRenderMode: ValueRenderOption, + upsert = false, + ): Promise { // Get current data in Google Sheet let rangeStart: string, rangeEnd: string, rangeFull: string; let sheet: string | undefined = undefined; @@ -333,14 +342,20 @@ export class GoogleSheet { itemKey = inputItem[indexKey] as string; // if ([undefined, null].includes(inputItem[indexKey] as string | undefined | null)) { if (itemKey === undefined || itemKey === null) { - // Item does not have the indexKey so we can ignore it + // Item does not have the indexKey so we can ignore it or append it if upsert true + if (upsert) { + const data = await this.appendSheetData([inputItem], this.encodeRange(range), keyRowIndex, valueInputMode); + } continue; } // Item does have the key so check if it exists in Sheet itemKeyIndex = keyColumnIndexLookup.indexOf(itemKey as string); if (itemKeyIndex === -1) { - // Key does not exist in the Sheet so it can not be updated so skip it + // Key does not exist in the Sheet so it can not be updated so skip it or append it if upsert true + if (upsert) { + const data = await this.appendSheetData([inputItem], this.encodeRange(range), keyRowIndex, valueInputMode); + } continue; } diff --git a/packages/nodes-base/nodes/Google/Sheet/GoogleSheets.node.ts b/packages/nodes-base/nodes/Google/Sheet/GoogleSheets.node.ts index eaa1782af..5736a56b3 100644 --- a/packages/nodes-base/nodes/Google/Sheet/GoogleSheets.node.ts +++ b/packages/nodes-base/nodes/Google/Sheet/GoogleSheets.node.ts @@ -133,6 +133,11 @@ export class GoogleSheets implements INodeType { value: 'create', description: 'Create a new sheet', }, + { + name: 'Create or Update', + value: 'upsert', + description: 'Create a new record, or update the current one if it already exists', + }, { name: 'Delete', value: 'delete', @@ -363,6 +368,7 @@ export class GoogleSheets implements INodeType { ], operation: [ 'update', + 'upsert', ], }, }, @@ -381,6 +387,7 @@ export class GoogleSheets implements INodeType { ], operation: [ 'update', + 'upsert', ], rawData: [ true, @@ -512,6 +519,7 @@ export class GoogleSheets implements INodeType { ], operation: [ 'update', + 'upsert', ], rawData: [ false, @@ -537,6 +545,7 @@ export class GoogleSheets implements INodeType { 'lookup', 'read', 'update', + 'upsert', ], }, }, @@ -579,6 +588,7 @@ export class GoogleSheets implements INodeType { '/operation': [ 'append', 'update', + 'upsert', ], }, }, @@ -637,6 +647,7 @@ export class GoogleSheets implements INodeType { show: { '/operation': [ 'update', + 'upsert', ], '/rawData': [ false, @@ -1293,10 +1304,11 @@ export class GoogleSheets implements INodeType { } return [this.helpers.returnJsonArray(returnData)]; - } else if (operation === 'update') { + } else if (operation === 'update' || operation === 'upsert') { // ---------------------------------- - // update + // update/upsert // ---------------------------------- + const upsert = operation === 'upsert' ? true : false; try { const rawData = this.getNodeParameter('rawData', 0) as boolean; @@ -1324,7 +1336,7 @@ export class GoogleSheets implements INodeType { setData.push(item.json); }); - const data = await sheet.updateSheetData(setData, keyName, range, keyRow, dataStartRow, valueInputMode, valueRenderMode); + const data = await sheet.updateSheetData(setData, keyName, range, keyRow, dataStartRow, valueInputMode, valueRenderMode, upsert); } // TODO: Should add this data somewhere // TODO: Should have something like add metadata which does not get passed through