Skip to content

Commit 2ae9aaa

Browse files
Merge pull request #76 from JarvusInnovations/features/patch-existing
feat: add --patch-existing option to CLI upsert
2 parents 14bd636 + 4ef3f64 commit 2ae9aaa

File tree

4 files changed

+8636
-30
lines changed

4 files changed

+8636
-30
lines changed

backend/commands/upsert.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const fs = require('fs');
22
const TOML = require('@iarna/toml');
33
const { parse: csvParse } = require('fast-csv');
4+
const deepmerge = require('deepmerge');
45

56
const inputFormats = {
67
json: readJsonFile,
@@ -46,6 +47,11 @@ exports.builder = {
4647
type: 'boolean',
4748
default: false,
4849
},
50+
'patch-existing': {
51+
describe: 'For existing records, patch in provided values so that additional properties not included in the input are preserved',
52+
type: 'boolean',
53+
default: false,
54+
},
4955
};
5056

5157
exports.handler = async function upsert({
@@ -57,6 +63,7 @@ exports.handler = async function upsert({
5763
encoding,
5864
attachments = null,
5965
deleteMissing,
66+
patchExisting,
6067
...argv
6168
}) {
6269
const logger = require('../lib/logger.js');
@@ -96,7 +103,13 @@ exports.handler = async function upsert({
96103

97104

98105
// clear sheet
106+
let inputSheet = sheet;
107+
99108
if (deleteMissing) {
109+
// re-open input sheet
110+
inputSheet = await sheet.clone();
111+
112+
// clear target sheet
100113
await sheet.clear();
101114
}
102115

@@ -113,8 +126,28 @@ exports.handler = async function upsert({
113126

114127

115128
// upsert record(s) into sheet
116-
for await (const inputRecord of inputRecords) {
117-
const { blob: outputBlob, path: outputPath } = await sheet.upsert(inputRecord);
129+
for await (let inputRecord of inputRecords) {
130+
131+
if (patchExisting) {
132+
// TODO: move more of this logic inside Sheet class
133+
134+
// fetch existing record from inputSheet
135+
const inputRecordPath = await inputSheet.pathForRecord(await inputSheet.normalizeRecord(inputRecord));
136+
137+
if (inputRecordPath) {
138+
const { root: inputSheetRoot } = await inputSheet.getCachedConfig();
139+
140+
// existing record find, merge
141+
const existingBlob = await inputSheet.dataTree.getChild(`${path.join(inputSheetRoot, inputRecordPath)}.toml`);
142+
143+
if (existingBlob) {
144+
const existingRecord = await inputSheet.readRecord(existingBlob);
145+
inputRecord = deepmerge(inputRecord, existingRecord);
146+
}
147+
}
148+
}
149+
150+
const { blob: outputBlob, path: outputPath } = await sheet.upsert(inputRecord, { patchExisting });
118151
console.log(`${outputBlob.hash}\t${outputPath}`);
119152

120153
if (attachments) {

backend/lib/Sheet.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,15 @@ class Sheet extends Configurable
277277
return this.dataTree.writeChild(root, this.dataTree.repo.createTree());
278278
}
279279

280+
async clone () {
281+
return new Sheet({
282+
workspace: this.workspace,
283+
name: this.name,
284+
dataTree: await this.dataTree.clone(),
285+
configPath: this.configPath,
286+
});
287+
}
288+
280289
async upsert (record) {
281290
const {
282291
root: sheetRoot,

0 commit comments

Comments
 (0)