Files
cloudbeaver/webapp/packages/plugin-connection-custom/src/CustomConnection/ConnectionFormDialog/ConnectionFormDialogController.ts
T

197 lines
5.8 KiB
TypeScript

/*
* cloudbeaver - Cloud Database Manager
* Copyright (C) 2020 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { observable, action } from 'mobx';
import { DBDriver, DatabaseAuthModelsResource } from '@cloudbeaver/core-connections';
import { injectable, IInitializableController, IDestructibleController } from '@cloudbeaver/core-di';
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
import { NotificationService } from '@cloudbeaver/core-events';
import { ErrorDetailsDialog } from '@cloudbeaver/core-notifications';
import { ConnectionConfig, GQLErrorCatcher, DatabaseAuthModel } from '@cloudbeaver/core-sdk';
import { CustomConnectionService } from '../../CustomConnectionService';
export enum ConnectionType {
Attributes,
URL
}
@injectable()
export class ConnectionFormDialogController
implements IInitializableController, IDestructibleController {
@observable connectionType = ConnectionType.Attributes;
@observable isLoading = true;
@observable isConnecting = false;
@observable driver!: DBDriver;
@observable authModel?: DatabaseAuthModel;
@observable config: ConnectionConfig = {
name: '',
driverId: '',
host: '',
port: '',
databaseName: '',
url: '',
properties: {},
credentials: {},
saveCredentials: false,
};
readonly error = new GQLErrorCatcher();
private onClose!: () => void;
private isDistructed = false;
constructor(
private customConnectionService: CustomConnectionService,
private notificationService: NotificationService,
private commonDialogService: CommonDialogService,
private dbAuthModelsResource: DatabaseAuthModelsResource
) { }
init(driver: DBDriver, onClose: () => void) {
this.driver = driver;
this.onClose = onClose;
this.loadDatabaseAuthModel();
this.setDriverDefaults();
}
destruct(): void {
this.isDistructed = true;
}
onChangeType = (type: ConnectionType) => {
this.connectionType = type;
};
onChange = (property: keyof ConnectionConfig, value: any) => {
this.config[property] = value;
};
onTestConnection = async () => {
this.isConnecting = true;
this.error.clear();
try {
await this.customConnectionService.testConnectionAsync(this.getConnectionConfig());
this.notificationService.logSuccess({ title: 'Connection is established' });
} catch (exception) {
this.notificationService.logException(exception, 'connections_connection_test_fail');
} finally {
this.isConnecting = false;
}
};
onCreateConnection = async () => {
this.isConnecting = true;
this.error.clear();
try {
const connection = await this.customConnectionService.createConnectionAsync(this.getConnectionConfig());
this.notificationService.logSuccess({ title: `Connection ${connection.name} created` });
this.onClose();
} catch (exception) {
this.notificationService.logException(exception, 'connections_connection_create_fail');
} finally {
this.isConnecting = false;
}
};
onShowDetails = () => {
if (this.error.exception) {
this.commonDialogService.open(ErrorDetailsDialog, this.error.exception);
}
};
private getConnectionConfig(): ConnectionConfig {
const config: ConnectionConfig = {};
config.name = this.config.name;
config.driverId = this.config.driverId;
if (this.connectionType === ConnectionType.Attributes) {
config.name = this.config.databaseName;
if (!this.driver?.embedded) {
config.host = this.config.host;
config.port = this.config.port;
config.name += `@${this.config.host}`;
}
config.databaseName = this.config.databaseName;
} else {
config.name = this.urlToConnectionName(this.config.name, this.config.url);
config.url = this.config.url;
}
if (this.authModel) {
config.authModelId = this.config.authModelId;
config.credentials = this.config.credentials;
config.saveCredentials = this.config.saveCredentials;
}
if (Object.keys(this.config.properties).length > 0) {
config.properties = this.config.properties;
}
return config;
}
@action
private setDriverDefaults() {
this.config.name = `${this.driver.name} (custom)`;
this.config.driverId = this.driver.id;
this.config.host = this.driver.defaultServer || 'localhost';
this.config.port = this.driver.defaultPort || '';
this.config.databaseName = this.driver.defaultDatabase;
this.config.url = this.driver.sampleURL || '';
this.config.properties = {};
this.config.authModelId = this.driver.defaultAuthModel;
this.config.credentials = {};
}
/**
* Creates connection name based on connection url
* @param defaultName default connection name if url parsing failed
* @param url connection url
*/
private urlToConnectionName(defaultName?: string, url?: string) {
let name = defaultName;
if (!url) {
return name;
}
const matches = /^.*:\/\/(.*?)(:.*?|)(\/(.*)?|)$/.exec(url);
if (!matches) {
return name;
}
name = matches[1];
if (matches[4]) {
name += `@${matches[4]}`;
}
return name;
}
private showError(exception: Error, message: string) {
if (!this.error.catch(exception) || this.isDistructed) {
this.notificationService.logException(exception, message);
}
}
private async loadDatabaseAuthModel() {
if (!this.driver || this.driver.anonymousAccess) {
this.isLoading = false;
return;
}
try {
this.authModel = await this.dbAuthModelsResource.load(this.driver.defaultAuthModel);
} catch (exception) {
this.notificationService.logException(exception, 'Can\'t load driver auth model');
} finally {
this.isLoading = false;
}
}
}