(core) Fix import bug when skipping non-text columns

Summary:
Skipping columns during incremental imports wasn't working for certain
column types, such as numeric columns. The column's default value was
being used instead (e.g. 0), overwriting values in the destination
table.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Subscribers: alexmojaki

Differential Revision: https://phab.getgrist.com/D3402
This commit is contained in:
George Gevoian
2022-04-28 08:43:31 -07:00
parent dc9e53edc8
commit ad04744b4a
3 changed files with 83 additions and 43 deletions

View File

@@ -137,8 +137,7 @@ export class ActiveDocImport {
mergeCols = stripPrefixes(mergeCols);
// Get column differences between `hiddenTableId` and `destTableId` for rows that exist in both tables.
const srcAndDestColIds: [string, string[]][] =
destCols.map(c => [c.colId!, [c.colId!.slice(IMPORT_TRANSFORM_COLUMN_PREFIX.length)]]);
const srcAndDestColIds: [string, string[]][] = destCols.map(c => [c.colId!, stripPrefixes([c.colId!])]);
const srcToDestColIds = new Map(srcAndDestColIds);
const comparisonResult = await this._getTableComparison(hiddenTableId, destTableId!, srcToDestColIds, mergeCols);
@@ -153,6 +152,11 @@ export class ActiveDocImport {
// Retrieve the function used to reconcile differences between source and destination.
const merge = getMergeFunction(mergeStrategy);
// Destination columns with a blank formula (i.e. skipped columns).
const skippedColumnIds = new Set(
stripPrefixes(destCols.filter(c => c.formula.trim() === '').map(c => c.colId!))
);
const numResultRows = comparisonResult[hiddenTableId + '.id'].length;
for (let i = 0; i < numResultRows; i++) {
const srcRowId = comparisonResult[hiddenTableId + '.id'][i] as number;
@@ -172,7 +176,12 @@ export class ActiveDocImport {
// Exclude unchanged cell values from the comparison.
if (srcVal === destVal) { continue; }
updatedRecords[srcColId][srcRowId] = [[destVal], [merge(srcVal, destVal)]];
const shouldSkip = skippedColumnIds.has(matchingDestColId);
updatedRecords[srcColId][srcRowId] = [
[destVal],
// For skipped columns, always use the destination value.
[shouldSkip ? destVal : merge(srcVal, destVal)]
];
}
}
@@ -419,7 +428,9 @@ export class ActiveDocImport {
const columnData: BulkColValues = {};
const srcColIds = srcCols.map(c => c.id as string);
const destCols = transformRule.destCols;
// Only include destination columns that weren't skipped.
const destCols = transformRule.destCols.filter(c => c.formula.trim() !== '');
for (const destCol of destCols) {
const formula = destCol.formula.trim();
if (!formula) { continue; }
@@ -487,6 +498,16 @@ export class ActiveDocImport {
const updatedRecords: BulkColValues = {};
const updatedRecordIds: number[] = [];
// Destination columns with a blank formula (i.e. skipped columns).
const skippedColumnIds = new Set(
stripPrefixes(destCols.filter(c => c.formula.trim() === '').map(c => c.colId!))
);
// Remove all skipped columns from the map.
srcToDestColIds.forEach((destColIds, srcColId) => {
srcToDestColIds.set(srcColId, destColIds.filter(id => !skippedColumnIds.has(id)));
});
const destColIds = flatten([...srcToDestColIds.values()]);
for (const id of destColIds) {
newRecords[id] = [];