mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-26 06:26:00 +00:00
introduced dbhandle instead of overwriting 3rd party client's fields
This commit is contained in:
@@ -11,7 +11,7 @@ const { dumpSqlSelect } = require('dbgate-sqltree');
|
||||
|
||||
const logger = getLogger('dbconnProcess');
|
||||
|
||||
let systemConnection;
|
||||
let dbhan;
|
||||
let storedConnection;
|
||||
let afterConnectCallbacks = [];
|
||||
let afterAnalyseCallbacks = [];
|
||||
@@ -49,7 +49,7 @@ async function handleFullRefresh() {
|
||||
loadingModel = true;
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
setStatusName('loadStructure');
|
||||
analysedStructure = await checkedAsyncCall(driver.analyseFull(systemConnection, serverVersion));
|
||||
analysedStructure = await checkedAsyncCall(driver.analyseFull(dbhan, serverVersion));
|
||||
analysedTime = new Date().getTime();
|
||||
process.send({ msgtype: 'structure', structure: analysedStructure });
|
||||
process.send({ msgtype: 'structureTime', analysedTime });
|
||||
@@ -64,7 +64,7 @@ async function handleIncrementalRefresh(forceSend) {
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
setStatusName('checkStructure');
|
||||
const newStructure = await checkedAsyncCall(
|
||||
driver.analyseIncremental(systemConnection, analysedStructure, serverVersion)
|
||||
driver.analyseIncremental(dbhan, analysedStructure, serverVersion)
|
||||
);
|
||||
analysedTime = new Date().getTime();
|
||||
if (newStructure != null) {
|
||||
@@ -103,7 +103,7 @@ function setStatusName(name) {
|
||||
|
||||
async function readVersion() {
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
const version = await driver.getVersion(systemConnection);
|
||||
const version = await driver.getVersion(dbhan);
|
||||
process.send({ msgtype: 'version', version });
|
||||
serverVersion = version;
|
||||
}
|
||||
@@ -114,8 +114,8 @@ async function handleConnect({ connection, structure, globalSettings }) {
|
||||
|
||||
if (!structure) setStatusName('pending');
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
systemConnection = await checkedAsyncCall(connectUtility(driver, storedConnection, 'app'));
|
||||
systemConnection.feedback = feedback => setStatus({ feedback });
|
||||
dbhan = await checkedAsyncCall(connectUtility(driver, storedConnection, 'app'));
|
||||
dbhan.feedback = feedback => setStatus({ feedback });
|
||||
await checkedAsyncCall(readVersion());
|
||||
if (structure) {
|
||||
analysedStructure = structure;
|
||||
@@ -138,7 +138,7 @@ async function handleConnect({ connection, structure, globalSettings }) {
|
||||
}
|
||||
|
||||
function waitConnected() {
|
||||
if (systemConnection) return Promise.resolve();
|
||||
if (dbhan) return Promise.resolve();
|
||||
return new Promise((resolve, reject) => {
|
||||
afterConnectCallbacks.push([resolve, reject]);
|
||||
});
|
||||
@@ -163,7 +163,7 @@ async function handleRunScript({ msgid, sql, useTransaction }, skipReadonlyCheck
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
try {
|
||||
if (!skipReadonlyCheck) ensureExecuteCustomScript(driver);
|
||||
await driver.script(systemConnection, sql, { useTransaction });
|
||||
await driver.script(dbhan, sql, { useTransaction });
|
||||
process.send({ msgtype: 'response', msgid });
|
||||
} catch (err) {
|
||||
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
|
||||
@@ -175,7 +175,7 @@ async function handleRunOperation({ msgid, operation, useTransaction }, skipRead
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
try {
|
||||
if (!skipReadonlyCheck) ensureExecuteCustomScript(driver);
|
||||
await driver.operation(systemConnection, operation, { useTransaction });
|
||||
await driver.operation(dbhan, operation, { useTransaction });
|
||||
process.send({ msgtype: 'response', msgid });
|
||||
} catch (err) {
|
||||
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
|
||||
@@ -188,7 +188,7 @@ async function handleQueryData({ msgid, sql }, skipReadonlyCheck = false) {
|
||||
try {
|
||||
if (!skipReadonlyCheck) ensureExecuteCustomScript(driver);
|
||||
// console.log(sql);
|
||||
const res = await driver.query(systemConnection, sql);
|
||||
const res = await driver.query(dbhan, sql);
|
||||
process.send({ msgtype: 'response', msgid, ...res });
|
||||
} catch (err) {
|
||||
process.send({ msgtype: 'response', msgid, errorMessage: err.message || 'Error executing SQL script' });
|
||||
@@ -214,23 +214,23 @@ async function handleDriverDataCore(msgid, callMethod) {
|
||||
}
|
||||
|
||||
async function handleSchemaList({ msgid }) {
|
||||
return handleDriverDataCore(msgid, driver => driver.listSchemas(systemConnection));
|
||||
return handleDriverDataCore(msgid, driver => driver.listSchemas(dbhan));
|
||||
}
|
||||
|
||||
async function handleCollectionData({ msgid, options }) {
|
||||
return handleDriverDataCore(msgid, driver => driver.readCollection(systemConnection, options));
|
||||
return handleDriverDataCore(msgid, driver => driver.readCollection(dbhan, options));
|
||||
}
|
||||
|
||||
async function handleLoadKeys({ msgid, root, filter }) {
|
||||
return handleDriverDataCore(msgid, driver => driver.loadKeys(systemConnection, root, filter));
|
||||
return handleDriverDataCore(msgid, driver => driver.loadKeys(dbhan, root, filter));
|
||||
}
|
||||
|
||||
async function handleExportKeys({ msgid, options }) {
|
||||
return handleDriverDataCore(msgid, driver => driver.exportKeys(systemConnection, options));
|
||||
return handleDriverDataCore(msgid, driver => driver.exportKeys(dbhan, options));
|
||||
}
|
||||
|
||||
async function handleLoadKeyInfo({ msgid, key }) {
|
||||
return handleDriverDataCore(msgid, driver => driver.loadKeyInfo(systemConnection, key));
|
||||
return handleDriverDataCore(msgid, driver => driver.loadKeyInfo(dbhan, key));
|
||||
}
|
||||
|
||||
async function handleCallMethod({ msgid, method, args }) {
|
||||
@@ -240,17 +240,17 @@ async function handleCallMethod({ msgid, method, args }) {
|
||||
}
|
||||
|
||||
ensureExecuteCustomScript(driver);
|
||||
return driver.callMethod(systemConnection, method, args);
|
||||
return driver.callMethod(dbhan, method, args);
|
||||
});
|
||||
}
|
||||
|
||||
async function handleLoadKeyTableRange({ msgid, key, cursor, count }) {
|
||||
return handleDriverDataCore(msgid, driver => driver.loadKeyTableRange(systemConnection, key, cursor, count));
|
||||
return handleDriverDataCore(msgid, driver => driver.loadKeyTableRange(dbhan, key, cursor, count));
|
||||
}
|
||||
|
||||
async function handleLoadFieldValues({ msgid, schemaName, pureName, field, search }) {
|
||||
return handleDriverDataCore(msgid, driver =>
|
||||
driver.loadFieldValues(systemConnection, { schemaName, pureName }, field, search)
|
||||
driver.loadFieldValues(dbhan, { schemaName, pureName }, field, search)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ async function handleUpdateCollection({ msgid, changeSet }) {
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
try {
|
||||
ensureExecuteCustomScript(driver);
|
||||
const result = await driver.updateCollection(systemConnection, changeSet);
|
||||
const result = await driver.updateCollection(dbhan, changeSet);
|
||||
process.send({ msgtype: 'response', msgid, result });
|
||||
} catch (err) {
|
||||
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
|
||||
@@ -281,7 +281,7 @@ async function handleSqlPreview({ msgid, objects, options }) {
|
||||
|
||||
try {
|
||||
const dmp = driver.createDumper();
|
||||
const generator = new SqlGenerator(analysedStructure, options, objects, dmp, driver, systemConnection);
|
||||
const generator = new SqlGenerator(analysedStructure, options, objects, dmp, driver, dbhan);
|
||||
|
||||
await generator.dump();
|
||||
process.send({ msgtype: 'response', msgid, sql: dmp.s, isTruncated: generator.isTruncated });
|
||||
@@ -301,7 +301,7 @@ async function handleGenerateDeploySql({ msgid, modelFolder }) {
|
||||
|
||||
try {
|
||||
const res = await generateDeploySql({
|
||||
systemConnection,
|
||||
systemConnection: dbhan,
|
||||
connection: storedConnection,
|
||||
analysedStructure,
|
||||
modelFolder,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DatabaseInfo, DatabaseModification, EngineDriver, SqlDialect } from 'dbgate-types';
|
||||
import { DatabaseHandle, DatabaseInfo, DatabaseModification, EngineDriver, SqlDialect } from 'dbgate-types';
|
||||
import _sortBy from 'lodash/sortBy';
|
||||
import _groupBy from 'lodash/groupBy';
|
||||
import _pick from 'lodash/pick';
|
||||
@@ -40,7 +40,7 @@ export class DatabaseAnalyser {
|
||||
dialect: SqlDialect;
|
||||
logger: Logger;
|
||||
|
||||
constructor(public pool, public driver: EngineDriver, version) {
|
||||
constructor(public dbhan: DatabaseHandle, public driver: EngineDriver, version) {
|
||||
this.dialect = (driver?.dialectByVersion && driver?.dialectByVersion(version)) || driver?.dialect;
|
||||
this.logger = logger;
|
||||
}
|
||||
@@ -242,8 +242,8 @@ export class DatabaseAnalyser {
|
||||
}
|
||||
|
||||
feedback(obj) {
|
||||
if (this.pool.feedback) {
|
||||
this.pool.feedback(obj);
|
||||
if (this.dbhan.feedback) {
|
||||
this.dbhan.feedback(obj);
|
||||
}
|
||||
if (obj && obj.analysingMessage) {
|
||||
logger.debug(obj.analysingMessage);
|
||||
@@ -318,7 +318,7 @@ export class DatabaseAnalyser {
|
||||
};
|
||||
}
|
||||
try {
|
||||
const res = await this.driver.query(this.pool, sql);
|
||||
const res = await this.driver.query(this.dbhan, sql);
|
||||
this.logger.debug({ rows: res.rows.length, template }, `Loaded analyser query`);
|
||||
return res;
|
||||
} catch (err) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { prepareTableForImport } from './tableTransforms';
|
||||
|
||||
const logger = getLogger('bulkStreamBase');
|
||||
|
||||
export function createBulkInsertStreamBase(driver: EngineDriver, stream, pool, name, options: WriteTableOptions): any {
|
||||
export function createBulkInsertStreamBase(driver: EngineDriver, stream, dbhan, name, options: WriteTableOptions): any {
|
||||
const fullNameQuoted = name.schemaName
|
||||
? `${driver.dialect.quoteIdentifier(name.schemaName)}.${driver.dialect.quoteIdentifier(name.pureName)}`
|
||||
: driver.dialect.quoteIdentifier(name.pureName);
|
||||
@@ -29,22 +29,22 @@ export function createBulkInsertStreamBase(driver: EngineDriver, stream, pool, n
|
||||
};
|
||||
|
||||
writable.checkStructure = async () => {
|
||||
let structure = await driver.analyseSingleTable(pool, name);
|
||||
let structure = await driver.analyseSingleTable(dbhan, name);
|
||||
// console.log('ANALYSING', name, structure);
|
||||
if (structure && options.dropIfExists) {
|
||||
logger.info(`Dropping table ${fullNameQuoted}`);
|
||||
await driver.script(pool, `DROP TABLE ${fullNameQuoted}`);
|
||||
await driver.script(dbhan, `DROP TABLE ${fullNameQuoted}`);
|
||||
}
|
||||
if (options.createIfNotExists && (!structure || options.dropIfExists)) {
|
||||
const dmp = driver.createDumper();
|
||||
const createdTableInfo = driver.adaptTableInfo(prepareTableForImport({ ...writable.structure, ...name }));
|
||||
dmp.createTable(createdTableInfo);
|
||||
logger.info({ sql: dmp.s }, `Creating table ${fullNameQuoted}`);
|
||||
await driver.script(pool, dmp.s);
|
||||
structure = await driver.analyseSingleTable(pool, name);
|
||||
await driver.script(dbhan, dmp.s);
|
||||
structure = await driver.analyseSingleTable(dbhan, name);
|
||||
}
|
||||
if (options.truncate) {
|
||||
await driver.script(pool, `TRUNCATE TABLE ${fullNameQuoted}`);
|
||||
await driver.script(dbhan, `TRUNCATE TABLE ${fullNameQuoted}`);
|
||||
}
|
||||
|
||||
writable.columnNames = _intersection(
|
||||
@@ -74,7 +74,7 @@ export function createBulkInsertStreamBase(driver: EngineDriver, stream, pool, n
|
||||
dmp.putRaw(';');
|
||||
// require('fs').writeFileSync('/home/jena/test.sql', dmp.s);
|
||||
// console.log(dmp.s);
|
||||
await driver.query(pool, dmp.s, { discardResult: true });
|
||||
await driver.query(dbhan, dmp.s, { discardResult: true });
|
||||
} else {
|
||||
for (const row of rows) {
|
||||
const dmp = driver.createDumper();
|
||||
@@ -85,13 +85,13 @@ export function createBulkInsertStreamBase(driver: EngineDriver, stream, pool, n
|
||||
dmp.putRaw('(');
|
||||
dmp.putCollection(',', writable.columnNames, col => dmp.putValue(row[col as string]));
|
||||
dmp.putRaw(')');
|
||||
await driver.query(pool, dmp.s, { discardResult: true });
|
||||
await driver.query(dbhan, dmp.s, { discardResult: true });
|
||||
}
|
||||
}
|
||||
if (options.commitAfterInsert) {
|
||||
const dmp = driver.createDumper();
|
||||
dmp.commitTransaction();
|
||||
await driver.query(pool, dmp.s, { discardResult: true });
|
||||
await driver.query(dbhan, dmp.s, { discardResult: true });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
73
packages/types/engines.d.ts
vendored
73
packages/types/engines.d.ts
vendored
@@ -130,6 +130,15 @@ export interface FilterBehaviourProvider {
|
||||
getFilterBehaviour(dataType: string, standardFilterBehaviours: { [id: string]: FilterBehaviour }): FilterBehaviour;
|
||||
}
|
||||
|
||||
export interface DatabaseHandle {
|
||||
client: any;
|
||||
database?: string;
|
||||
feedback?: (message: any) => void;
|
||||
getDatabase?: () => any;
|
||||
connectionType?: string;
|
||||
treeKeySeparator?: string;
|
||||
}
|
||||
|
||||
export interface EngineDriver extends FilterBehaviourProvider {
|
||||
engine: string;
|
||||
title: string;
|
||||
@@ -171,52 +180,52 @@ export interface EngineDriver extends FilterBehaviourProvider {
|
||||
defaultSocketPath?: string;
|
||||
authTypeLabel?: string;
|
||||
importExportArgs?: any[];
|
||||
connect({ server, port, user, password, database }): Promise<any>;
|
||||
close(pool): Promise<any>;
|
||||
query(pool: any, sql: string, options?: QueryOptions): Promise<QueryResult>;
|
||||
stream(pool: any, sql: string, options: StreamOptions);
|
||||
readQuery(pool: any, sql: string, structure?: TableInfo): Promise<stream.Readable>;
|
||||
readJsonQuery(pool: any, query: any, structure?: TableInfo): Promise<stream.Readable>;
|
||||
writeTable(pool: any, name: NamedObjectInfo, options: WriteTableOptions): Promise<stream.Writable>;
|
||||
connect({ server, port, user, password, database }): Promise<DatabaseHandle>;
|
||||
close(dbhan: DatabaseHandle): Promise<any>;
|
||||
query(dbhan: DatabaseHandle, sql: string, options?: QueryOptions): Promise<QueryResult>;
|
||||
stream(dbhan: DatabaseHandle, sql: string, options: StreamOptions);
|
||||
readQuery(dbhan: DatabaseHandle, sql: string, structure?: TableInfo): Promise<stream.Readable>;
|
||||
readJsonQuery(dbhan: DatabaseHandle, query: any, structure?: TableInfo): Promise<stream.Readable>;
|
||||
writeTable(dbhan: DatabaseHandle, name: NamedObjectInfo, options: WriteTableOptions): Promise<stream.Writable>;
|
||||
analyseSingleObject(
|
||||
pool: any,
|
||||
dbhan: DatabaseHandle,
|
||||
name: NamedObjectInfo,
|
||||
objectTypeField: keyof DatabaseInfo
|
||||
): Promise<TableInfo | ViewInfo | ProcedureInfo | FunctionInfo | TriggerInfo>;
|
||||
analyseSingleTable(pool: any, name: NamedObjectInfo): Promise<TableInfo>;
|
||||
getVersion(pool: any): Promise<{ version: string }>;
|
||||
listDatabases(pool: any): Promise<
|
||||
analyseSingleTable(dbhan: DatabaseHandle, name: NamedObjectInfo): Promise<TableInfo>;
|
||||
getVersion(dbhan: DatabaseHandle): Promise<{ version: string }>;
|
||||
listDatabases(dbhan: DatabaseHandle): Promise<
|
||||
{
|
||||
name: string;
|
||||
}[]
|
||||
>;
|
||||
loadKeys(pool, root: string, filter?: string): Promise;
|
||||
exportKeys(pool, options: {}): Promise;
|
||||
loadKeyInfo(pool, key): Promise;
|
||||
loadKeyTableRange(pool, key, cursor, count): Promise;
|
||||
loadFieldValues(pool: any, name: NamedObjectInfo, field: string, search: string): Promise;
|
||||
analyseFull(pool: any, serverVersion): Promise<DatabaseInfo>;
|
||||
analyseIncremental(pool: any, structure: DatabaseInfo, serverVersion): Promise<DatabaseInfo>;
|
||||
loadKeys(dbhan: DatabaseHandle, root: string, filter?: string): Promise;
|
||||
exportKeys(dbhan: DatabaseHandle, options: {}): Promise;
|
||||
loadKeyInfo(dbhan: DatabaseHandle, key): Promise;
|
||||
loadKeyTableRange(dbhan: DatabaseHandle, key, cursor, count): Promise;
|
||||
loadFieldValues(dbhan: DatabaseHandle, name: NamedObjectInfo, field: string, search: string): Promise;
|
||||
analyseFull(dbhan: DatabaseHandle, serverVersion): Promise<DatabaseInfo>;
|
||||
analyseIncremental(dbhan: DatabaseHandle, structure: DatabaseInfo, serverVersion): Promise<DatabaseInfo>;
|
||||
dialect: SqlDialect;
|
||||
dialectByVersion(version): SqlDialect;
|
||||
createDumper(options = null): SqlDumper;
|
||||
createBackupDumper(pool: any, options): Promise<SqlBackupDumper>;
|
||||
createBackupDumper(dbhan: DatabaseHandle, options): Promise<SqlBackupDumper>;
|
||||
getAuthTypes(): EngineAuthType[];
|
||||
readCollection(pool: any, options: ReadCollectionOptions): Promise<any>;
|
||||
updateCollection(pool: any, changeSet: any): Promise<any>;
|
||||
readCollection(dbhan: DatabaseHandle, options: ReadCollectionOptions): Promise<any>;
|
||||
updateCollection(dbhan: DatabaseHandle, changeSet: any): Promise<any>;
|
||||
getCollectionUpdateScript(changeSet: any, collectionInfo: CollectionInfo): string;
|
||||
createDatabase(pool: any, name: string): Promise;
|
||||
dropDatabase(pool: any, name: string): Promise;
|
||||
createDatabase(dbhan: DatabaseHandle, name: string): Promise;
|
||||
dropDatabase(dbhan: DatabaseHandle, name: string): Promise;
|
||||
getQuerySplitterOptions(usage: 'stream' | 'script' | 'editor'): any;
|
||||
script(pool: any, sql: string, options?: RunScriptOptions): Promise;
|
||||
operation(pool: any, operation: {}, options?: RunScriptOptions): Promise;
|
||||
script(dbhan: DatabaseHandle, sql: string, options?: RunScriptOptions): Promise;
|
||||
operation(dbhan: DatabaseHandle, operation: {}, options?: RunScriptOptions): Promise;
|
||||
getNewObjectTemplates(): NewObjectTemplate[];
|
||||
// direct call of pool method, only some methods could be supported, on only some drivers
|
||||
callMethod(pool, method, args);
|
||||
serverSummary(pool): Promise<ServerSummary>;
|
||||
summaryCommand(pool, command, row): Promise<void>;
|
||||
startProfiler(pool, options): Promise<any>;
|
||||
stopProfiler(pool, profiler): Promise<void>;
|
||||
// direct call of dbhan.client method, only some methods could be supported, on only some drivers
|
||||
callMethod(dbhan: DatabaseHandle, method, args);
|
||||
serverSummary(dbhan: DatabaseHandle): Promise<ServerSummary>;
|
||||
summaryCommand(dbhan: DatabaseHandle, command, row): Promise<void>;
|
||||
startProfiler(dbhan: DatabaseHandle, options): Promise<any>;
|
||||
stopProfiler(dbhan: DatabaseHandle, profiler): Promise<void>;
|
||||
getRedirectAuthUrl(connection, options): Promise<{ url: string; sid: string }>;
|
||||
getAuthTokenFromCode(connection, options): Promise<string>;
|
||||
getAccessTokenFromAuth(connection, req): Promise<string | null>;
|
||||
@@ -231,7 +240,7 @@ export interface EngineDriver extends FilterBehaviourProvider {
|
||||
): any[];
|
||||
// adapts table info from different source (import, other database) to be suitable for this database
|
||||
adaptTableInfo(table: TableInfo): TableInfo;
|
||||
async listSchemas(pool): SchemaInfo[];
|
||||
listSchemas(dbhan: DatabaseHandle): SchemaInfo[];
|
||||
|
||||
analyserClass?: any;
|
||||
dumperClass?: any;
|
||||
|
||||
Reference in New Issue
Block a user