diff --git a/integration-tests/__tests__/data-replicator.spec.js b/integration-tests/__tests__/data-replicator.spec.js index d9c089c85..95811ea49 100644 --- a/integration-tests/__tests__/data-replicator.spec.js +++ b/integration-tests/__tests__/data-replicator.spec.js @@ -303,4 +303,52 @@ describe('Data replicator', () => { }), 15 * 1000 ); + + test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))( + 'Skip columns for update - %s', + testWrapper(async (conn, driver, engine) => { + runCommandOnDriver(conn, driver, dmp => + dmp.createTable({ + pureName: 't1', + columns: [ + { columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true }, + { columnName: 'key', dataType: 'varchar(50)', notNull: true }, + { columnName: 'val', dataType: 'varchar(50)' }, + ], + primaryKey: { + columns: [{ columnName: 'id' }], + }, + }) + ); + + const getcfg = (v1 = 'v1') => ({ + systemConnection: conn, + driver, + items: [ + { + name: 't1', + matchColumns: ['key'], + skipUpdateColumns: ['val'], + findExisting: true, + updateExisting: true, + createNew: true, + jsonArray: [ + { key: '1', val: v1 }, + { key: '2', val: 'v2' }, + { key: '3', val: 'v3' }, + ], + }, + ], + }); + + await dataReplicator(getcfg('v1')); + + const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select ~val from ~t1 where ~key='1'`)); + expect(res1.rows[0].val).toEqual('v1'); + + await dataReplicator(getcfg('v2')); + const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select ~val from ~t1 where ~key='1'`)); + expect(res2.rows[0].val).toEqual('v1'); + }) + ); }); diff --git a/packages/api/src/shell/dataReplicator.js b/packages/api/src/shell/dataReplicator.js index cc97b1a7e..b84829376 100644 --- a/packages/api/src/shell/dataReplicator.js +++ b/packages/api/src/shell/dataReplicator.js @@ -64,6 +64,7 @@ async function dataReplicator({ createNew: compileOperationFunction(item.createNew, item.createCondition), updateExisting: compileOperationFunction(item.updateExisting, item.updateCondition), deleteMissing: !!item.deleteMissing, + skipUpdateColumns: item.skipUpdateColumns, deleteRestrictionColumns: item.deleteRestrictionColumns ?? [], openStream: item.openStream ? item.openStream diff --git a/packages/datalib/src/DataReplicator.ts b/packages/datalib/src/DataReplicator.ts index 668aee480..8b93e31ec 100644 --- a/packages/datalib/src/DataReplicator.ts +++ b/packages/datalib/src/DataReplicator.ts @@ -23,6 +23,7 @@ export interface DataReplicatorItem { deleteMissing: boolean; deleteRestrictionColumns: string[]; matchColumns: string[]; + skipUpdateColumns?: string[]; } export interface DataReplicatorOptions { @@ -151,7 +152,12 @@ class ReplicatorItemHolder { chunk, this.table.columns.map(x => x.columnName) ), - [this.autoColumn, ...this.backReferences.map(x => x.columnName), ...this.references.map(x => x.columnName)] + [ + this.autoColumn, + ...this.backReferences.map(x => x.columnName), + ...this.references.map(x => x.columnName), + ...(this.item.skipUpdateColumns || []), + ] ); return res;