mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
used transaction for save table data
This commit is contained in:
parent
722789ca01
commit
e9a01a1ffd
@ -171,11 +171,11 @@ module.exports = {
|
||||
},
|
||||
|
||||
runScript_meta: true,
|
||||
async runScript({ conid, database, sql }, req) {
|
||||
async runScript({ conid, database, sql, useTransaction }, req) {
|
||||
testConnectionPermission(conid, req);
|
||||
logger.info({ conid, database, sql }, 'Processing script');
|
||||
const opened = await this.ensureOpened(conid, database);
|
||||
const res = await this.sendRequest(opened, { msgtype: 'runScript', sql });
|
||||
const res = await this.sendRequest(opened, { msgtype: 'runScript', sql, useTransaction });
|
||||
return res;
|
||||
},
|
||||
|
||||
|
@ -158,12 +158,12 @@ function resolveAnalysedPromises() {
|
||||
afterAnalyseCallbacks = [];
|
||||
}
|
||||
|
||||
async function handleRunScript({ msgid, sql }, skipReadonlyCheck = false) {
|
||||
async function handleRunScript({ msgid, sql, useTransaction }, skipReadonlyCheck = false) {
|
||||
await waitConnected();
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
try {
|
||||
if (!skipReadonlyCheck) ensureExecuteCustomScript(driver);
|
||||
await driver.script(systemConnection, sql);
|
||||
await driver.script(systemConnection, sql, { useTransaction });
|
||||
process.send({ msgtype: 'response', msgid });
|
||||
} catch (err) {
|
||||
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
|
||||
|
@ -533,6 +533,10 @@ export class SqlDumper implements AlterProcessor {
|
||||
this.putCmd('^commit');
|
||||
}
|
||||
|
||||
rollbackTransaction() {
|
||||
this.putCmd('^rollback');
|
||||
}
|
||||
|
||||
alterProlog() {}
|
||||
alterEpilog() {}
|
||||
|
||||
|
@ -2,6 +2,7 @@ import _compact from 'lodash/compact';
|
||||
import { SqlDumper } from './SqlDumper';
|
||||
import { splitQuery } from 'dbgate-query-splitter';
|
||||
import { dumpSqlSelect } from 'dbgate-sqltree';
|
||||
import { EngineDriver, RunScriptOptions } from 'dbgate-types';
|
||||
|
||||
const dialect = {
|
||||
limitSelect: true,
|
||||
@ -19,6 +20,12 @@ const dialect = {
|
||||
defaultSchemaName: null,
|
||||
};
|
||||
|
||||
export async function runCommandOnDriver(pool, driver: EngineDriver, cmd: (dmp: SqlDumper) => void) {
|
||||
const dmp = driver.createDumper();
|
||||
cmd(dmp as any);
|
||||
await driver.query(pool, dmp.s, { discardResult: true });
|
||||
}
|
||||
|
||||
export const driverBase = {
|
||||
analyserClass: null,
|
||||
dumperClass: SqlDumper,
|
||||
@ -41,12 +48,25 @@ export const driverBase = {
|
||||
const analyser = new this.analyserClass(pool, this, version);
|
||||
return analyser.incrementalAnalysis(structure);
|
||||
},
|
||||
createDumper(options = null) {
|
||||
createDumper(options = null): SqlDumper {
|
||||
return new this.dumperClass(this, options);
|
||||
},
|
||||
async script(pool, sql) {
|
||||
async script(pool, sql, options: RunScriptOptions) {
|
||||
if (options?.useTransaction) {
|
||||
runCommandOnDriver(pool, this, dmp => dmp.beginTransaction());
|
||||
}
|
||||
for (const sqlItem of splitQuery(sql, this.getQuerySplitterOptions('script'))) {
|
||||
await this.query(pool, sqlItem, { discardResult: true });
|
||||
try {
|
||||
await this.query(pool, sqlItem, { discardResult: true });
|
||||
} catch (err) {
|
||||
if (options?.useTransaction) {
|
||||
runCommandOnDriver(pool, this, dmp => dmp.rollbackTransaction());
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
if (options?.useTransaction) {
|
||||
runCommandOnDriver(pool, this, dmp => dmp.commitTransaction());
|
||||
}
|
||||
},
|
||||
getNewObjectTemplates() {
|
||||
@ -113,5 +133,5 @@ export const driverBase = {
|
||||
return this.readQuery(pool, dmp.s, structure);
|
||||
},
|
||||
showConnectionField: (field, values) => false,
|
||||
showConnectionTab: (field) => true,
|
||||
showConnectionTab: field => true,
|
||||
};
|
||||
|
6
packages/types/engines.d.ts
vendored
6
packages/types/engines.d.ts
vendored
@ -12,6 +12,10 @@ export interface StreamOptions {
|
||||
info?: (info) => void;
|
||||
}
|
||||
|
||||
export interface RunScriptOptions {
|
||||
useTransaction: boolean;
|
||||
}
|
||||
|
||||
export interface QueryOptions {
|
||||
discardResult?: boolean;
|
||||
}
|
||||
@ -130,7 +134,7 @@ export interface EngineDriver {
|
||||
createDatabase(pool: any, name: string): Promise;
|
||||
dropDatabase(pool: any, name: string): Promise;
|
||||
getQuerySplitterOptions(usage: 'stream' | 'script' | 'editor'): any;
|
||||
script(pool: any, sql: string): Promise;
|
||||
script(pool: any, sql: string, options?: RunScriptOptions): Promise;
|
||||
getNewObjectTemplates(): NewObjectTemplate[];
|
||||
// direct call of pool method, only some methods could be supported, on only some drivers
|
||||
callMethod(pool, method, args);
|
||||
|
@ -121,7 +121,7 @@
|
||||
const [changeSetStore, dispatchChangeSet] = createUndoReducer(createChangeSet());
|
||||
|
||||
async function handleConfirmSql(sql) {
|
||||
const resp = await apiCall('database-connections/run-script', { conid, database, sql });
|
||||
const resp = await apiCall('database-connections/run-script', { conid, database, sql, useTransaction: true });
|
||||
const { errorMessage } = resp || {};
|
||||
if (errorMessage) {
|
||||
showModal(ErrorMessageModal, { title: 'Error when saving', message: errorMessage });
|
||||
|
Loading…
Reference in New Issue
Block a user