mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-18 20:46:01 +00:00
111 lines
3.1 KiB
TypeScript
111 lines
3.1 KiB
TypeScript
import _ from 'lodash';
|
|
import uuidv1 from 'uuid/v1';
|
|
import uuidv4 from 'uuid/v4';
|
|
import moment from 'moment';
|
|
import { MacroDefinition, MacroSelectedCell } from './MacroDefinition';
|
|
import { ChangeSet, setChangeSetValue, setChangeSetRowData } from './ChangeSet';
|
|
import { GridDisplay } from './GridDisplay';
|
|
|
|
const getMacroFunction = {
|
|
transformValue: code => `
|
|
(value, args, modules, rowIndex, row, columnName) => {
|
|
${code}
|
|
}
|
|
`,
|
|
transformRow: code => `
|
|
(row, args, modules, rowIndex, columns) => {
|
|
${code}
|
|
}
|
|
`,
|
|
};
|
|
|
|
const modules = {
|
|
lodash: _,
|
|
uuidv1,
|
|
uuidv4,
|
|
moment,
|
|
};
|
|
|
|
export function compileMacroFunction(macro: MacroDefinition, errors = []) {
|
|
if (!macro) return null;
|
|
let func;
|
|
try {
|
|
func = eval(getMacroFunction[macro.type](macro.code));
|
|
return func;
|
|
} catch (err) {
|
|
errors.push(`Error compiling macro ${macro.name}: ${err.message}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function runMacroOnValue(compiledFunc, macroArgs, value, rowIndex: number, row, column: string, errors = []) {
|
|
if (!compiledFunc) return value;
|
|
try {
|
|
const res = compiledFunc(value, macroArgs, modules, rowIndex, row, column);
|
|
return res;
|
|
} catch (err) {
|
|
errors.push(`Error processing column ${column} on row ${rowIndex}: ${err.message}`);
|
|
return value;
|
|
}
|
|
}
|
|
|
|
export function runMacroOnRow(compiledFunc, macroArgs, rowIndex: number, row: any, columns: string[], errors = []) {
|
|
if (!compiledFunc) return row;
|
|
try {
|
|
const res = compiledFunc(row, macroArgs, modules, rowIndex, columns);
|
|
return res;
|
|
} catch (err) {
|
|
errors.push(`Error processing row ${rowIndex}: ${err.message}`);
|
|
return row;
|
|
}
|
|
}
|
|
|
|
export function runMacroOnChangeSet(
|
|
macro: MacroDefinition,
|
|
macroArgs: {},
|
|
selectedCells: MacroSelectedCell[],
|
|
changeSet: ChangeSet,
|
|
display: GridDisplay,
|
|
useRowIndexInsteaOfCondition: boolean
|
|
): ChangeSet {
|
|
const errors = [];
|
|
const compiledMacroFunc = compileMacroFunction(macro, errors);
|
|
if (!compiledMacroFunc) return null;
|
|
|
|
if (macro.type == 'transformValue') {
|
|
let res = changeSet;
|
|
for (const cell of selectedCells) {
|
|
const definition = display.getChangeSetField(
|
|
cell.rowData,
|
|
cell.column,
|
|
undefined,
|
|
useRowIndexInsteaOfCondition ? cell.row : undefined,
|
|
useRowIndexInsteaOfCondition
|
|
);
|
|
const macroResult = runMacroOnValue(
|
|
compiledMacroFunc,
|
|
macroArgs,
|
|
cell.value,
|
|
cell.row,
|
|
cell.rowData,
|
|
cell.column,
|
|
errors
|
|
);
|
|
res = setChangeSetValue(res, definition, macroResult);
|
|
}
|
|
return res;
|
|
}
|
|
if (macro.type == 'transformRow') {
|
|
let res = changeSet;
|
|
const rowIndexes = _.uniq(selectedCells.map(x => x.row));
|
|
for (const index of rowIndexes) {
|
|
const rowData = selectedCells.find(x => x.row == index)?.rowData;
|
|
const columns = _.uniq(selectedCells.map(x => x.column));
|
|
const definition = display.getChangeSetRow(rowData, null, index, true);
|
|
const newRow = runMacroOnRow(compiledMacroFunc, macroArgs, index, rowData, columns);
|
|
res = setChangeSetRowData(res, definition, newRow);
|
|
}
|
|
return res;
|
|
}
|
|
}
|