From 8ae64a9dcfff5f5d1c140ea025f1966bd2da3e78 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 1 Dec 2025 11:06:18 +0100 Subject: [PATCH] restore script - update --- packages/sqltree/src/dumpSqlExpression.ts | 7 ++ packages/sqltree/src/types.ts | 8 +- .../web/src/utility/tableRestoreScript.ts | 82 +++++++++++++++---- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/packages/sqltree/src/dumpSqlExpression.ts b/packages/sqltree/src/dumpSqlExpression.ts index aeaf3b288..f9447f792 100644 --- a/packages/sqltree/src/dumpSqlExpression.ts +++ b/packages/sqltree/src/dumpSqlExpression.ts @@ -2,6 +2,7 @@ import _ from 'lodash'; import type { SqlDumper } from 'dbgate-types'; import { Expression, ColumnRefExpression } from './types'; import { dumpSqlSourceRef } from './dumpSqlSource'; +import { dumpSqlSelect } from './dumpSqlCommand'; export function dumpSqlExpression(dmp: SqlDumper, expr: Expression) { switch (expr.exprType) { @@ -67,5 +68,11 @@ export function dumpSqlExpression(dmp: SqlDumper, expr: Expression) { }); dmp.put(')'); break; + + case 'select': + dmp.put('('); + dumpSqlSelect(dmp, expr.select); + dmp.put(')'); + break; } } diff --git a/packages/sqltree/src/types.ts b/packages/sqltree/src/types.ts index 493745059..ea7c5c994 100644 --- a/packages/sqltree/src/types.ts +++ b/packages/sqltree/src/types.ts @@ -227,6 +227,11 @@ export interface RowNumberExpression { orderBy: OrderByExpression[]; } +export interface SelectExpression { + exprType: 'select'; + select: Select; +} + export type Expression = | ColumnRefExpression | ValueExpression @@ -236,7 +241,8 @@ export type Expression = | CallExpression | MethodCallExpression | TranformExpression - | RowNumberExpression; + | RowNumberExpression + | SelectExpression; export type OrderByExpression = Expression & { direction: 'ASC' | 'DESC' }; export type ResultField = Expression & { alias?: string }; diff --git a/packages/web/src/utility/tableRestoreScript.ts b/packages/web/src/utility/tableRestoreScript.ts index ba0b9ea89..6d9d6fd1e 100644 --- a/packages/web/src/utility/tableRestoreScript.ts +++ b/packages/web/src/utility/tableRestoreScript.ts @@ -1,5 +1,5 @@ -import _ from 'lodash'; -import { dumpSqlInsert, Insert } from 'dbgate-sqltree'; +import _, { cond } from 'lodash'; +import { Condition, dumpSqlInsert, dumpSqlUpdate, Insert, Update } from 'dbgate-sqltree'; import { TableInfo, SqlDumper } from 'dbgate-types'; export function createTableRestoreScript(backupTable: TableInfo, originalTable: TableInfo, dmp: SqlDumper) { @@ -11,6 +11,69 @@ export function createTableRestoreScript(backupTable: TableInfo, originalTable: originalTable.primaryKey?.columns?.map(x => x.columnName) || [], backupTable.columns.map(x => x.columnName) ); + const valueColumns = _.difference(bothColumns, keyColumns); + + function makeColumnCond(colName: string, operator: '=' | '<>' | '<' | '>' | '<=' | '>=' = '='): Condition { + return { + conditionType: 'binary', + operator, + left: { + exprType: 'column', + columnName: colName, + source: { name: originalTable }, + }, + right: { + exprType: 'column', + columnName: colName, + source: { alias: 'bak' }, + }, + }; + } + + const update: Update = { + commandType: 'update', + from: { name: originalTable }, + fields: valueColumns.map(colName => ({ + exprType: 'select', + select: { + commandType: 'select', + from: { name: backupTable, alias: 'bak' }, + columns: [ + { + exprType: 'column', + columnName: colName, + source: { alias: 'bak' }, + }, + ], + where: { + conditionType: 'and', + conditions: keyColumns.map(colName => makeColumnCond(colName)), + }, + }, + targetColumn: colName, + })), + where: { + conditionType: 'exists', + subQuery: { + commandType: 'select', + from: { name: backupTable, alias: 'bak' }, + selectAll: true, + where: { + conditionType: 'and', + conditions: [ + ...keyColumns.map(keyColName => makeColumnCond(keyColName)), + { + conditionType: 'or', + conditions: valueColumns.map(colName => makeColumnCond(colName, '<>')), + }, + ], + }, + }, + }, + }; + dumpSqlUpdate(dmp, update); + dmp.endCommand(); + const insert: Insert = { commandType: 'insert', targetTable: originalTable, @@ -23,20 +86,7 @@ export function createTableRestoreScript(backupTable: TableInfo, originalTable: whereNotExistsSource: { name: backupTable, alias: 'bak' }, insertWhereNotExistsCondition: { conditionType: 'and', - conditions: keyColumns.map(colName => ({ - conditionType: 'binary', - operator: '=', - left: { - exprType: 'column', - columnName: colName, - source: { name: originalTable }, - }, - right: { - exprType: 'column', - columnName: colName, - source: { alias: 'bak' }, - }, - })), + conditions: keyColumns.map(colName => makeColumnCond(colName)), }, };